@praxis.guard/auditor-cli 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.vscode.md +48 -0
- package/dist/adapters/copilot-cli/adapter.d.ts +10 -0
- package/dist/adapters/copilot-cli/adapter.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/adapter.js +105 -0
- package/dist/adapters/copilot-cli/adapter.js.map +1 -0
- package/dist/adapters/copilot-cli/config.d.ts +18 -0
- package/dist/adapters/copilot-cli/config.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/config.js +118 -0
- package/dist/adapters/copilot-cli/config.js.map +1 -0
- package/dist/adapters/copilot-cli/index.d.ts +3 -0
- package/dist/adapters/copilot-cli/index.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/index.js +3 -0
- package/dist/adapters/copilot-cli/index.js.map +1 -0
- package/dist/adapters/copilot-cli/paths.d.ts +8 -0
- package/dist/adapters/copilot-cli/paths.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/paths.js +18 -0
- package/dist/adapters/copilot-cli/paths.js.map +1 -0
- package/dist/adapters/copilot-cli.d.ts +1 -13
- package/dist/adapters/copilot-cli.d.ts.map +1 -1
- package/dist/adapters/copilot-cli.js +1 -231
- package/dist/adapters/copilot-cli.js.map +1 -1
- package/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +2 -0
- package/dist/adapters/registry.js.map +1 -1
- package/dist/adapters/types.d.ts +1 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/vscode.d.ts +9 -0
- package/dist/adapters/vscode.d.ts.map +1 -0
- package/dist/adapters/vscode.js +87 -0
- package/dist/adapters/vscode.js.map +1 -0
- package/dist/codex/config-hooks.d.ts +7 -0
- package/dist/codex/config-hooks.d.ts.map +1 -0
- package/dist/codex/config-hooks.js +61 -0
- package/dist/codex/config-hooks.js.map +1 -0
- package/dist/codex/config-io.d.ts +6 -0
- package/dist/codex/config-io.d.ts.map +1 -0
- package/dist/codex/config-io.js +34 -0
- package/dist/codex/config-io.js.map +1 -0
- package/dist/codex/config-toml.d.ts +4 -0
- package/dist/codex/config-toml.d.ts.map +1 -0
- package/dist/codex/config-toml.js +65 -0
- package/dist/codex/config-toml.js.map +1 -0
- package/dist/codex/config.d.ts +1 -4
- package/dist/codex/config.d.ts.map +1 -1
- package/dist/codex/config.js +8 -152
- package/dist/codex/config.js.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-cli.js","sourceRoot":"","sources":["../../src/adapters/copilot-cli.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"copilot-cli.js","sourceRoot":"","sources":["../../src/adapters/copilot-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,YAAY,EAO/C,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,YAAY,CAIpD;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,IAAI,YAAY,EAAE,CAQxD"}
|
|
@@ -3,6 +3,7 @@ import { ClaudeDesktopAdapter } from "./claude-desktop.js";
|
|
|
3
3
|
import { CodexAdapter } from "./codex.js";
|
|
4
4
|
import { CopilotCliAdapter } from "./copilot-cli.js";
|
|
5
5
|
import { CursorAdapter } from "./cursor.js";
|
|
6
|
+
import { VscodeAdapter } from "./vscode.js";
|
|
6
7
|
/**
|
|
7
8
|
* The set of agent adapters known to the CLI. Adding a new host is one append
|
|
8
9
|
* here plus the new adapter file.
|
|
@@ -13,6 +14,7 @@ export const ALL_ADAPTERS = [
|
|
|
13
14
|
new ClaudeCodeAdapter(),
|
|
14
15
|
new CodexAdapter(),
|
|
15
16
|
new CopilotCliAdapter(),
|
|
17
|
+
new VscodeAdapter(),
|
|
16
18
|
];
|
|
17
19
|
export function getAdapter(id) {
|
|
18
20
|
const found = ALL_ADAPTERS.find((a) => a.id === id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,IAAI,aAAa,EAAE;IACnB,IAAI,oBAAoB,EAAE;IAC1B,IAAI,iBAAiB,EAAE;IACvB,IAAI,YAAY,EAAE;IAClB,IAAI,iBAAiB,EAAE;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,IAAI,aAAa,EAAE;IACnB,IAAI,oBAAoB,EAAE;IAC1B,IAAI,iBAAiB,EAAE;IACvB,IAAI,YAAY,EAAE;IAClB,IAAI,iBAAiB,EAAE;IACvB,IAAI,aAAa,EAAE;CACpB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,EAAW;IACpC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,EAAE,EAAE,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,uBAAuB;IACrC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,OAAO,CAAC,CAAC,eAAe,EAAE,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/adapters/types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `upsertHook` and `upsertCloud` are optional — hosts that don't support pre-tool hooks
|
|
7
7
|
* (e.g. Claude Desktop) simply omit them rather than implement no-op stubs.
|
|
8
8
|
*/
|
|
9
|
-
export type AgentId = "cursor" | "claude-desktop" | "claude-code" | "codex" | "copilot-cli";
|
|
9
|
+
export type AgentId = "cursor" | "claude-desktop" | "claude-code" | "codex" | "copilot-cli" | "vscode";
|
|
10
10
|
export type SetupResult = {
|
|
11
11
|
path: string;
|
|
12
12
|
changed: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,gBAAgB,GAAG,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentAdapter, AgentStatus, SetupResult, StatusOpts, UpsertMcpOpts } from "./types.js";
|
|
2
|
+
export declare class VscodeAdapter implements AgentAdapter {
|
|
3
|
+
readonly id: "vscode";
|
|
4
|
+
readonly label = "Visual Studio Code";
|
|
5
|
+
detectInstalled(): boolean;
|
|
6
|
+
upsertMcp(opts: UpsertMcpOpts): Promise<SetupResult>;
|
|
7
|
+
status(opts?: StatusOpts): Promise<AgentStatus>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=vscode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.d.ts","sourceRoot":"","sources":["../../src/adapters/vscode.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AAoCpB,qBAAa,aAAc,YAAW,YAAY;IAChD,QAAQ,CAAC,EAAE,EAAG,QAAQ,CAAU;IAChC,QAAQ,CAAC,KAAK,wBAAwB;IAEtC,eAAe,IAAI,OAAO;IAKpB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBpD,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAiBtD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readJson, writeJsonAtomic } from "./claude-code/config-io.js";
|
|
5
|
+
const AGENT_HOST = "vscode";
|
|
6
|
+
function codeUserSettingsCandidates() {
|
|
7
|
+
const home = os.homedir();
|
|
8
|
+
const candidates = [];
|
|
9
|
+
if (process.platform === "darwin") {
|
|
10
|
+
candidates.push(path.join(home, "Library", "Application Support", "Code", "User", "settings.json"));
|
|
11
|
+
candidates.push(path.join(home, "Library", "Application Support", "Code - Insiders", "User", "settings.json"));
|
|
12
|
+
}
|
|
13
|
+
else if (process.platform === "win32") {
|
|
14
|
+
const appdata = process.env.APPDATA || path.join(home, "AppData", "Roaming");
|
|
15
|
+
candidates.push(path.join(appdata, "Code", "User", "settings.json"));
|
|
16
|
+
candidates.push(path.join(appdata, "Code - Insiders", "User", "settings.json"));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
candidates.push(path.join(home, ".config", "Code", "User", "settings.json"));
|
|
20
|
+
candidates.push(path.join(home, ".config", "Code - Insiders", "User", "settings.json"));
|
|
21
|
+
}
|
|
22
|
+
return candidates;
|
|
23
|
+
}
|
|
24
|
+
function commandAvailable(command) {
|
|
25
|
+
const pathValue = process.env.PATH ?? "";
|
|
26
|
+
const extensions = process.platform === "win32"
|
|
27
|
+
? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
|
|
28
|
+
: [""];
|
|
29
|
+
return pathValue.split(path.delimiter).some((dir) => extensions.some((ext) => {
|
|
30
|
+
const candidate = path.join(dir || ".", `${command}${ext}`);
|
|
31
|
+
try {
|
|
32
|
+
return existsSync(candidate);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
export class VscodeAdapter {
|
|
40
|
+
id = "vscode";
|
|
41
|
+
label = "Visual Studio Code";
|
|
42
|
+
detectInstalled() {
|
|
43
|
+
const candidates = codeUserSettingsCandidates();
|
|
44
|
+
return candidates.some((p) => existsSync(p));
|
|
45
|
+
}
|
|
46
|
+
async upsertMcp(opts) {
|
|
47
|
+
const candidates = codeUserSettingsCandidates();
|
|
48
|
+
const cfgPath = (opts.explicitPath?.trim() || candidates[0]);
|
|
49
|
+
const existing = await readJson(cfgPath).catch(() => null);
|
|
50
|
+
const config = existing ? JSON.parse(JSON.stringify(existing)) : {};
|
|
51
|
+
const platformKey = process.platform === "darwin" ? "terminal.integrated.env.osx"
|
|
52
|
+
: process.platform === "win32" ? "terminal.integrated.env.windows"
|
|
53
|
+
: "terminal.integrated.env.linux";
|
|
54
|
+
const envBlock = (config[platformKey] && typeof config[platformKey] === "object") ? { ...config[platformKey] } : {};
|
|
55
|
+
envBlock.PRAXIS_AGENT_HOST = AGENT_HOST;
|
|
56
|
+
config[platformKey] = envBlock;
|
|
57
|
+
const changed = JSON.stringify(existing ?? {}) !== JSON.stringify(config);
|
|
58
|
+
if (changed && !opts.dryRun)
|
|
59
|
+
await writeJsonAtomic(cfgPath, config);
|
|
60
|
+
return {
|
|
61
|
+
path: cfgPath,
|
|
62
|
+
changed,
|
|
63
|
+
message: changed
|
|
64
|
+
? opts.dryRun ? "would update VS Code user settings with PRAXIS_AGENT_HOST" : "updated VS Code user settings with PRAXIS_AGENT_HOST"
|
|
65
|
+
: "VS Code user settings already contain PRAXIS_AGENT_HOST",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async status(opts) {
|
|
69
|
+
const candidates = codeUserSettingsCandidates();
|
|
70
|
+
const cfgPath = (opts?.mcpConfigPath?.trim() || candidates[0]);
|
|
71
|
+
const warnings = [];
|
|
72
|
+
const cfg = await readJson(cfgPath).catch(() => null);
|
|
73
|
+
const platformKey = process.platform === "darwin" ? "terminal.integrated.env.osx"
|
|
74
|
+
: process.platform === "win32" ? "terminal.integrated.env.windows"
|
|
75
|
+
: "terminal.integrated.env.linux";
|
|
76
|
+
const hasEnv = !!(cfg && cfg[platformKey] && typeof cfg[platformKey] === "object" && cfg[platformKey].PRAXIS_AGENT_HOST === AGENT_HOST);
|
|
77
|
+
if (!hasEnv)
|
|
78
|
+
warnings.push(`VS Code does not have PRAXIS_AGENT_HOST=${AGENT_HOST} in ${cfgPath}; run: auditor setup mcp --for=vscode`);
|
|
79
|
+
return {
|
|
80
|
+
installed: this.detectInstalled(),
|
|
81
|
+
mcp: { configured: hasEnv, path: cfgPath },
|
|
82
|
+
warnings,
|
|
83
|
+
ready: hasEnv,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.js","sourceRoot":"","sources":["../../src/adapters/vscode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type JsonMap = Record<string, unknown>;
|
|
2
|
+
export declare function mergeCodexHooks(existing: JsonMap | null): JsonMap;
|
|
3
|
+
export declare function hooksContainCommand(config: JsonMap | null, event: string, command: string): boolean;
|
|
4
|
+
export declare const CODEX_PRE_TOOL_COMMAND = "auditor hook codex-pre-tool-use";
|
|
5
|
+
export declare const CODEX_PERMISSION_COMMAND = "auditor hook codex-permission-request";
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=config-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-hooks.d.ts","sourceRoot":"","sources":["../../src/codex/config-hooks.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAyBvC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAqBjE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAYnG;AAED,eAAO,MAAM,sBAAsB,oCAAmB,CAAC;AACvD,eAAO,MAAM,wBAAwB,0CAAqB,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const PRE_TOOL_COMMAND = "auditor hook codex-pre-tool-use";
|
|
2
|
+
const PERMISSION_COMMAND = "auditor hook codex-permission-request";
|
|
3
|
+
function commandHook(command, statusMessage) {
|
|
4
|
+
return { type: "command", command, timeout: 30, statusMessage };
|
|
5
|
+
}
|
|
6
|
+
function isPraxisHookGroup(value) {
|
|
7
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
8
|
+
return false;
|
|
9
|
+
const hooks = value.hooks;
|
|
10
|
+
if (!Array.isArray(hooks))
|
|
11
|
+
return false;
|
|
12
|
+
return hooks.some((hook) => {
|
|
13
|
+
if (!hook || typeof hook !== "object" || Array.isArray(hook))
|
|
14
|
+
return false;
|
|
15
|
+
const command = hook.command;
|
|
16
|
+
return command === PRE_TOOL_COMMAND || command === PERMISSION_COMMAND;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function replacePraxisGroups(existing, additions) {
|
|
20
|
+
const groups = Array.isArray(existing) ? existing.filter((entry) => !isPraxisHookGroup(entry)) : [];
|
|
21
|
+
return [...groups, ...additions];
|
|
22
|
+
}
|
|
23
|
+
export function mergeCodexHooks(existing) {
|
|
24
|
+
const config = existing ? structuredClone(existing) : {};
|
|
25
|
+
const hooks = config.hooks && typeof config.hooks === "object" && !Array.isArray(config.hooks)
|
|
26
|
+
? config.hooks
|
|
27
|
+
: {};
|
|
28
|
+
config.hooks = hooks;
|
|
29
|
+
hooks.PreToolUse = replacePraxisGroups(hooks.PreToolUse, [
|
|
30
|
+
{
|
|
31
|
+
matcher: "^Bash$|^mcp__.*",
|
|
32
|
+
hooks: [commandHook(PRE_TOOL_COMMAND, "Checking Praxis policy")],
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
hooks.PermissionRequest = replacePraxisGroups(hooks.PermissionRequest, [
|
|
36
|
+
{
|
|
37
|
+
matcher: "^Bash$|^mcp__.*",
|
|
38
|
+
hooks: [commandHook(PERMISSION_COMMAND, "Checking Praxis approval")],
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
return config;
|
|
42
|
+
}
|
|
43
|
+
export function hooksContainCommand(config, event, command) {
|
|
44
|
+
const hooks = config?.hooks;
|
|
45
|
+
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks))
|
|
46
|
+
return false;
|
|
47
|
+
const groups = hooks[event];
|
|
48
|
+
if (!Array.isArray(groups))
|
|
49
|
+
return false;
|
|
50
|
+
return groups.some((group) => {
|
|
51
|
+
if (!group || typeof group !== "object" || Array.isArray(group))
|
|
52
|
+
return false;
|
|
53
|
+
const handlers = group.hooks;
|
|
54
|
+
return Array.isArray(handlers) && handlers.some((handler) => {
|
|
55
|
+
return !!handler && typeof handler === "object" && handler.command === command;
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export const CODEX_PRE_TOOL_COMMAND = PRE_TOOL_COMMAND;
|
|
60
|
+
export const CODEX_PERMISSION_COMMAND = PERMISSION_COMMAND;
|
|
61
|
+
//# sourceMappingURL=config-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-hooks.js","sourceRoot":"","sources":["../../src/codex/config-hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type JsonMap = Record<string, unknown>;
|
|
2
|
+
export declare function readText(pathname: string): Promise<string>;
|
|
3
|
+
export declare function writeAtomic(pathname: string, content: string): Promise<void>;
|
|
4
|
+
export declare function readJson(pathname: string): Promise<JsonMap | null>;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=config-io.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-io.d.ts","sourceRoot":"","sources":["../../src/codex/config-io.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvC,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOhE;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlF;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAYxE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function readText(pathname) {
|
|
4
|
+
try {
|
|
5
|
+
return await readFile(pathname, "utf8");
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
if (error.code === "ENOENT")
|
|
9
|
+
return "";
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function writeAtomic(pathname, content) {
|
|
14
|
+
await mkdir(path.dirname(pathname), { recursive: true });
|
|
15
|
+
const temp = path.join(path.dirname(pathname), `.${path.basename(pathname)}.tmp.${process.pid}`);
|
|
16
|
+
await writeFile(temp, content, "utf8");
|
|
17
|
+
await rename(temp, pathname);
|
|
18
|
+
}
|
|
19
|
+
export async function readJson(pathname) {
|
|
20
|
+
const raw = await readText(pathname);
|
|
21
|
+
if (!raw)
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(raw);
|
|
25
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
26
|
+
throw new Error("JSON root must be an object");
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`Invalid JSON at ${pathname}: ${String(error)}. Refusing to overwrite existing file.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config-io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-io.js","sourceRoot":"","sources":["../../src/codex/config-io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAClE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,OAAe;IACjE,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACjG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,MAAiB,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,KAAK,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACzG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-toml.d.ts","sourceRoot":"","sources":["../../src/codex/config-toml.ts"],"names":[],"mappings":"AA8DA,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const MCP_HEADER = '[mcp_servers."praxis-guard"]';
|
|
2
|
+
const MCP_ENV_HEADER = '[mcp_servers."praxis-guard".env]';
|
|
3
|
+
function isTableHeader(line) {
|
|
4
|
+
return /^\s*\[\[?[^\]]+\]\]?\s*(?:#.*)?$/.test(line);
|
|
5
|
+
}
|
|
6
|
+
function isPraxisMcpHeader(line) {
|
|
7
|
+
return /^\s*\[mcp_servers\.(?:"praxis-guard"|'praxis-guard'|praxis-guard)(?:\.env)?\]\s*(?:#.*)?$/.test(line);
|
|
8
|
+
}
|
|
9
|
+
function removePraxisMcpTables(source) {
|
|
10
|
+
const lines = source.split(/\r?\n/);
|
|
11
|
+
const kept = [];
|
|
12
|
+
let removing = false;
|
|
13
|
+
for (const line of lines) {
|
|
14
|
+
if (isTableHeader(line)) {
|
|
15
|
+
removing = isPraxisMcpHeader(line);
|
|
16
|
+
}
|
|
17
|
+
if (!removing)
|
|
18
|
+
kept.push(line);
|
|
19
|
+
}
|
|
20
|
+
return kept.join("\n").trimEnd();
|
|
21
|
+
}
|
|
22
|
+
function renderPraxisMcpConfig() {
|
|
23
|
+
return [
|
|
24
|
+
MCP_HEADER,
|
|
25
|
+
'command = "auditor"',
|
|
26
|
+
'args = ["mcp"]',
|
|
27
|
+
"",
|
|
28
|
+
MCP_ENV_HEADER,
|
|
29
|
+
'PRAXIS_AGENT_HOST = "codex-app"',
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
function disableUnifiedExec(source) {
|
|
33
|
+
const lines = source.split(/\r?\n/);
|
|
34
|
+
const featuresIndex = lines.findIndex((line) => /^\s*\[features\]\s*(?:#.*)?$/.test(line));
|
|
35
|
+
if (featuresIndex === -1) {
|
|
36
|
+
const base = source.trimEnd();
|
|
37
|
+
return `${base ? `${base}\n\n` : ""}[features]\nunified_exec = false`;
|
|
38
|
+
}
|
|
39
|
+
let tableEnd = lines.length;
|
|
40
|
+
for (let i = featuresIndex + 1; i < lines.length; i++) {
|
|
41
|
+
if (isTableHeader(lines[i] ?? "")) {
|
|
42
|
+
tableEnd = i;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const keyIndex = lines.findIndex((line, index) => index > featuresIndex && index < tableEnd && /^\s*unified_exec\s*=/.test(line));
|
|
47
|
+
if (keyIndex >= 0)
|
|
48
|
+
lines[keyIndex] = "unified_exec = false";
|
|
49
|
+
else
|
|
50
|
+
lines.splice(featuresIndex + 1, 0, "unified_exec = false");
|
|
51
|
+
return lines.join("\n").trimEnd();
|
|
52
|
+
}
|
|
53
|
+
export function mergeCodexConfigToml(source) {
|
|
54
|
+
const base = disableUnifiedExec(removePraxisMcpTables(source));
|
|
55
|
+
return `${base ? `${base}\n\n` : ""}${renderPraxisMcpConfig()}\n`;
|
|
56
|
+
}
|
|
57
|
+
export function isPraxisMcpConfigured(config) {
|
|
58
|
+
return config.includes(MCP_HEADER)
|
|
59
|
+
&& config.includes('command = "auditor"')
|
|
60
|
+
&& config.includes('PRAXIS_AGENT_HOST = "codex-app"');
|
|
61
|
+
}
|
|
62
|
+
export function isUnifiedExecDisabled(config) {
|
|
63
|
+
return /^\s*unified_exec\s*=\s*false\s*(?:#.*)?$/m.test(config);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=config-toml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-toml.js","sourceRoot":"","sources":["../../src/codex/config-toml.ts"],"names":[],"mappings":"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"}
|
package/dist/codex/config.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
type JsonMap = Record<string, unknown>;
|
|
2
1
|
export type CodexSetupResult = {
|
|
3
2
|
path: string;
|
|
4
3
|
changed: boolean;
|
|
@@ -15,10 +14,8 @@ export type CodexSetupStatus = {
|
|
|
15
14
|
};
|
|
16
15
|
export declare function codexConfigPath(projectDir: string): string;
|
|
17
16
|
export declare function codexHooksPath(projectDir: string): string;
|
|
18
|
-
export
|
|
19
|
-
export declare function mergeCodexHooks(existing: JsonMap | null): JsonMap;
|
|
17
|
+
export { mergeCodexConfigToml } from "./config-toml.js";
|
|
20
18
|
export declare function upsertCodexConfig(projectDir: string, dryRun?: boolean): Promise<CodexSetupResult>;
|
|
21
19
|
export declare function upsertCodexHooks(projectDir: string, dryRun?: boolean): Promise<CodexSetupResult>;
|
|
22
20
|
export declare function readCodexSetupStatus(projectDir: string): Promise<CodexSetupStatus>;
|
|
23
|
-
export {};
|
|
24
21
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/codex/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/codex/config.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,2BAA2B,EAAE,OAAO,CAAC;IACrC,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAWrG;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYpG;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAcxF"}
|
package/dist/codex/config.js
CHANGED
|
@@ -1,142 +1,16 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
3
|
+
import { CODEX_PERMISSION_COMMAND, CODEX_PRE_TOOL_COMMAND, hooksContainCommand, mergeCodexHooks, } from "./config-hooks.js";
|
|
4
|
+
import { readJson, readText, writeAtomic } from "./config-io.js";
|
|
5
|
+
import { isPraxisMcpConfigured, isUnifiedExecDisabled, mergeCodexConfigToml, } from "./config-toml.js";
|
|
4
6
|
const CODEX_DIR = ".codex";
|
|
5
|
-
const MCP_HEADER = '[mcp_servers."praxis-guard"]';
|
|
6
|
-
const MCP_ENV_HEADER = '[mcp_servers."praxis-guard".env]';
|
|
7
|
-
const PRE_TOOL_COMMAND = "auditor hook codex-pre-tool-use";
|
|
8
|
-
const PERMISSION_COMMAND = "auditor hook codex-permission-request";
|
|
9
7
|
export function codexConfigPath(projectDir) {
|
|
10
8
|
return path.join(projectDir, CODEX_DIR, "config.toml");
|
|
11
9
|
}
|
|
12
10
|
export function codexHooksPath(projectDir) {
|
|
13
11
|
return path.join(projectDir, CODEX_DIR, "hooks.json");
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
return await readFile(pathname, "utf8");
|
|
18
|
-
}
|
|
19
|
-
catch (error) {
|
|
20
|
-
if (error.code === "ENOENT")
|
|
21
|
-
return "";
|
|
22
|
-
throw error;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function writeAtomic(pathname, content) {
|
|
26
|
-
await mkdir(path.dirname(pathname), { recursive: true });
|
|
27
|
-
const temp = path.join(path.dirname(pathname), `.${path.basename(pathname)}.tmp.${process.pid}`);
|
|
28
|
-
await writeFile(temp, content, "utf8");
|
|
29
|
-
await rename(temp, pathname);
|
|
30
|
-
}
|
|
31
|
-
function isTableHeader(line) {
|
|
32
|
-
return /^\s*\[\[?[^\]]+\]\]?\s*(?:#.*)?$/.test(line);
|
|
33
|
-
}
|
|
34
|
-
function isPraxisMcpHeader(line) {
|
|
35
|
-
return /^\s*\[mcp_servers\.(?:"praxis-guard"|'praxis-guard'|praxis-guard)(?:\.env)?\]\s*(?:#.*)?$/.test(line);
|
|
36
|
-
}
|
|
37
|
-
function removePraxisMcpTables(source) {
|
|
38
|
-
const lines = source.split(/\r?\n/);
|
|
39
|
-
const kept = [];
|
|
40
|
-
let removing = false;
|
|
41
|
-
for (const line of lines) {
|
|
42
|
-
if (isTableHeader(line)) {
|
|
43
|
-
removing = isPraxisMcpHeader(line);
|
|
44
|
-
}
|
|
45
|
-
if (!removing)
|
|
46
|
-
kept.push(line);
|
|
47
|
-
}
|
|
48
|
-
return kept.join("\n").trimEnd();
|
|
49
|
-
}
|
|
50
|
-
function renderPraxisMcpConfig() {
|
|
51
|
-
return [
|
|
52
|
-
MCP_HEADER,
|
|
53
|
-
'command = "auditor"',
|
|
54
|
-
'args = ["mcp"]',
|
|
55
|
-
"",
|
|
56
|
-
MCP_ENV_HEADER,
|
|
57
|
-
'PRAXIS_AGENT_HOST = "codex-app"',
|
|
58
|
-
].join("\n");
|
|
59
|
-
}
|
|
60
|
-
function disableUnifiedExec(source) {
|
|
61
|
-
const lines = source.split(/\r?\n/);
|
|
62
|
-
const featuresIndex = lines.findIndex((line) => /^\s*\[features\]\s*(?:#.*)?$/.test(line));
|
|
63
|
-
if (featuresIndex === -1) {
|
|
64
|
-
const base = source.trimEnd();
|
|
65
|
-
return `${base ? `${base}\n\n` : ""}[features]\nunified_exec = false`;
|
|
66
|
-
}
|
|
67
|
-
let tableEnd = lines.length;
|
|
68
|
-
for (let i = featuresIndex + 1; i < lines.length; i++) {
|
|
69
|
-
if (isTableHeader(lines[i] ?? "")) {
|
|
70
|
-
tableEnd = i;
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const keyIndex = lines.findIndex((line, index) => index > featuresIndex && index < tableEnd && /^\s*unified_exec\s*=/.test(line));
|
|
75
|
-
if (keyIndex >= 0)
|
|
76
|
-
lines[keyIndex] = "unified_exec = false";
|
|
77
|
-
else
|
|
78
|
-
lines.splice(featuresIndex + 1, 0, "unified_exec = false");
|
|
79
|
-
return lines.join("\n").trimEnd();
|
|
80
|
-
}
|
|
81
|
-
export function mergeCodexConfigToml(source) {
|
|
82
|
-
const base = disableUnifiedExec(removePraxisMcpTables(source));
|
|
83
|
-
return `${base ? `${base}\n\n` : ""}${renderPraxisMcpConfig()}\n`;
|
|
84
|
-
}
|
|
85
|
-
async function readJson(pathname) {
|
|
86
|
-
const raw = await readText(pathname);
|
|
87
|
-
if (!raw)
|
|
88
|
-
return null;
|
|
89
|
-
try {
|
|
90
|
-
const parsed = JSON.parse(raw);
|
|
91
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
92
|
-
throw new Error("JSON root must be an object");
|
|
93
|
-
}
|
|
94
|
-
return parsed;
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
throw new Error(`Invalid JSON at ${pathname}: ${String(error)}. Refusing to overwrite existing file.`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function commandHook(command, statusMessage) {
|
|
101
|
-
return { type: "command", command, timeout: 30, statusMessage };
|
|
102
|
-
}
|
|
103
|
-
function isPraxisHookGroup(value) {
|
|
104
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
105
|
-
return false;
|
|
106
|
-
const hooks = value.hooks;
|
|
107
|
-
if (!Array.isArray(hooks))
|
|
108
|
-
return false;
|
|
109
|
-
return hooks.some((hook) => {
|
|
110
|
-
if (!hook || typeof hook !== "object" || Array.isArray(hook))
|
|
111
|
-
return false;
|
|
112
|
-
const command = hook.command;
|
|
113
|
-
return command === PRE_TOOL_COMMAND || command === PERMISSION_COMMAND;
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
function replacePraxisGroups(existing, additions) {
|
|
117
|
-
const groups = Array.isArray(existing) ? existing.filter((entry) => !isPraxisHookGroup(entry)) : [];
|
|
118
|
-
return [...groups, ...additions];
|
|
119
|
-
}
|
|
120
|
-
export function mergeCodexHooks(existing) {
|
|
121
|
-
const config = existing ? structuredClone(existing) : {};
|
|
122
|
-
const hooks = config.hooks && typeof config.hooks === "object" && !Array.isArray(config.hooks)
|
|
123
|
-
? config.hooks
|
|
124
|
-
: {};
|
|
125
|
-
config.hooks = hooks;
|
|
126
|
-
hooks.PreToolUse = replacePraxisGroups(hooks.PreToolUse, [
|
|
127
|
-
{
|
|
128
|
-
matcher: "^Bash$|^mcp__.*",
|
|
129
|
-
hooks: [commandHook(PRE_TOOL_COMMAND, "Checking Praxis policy")],
|
|
130
|
-
},
|
|
131
|
-
]);
|
|
132
|
-
hooks.PermissionRequest = replacePraxisGroups(hooks.PermissionRequest, [
|
|
133
|
-
{
|
|
134
|
-
matcher: "^Bash$|^mcp__.*",
|
|
135
|
-
hooks: [commandHook(PERMISSION_COMMAND, "Checking Praxis approval")],
|
|
136
|
-
},
|
|
137
|
-
]);
|
|
138
|
-
return config;
|
|
139
|
-
}
|
|
13
|
+
export { mergeCodexConfigToml } from "./config-toml.js";
|
|
140
14
|
export async function upsertCodexConfig(projectDir, dryRun = false) {
|
|
141
15
|
const pathname = codexConfigPath(projectDir);
|
|
142
16
|
const before = await readText(pathname);
|
|
@@ -164,22 +38,6 @@ export async function upsertCodexHooks(projectDir, dryRun = false) {
|
|
|
164
38
|
message: changed ? (dryRun ? "would update Codex hooks" : "updated Codex hooks") : "Codex hooks already up to date",
|
|
165
39
|
};
|
|
166
40
|
}
|
|
167
|
-
function hooksContainCommand(config, event, command) {
|
|
168
|
-
const hooks = config?.hooks;
|
|
169
|
-
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks))
|
|
170
|
-
return false;
|
|
171
|
-
const groups = hooks[event];
|
|
172
|
-
if (!Array.isArray(groups))
|
|
173
|
-
return false;
|
|
174
|
-
return groups.some((group) => {
|
|
175
|
-
if (!group || typeof group !== "object" || Array.isArray(group))
|
|
176
|
-
return false;
|
|
177
|
-
const handlers = group.hooks;
|
|
178
|
-
return Array.isArray(handlers) && handlers.some((handler) => {
|
|
179
|
-
return !!handler && typeof handler === "object" && handler.command === command;
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
41
|
export async function readCodexSetupStatus(projectDir) {
|
|
184
42
|
const configPath = codexConfigPath(projectDir);
|
|
185
43
|
const hooksPath = codexHooksPath(projectDir);
|
|
@@ -187,12 +45,10 @@ export async function readCodexSetupStatus(projectDir) {
|
|
|
187
45
|
return {
|
|
188
46
|
configPath,
|
|
189
47
|
hooksPath,
|
|
190
|
-
mcpConfigured: config
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
preToolUseConfigured: hooksContainCommand(hooks, "PreToolUse", PRE_TOOL_COMMAND),
|
|
195
|
-
permissionRequestConfigured: hooksContainCommand(hooks, "PermissionRequest", PERMISSION_COMMAND),
|
|
48
|
+
mcpConfigured: isPraxisMcpConfigured(config),
|
|
49
|
+
unifiedExecDisabled: isUnifiedExecDisabled(config),
|
|
50
|
+
preToolUseConfigured: hooksContainCommand(hooks, "PreToolUse", CODEX_PRE_TOOL_COMMAND),
|
|
51
|
+
permissionRequestConfigured: hooksContainCommand(hooks, "PermissionRequest", CODEX_PERMISSION_COMMAND),
|
|
196
52
|
agentsGuidancePresent: existsSync(path.join(projectDir, "AGENTS.md")) || existsSync(path.join(projectDir, "AGENT.md")),
|
|
197
53
|
};
|
|
198
54
|
}
|