Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
9615371
refactor(plugin): share workbench migration SQL
mldangelo-oai Oct 6, 2026
ef79022
refactor(plugin): initialize workbench databases with Node SQLite
mldangelo-oai Oct 6, 2026
aef7012
fix(plugin): preserve configured workbench storage paths
mldangelo-oai Oct 6, 2026
25fd333
refactor(plugin): pass the resolved database location to Node
mldangelo-oai Oct 6, 2026
284248f
fix(plugin): preserve database row identity and private storage
mldangelo-oai Oct 6, 2026
4b242d4
fix(plugin): initialize trailing-separator directory links
mldangelo-oai Oct 6, 2026
8332ed4
fix(sdk): normalize the workbench directory once
mldangelo-oai Oct 6, 2026
b3f340d
test(plugin): use native directory traversal expectations
mldangelo-oai Oct 6, 2026
61eb31f
fix(sdk): resolve the Bun Node fallback through trusted paths
mldangelo-oai Oct 6, 2026
ff7e211
test(plugin): inspect Windows ACLs without module discovery
mldangelo-oai Oct 6, 2026
7be20ab
refactor(plugin): share checkpoint metadata backfills
mldangelo-oai Oct 6, 2026
5bbae58
Merge branch 'dev/codex/sqlite-shared-migrations' into mdangelo/codex…
mldangelo-oai Oct 6, 2026
274da03
refactor(plugin): simplify SQLite migrations and directory setup
mldangelo-oai Oct 6, 2026
33f9811
fix(plugin): preserve checkpoint diagnostics during upgrades
mldangelo-oai Oct 6, 2026
3ba797c
Merge shared migration diagnostic fixes
mldangelo-oai Oct 6, 2026
9afb26a
fix(plugin): preserve database errors and private Windows setup
mldangelo-oai Oct 6, 2026
277cb43
test(sdk): inherit Node lookup environment in Windows fixtures
mldangelo-oai Oct 6, 2026
6a707aa
Merge main into Node SQLite initialization
mldangelo-oai Oct 6, 2026
1866286
Merge commit '9911573a1794fae921049100fe3db694479e7be2' into HEAD
mldangelo-oai Oct 7, 2026
e7d45b8
Merge updated shared migrations into Node SQLite initialization
mldangelo-oai Oct 7, 2026
9855f2e
fix(sdk): pin findings state during initialization
mldangelo-oai Oct 7, 2026
2b00ca0
Merge latest main into shared migrations
mldangelo-oai Oct 7, 2026
5a68ba3
fix(storage): preserve workflow scopes during legacy migration
mldangelo-oai Oct 7, 2026
8c55467
Merge updated shared migrations
mldangelo-oai Oct 7, 2026
47f8188
fix(sdk): retain lazily resolved workbench Python
mldangelo-oai Oct 7, 2026
dac3c59
Merge latest main into shared migrations
mldangelo-oai Oct 7, 2026
1f23d98
fix(storage): preserve workflow metadata during legacy migrations
mldangelo-oai Oct 7, 2026
21ecf6d
Merge latest main and lossless migration metadata
mldangelo-oai Oct 7, 2026
78d91f6
Merge latest main into shared migrations
mldangelo-oai Oct 7, 2026
eebdebe
Merge updated migration stack
mldangelo-oai Oct 7, 2026
156e7a3
Merge latest main into shared migrations
mldangelo-oai Oct 7, 2026
2b7700e
Merge updated migration stack
mldangelo-oai Oct 7, 2026
5d7e6ab
Merge scan-name migration from main
mldangelo-oai Oct 7, 2026
ebfd7eb
Merge scan-name migration through native database tests
mldangelo-oai Oct 7, 2026
1709edf
Preserve Python configuration context during native initialization
mldangelo-oai Oct 7, 2026
dbcad47
Merge latest main into migration stack
mldangelo-oai Oct 7, 2026
896d1fe
Merge latest main into migration stack
mldangelo-oai Oct 7, 2026
a7406da
Preserve the findings store trust context for Node helpers
mldangelo-oai Oct 7, 2026
a3b6772
Merge main test fixture refactors into migration stack
mldangelo-oai Oct 7, 2026
c17cd09
Merge main test fixture refactors into migration stack
mldangelo-oai Oct 7, 2026
e3a7ca0
Merge refreshed base PR #1333
mldangelo-oai Oct 7, 2026
4e95901
Merge latest main
mldangelo-oai Oct 7, 2026
2e94611
Preserve initialized findings executable search paths
mldangelo-oai Oct 7, 2026
e45b846
Preserve POSIX PATH traversal when capturing store settings
mldangelo-oai Oct 7, 2026
fe56307
Merge latest main dependency update
mldangelo-oai Oct 7, 2026
09ba915
Merge updated base PR #1333
mldangelo-oai Oct 7, 2026
d37a2a0
Merge latest main runtime and path fixes
mldangelo-oai Oct 7, 2026
ae5eff7
Merge updated base PR #1333
mldangelo-oai Oct 7, 2026
086d3f8
Merge latest main
mldangelo-oai Oct 7, 2026
015bb46
Merge updated base PR #1333
mldangelo-oai Oct 7, 2026
ccb4832
Merge latest main
mldangelo-oai Oct 7, 2026
782a49a
Merge updated base PR #1333
mldangelo-oai Oct 7, 2026
01dd9b4
fix(storage): capture managed Python cache before deferred lookup
mldangelo-oai Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion plugins/codex-security/mcp-app/helpers-main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { closeSync, readFileSync } from "node:fs";
import { parseArgs } from "node:util";
import { resolveSecurityMdCommand } from "./src/helpers/resolve-security-md";
import { decodePosixBytes } from "./src/helpers/posix-path";
import { windowsBinding } from "./src/native";
Expand All @@ -8,6 +9,8 @@ import { deepReviewInputCommand } from "./src/helpers/deep-review-input";
import { rankShardsCommand } from "./src/helpers/rank-shards";
import { rankPoolCommand } from "./src/helpers/rank-pool";
import { bindRepoScopesCommand } from "./src/helpers/bind-repo-scopes";
import { escapeControls } from "./src/helpers/json";
import { decodeUtf8 } from "./src/helpers/utf8";

let commandLine = process.argv.slice(2);
if (process.platform === "win32") {
Expand Down Expand Up @@ -58,9 +61,40 @@ if (command === "resolve-security-md") {
process.exitCode = rankPoolCommand(command, args, posixHome);
} else if (command === "bind-repo-scopes") {
process.exitCode = bindRepoScopesCommand(args, posixHome);
} else if (command === "database-info") {
void (async () => {
const { values } = parseArgs({
args,
options: { help: { type: "boolean", short: "h" } },
});
if (values.help) {
console.log(
"Usage: database-info (reads a JSON absolute state-directory string from stdin)",
);
return;
}
const { databaseInfo } = await import("./src/workbench/database");
console.log(
JSON.stringify(
await databaseInfo(JSON.parse(decodeUtf8(readFileSync(0)))),
).replace(/[\p{Cc}\p{Cf}]/gu, (character) =>
character
.split("")
.map(
(unit) => `\\u${unit.charCodeAt(0).toString(16).padStart(4, "0")}`,
)
.join(""),
),
);
})().catch((error: unknown) => {
console.error(
escapeControls(error instanceof Error ? error.message : String(error)),
);
process.exitCode = 1;
});
} else {
console.error(
"Usage: launch_codex_security_mcp[.cmd] --helper <resolve-security-md | normalize-candidates | validate-patch-risk-assessment | copy-deep-review-input | select-deep-review-input | make-rank-shards | validate-rank-shard | merge-rank-outputs | make-rank-pool-plan | validate-rank-worker | validate-rank-pool | bind-repo-scopes> [options]",
"Usage: launch_codex_security_mcp[.cmd] --helper <resolve-security-md | normalize-candidates | validate-patch-risk-assessment | copy-deep-review-input | select-deep-review-input | make-rank-shards | validate-rank-shard | merge-rank-outputs | make-rank-pool-plan | validate-rank-worker | validate-rank-pool | bind-repo-scopes | database-info> [options]",
);
process.exitCode = 2;
}
98 changes: 98 additions & 0 deletions plugins/codex-security/mcp-app/src/workbench/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
chmodSync,
lstatSync,
mkdirSync,
readlinkSync,
realpathSync,
statSync,
} from "node:fs";
import { dirname, isAbsolute, join, sep } from "node:path";
import { DatabaseSync } from "node:sqlite";
import { setTimeout } from "node:timers/promises";
import { applyMigrations } from "./migrations";
import { decodePosixBytes, encodePosixPath } from "../helpers/posix-path";
import { windowsBinding } from "../native";
import { widePath, windowsFileSystem } from "../../../native/windows-files.mjs";

function createStateDirectory(path: string): void {
if (process.platform !== "win32") path = path.replace(/\/+$/u, "") || "/";
const nativePath =
process.platform === "win32" ? path : encodePosixPath(path);
if (statSync(nativePath, { throwIfNoEntry: false })?.isDirectory()) return;
const entry = lstatSync(nativePath, { throwIfNoEntry: false });
if (entry?.isSymbolicLink()) {
const target =
process.platform === "win32"
? readlinkSync(nativePath)
: decodePosixBytes(readlinkSync(nativePath, { encoding: "buffer" }));
createStateDirectory(
isAbsolute(target) ? target : `${dirname(path)}${sep}${target}`,
);
return;
}
if (!entry) {
const parent = dirname(path);
if (parent !== path) createStateDirectory(parent);
}
try {
if (process.platform === "win32")
windowsFileSystem(windowsBinding()).mkdirPrivate(widePath(path));
else mkdirSync(nativePath, { mode: 0o700 });
} catch (error) {
if (!statSync(nativePath, { throwIfNoEntry: false })?.isDirectory())
throw error;
}
}

export async function openWorkbenchDatabase(
databasePath: string,
{ deferred = false }: { deferred?: boolean } = {},
): Promise<DatabaseSync> {
createStateDirectory(dirname(databasePath));
for (let attempt = 0; ; attempt++) {
const database = new DatabaseSync(databasePath);
try {
database.exec("PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000;");
applyMigrations(database, undefined, !deferred || attempt > 0);
database.exec("PRAGMA journal_mode = WAL");
chmodSync(databasePath, 0o600);
return database;
} catch (error) {
database.close();
const busy =
error instanceof Error &&
"errcode" in error &&
[5, 6].includes(Number(error.errcode) & 0xff);
if (attempt === 4 || !busy) throw error;
await setTimeout(50 * 2 ** attempt);
}
}
}

export async function databaseInfo(
state: string,
): Promise<{ databasePath: string }> {
if (
typeof state !== "string" ||
!isAbsolute(state) ||
!state.isWellFormed()
) {
throw new Error(
"database-info requires an absolute Unicode state-directory string.",
);
}
// Keep an ASCII alias usable even when its destination has raw POSIX bytes.
const database = await openWorkbenchDatabase(
`${state}${sep}workbench.sqlite3`,
{ deferred: true },
);
database.close();
const canonicalState =
process.platform === "win32"
? realpathSync.native(state)
: decodePosixBytes(
realpathSync.native(encodePosixPath(state), { encoding: "buffer" }),
);
const databasePath = join(canonicalState, "workbench.sqlite3");
return { databasePath };
}
Loading
Loading