@praxis.guard/auditor-cli 0.0.44 → 0.0.45
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.md +15 -0
- package/dist/cli/dispatch-hook.d.ts +2 -0
- package/dist/cli/dispatch-hook.d.ts.map +1 -0
- package/dist/cli/dispatch-hook.js +29 -0
- package/dist/cli/dispatch-hook.js.map +1 -0
- package/dist/cli/dispatch-setup.d.ts +2 -0
- package/dist/cli/dispatch-setup.d.ts.map +1 -0
- package/dist/cli/dispatch-setup.js +34 -0
- package/dist/cli/dispatch-setup.js.map +1 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +61 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +6 -96
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/setup-codex.d.ts +9 -0
- package/dist/cli/setup-codex.d.ts.map +1 -0
- package/dist/cli/setup-codex.js +61 -0
- package/dist/cli/setup-codex.js.map +1 -0
- package/dist/codex/config.d.ts +23 -0
- package/dist/codex/config.d.ts.map +1 -0
- package/dist/codex/config.js +177 -0
- package/dist/codex/config.js.map +1 -0
- package/dist/codex/evaluate-tool.d.ts +28 -0
- package/dist/codex/evaluate-tool.d.ts.map +1 -0
- package/dist/codex/evaluate-tool.js +183 -0
- package/dist/codex/evaluate-tool.js.map +1 -0
- package/dist/codex/permission-handoff.d.ts +13 -0
- package/dist/codex/permission-handoff.d.ts.map +1 -0
- package/dist/codex/permission-handoff.js +36 -0
- package/dist/codex/permission-handoff.js.map +1 -0
- package/dist/hooks/run-codex-hooks.d.ts +3 -0
- package/dist/hooks/run-codex-hooks.d.ts.map +1 -0
- package/dist/hooks/run-codex-hooks.js +77 -0
- package/dist/hooks/run-codex-hooks.js.map +1 -0
- package/dist/telemetry/agent-host.d.ts +1 -1
- package/dist/telemetry/agent-host.d.ts.map +1 -1
- package/dist/telemetry/agent-host.js +7 -1
- package/dist/telemetry/agent-host.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,21 @@ Each `auditor setup` command auto-detects installed agents and configures all of
|
|
|
21
21
|
|-------|-----|----------------|--------------|
|
|
22
22
|
| **Cursor** (`--for=cursor`) | `~/.cursor/mcp.json` | `~/.cursor/hooks.json` (or `.cursor/hooks.json` per-project) | `.cursor/environment.json` |
|
|
23
23
|
| **Claude Desktop** (`--for=claude-desktop`) | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%/Claude/claude_desktop_config.json` (Windows) | — | — |
|
|
24
|
+
| **Claude Code** (`--for=claude-code`) | `~/.claude.json` | `PreToolUse` for Bash | — |
|
|
25
|
+
|
|
26
|
+
## Codex app workflow
|
|
27
|
+
|
|
28
|
+
Codex support is repo-local rather than an auto-detected host adapter:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
auditor setup codex
|
|
32
|
+
auditor setup codex doctor
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Setup merges the Praxis MCP server into `.codex/config.toml` and installs `PreToolUse` and
|
|
36
|
+
`PermissionRequest` hooks in `.codex/hooks.json`. Open the repository in Codex and review/trust
|
|
37
|
+
the hook definitions before they can run. V1 governs Bash and MCP calls; Praxis's own `guard`
|
|
38
|
+
and `guard_wait` tools are excluded so approval requests cannot block themselves.
|
|
24
39
|
|
|
25
40
|
The MCP server tags itself with `PRAXIS_AGENT_HOST=<agent>` in its registration env so heartbeats report which host launched it. See [docs/auditor-cli-multi-agent-adapter-design.md](../../docs/auditor-cli-multi-agent-adapter-design.md) for the full design.
|
|
26
41
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-hook.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch-hook.ts"],"names":[],"mappings":"AAIA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBpF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { runBeforeMcpHookFromStdin } from "../hooks/run-before-mcp.js";
|
|
2
|
+
import { runBeforeShellHookFromStdin } from "../hooks/run-before-shell.js";
|
|
3
|
+
import { runClaudeCodePreToolUseHookFromStdin } from "../hooks/run-claude-code-pre-tool-use.js";
|
|
4
|
+
export async function dispatchHookCommand(name) {
|
|
5
|
+
if (name === "before-shell") {
|
|
6
|
+
await runBeforeShellHookFromStdin();
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (name === "before-mcp") {
|
|
10
|
+
await runBeforeMcpHookFromStdin();
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (name === "claude-code") {
|
|
14
|
+
await runClaudeCodePreToolUseHookFromStdin();
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (name === "codex-pre-tool-use") {
|
|
18
|
+
const { runCodexPreToolUseHookFromStdin } = await import("../hooks/run-codex-hooks.js");
|
|
19
|
+
await runCodexPreToolUseHookFromStdin();
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (name === "codex-permission-request") {
|
|
23
|
+
const { runCodexPermissionRequestHookFromStdin } = await import("../hooks/run-codex-hooks.js");
|
|
24
|
+
await runCodexPermissionRequestHookFromStdin();
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=dispatch-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-hook.js","sourceRoot":"","sources":["../../src/cli/dispatch-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,oCAAoC,EAAE,MAAM,0CAA0C,CAAC;AAEhG,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAwB;IAChE,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,MAAM,2BAA2B,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,yBAAyB,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3B,MAAM,oCAAoC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;QAClC,MAAM,EAAE,+BAA+B,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACxF,MAAM,+BAA+B,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,0BAA0B,EAAE,CAAC;QACxC,MAAM,EAAE,sCAAsC,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAC/F,MAAM,sCAAsC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-setup.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch-setup.ts"],"names":[],"mappings":"AAAA,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCjG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export async function dispatchSetupCommand(sub, args) {
|
|
2
|
+
if (sub === "all") {
|
|
3
|
+
const { runSetupAll } = await import("./setup-all.js");
|
|
4
|
+
await runSetupAll(args);
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
if (sub === "hook") {
|
|
8
|
+
const { runSetupHook } = await import("./setup-hook.js");
|
|
9
|
+
await runSetupHook(args);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (sub === "mcp") {
|
|
13
|
+
const { runSetupMcp } = await import("./setup-mcp.js");
|
|
14
|
+
await runSetupMcp(args);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (sub === "cloud") {
|
|
18
|
+
const { runSetupCloud } = await import("./setup-cloud.js");
|
|
19
|
+
await runSetupCloud(args);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (sub === "doctor") {
|
|
23
|
+
const { runSetupDoctor } = await import("./setup-doctor.js");
|
|
24
|
+
await runSetupDoctor(args);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (sub === "codex") {
|
|
28
|
+
const { runSetupCodex } = await import("./setup-codex.js");
|
|
29
|
+
await runSetupCodex(args);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Unknown setup command: ${sub ?? "(missing)"}`);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=dispatch-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-setup.js","sourceRoot":"","sources":["../../src/cli/dispatch-setup.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAuB,EAAE,IAAc;IAChF,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvD,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACzD,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvD,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC3D,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrB,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC7D,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC3D,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AA2DA,wBAAgB,SAAS,IAAI,IAAI,CAEhC"}
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
const HELP_TEXT = `auditor — Praxis guard CLI
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
auditor setup all Global hook + MCP; cloud environment.json in cwd (or --project)
|
|
6
|
+
auditor setup hook Configure ~/.cursor/hooks.json (all workspaces; use --project for repo)
|
|
7
|
+
auditor setup mcp Configure ~/.cursor/mcp.json praxis-guard server
|
|
8
|
+
auditor setup cloud Configure .cursor/environment.json for Cloud Agents
|
|
9
|
+
auditor setup doctor Validate global hook + MCP setup (reports project hooks too)
|
|
10
|
+
auditor setup codex Configure repo-local .codex MCP + hooks (--project, --dry-run)
|
|
11
|
+
auditor setup codex doctor Validate repo-local Codex setup
|
|
12
|
+
auditor login Authenticate this CLI with your Praxis account (device code flow)
|
|
13
|
+
auditor logout [--revoke] Remove saved credentials (and optionally revoke token server-side)
|
|
14
|
+
auditor token create Generate a new bearer token (for Cloud Agents, CI, etc.)
|
|
15
|
+
auditor whoami Show signed-in uid, email, and token source (calls Cloud Function)
|
|
16
|
+
auditor mcp MCP stdio server (tools: guard, guard_wait) — use in Cursor mcp.json
|
|
17
|
+
auditor approvals list List pending approval requests
|
|
18
|
+
auditor approvals open <id> Print approval URL for a request
|
|
19
|
+
auditor approvals approve <id> Dev-only: approve request (GUARD_APPROVAL_DEV=1)
|
|
20
|
+
auditor approvals deny <id> Deny an approval request (human auth or dev)
|
|
21
|
+
auditor approvals watch <id> Poll until approved and write execution ticket
|
|
22
|
+
auditor hook before-shell Cursor beforeShellExecution (stdin JSON → stdout JSON)
|
|
23
|
+
auditor hook before-mcp Cursor beforeMCPExecution (stdin JSON → stdout JSON)
|
|
24
|
+
auditor hook claude-code Claude Code PreToolUse/Bash (stdin JSON → stdout JSON)
|
|
25
|
+
auditor hook codex-pre-tool-use Codex PreToolUse (Bash + MCP)
|
|
26
|
+
auditor hook codex-permission-request Codex PermissionRequest (Bash + MCP)
|
|
27
|
+
auditor doctor Show policy path, sync revision, auth status
|
|
28
|
+
auditor policies sync Fetch policies from Cloud Functions → local policies.v1.json + meta
|
|
29
|
+
auditor version Package version and git short SHA when available
|
|
30
|
+
auditor help | --help This message
|
|
31
|
+
|
|
32
|
+
Auth:
|
|
33
|
+
Token is resolved in order: PRAXIS_GUARD_TOKEN env var → ~/.config/praxis/credentials.json.
|
|
34
|
+
Run \`auditor login\` to authenticate interactively.
|
|
35
|
+
|
|
36
|
+
Defaults (production):
|
|
37
|
+
Project ID and region use built-in Praxis production values unless overridden below.
|
|
38
|
+
Function URLs are derived from project/region or explicit base-url env vars.
|
|
39
|
+
|
|
40
|
+
Local development:
|
|
41
|
+
Set PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST to your Functions emulator host:port.
|
|
42
|
+
|
|
43
|
+
Env (all optional):
|
|
44
|
+
PRAXIS_GUARD_TOKEN Override token (CI/CD). Skips credential file.
|
|
45
|
+
PRAXIS_FIREBASE_ID_TOKEN Alternative: Firebase Auth ID JWT for the functions project.
|
|
46
|
+
PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST Functions emulator host:port (local dev).
|
|
47
|
+
PRAXIS_FIREBASE_PROJECT_ID Override Firebase project id.
|
|
48
|
+
PRAXIS_FIREBASE_FUNCTIONS_REGION Override Functions region.
|
|
49
|
+
PRAXIS_FIREBASE_CALLABLE_BASE_URL Full override base URL (no trailing slash).
|
|
50
|
+
PRAXIS_GUARD_EVENT_URL Full override for guard event endpoint.
|
|
51
|
+
PRAXIS_APP_URL Web app origin for login and approval links.
|
|
52
|
+
PRAXIS_POLICIES_V1_PATH Override path for policies.v1.json (default: ~/.praxis/policies.v1.json).
|
|
53
|
+
PRAXIS_POLICIES_META_PATH Override path for policies.v1.meta.json (default beside policy file).
|
|
54
|
+
PRAXIS_GUARD_STORAGE_ROOT Workspace root for .praxis/guard tickets/pending (auto-detected from cwd).
|
|
55
|
+
PRAXIS_HOOK_INLINE_APPROVAL Set to 0 to disable hook-inline approval request on MUTATE deny (default: on).
|
|
56
|
+
PRAXIS_HOOK_INLINE_APPROVAL_TIMEOUT_MS Max ms for inline approval HTTP from hooks (default: 1200).
|
|
57
|
+
`;
|
|
58
|
+
export function printHelp() {
|
|
59
|
+
process.stdout.write(HELP_TEXT);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDjB,CAAC;AAEF,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAQA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkH1D"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,63 +1,9 @@
|
|
|
1
1
|
import process from "node:process";
|
|
2
2
|
import { runDoctor } from "./doctor.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { dispatchHookCommand } from "./dispatch-hook.js";
|
|
4
|
+
import { dispatchSetupCommand } from "./dispatch-setup.js";
|
|
5
|
+
import { printHelp } from "./help.js";
|
|
6
6
|
import { runVersion } from "./version.js";
|
|
7
|
-
function printHelp() {
|
|
8
|
-
process.stdout.write(`auditor — Praxis guard CLI
|
|
9
|
-
|
|
10
|
-
Usage:
|
|
11
|
-
auditor setup all Global hook + MCP; cloud environment.json in cwd (or --project)
|
|
12
|
-
auditor setup hook Configure ~/.cursor/hooks.json (all workspaces; use --project for repo)
|
|
13
|
-
auditor setup mcp Configure ~/.cursor/mcp.json praxis-guard server
|
|
14
|
-
auditor setup cloud Configure .cursor/environment.json for Cloud Agents
|
|
15
|
-
auditor setup doctor Validate global hook + MCP setup (reports project hooks too)
|
|
16
|
-
auditor login Authenticate this CLI with your Praxis account (device code flow)
|
|
17
|
-
auditor logout [--revoke] Remove saved credentials (and optionally revoke token server-side)
|
|
18
|
-
auditor token create Generate a new bearer token (for Cloud Agents, CI, etc.)
|
|
19
|
-
auditor whoami Show signed-in uid, email, and token source (calls Cloud Function)
|
|
20
|
-
auditor mcp MCP stdio server (tools: guard, guard_wait) — use in Cursor mcp.json
|
|
21
|
-
auditor approvals list List pending approval requests
|
|
22
|
-
auditor approvals open <id> Print approval URL for a request
|
|
23
|
-
auditor approvals approve <id> Dev-only: approve request (GUARD_APPROVAL_DEV=1)
|
|
24
|
-
auditor approvals deny <id> Deny an approval request (human auth or dev)
|
|
25
|
-
auditor approvals watch <id> Poll until approved and write execution ticket
|
|
26
|
-
auditor hook before-shell Cursor beforeShellExecution (stdin JSON → stdout JSON)
|
|
27
|
-
auditor hook before-mcp Cursor beforeMCPExecution (stdin JSON → stdout JSON)
|
|
28
|
-
auditor hook claude-code Claude Code PreToolUse/Bash (stdin JSON → stdout JSON)
|
|
29
|
-
auditor doctor Show policy path, sync revision, auth status
|
|
30
|
-
auditor policies sync Fetch policies from Cloud Functions → local policies.v1.json + meta
|
|
31
|
-
auditor version Package version and git short SHA when available
|
|
32
|
-
auditor help | --help This message
|
|
33
|
-
|
|
34
|
-
Auth:
|
|
35
|
-
Token is resolved in order: PRAXIS_GUARD_TOKEN env var → ~/.config/praxis/credentials.json.
|
|
36
|
-
Run \`auditor login\` to authenticate interactively.
|
|
37
|
-
|
|
38
|
-
Defaults (production):
|
|
39
|
-
Project ID and region use built-in Praxis production values unless overridden below.
|
|
40
|
-
Function URLs are derived from project/region or explicit base-url env vars.
|
|
41
|
-
|
|
42
|
-
Local development:
|
|
43
|
-
Set PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST to your Functions emulator host:port.
|
|
44
|
-
|
|
45
|
-
Env (all optional):
|
|
46
|
-
PRAXIS_GUARD_TOKEN Override token (CI/CD). Skips credential file.
|
|
47
|
-
PRAXIS_FIREBASE_ID_TOKEN Alternative: Firebase Auth ID JWT for the functions project.
|
|
48
|
-
PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST Functions emulator host:port (local dev).
|
|
49
|
-
PRAXIS_FIREBASE_PROJECT_ID Override Firebase project id.
|
|
50
|
-
PRAXIS_FIREBASE_FUNCTIONS_REGION Override Functions region.
|
|
51
|
-
PRAXIS_FIREBASE_CALLABLE_BASE_URL Full override base URL (no trailing slash).
|
|
52
|
-
PRAXIS_GUARD_EVENT_URL Full override for guard event endpoint.
|
|
53
|
-
PRAXIS_APP_URL Web app origin for login and approval links.
|
|
54
|
-
PRAXIS_POLICIES_V1_PATH Override path for policies.v1.json (default: ~/.praxis/policies.v1.json).
|
|
55
|
-
PRAXIS_POLICIES_META_PATH Override path for policies.v1.meta.json (default beside policy file).
|
|
56
|
-
PRAXIS_GUARD_STORAGE_ROOT Workspace root for .praxis/guard tickets/pending (auto-detected from cwd).
|
|
57
|
-
PRAXIS_HOOK_INLINE_APPROVAL Set to 0 to disable hook-inline approval request on MUTATE deny (default: on).
|
|
58
|
-
PRAXIS_HOOK_INLINE_APPROVAL_TIMEOUT_MS Max ms for inline approval HTTP from hooks (default: 1200).
|
|
59
|
-
`);
|
|
60
|
-
}
|
|
61
7
|
export async function runCli(argv) {
|
|
62
8
|
const a0 = argv[0];
|
|
63
9
|
const a1 = argv[1];
|
|
@@ -90,35 +36,9 @@ export async function runCli(argv) {
|
|
|
90
36
|
return;
|
|
91
37
|
}
|
|
92
38
|
if (a0 === "setup") {
|
|
93
|
-
const sub = a1;
|
|
94
|
-
const rest = argv.slice(2);
|
|
95
39
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
await runSetupAll(rest);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (sub === "hook") {
|
|
102
|
-
const { runSetupHook } = await import("./setup-hook.js");
|
|
103
|
-
await runSetupHook(rest);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (sub === "mcp") {
|
|
107
|
-
const { runSetupMcp } = await import("./setup-mcp.js");
|
|
108
|
-
await runSetupMcp(rest);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (sub === "cloud") {
|
|
112
|
-
const { runSetupCloud } = await import("./setup-cloud.js");
|
|
113
|
-
await runSetupCloud(rest);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (sub === "doctor") {
|
|
117
|
-
const { runSetupDoctor } = await import("./setup-doctor.js");
|
|
118
|
-
await runSetupDoctor(rest);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
throw new Error(`Unknown setup command: ${sub ?? "(missing)"}`);
|
|
40
|
+
await dispatchSetupCommand(a1, argv.slice(2));
|
|
41
|
+
return;
|
|
122
42
|
}
|
|
123
43
|
catch (e) {
|
|
124
44
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -176,18 +96,8 @@ export async function runCli(argv) {
|
|
|
176
96
|
await runMcpStdioServer();
|
|
177
97
|
return;
|
|
178
98
|
}
|
|
179
|
-
if (a0 === "hook" && a1
|
|
180
|
-
await runBeforeShellHookFromStdin();
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
if (a0 === "hook" && a1 === "before-mcp") {
|
|
184
|
-
await runBeforeMcpHookFromStdin();
|
|
99
|
+
if (a0 === "hook" && (await dispatchHookCommand(a1)))
|
|
185
100
|
return;
|
|
186
|
-
}
|
|
187
|
-
if (a0 === "hook" && a1 === "claude-code") {
|
|
188
|
-
await runClaudeCodePreToolUseHookFromStdin();
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
101
|
if (a0 === "approvals") {
|
|
192
102
|
const { runApprovals } = await import("./approvals.js");
|
|
193
103
|
try {
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type CodexSetupOptions = {
|
|
2
|
+
projectDir: string;
|
|
3
|
+
dryRun: boolean;
|
|
4
|
+
doctor: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function parseSetupCodexOptions(args: string[]): CodexSetupOptions;
|
|
7
|
+
export declare function runSetupCodex(args: string[]): Promise<void>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=setup-codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-codex.d.ts","sourceRoot":"","sources":["../../src/cli/setup-codex.ts"],"names":[],"mappings":"AAQA,KAAK,iBAAiB,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CA0BxE;AAmBD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAejE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { readCodexSetupStatus, upsertCodexConfig, upsertCodexHooks, } from "../codex/config.js";
|
|
3
|
+
export function parseSetupCodexOptions(args) {
|
|
4
|
+
let projectDir = process.cwd();
|
|
5
|
+
let dryRun = false;
|
|
6
|
+
let doctor = false;
|
|
7
|
+
for (let i = 0; i < args.length; i++) {
|
|
8
|
+
const arg = args[i];
|
|
9
|
+
if (arg === "doctor") {
|
|
10
|
+
doctor = true;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (arg === "--dry-run") {
|
|
14
|
+
dryRun = true;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (arg === "--project") {
|
|
18
|
+
const value = args[i + 1];
|
|
19
|
+
if (!value)
|
|
20
|
+
throw new Error("Missing value for --project");
|
|
21
|
+
projectDir = value;
|
|
22
|
+
i++;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`Unknown setup codex option: ${arg}`);
|
|
26
|
+
}
|
|
27
|
+
return { projectDir, dryRun, doctor };
|
|
28
|
+
}
|
|
29
|
+
async function runCodexDoctor(projectDir) {
|
|
30
|
+
const status = await readCodexSetupStatus(projectDir);
|
|
31
|
+
const hookReady = status.preToolUseConfigured && status.permissionRequestConfigured;
|
|
32
|
+
const ready = status.mcpConfigured && hookReady;
|
|
33
|
+
const lines = [
|
|
34
|
+
`Codex setup doctor (${projectDir}):`,
|
|
35
|
+
` MCP: ${status.mcpConfigured ? "configured" : "missing"} (${status.configPath})`,
|
|
36
|
+
` PreToolUse: ${status.preToolUseConfigured ? "configured" : "missing"} (${status.hooksPath})`,
|
|
37
|
+
` PermissionRequest: ${status.permissionRequestConfigured ? "configured" : "missing"} (${status.hooksPath})`,
|
|
38
|
+
` AGENTS.md: ${status.agentsGuidancePresent ? "present" : "missing (recommended)"}`,
|
|
39
|
+
" Hook trust: cannot be verified by auditor; review and trust the hooks in Codex.",
|
|
40
|
+
` Ready: ${ready ? "yes" : "no"}`,
|
|
41
|
+
];
|
|
42
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
43
|
+
if (!ready)
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
export async function runSetupCodex(args) {
|
|
47
|
+
const opts = parseSetupCodexOptions(args);
|
|
48
|
+
if (opts.doctor) {
|
|
49
|
+
await runCodexDoctor(opts.projectDir);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const [config, hooks] = await Promise.all([
|
|
53
|
+
upsertCodexConfig(opts.projectDir, opts.dryRun),
|
|
54
|
+
upsertCodexHooks(opts.projectDir, opts.dryRun),
|
|
55
|
+
]);
|
|
56
|
+
process.stdout.write(`setup codex (${opts.projectDir}):\n`);
|
|
57
|
+
process.stdout.write(` mcp: ${config.message}\n path: ${config.path}\n`);
|
|
58
|
+
process.stdout.write(` hooks: ${hooks.message}\n path: ${hooks.path}\n`);
|
|
59
|
+
process.stdout.write(" next: open the project in Codex and review/trust the Praxis hooks.\n");
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=setup-codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-codex.js","sourceRoot":"","sources":["../../src/cli/setup-codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type JsonMap = Record<string, unknown>;
|
|
2
|
+
export type CodexSetupResult = {
|
|
3
|
+
path: string;
|
|
4
|
+
changed: boolean;
|
|
5
|
+
message: string;
|
|
6
|
+
};
|
|
7
|
+
export type CodexSetupStatus = {
|
|
8
|
+
configPath: string;
|
|
9
|
+
hooksPath: string;
|
|
10
|
+
mcpConfigured: boolean;
|
|
11
|
+
preToolUseConfigured: boolean;
|
|
12
|
+
permissionRequestConfigured: boolean;
|
|
13
|
+
agentsGuidancePresent: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare function codexConfigPath(projectDir: string): string;
|
|
16
|
+
export declare function codexHooksPath(projectDir: string): string;
|
|
17
|
+
export declare function mergeCodexConfigToml(source: string): string;
|
|
18
|
+
export declare function mergeCodexHooks(existing: JsonMap | null): JsonMap;
|
|
19
|
+
export declare function upsertCodexConfig(projectDir: string, dryRun?: boolean): Promise<CodexSetupResult>;
|
|
20
|
+
export declare function upsertCodexHooks(projectDir: string, dryRun?: boolean): Promise<CodexSetupResult>;
|
|
21
|
+
export declare function readCodexSetupStatus(projectDir: string): Promise<CodexSetupStatus>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/codex/config.ts"],"names":[],"mappings":"AAUA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvC,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,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;AAsDD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG3D;AAoCD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAqBjE;AAED,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;AAgBD,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgBxF"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
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
|
+
export function codexConfigPath(projectDir) {
|
|
10
|
+
return path.join(projectDir, CODEX_DIR, "config.toml");
|
|
11
|
+
}
|
|
12
|
+
export function codexHooksPath(projectDir) {
|
|
13
|
+
return path.join(projectDir, CODEX_DIR, "hooks.json");
|
|
14
|
+
}
|
|
15
|
+
async function readText(pathname) {
|
|
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
|
+
export function mergeCodexConfigToml(source) {
|
|
61
|
+
const base = removePraxisMcpTables(source);
|
|
62
|
+
return `${base ? `${base}\n\n` : ""}${renderPraxisMcpConfig()}\n`;
|
|
63
|
+
}
|
|
64
|
+
async function readJson(pathname) {
|
|
65
|
+
const raw = await readText(pathname);
|
|
66
|
+
if (!raw)
|
|
67
|
+
return null;
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(raw);
|
|
70
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
71
|
+
throw new Error("JSON root must be an object");
|
|
72
|
+
}
|
|
73
|
+
return parsed;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw new Error(`Invalid JSON at ${pathname}: ${String(error)}. Refusing to overwrite existing file.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function commandHook(command, statusMessage) {
|
|
80
|
+
return { type: "command", command, timeout: 30, statusMessage };
|
|
81
|
+
}
|
|
82
|
+
function isPraxisHookGroup(value) {
|
|
83
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
84
|
+
return false;
|
|
85
|
+
const hooks = value.hooks;
|
|
86
|
+
if (!Array.isArray(hooks))
|
|
87
|
+
return false;
|
|
88
|
+
return hooks.some((hook) => {
|
|
89
|
+
if (!hook || typeof hook !== "object" || Array.isArray(hook))
|
|
90
|
+
return false;
|
|
91
|
+
const command = hook.command;
|
|
92
|
+
return command === PRE_TOOL_COMMAND || command === PERMISSION_COMMAND;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function replacePraxisGroups(existing, additions) {
|
|
96
|
+
const groups = Array.isArray(existing) ? existing.filter((entry) => !isPraxisHookGroup(entry)) : [];
|
|
97
|
+
return [...groups, ...additions];
|
|
98
|
+
}
|
|
99
|
+
export function mergeCodexHooks(existing) {
|
|
100
|
+
const config = existing ? structuredClone(existing) : {};
|
|
101
|
+
const hooks = config.hooks && typeof config.hooks === "object" && !Array.isArray(config.hooks)
|
|
102
|
+
? config.hooks
|
|
103
|
+
: {};
|
|
104
|
+
config.hooks = hooks;
|
|
105
|
+
hooks.PreToolUse = replacePraxisGroups(hooks.PreToolUse, [
|
|
106
|
+
{
|
|
107
|
+
matcher: "^Bash$|^mcp__.*",
|
|
108
|
+
hooks: [commandHook(PRE_TOOL_COMMAND, "Checking Praxis policy")],
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
hooks.PermissionRequest = replacePraxisGroups(hooks.PermissionRequest, [
|
|
112
|
+
{
|
|
113
|
+
matcher: "^Bash$|^mcp__.*",
|
|
114
|
+
hooks: [commandHook(PERMISSION_COMMAND, "Checking Praxis approval")],
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
export async function upsertCodexConfig(projectDir, dryRun = false) {
|
|
120
|
+
const pathname = codexConfigPath(projectDir);
|
|
121
|
+
const before = await readText(pathname);
|
|
122
|
+
const after = mergeCodexConfigToml(before);
|
|
123
|
+
const changed = before !== after;
|
|
124
|
+
if (changed && !dryRun)
|
|
125
|
+
await writeAtomic(pathname, after);
|
|
126
|
+
return {
|
|
127
|
+
path: pathname,
|
|
128
|
+
changed,
|
|
129
|
+
message: changed ? (dryRun ? "would update Codex MCP config" : "updated Codex MCP config") : "Codex MCP config already up to date",
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export async function upsertCodexHooks(projectDir, dryRun = false) {
|
|
133
|
+
const pathname = codexHooksPath(projectDir);
|
|
134
|
+
const existing = await readJson(pathname);
|
|
135
|
+
const before = existing ? `${JSON.stringify(existing, null, 2)}\n` : "";
|
|
136
|
+
const after = `${JSON.stringify(mergeCodexHooks(existing), null, 2)}\n`;
|
|
137
|
+
const changed = before !== after;
|
|
138
|
+
if (changed && !dryRun)
|
|
139
|
+
await writeAtomic(pathname, after);
|
|
140
|
+
return {
|
|
141
|
+
path: pathname,
|
|
142
|
+
changed,
|
|
143
|
+
message: changed ? (dryRun ? "would update Codex hooks" : "updated Codex hooks") : "Codex hooks already up to date",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function hooksContainCommand(config, event, command) {
|
|
147
|
+
const hooks = config?.hooks;
|
|
148
|
+
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks))
|
|
149
|
+
return false;
|
|
150
|
+
const groups = hooks[event];
|
|
151
|
+
if (!Array.isArray(groups))
|
|
152
|
+
return false;
|
|
153
|
+
return groups.some((group) => {
|
|
154
|
+
if (!group || typeof group !== "object" || Array.isArray(group))
|
|
155
|
+
return false;
|
|
156
|
+
const handlers = group.hooks;
|
|
157
|
+
return Array.isArray(handlers) && handlers.some((handler) => {
|
|
158
|
+
return !!handler && typeof handler === "object" && handler.command === command;
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
export async function readCodexSetupStatus(projectDir) {
|
|
163
|
+
const configPath = codexConfigPath(projectDir);
|
|
164
|
+
const hooksPath = codexHooksPath(projectDir);
|
|
165
|
+
const [config, hooks] = await Promise.all([readText(configPath), readJson(hooksPath).catch(() => null)]);
|
|
166
|
+
return {
|
|
167
|
+
configPath,
|
|
168
|
+
hooksPath,
|
|
169
|
+
mcpConfigured: config.includes(MCP_HEADER) &&
|
|
170
|
+
config.includes('command = "auditor"') &&
|
|
171
|
+
config.includes('PRAXIS_AGENT_HOST = "codex-app"'),
|
|
172
|
+
preToolUseConfigured: hooksContainCommand(hooks, "PreToolUse", PRE_TOOL_COMMAND),
|
|
173
|
+
permissionRequestConfigured: hooksContainCommand(hooks, "PermissionRequest", PERMISSION_COMMAND),
|
|
174
|
+
agentsGuidancePresent: existsSync(path.join(projectDir, "AGENTS.md")) || existsSync(path.join(projectDir, "AGENT.md")),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/codex/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Tier } from "../policy/index.js";
|
|
2
|
+
export type CodexToolPayload = {
|
|
3
|
+
session_id?: string;
|
|
4
|
+
turn_id?: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
hook_event_name?: string;
|
|
7
|
+
tool_name?: string;
|
|
8
|
+
tool_use_id?: string;
|
|
9
|
+
tool_input?: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type CodexEvaluation = {
|
|
12
|
+
governed: boolean;
|
|
13
|
+
allowed: boolean;
|
|
14
|
+
tier: Tier;
|
|
15
|
+
argv: string[];
|
|
16
|
+
reason?: string;
|
|
17
|
+
storageRoot: string;
|
|
18
|
+
toolInputHash?: string | null;
|
|
19
|
+
};
|
|
20
|
+
type McpIdentity = {
|
|
21
|
+
server: string;
|
|
22
|
+
tool: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseCodexMcpToolName(toolName: string): McpIdentity | null;
|
|
25
|
+
export declare function isPraxisGuardTool(toolName: string): boolean;
|
|
26
|
+
export declare function evaluateCodexTool(payload: CodexToolPayload): Promise<CodexEvaluation>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=evaluate-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate-tool.d.ts","sourceRoot":"","sources":["../../src/codex/evaluate-tool.ts"],"names":[],"mappings":"AAMA,OAAO,EAA0C,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQvF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAK1E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI3D;AAuKD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAW3F"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { appendAuditJsonl } from "../audit/jsonl.js";
|
|
2
|
+
import { toolInputSha256 } from "../approval/fingerprint.js";
|
|
3
|
+
import { resolveGuardStorageRoot } from "../bridge/guard-storage-root.js";
|
|
4
|
+
import { formatHookDenyMessages } from "../hooks/agent-message.js";
|
|
5
|
+
import { resolveMutateHookPermission } from "../hooks/before-mcp-mutate.js";
|
|
6
|
+
import { resolveShellMutateHookPermission } from "../hooks/before-shell-mutate.js";
|
|
7
|
+
import { loadPoliciesV1, readPoliciesV1Revision } from "../policy/index.js";
|
|
8
|
+
import { analyzeShellCommand } from "../shell/analyze-command.js";
|
|
9
|
+
import { commandMayContainGovernedTool } from "../shell/governed-tools.js";
|
|
10
|
+
import { evaluateMcpProposal } from "../shell/evaluate.js";
|
|
11
|
+
import { sendGuardEvent } from "../telemetry/guard-events.js";
|
|
12
|
+
import { recordCodexPermissionHandoff } from "./permission-handoff.js";
|
|
13
|
+
export function parseCodexMcpToolName(toolName) {
|
|
14
|
+
if (!toolName.startsWith("mcp__"))
|
|
15
|
+
return null;
|
|
16
|
+
const parts = toolName.slice("mcp__".length).split("__");
|
|
17
|
+
if (parts.length < 2)
|
|
18
|
+
return null;
|
|
19
|
+
return { server: parts.slice(0, -1).join("__") || "stdio", tool: parts.at(-1) || "_" };
|
|
20
|
+
}
|
|
21
|
+
export function isPraxisGuardTool(toolName) {
|
|
22
|
+
const identity = parseCodexMcpToolName(toolName);
|
|
23
|
+
if (!identity || (identity.tool !== "guard" && identity.tool !== "guard_wait"))
|
|
24
|
+
return false;
|
|
25
|
+
return /^praxis(?:-|_)guard$/i.test(identity.server);
|
|
26
|
+
}
|
|
27
|
+
function codexReason(input) {
|
|
28
|
+
const formatted = formatHookDenyMessages({
|
|
29
|
+
hook: input.kind === "shell" ? "beforeShellExecution" : "beforeMCPExecution",
|
|
30
|
+
tier: input.tier,
|
|
31
|
+
argv: input.argv,
|
|
32
|
+
reasons: input.reasons,
|
|
33
|
+
toolName: input.toolName,
|
|
34
|
+
inlineApproval: input.inlineApproval,
|
|
35
|
+
});
|
|
36
|
+
return formatted.agent_message;
|
|
37
|
+
}
|
|
38
|
+
async function auditAndSend(input) {
|
|
39
|
+
const event = {
|
|
40
|
+
ts: new Date().toISOString(),
|
|
41
|
+
hook: "codexPreToolUse",
|
|
42
|
+
agent: "codex-app",
|
|
43
|
+
tool_name: input.payload.tool_name,
|
|
44
|
+
tool_input: input.payload.tool_input,
|
|
45
|
+
argv: input.argv,
|
|
46
|
+
tier: input.tier,
|
|
47
|
+
decision: input.allowed ? "allow" : "block",
|
|
48
|
+
governed: input.governed,
|
|
49
|
+
ticketConsumed: input.ticketConsumed,
|
|
50
|
+
reasons: input.reasons,
|
|
51
|
+
latency_ms: input.latencyMs,
|
|
52
|
+
};
|
|
53
|
+
await appendAuditJsonl(event, input.storageRoot).catch((error) => {
|
|
54
|
+
process.stderr.write(`[auditor] audit log append failed: ${String(error)}\n`);
|
|
55
|
+
});
|
|
56
|
+
await sendGuardEvent({
|
|
57
|
+
...event,
|
|
58
|
+
status: input.allowed ? "passed" : "blocked",
|
|
59
|
+
tool: input.kind === "shell" ? "auditor-hook" : "auditor-hook-mcp",
|
|
60
|
+
command_path: input.argv[0] ?? null,
|
|
61
|
+
verb: input.argv[1] ?? null,
|
|
62
|
+
resource: input.argv.slice(2).join(" ") || null,
|
|
63
|
+
kind: input.kind,
|
|
64
|
+
...(input.policyRevision !== null ? { policy_revision: input.policyRevision } : {}),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function shellReasons(analysis) {
|
|
68
|
+
const reasons = [];
|
|
69
|
+
if (!analysis.primary.evaluation.classification.matched)
|
|
70
|
+
reasons.push("unknown_command(default_deny)");
|
|
71
|
+
if (analysis.primary.evaluation.flags.metacharacters || analysis.raw_metacharacters)
|
|
72
|
+
reasons.push("metacharacters");
|
|
73
|
+
if (analysis.primary.evaluation.flags.dangerous_flags)
|
|
74
|
+
reasons.push("dangerous_flags");
|
|
75
|
+
if (analysis.fail_closed)
|
|
76
|
+
reasons.push("unparseable(fail_closed)");
|
|
77
|
+
if (analysis.invocations.length > 1)
|
|
78
|
+
reasons.push(`multiple_governed_invocations(${analysis.invocations.length})`);
|
|
79
|
+
return reasons;
|
|
80
|
+
}
|
|
81
|
+
async function evaluateBash(payload, started) {
|
|
82
|
+
const command = payload.tool_input && typeof payload.tool_input === "object"
|
|
83
|
+
? payload.tool_input.command
|
|
84
|
+
: undefined;
|
|
85
|
+
const rawCommand = typeof command === "string" ? command : "";
|
|
86
|
+
const storageRoot = resolveGuardStorageRoot(payload.cwd);
|
|
87
|
+
if (!rawCommand || !commandMayContainGovernedTool(rawCommand)) {
|
|
88
|
+
return { governed: false, allowed: true, tier: "READ", argv: [], storageRoot };
|
|
89
|
+
}
|
|
90
|
+
const [policy, policyRevision] = await Promise.all([loadPoliciesV1(), readPoliciesV1Revision()]);
|
|
91
|
+
const analysis = analyzeShellCommand(rawCommand, policy);
|
|
92
|
+
if (analysis.skipped) {
|
|
93
|
+
return { governed: false, allowed: true, tier: "READ", argv: [], storageRoot };
|
|
94
|
+
}
|
|
95
|
+
const argv = analysis.primary.canonical_argv;
|
|
96
|
+
const tier = analysis.tier;
|
|
97
|
+
const reasons = shellReasons(analysis);
|
|
98
|
+
let allowed = tier === "READ";
|
|
99
|
+
let ticketConsumed = false;
|
|
100
|
+
let inlineApproval = null;
|
|
101
|
+
if (tier === "MUTATE") {
|
|
102
|
+
const mutate = await resolveShellMutateHookPermission({
|
|
103
|
+
tier,
|
|
104
|
+
argv,
|
|
105
|
+
analysis,
|
|
106
|
+
storageRoot,
|
|
107
|
+
rawDisplay: rawCommand,
|
|
108
|
+
policyRevision,
|
|
109
|
+
initialReasons: reasons,
|
|
110
|
+
});
|
|
111
|
+
allowed = mutate.permission === "allow";
|
|
112
|
+
ticketConsumed = mutate.ticketConsumed;
|
|
113
|
+
inlineApproval = mutate.inlineApproval;
|
|
114
|
+
reasons.splice(0, reasons.length, ...mutate.reasons);
|
|
115
|
+
}
|
|
116
|
+
if (ticketConsumed) {
|
|
117
|
+
await recordCodexPermissionHandoff({ storageRoot, argv, turnId: payload.turn_id });
|
|
118
|
+
}
|
|
119
|
+
const reason = allowed ? undefined : codexReason({ kind: "shell", tier, argv, reasons, inlineApproval });
|
|
120
|
+
await auditAndSend({ payload, kind: "shell", tier, argv, allowed, governed: true, ticketConsumed, reasons, policyRevision, storageRoot, latencyMs: performance.now() - started });
|
|
121
|
+
return { governed: true, allowed, tier, argv, reason, storageRoot };
|
|
122
|
+
}
|
|
123
|
+
async function evaluateMcp(payload, started) {
|
|
124
|
+
const toolName = payload.tool_name ?? "";
|
|
125
|
+
const identity = parseCodexMcpToolName(toolName);
|
|
126
|
+
const storageRoot = resolveGuardStorageRoot(payload.cwd);
|
|
127
|
+
if (!identity || isPraxisGuardTool(toolName)) {
|
|
128
|
+
return { governed: false, allowed: true, tier: "READ", argv: [], storageRoot };
|
|
129
|
+
}
|
|
130
|
+
const argv = ["mcp", identity.server, identity.tool];
|
|
131
|
+
const [policy, policyRevision] = await Promise.all([loadPoliciesV1(), readPoliciesV1Revision()]);
|
|
132
|
+
const { skipped, evaluation } = evaluateMcpProposal(policy, argv);
|
|
133
|
+
if (skipped)
|
|
134
|
+
return { governed: false, allowed: true, tier: "READ", argv, storageRoot };
|
|
135
|
+
const tier = evaluation.tier;
|
|
136
|
+
const reasons = evaluation.reasons.map((reason) => reason.message);
|
|
137
|
+
const toolInputHash = toolInputSha256(payload.tool_input);
|
|
138
|
+
let allowed = tier === "READ";
|
|
139
|
+
let ticketConsumed = false;
|
|
140
|
+
let inlineApproval = null;
|
|
141
|
+
if (tier === "MUTATE") {
|
|
142
|
+
const mutate = await resolveMutateHookPermission({
|
|
143
|
+
argv,
|
|
144
|
+
tier,
|
|
145
|
+
storageRoot,
|
|
146
|
+
toolInputHash,
|
|
147
|
+
rawToolName: toolName,
|
|
148
|
+
toolInputPreview: JSON.stringify(payload.tool_input ?? {}).slice(0, 200),
|
|
149
|
+
policyRevision,
|
|
150
|
+
initialReasons: reasons,
|
|
151
|
+
});
|
|
152
|
+
allowed = mutate.permission === "allow";
|
|
153
|
+
ticketConsumed = mutate.ticketConsumed;
|
|
154
|
+
inlineApproval = mutate.inlineApproval;
|
|
155
|
+
reasons.splice(0, reasons.length, ...mutate.reasons);
|
|
156
|
+
}
|
|
157
|
+
if (ticketConsumed) {
|
|
158
|
+
await recordCodexPermissionHandoff({
|
|
159
|
+
storageRoot,
|
|
160
|
+
argv,
|
|
161
|
+
toolInputHash,
|
|
162
|
+
turnId: payload.turn_id,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
const reason = allowed ? undefined : codexReason({ kind: "mcp", tier, argv, reasons, toolName, inlineApproval });
|
|
166
|
+
await auditAndSend({ payload, kind: "mcp", tier, argv, allowed, governed: true, ticketConsumed, reasons, policyRevision, storageRoot, latencyMs: performance.now() - started });
|
|
167
|
+
return { governed: true, allowed, tier, argv, reason, storageRoot, toolInputHash };
|
|
168
|
+
}
|
|
169
|
+
export async function evaluateCodexTool(payload) {
|
|
170
|
+
const started = performance.now();
|
|
171
|
+
if (payload.tool_name === "Bash")
|
|
172
|
+
return evaluateBash(payload, started);
|
|
173
|
+
if (payload.tool_name?.startsWith("mcp__"))
|
|
174
|
+
return evaluateMcp(payload, started);
|
|
175
|
+
return {
|
|
176
|
+
governed: false,
|
|
177
|
+
allowed: true,
|
|
178
|
+
tier: "READ",
|
|
179
|
+
argv: [],
|
|
180
|
+
storageRoot: resolveGuardStorageRoot(payload.cwd),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=evaluate-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate-tool.js","sourceRoot":"","sources":["../../src/codex/evaluate-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function recordCodexPermissionHandoff(input: {
|
|
2
|
+
storageRoot: string;
|
|
3
|
+
argv: readonly string[];
|
|
4
|
+
toolInputHash?: string | null;
|
|
5
|
+
turnId?: string | null;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function consumeCodexPermissionHandoff(input: {
|
|
8
|
+
storageRoot: string;
|
|
9
|
+
argv: readonly string[];
|
|
10
|
+
toolInputHash?: string | null;
|
|
11
|
+
turnId?: string | null;
|
|
12
|
+
}): Promise<boolean>;
|
|
13
|
+
//# sourceMappingURL=permission-handoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-handoff.d.ts","sourceRoot":"","sources":["../../src/codex/permission-handoff.ts"],"names":[],"mappings":"AAgCA,wBAAsB,4BAA4B,CAAC,KAAK,EAAE;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhB;AAED,wBAAsB,6BAA6B,CAAC,KAAK,EAAE;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { guardSubpath } from "../bridge/guard-storage-root.js";
|
|
5
|
+
const HANDOFF_TTL_MS = 2 * 60 * 1000;
|
|
6
|
+
function handoffKey(argv, toolInputHash, turnId) {
|
|
7
|
+
return createHash("sha256")
|
|
8
|
+
.update(JSON.stringify({ argv: [...argv], toolInputHash: toolInputHash ?? null, turnId: turnId ?? null }))
|
|
9
|
+
.digest("hex");
|
|
10
|
+
}
|
|
11
|
+
function handoffPath(storageRoot, argv, toolInputHash, turnId) {
|
|
12
|
+
return path.join(guardSubpath("codex-permission-handoffs", storageRoot), `${handoffKey(argv, toolInputHash, turnId)}.json`);
|
|
13
|
+
}
|
|
14
|
+
export async function recordCodexPermissionHandoff(input) {
|
|
15
|
+
const pathname = handoffPath(input.storageRoot, input.argv, input.toolInputHash, input.turnId);
|
|
16
|
+
await mkdir(path.dirname(pathname), { recursive: true });
|
|
17
|
+
await writeFile(pathname, `${JSON.stringify({ createdAt: Date.now() })}\n`, {
|
|
18
|
+
encoding: "utf8",
|
|
19
|
+
mode: 0o600,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function consumeCodexPermissionHandoff(input) {
|
|
23
|
+
const pathname = handoffPath(input.storageRoot, input.argv, input.toolInputHash, input.turnId);
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(await readFile(pathname, "utf8"));
|
|
26
|
+
await unlink(pathname).catch(() => undefined);
|
|
27
|
+
return typeof parsed.createdAt === "number" && Date.now() - parsed.createdAt <= HANDOFF_TTL_MS;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error.code === "ENOENT")
|
|
31
|
+
return false;
|
|
32
|
+
await unlink(pathname).catch(() => undefined);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=permission-handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-handoff.js","sourceRoot":"","sources":["../../src/codex/permission-handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAErC,SAAS,UAAU,CACjB,IAAuB,EACvB,aAA6B,EAC7B,MAAsB;IAEtB,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CACL,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,aAAa,EAAE,aAAa,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,CAClG;SACA,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAClB,WAAmB,EACnB,IAAuB,EACvB,aAA6B,EAC7B,MAAsB;IAEtB,OAAO,IAAI,CAAC,IAAI,CACd,YAAY,CAAC,2BAA2B,EAAE,WAAW,CAAC,EACtD,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAKlD;IACC,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/F,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE;QAC1E,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAKnD;IACC,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/F,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAC;QACvF,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9C,OAAO,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC;IACjG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrE,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-codex-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/run-codex-hooks.ts"],"names":[],"mappings":"AA8BA,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBrE;AAED,wBAAsB,sCAAsC,IAAI,OAAO,CAAC,IAAI,CAAC,CAoC5E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { consumeCodexPermissionHandoff } from "../codex/permission-handoff.js";
|
|
2
|
+
import { evaluateCodexTool } from "../codex/evaluate-tool.js";
|
|
3
|
+
async function readStdinJson() {
|
|
4
|
+
let data = "";
|
|
5
|
+
for await (const chunk of process.stdin)
|
|
6
|
+
data += String(chunk);
|
|
7
|
+
return JSON.parse(data);
|
|
8
|
+
}
|
|
9
|
+
function writeJson(value) {
|
|
10
|
+
process.stdout.write(JSON.stringify(value));
|
|
11
|
+
}
|
|
12
|
+
export async function runCodexPreToolUseHookFromStdin() {
|
|
13
|
+
try {
|
|
14
|
+
const payload = await readStdinJson();
|
|
15
|
+
const result = await evaluateCodexTool(payload);
|
|
16
|
+
if (!result.governed) {
|
|
17
|
+
writeJson({});
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const response = {
|
|
21
|
+
hookSpecificOutput: {
|
|
22
|
+
hookEventName: "PreToolUse",
|
|
23
|
+
permissionDecision: result.allowed ? "allow" : "deny",
|
|
24
|
+
...(result.reason ? { permissionDecisionReason: result.reason } : {}),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
writeJson(response);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
writeJson({
|
|
31
|
+
hookSpecificOutput: {
|
|
32
|
+
hookEventName: "PreToolUse",
|
|
33
|
+
permissionDecision: "deny",
|
|
34
|
+
permissionDecisionReason: `Praxis guard hook failed closed: ${String(error)}`,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function runCodexPermissionRequestHookFromStdin() {
|
|
40
|
+
try {
|
|
41
|
+
const payload = await readStdinJson();
|
|
42
|
+
const result = await evaluateCodexTool(payload);
|
|
43
|
+
if (!result.governed || result.tier === "READ") {
|
|
44
|
+
writeJson({});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const handedOff = await consumeCodexPermissionHandoff({
|
|
48
|
+
storageRoot: result.storageRoot,
|
|
49
|
+
argv: result.argv,
|
|
50
|
+
toolInputHash: result.toolInputHash,
|
|
51
|
+
turnId: payload.turn_id,
|
|
52
|
+
});
|
|
53
|
+
if (handedOff) {
|
|
54
|
+
writeJson({});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const response = {
|
|
58
|
+
hookSpecificOutput: {
|
|
59
|
+
hookEventName: "PermissionRequest",
|
|
60
|
+
decision: {
|
|
61
|
+
behavior: "deny",
|
|
62
|
+
message: result.reason ?? "Use the Praxis guard approval flow for this action.",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
writeJson(response);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
writeJson({
|
|
70
|
+
hookSpecificOutput: {
|
|
71
|
+
hookEventName: "PermissionRequest",
|
|
72
|
+
decision: { behavior: "deny", message: `Praxis guard hook failed closed: ${String(error)}` },
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=run-codex-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-codex-hooks.js","sourceRoot":"","sources":["../../src/hooks/run-codex-hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,6 @@ import type { AgentId } from "../adapters/types.js";
|
|
|
6
6
|
* Returns "unknown" when the env var is unset (legacy installs that pre-date
|
|
7
7
|
* adapter tagging). See docs/auditor-cli-multi-agent-adapter-design.md § PR 3.
|
|
8
8
|
*/
|
|
9
|
-
export type AgentHost = AgentId | "unknown";
|
|
9
|
+
export type AgentHost = AgentId | "codex-app" | "unknown";
|
|
10
10
|
export declare function resolveAgentHost(): AgentHost;
|
|
11
11
|
//# sourceMappingURL=agent-host.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-host.d.ts","sourceRoot":"","sources":["../../src/telemetry/agent-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-host.d.ts","sourceRoot":"","sources":["../../src/telemetry/agent-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;AAU1D,wBAAgB,gBAAgB,IAAI,SAAS,CAI5C"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
const KNOWN_HOSTS = [
|
|
1
|
+
const KNOWN_HOSTS = [
|
|
2
|
+
"cursor",
|
|
3
|
+
"claude-desktop",
|
|
4
|
+
"claude-code",
|
|
5
|
+
"codex-app",
|
|
6
|
+
"unknown",
|
|
7
|
+
];
|
|
2
8
|
export function resolveAgentHost() {
|
|
3
9
|
const raw = process.env.PRAXIS_AGENT_HOST?.trim();
|
|
4
10
|
if (!raw)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-host.js","sourceRoot":"","sources":["../../src/telemetry/agent-host.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,GAAyB,
|
|
1
|
+
{"version":3,"file":"agent-host.js","sourceRoot":"","sources":["../../src/telemetry/agent-host.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,GAAyB;IACxC,QAAQ;IACR,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,SAAS;CACV,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAQ,WAAiC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC"}
|