@zaip-ai/cli 4.2.0 → 4.3.0
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/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/services/adapters.d.ts +2 -2
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +11 -63
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/agent-adapters.d.ts.map +1 -1
- package/dist/services/agent-adapters.js +3 -7
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/agent-adapters.test.js +43 -11
- package/dist/services/agent-adapters.test.js.map +1 -1
- package/dist/services/codex-config-template.js +2 -2
- package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.js +38 -14
- package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
- package/dist/services/codex-hook-activation.d.ts +4 -0
- package/dist/services/codex-hook-activation.d.ts.map +1 -0
- package/dist/services/codex-hook-activation.js +64 -0
- package/dist/services/codex-hook-activation.js.map +1 -0
- package/dist/services/codex-model-policy.d.ts +4 -0
- package/dist/services/codex-model-policy.d.ts.map +1 -0
- package/dist/services/codex-model-policy.js +24 -0
- package/dist/services/codex-model-policy.js.map +1 -0
- package/dist/services/codex-native-tool-authority-template.d.ts +2 -0
- package/dist/services/codex-native-tool-authority-template.d.ts.map +1 -0
- package/dist/services/codex-native-tool-authority-template.js +89 -0
- package/dist/services/codex-native-tool-authority-template.js.map +1 -0
- package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.js +59 -86
- package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.test.js +200 -1
- package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
- package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
- package/dist/services/codex-pre-tool-support-template.js +303 -12
- package/dist/services/codex-pre-tool-support-template.js.map +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
- package/dist/services/codex-subagent-hook-template.js +11 -4
- package/dist/services/codex-subagent-hook-template.js.map +1 -1
- package/dist/services/codex-validation-runtime-template.d.ts +3 -0
- package/dist/services/codex-validation-runtime-template.d.ts.map +1 -0
- package/dist/services/codex-validation-runtime-template.js +18 -0
- package/dist/services/codex-validation-runtime-template.js.map +1 -0
- package/dist/services/codex-windows-hook-command.js +1 -1
- package/dist/services/codex-windows-hook-command.js.map +1 -1
- package/dist/services/codex-windows-hook-command.test.js +22 -0
- package/dist/services/codex-windows-hook-command.test.js.map +1 -1
- package/dist/services/global-codex-config-fixtures.d.ts +12 -0
- package/dist/services/global-codex-config-fixtures.d.ts.map +1 -0
- package/dist/services/global-codex-config-fixtures.js +38 -0
- package/dist/services/global-codex-config-fixtures.js.map +1 -0
- package/dist/services/global-codex-config-migration.test.d.ts +2 -0
- package/dist/services/global-codex-config-migration.test.d.ts.map +1 -0
- package/dist/services/global-codex-config-migration.test.js +301 -0
- package/dist/services/global-codex-config-migration.test.js.map +1 -0
- package/dist/services/global-codex-config-transaction.d.ts +15 -0
- package/dist/services/global-codex-config-transaction.d.ts.map +1 -0
- package/dist/services/global-codex-config-transaction.js +89 -0
- package/dist/services/global-codex-config-transaction.js.map +1 -0
- package/dist/services/global-codex-config-transaction.test.d.ts +2 -0
- package/dist/services/global-codex-config-transaction.test.d.ts.map +1 -0
- package/dist/services/global-codex-config-transaction.test.js +145 -0
- package/dist/services/global-codex-config-transaction.test.js.map +1 -0
- package/dist/services/global-codex-config.d.ts +10 -11
- package/dist/services/global-codex-config.d.ts.map +1 -1
- package/dist/services/global-codex-config.js +225 -107
- package/dist/services/global-codex-config.js.map +1 -1
- package/dist/services/global-codex-config.test.js +6 -6
- package/dist/services/global-codex-config.test.js.map +1 -1
- package/dist/services/hook-readiness.d.ts +7 -0
- package/dist/services/hook-readiness.d.ts.map +1 -0
- package/dist/services/hook-readiness.js +17 -0
- package/dist/services/hook-readiness.js.map +1 -0
- package/dist/services/logger.d.ts +2 -0
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +15 -1
- package/dist/services/logger.js.map +1 -1
- package/dist/services/logger.test.js +3 -0
- package/dist/services/logger.test.js.map +1 -1
- package/dist/services/managed-adapter.d.ts +6 -0
- package/dist/services/managed-adapter.d.ts.map +1 -0
- package/dist/services/managed-adapter.js +63 -0
- package/dist/services/managed-adapter.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/README.md +8 -0
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +1 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -2
- package/templates/.agents/dashboard/.zaip-managed.json +40 -32
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-DlN5EMmD.js → DashboardHelpDialog-CkQ_y8kg.js} +60 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BRdoeTWk.js → ProjectSettingsPage-doIMhei7.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-B_5u4Xnp.js → TraceabilityWorkspace-C_4ftjyB.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-C4rLXrz_.js → index-Rbmpz4UO.js} +2 -2
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +1 -1
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +175 -175
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +135 -135
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +175 -175
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operation-detail.test.ts +106 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +0 -13
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +17 -230
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-fixture.test-support.ts +239 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +28 -8
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/design/.zaip-managed.json +3 -3
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/astra-diagnostic.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +627 -177
- package/templates/.agents/runtime/checksums.sha256 +5 -5
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/provenance.json +4 -4
- package/templates/.agents/runtime/sbom.cdx.json +1 -1
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +26 -0
- package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +2 -0
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +31 -1
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +26 -1
- package/templates/.agents/skills/zaip-skill-task/references/commit-policy.md +8 -1
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +52 -1
- package/templates/template-manifest.json +95 -87
|
@@ -2,11 +2,15 @@ export const CODEX_CONVERSATION_LIFECYCLE_HOOK = String.raw `import { writeSync
|
|
|
2
2
|
import { lstat, open, readFile, realpath, mkdir, rename, writeFile, appendFile, unlink } from "node:fs/promises";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
|
-
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
5
|
+
import { dirname, isAbsolute, relative, resolve, toNamespacedPath } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
const hookRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
8
|
+
const activation = await import("./zaip-hook-activation.mjs").catch(() => null);
|
|
8
9
|
let root = hookRoot, local;
|
|
9
|
-
|
|
10
|
+
// The host hook stays below 10s. Explicit CLI recovery runs in the active Codex
|
|
11
|
+
// tool session and may finish expensive canonical closure within its own bound.
|
|
12
|
+
const replay = process.argv.length === 3 && process.argv[2] === "--replay-receipt";
|
|
13
|
+
const deadline = Date.now() + (replay ? 45000 : 8000);
|
|
10
14
|
const readChunkBytes = 1024 * 1024, maxLineBytes = 8 * 1024 * 1024, maxReadBytes = 16 * 1024 * 1024;
|
|
11
15
|
const hash = value => createHash("sha256").update(value).digest("hex");
|
|
12
16
|
const parse = value => { try { return JSON.parse(value); } catch { return null; } };
|
|
@@ -16,10 +20,10 @@ let raw = ""; for await (const chunk of process.stdin) raw += chunk;
|
|
|
16
20
|
const event = parse(raw), session = text(event?.session_id), turn = text(event?.turn_id);
|
|
17
21
|
let receipt, receiptPath, lease;
|
|
18
22
|
function reply(pending = false) {
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
writeSync(1, JSON.stringify(
|
|
23
|
+
if (!replay) activation?.recordActivation(root, event, pending ? "pending" : "observed");
|
|
24
|
+
// Closure belongs to the live orchestrator. Stop only records/reconciles;
|
|
25
|
+
// a pending receipt must never manufacture another user prompt.
|
|
26
|
+
writeSync(1, JSON.stringify({}) + "\n");
|
|
23
27
|
}
|
|
24
28
|
async function save(path, value) {
|
|
25
29
|
await mkdir(dirname(path), { recursive: true });
|
|
@@ -51,8 +55,11 @@ function proof(offset, line) { return { offset, length: line.length, sha256: has
|
|
|
51
55
|
function sessionOf(row) { return row?.type === "session_meta" ? row.payload?.id ?? row.payload?.session_id : row?.payload?.type === "session_meta" ? row.payload.id ?? row.payload.session_id : null; }
|
|
52
56
|
async function terminal(path) {
|
|
53
57
|
if (!path || !isAbsolute(path)) throw new Error("transcript_missing");
|
|
58
|
+
// A local Windows namespace is not a network UNC path. Keep devices and UNC blocked.
|
|
59
|
+
if (/^(?:\\\\|\/\/)/.test(path) && !/^\\\\\?\\[a-z]:\\/i.test(path)) throw new Error("transcript_unsafe");
|
|
60
|
+
const identity = value => process.platform === "win32" ? toNamespacedPath(resolve(value)).toLowerCase() : resolve(value);
|
|
54
61
|
const link = await lstat(path);
|
|
55
|
-
if (!link.isFile() || link.isSymbolicLink() || (await realpath(path))
|
|
62
|
+
if (!link.isFile() || link.isSymbolicLink() || identity(await realpath(path)) !== identity(path)) throw new Error("transcript_unsafe");
|
|
56
63
|
const h = await open(path, "r");
|
|
57
64
|
try {
|
|
58
65
|
const stat = await h.stat(), sig = signature(stat), prior = receipt.cursor;
|
|
@@ -62,7 +69,23 @@ async function terminal(path) {
|
|
|
62
69
|
if (same && prior.session_proof) same = hash(await bytes(h, prior.session_proof.offset, prior.session_proof.length)) === prior.session_proof.sha256;
|
|
63
70
|
let offset = same ? prior.offset : 0, trusted = same && prior.trusted === true;
|
|
64
71
|
let sessionProof = same ? prior.session_proof : null, terminalProof = same ? prior.terminal_proof : null, status = same ? prior.terminal_status : null;
|
|
65
|
-
let
|
|
72
|
+
let initialReadBytes = 0;
|
|
73
|
+
// The live Stop belongs to the current tail, not hundreds of MB of earlier
|
|
74
|
+
// turns. Authenticate the first session row, then align a bounded tail scan.
|
|
75
|
+
// Explicit historical replay retains the full resumable scan when no cursor exists.
|
|
76
|
+
if (!same && !replay && sig.size > maxReadBytes) {
|
|
77
|
+
const header = await bytes(h, 0, readChunkBytes), end = header.indexOf(10);
|
|
78
|
+
if (end < 0) throw new Error("transcript_session_header_too_large");
|
|
79
|
+
const first = header.subarray(0, end + 1);
|
|
80
|
+
if (sessionOf(parse(first.toString("utf8"))) !== session) throw new Error("transcript_session_mismatch");
|
|
81
|
+
trusted = true; sessionProof = proof(0, first);
|
|
82
|
+
const tailStart = sig.size - Math.floor((maxReadBytes - readChunkBytes) / 2);
|
|
83
|
+
const boundary = await bytes(h, tailStart, sig.size - tailStart), newline = boundary.indexOf(10);
|
|
84
|
+
if (newline < 0) throw new Error("transcript_tail_boundary_unavailable");
|
|
85
|
+
offset = tailStart + newline + 1;
|
|
86
|
+
initialReadBytes = header.length + boundary.length;
|
|
87
|
+
}
|
|
88
|
+
let readBytes = initialReadBytes, scanOffset = offset, lineOffset = offset, lineBytes = 0, lineParts = [];
|
|
66
89
|
const consume = line => {
|
|
67
90
|
const row = parse(line.toString("utf8"));
|
|
68
91
|
if (!row && line.toString("utf8").trim()) throw new Error("transcript_invalid_jsonl");
|
|
@@ -153,11 +176,12 @@ try {
|
|
|
153
176
|
if (!lease) { await note("stop_worker_busy"); reply(true); process.exit(0); }
|
|
154
177
|
const old = parse(await readFile(receiptPath, "utf8").catch(() => ""));
|
|
155
178
|
receipt = old?.schema_version === 1 && old.session_id === session && old.turn_id === turn ? old : { schema_version: 1, session_id: session, turn_id: turn, state: "pending", attempts: 0 };
|
|
156
|
-
|
|
179
|
+
const transcriptPath = text(event.transcript_path) ?? text(receipt.event?.transcript_path);
|
|
180
|
+
receipt.event = { hook_event_name: "Stop", cwd: root, session_id: session, turn_id: turn, transcript_path: transcriptPath, stop_hook_active: true };
|
|
157
181
|
if (receipt.state === "persisted") { reply(); } else {
|
|
158
182
|
receipt.attempts += 1; receipt.state = "pending"; await save(receiptPath, receipt);
|
|
159
183
|
let status = null;
|
|
160
|
-
for (const delay of [0, 250, 750]) { if (delay) await new Promise(r => setTimeout(r, delay)); status = await terminal(
|
|
184
|
+
for (const delay of [0, 250, 750]) { if (delay) await new Promise(r => setTimeout(r, delay)); status = await terminal(transcriptPath); if (status) break; }
|
|
161
185
|
if (!status) throw new Error("transcript_pending");
|
|
162
186
|
const cli = resolve(root, ".agents/runtime/bin/zaip.mjs");
|
|
163
187
|
const correlation = parse(await readFile(resolve(root, ".local/codex-telemetry-spool/v1/correlations", correlationKey + ".json"), "utf8").catch(() => ""));
|
|
@@ -165,14 +189,14 @@ try {
|
|
|
165
189
|
if (correlation?.schema_version === 1 && correlation.thread_id === session && correlation.turn_id === turn && correlation.agent_path === null && typeof correlation.run_id === "string") {
|
|
166
190
|
intake = { run: { run_id: correlation.run_id }, task: correlation.task_id === null ? null : { id: correlation.task_id } };
|
|
167
191
|
} else {
|
|
168
|
-
const started = await call(cli, ["conversation", "start", "--intent", "conversation"],
|
|
192
|
+
const started = await call(cli, ["conversation", "start", "--intent", "conversation"], transcriptPath);
|
|
169
193
|
if (started.code !== 0) throw new Error("start_pending");
|
|
170
194
|
intake = parse(started.out);
|
|
171
195
|
}
|
|
172
196
|
const run = intake?.run?.run_id;
|
|
173
197
|
if (typeof run !== "string" || (intake.task !== null && typeof intake.task?.id !== "string")) throw new Error("start_pending");
|
|
174
198
|
receipt.run_id = run; await save(receiptPath, receipt);
|
|
175
|
-
const result = await call(cli, ["subagent", "reconcile-stop", "--session", session, "--turn", turn],
|
|
199
|
+
const result = await call(cli, ["subagent", "reconcile-stop", "--session", session, "--turn", turn], transcriptPath);
|
|
176
200
|
const outcome = parse(result.out);
|
|
177
201
|
const terminalStates = ["completed", "blocked", "failed", "cancelled"];
|
|
178
202
|
const closed = intake.task === null
|
|
@@ -180,7 +204,7 @@ try {
|
|
|
180
204
|
: outcome?.status === "closed" && outcome.parent_run_id === run && outcome.reconciliation?.tasks?.some(task => task.id === intake.task.id && terminalStates.includes(task.status));
|
|
181
205
|
if (result.code !== 0 || !closed) throw new Error("closure_pending");
|
|
182
206
|
if (intake.task !== null && status === "completed") {
|
|
183
|
-
const shown = await call(cli, ["task", "recovery-status", intake.task.id],
|
|
207
|
+
const shown = await call(cli, ["task", "recovery-status", intake.task.id], transcriptPath);
|
|
184
208
|
const recovery = parse(shown.out);
|
|
185
209
|
if (shown.code !== 0 || recovery?.task_id !== intake.task.id || typeof recovery.task_status !== "string") throw new Error("task_state_pending");
|
|
186
210
|
if (["executing", "verifying"].includes(recovery.task_status)) throw new Error("owned_task_active");
|
|
@@ -194,7 +218,7 @@ try {
|
|
|
194
218
|
}
|
|
195
219
|
}
|
|
196
220
|
if (intake.task !== null) {
|
|
197
|
-
const usage = await call(cli, ["run", "usage", run, "--disable-codex-raw"],
|
|
221
|
+
const usage = await call(cli, ["run", "usage", run, "--disable-codex-raw"], transcriptPath);
|
|
198
222
|
if (usage.code !== 0 || parse(usage.out) === null) throw new Error("telemetry_pending");
|
|
199
223
|
}
|
|
200
224
|
receipt.state = "persisted"; receipt.persisted_at = new Date().toISOString(); receipt.error = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-conversation-lifecycle-hook.js","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"codex-conversation-lifecycle-hook.js","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsO1D,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const HOOK_ACTIVATION_EVENTS: readonly ["PreToolUse", "SubagentStart", "SubagentStop", "Stop"];
|
|
2
|
+
export declare const HOOK_ACTIVATION_FILES: readonly [".codex/config.toml", ".codex/hooks/zaip-pre-tool-use.mjs", ".codex/hooks/zaip-pre-tool-support.mjs", ".codex/hooks/zaip-native-tool-authority.mjs", ".codex/hooks/zaip-subagent-lifecycle.mjs", ".codex/hooks/zaip-conversation-lifecycle.mjs", ".codex/hooks/zaip-hook-activation.mjs"];
|
|
3
|
+
export declare const CODEX_HOOK_ACTIVATION: string;
|
|
4
|
+
//# sourceMappingURL=codex-hook-activation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-hook-activation.d.ts","sourceRoot":"","sources":["../../src/services/codex-hook-activation.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,YACjC,YAAY,EACZ,eAAe,EACf,cAAc,EACd,MAAM,CACE,CAAC;AACX,eAAO,MAAM,qBAAqB,YAChC,oBAAoB,EACpB,oCAAoC,EACpC,wCAAwC,EACxC,6CAA6C,EAC7C,0CAA0C,EAC1C,8CAA8C,EAC9C,uCAAuC,CAC/B,CAAC;AAGX,eAAO,MAAM,qBAAqB,QA8CjC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export const HOOK_ACTIVATION_EVENTS = [
|
|
2
|
+
"PreToolUse",
|
|
3
|
+
"SubagentStart",
|
|
4
|
+
"SubagentStop",
|
|
5
|
+
"Stop",
|
|
6
|
+
];
|
|
7
|
+
export const HOOK_ACTIVATION_FILES = [
|
|
8
|
+
".codex/config.toml",
|
|
9
|
+
".codex/hooks/zaip-pre-tool-use.mjs",
|
|
10
|
+
".codex/hooks/zaip-pre-tool-support.mjs",
|
|
11
|
+
".codex/hooks/zaip-native-tool-authority.mjs",
|
|
12
|
+
".codex/hooks/zaip-subagent-lifecycle.mjs",
|
|
13
|
+
".codex/hooks/zaip-conversation-lifecycle.mjs",
|
|
14
|
+
".codex/hooks/zaip-hook-activation.mjs",
|
|
15
|
+
];
|
|
16
|
+
// Local diagnostic evidence, not a replacement for Codex's trust store or a security boundary.
|
|
17
|
+
export const CODEX_HOOK_ACTIVATION = String.raw `import { createHash, randomUUID } from "node:crypto";
|
|
18
|
+
import { lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { dirname, resolve } from "node:path";
|
|
20
|
+
const files = ${JSON.stringify(HOOK_ACTIVATION_FILES)};
|
|
21
|
+
const events = ${JSON.stringify(HOOK_ACTIVATION_EVENTS)};
|
|
22
|
+
const digest = text => createHash("sha256").update(text).digest("hex");
|
|
23
|
+
function regular(path) {
|
|
24
|
+
const s = lstatSync(path);
|
|
25
|
+
if (!s.isFile() || s.isSymbolicLink() || s.size > 2097152) throw new Error("unsafe activation input");
|
|
26
|
+
return readFileSync(path);
|
|
27
|
+
}
|
|
28
|
+
export function recordActivation(root, event, outcome = "observed") {
|
|
29
|
+
try {
|
|
30
|
+
const name = event?.hook_event_name;
|
|
31
|
+
let directory = root;
|
|
32
|
+
for (const part of [".local", "hooks", "activation"]) {
|
|
33
|
+
directory = resolve(directory, part);
|
|
34
|
+
try { mkdirSync(directory); } catch (e) { if (e.code !== "EEXIST") throw e; }
|
|
35
|
+
const s = lstatSync(directory);
|
|
36
|
+
if (!s.isDirectory() || s.isSymbolicLink() || realpathSync(directory).toLowerCase() !== directory.toLowerCase()) return;
|
|
37
|
+
}
|
|
38
|
+
const reason = !events.includes(name) ? "event_missing_or_unknown" :
|
|
39
|
+
typeof event.session_id !== "string" || !event.session_id ? "session_missing" :
|
|
40
|
+
typeof event.turn_id !== "string" || !event.turn_id ? "turn_missing" :
|
|
41
|
+
process.env.CODEX_THREAD_ID && process.env.CODEX_THREAD_ID !== event.session_id ? "host_identity_mismatch" : null;
|
|
42
|
+
if (reason) {
|
|
43
|
+
// No payload, command, environment value or secret is persisted here.
|
|
44
|
+
const diagnostic = resolve(directory, "diagnostic.json");
|
|
45
|
+
const temporary = diagnostic + ".tmp-" + randomUUID();
|
|
46
|
+
writeFileSync(temporary, JSON.stringify({ reason, observed_at: new Date().toISOString() }), { flag: "wx", mode: 0o600 });
|
|
47
|
+
renameSync(temporary, diagnostic);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Hook processes do not necessarily inherit CODEX_THREAD_ID. The event is the
|
|
51
|
+
// protocol identity; receipts remain diagnostics, never proof of Codex trust.
|
|
52
|
+
const fingerprint = digest(JSON.stringify(files.map(file => [file, digest(regular(resolve(root, file)))])));
|
|
53
|
+
const path = resolve(directory, name + ".json");
|
|
54
|
+
const temporary = path + ".tmp-" + randomUUID();
|
|
55
|
+
writeFileSync(temporary, JSON.stringify({ schema_version: 1, event: name, fingerprint,
|
|
56
|
+
session_id: event.session_id, turn_id: event.turn_id, outcome,
|
|
57
|
+
identity_source: process.env.CODEX_THREAD_ID ? "event_and_environment" : "hook_event",
|
|
58
|
+
observed_at: new Date().toISOString() }) + "\n",
|
|
59
|
+
{ flag: "wx", mode: 0o600 });
|
|
60
|
+
renameSync(temporary, path);
|
|
61
|
+
} catch { /* Diagnostics must not break a tool or turn. Missing evidence stays unknown. */ }
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
//# sourceMappingURL=codex-hook-activation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-hook-activation.js","sourceRoot":"","sources":["../../src/services/codex-hook-activation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,eAAe;IACf,cAAc;IACd,MAAM;CACE,CAAC;AACX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB;IACpB,oCAAoC;IACpC,wCAAwC;IACxC,6CAA6C;IAC7C,0CAA0C;IAC1C,8CAA8C;IAC9C,uCAAuC;CAC/B,CAAC;AAEX,+FAA+F;AAC/F,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,GAAG,CAAA;;;gBAG/B,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;iBACpC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-model-policy.d.ts","sourceRoot":"","sources":["../../src/services/codex-model-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUzD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,MAAM,EAAE,CAM9E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAY7D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function followsDispatchPolicy(agent) {
|
|
2
|
+
return (agent.role === "orchestrator" ||
|
|
3
|
+
(["builder", "task-executor"].includes(agent.role) &&
|
|
4
|
+
agent.execution_eligibility.includes("delivery")));
|
|
5
|
+
}
|
|
6
|
+
export function codexModelInstructions(agent) {
|
|
7
|
+
return followsDispatchPolicy(agent)
|
|
8
|
+
? [
|
|
9
|
+
"Model and reasoning effort are controlled by the authorized dispatch policy. Catalog preferences are dispatch defaults, not permanent native locks. Before dispatch, the authorized host must select and validate the model/effort allowed by the frozen Task policy and the host's manual selection. Record the requested configuration separately from the effective model/effort observed from the host; never silently inherit a parent configuration or claim a model switch from instructions. If the host cannot select or verify the required configuration, report the capability as unavailable and return the blocked dispatch to the orchestrator.",
|
|
10
|
+
]
|
|
11
|
+
: [];
|
|
12
|
+
}
|
|
13
|
+
export function codexModelConfig(agent) {
|
|
14
|
+
const model = agent.model.preferred[0];
|
|
15
|
+
if (followsDispatchPolicy(agent) ||
|
|
16
|
+
agent.model.preferred.length !== 1 ||
|
|
17
|
+
model === undefined ||
|
|
18
|
+
model === "policy-selected") {
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
const effort = agent.model.reasoning_effort;
|
|
22
|
+
return `model = ${JSON.stringify(model)}\n${effort === undefined ? "" : `model_reasoning_effort = ${JSON.stringify(effort)}\n`}`;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=codex-model-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-model-policy.js","sourceRoot":"","sources":["../../src/services/codex-model-policy.ts"],"names":[],"mappings":"AAEA,SAAS,qBAAqB,CAAC,KAAoB;IACjD,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,cAAc;QAC7B,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAChD,KAAK,CAAC,qBAAqB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CACpD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAoB;IACzD,OAAO,qBAAqB,CAAC,KAAK,CAAC;QACjC,CAAC,CAAC;YACE,goBAAgoB;SACjoB;QACH,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACvC,IACE,qBAAqB,CAAC,KAAK,CAAC;QAC5B,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAClC,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,iBAAiB,EAC3B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC5C,OAAO,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AACnI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-native-tool-authority-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gCAAgC,QAsFT,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { CODEX_VALIDATION_RUNTIME_SUPPORT } from "./codex-validation-runtime-template.js";
|
|
2
|
+
export const CODEX_NATIVE_TOOL_AUTHORITY_HOOK = String.raw `import { createHash } from "node:crypto";
|
|
3
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
4
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
5
|
+
const inside = (path, root) => { const scoped = relative(root, resolve(path)); return scoped === "" || (!scoped.startsWith("..") && !isAbsolute(scoped)); };
|
|
6
|
+
const authorityPath = path => /^(?:\.agents\/(?:records|data\/runs)\/|\.local\/(?:codex-hook-|codex-telemetry-spool\/|runs\/))/i.test(path.replaceAll("\\", "/"));
|
|
7
|
+
/** Inspect existing ancestors too: a missing destination can still traverse a junction. */
|
|
8
|
+
export async function isSafePatchPath(target, root) {
|
|
9
|
+
if (!inside(target, root)) return false;
|
|
10
|
+
for (let path = resolve(target);; path = dirname(path)) {
|
|
11
|
+
try {
|
|
12
|
+
const info = await lstat(path);
|
|
13
|
+
if (info.isSymbolicLink() || (info.isFile() && info.nlink !== 1)) return false;
|
|
14
|
+
} catch (error) { if (error.code !== "ENOENT") return false; }
|
|
15
|
+
if (path === resolve(root)) return true;
|
|
16
|
+
if (dirname(path) === path) return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function canonicalScopes(id, root, boundedRead) {
|
|
20
|
+
const date = typeof id === "string" && /^TASK-(\d{4})-(\d{2})-(\d{2})-[A-Z0-9-]+$/.exec(id);
|
|
21
|
+
if (!date) throw new Error("invalid_task");
|
|
22
|
+
const text = await boundedRead(resolve(root, ".agents/records/tasks", date[1], date[2], id + ".md"), 262144);
|
|
23
|
+
const front = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text)?.[1];
|
|
24
|
+
if (!front || ["id", "status", "write_scopes"].some(key => (front.match(new RegExp("^" + key + ":", "gm")) ?? []).length !== 1) ||
|
|
25
|
+
!front.split(/\r?\n/).includes("id: " + id) || !/^status: (?:executing|verifying)$/m.test(front.replaceAll("\r", ""))) throw new Error("inactive_task");
|
|
26
|
+
const lists = [...front.matchAll(/^write_scopes:\r?\n((?: - [^\r\n]+(?:\r?\n|$))+)/gm)];
|
|
27
|
+
if (lists.length !== 1) throw new Error("invalid_scopes");
|
|
28
|
+
return lists[0][1].trimEnd().split(/\r?\n/).map(line => {
|
|
29
|
+
const value = line.slice(4);
|
|
30
|
+
if (value.startsWith('"')) return JSON.parse(value);
|
|
31
|
+
if (value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1).replaceAll("''", "'");
|
|
32
|
+
if (/[\r\n\x00]|(?:^|\s)#|:\s|^[!&*\[{]/.test(value)) throw new Error("ambiguous_scope");
|
|
33
|
+
return value;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** Validate only this native child's patch scope and its still-active canonical ancestry. */
|
|
37
|
+
export async function hasNativeDelegatedPatch(event, repositoryRoot, boundedRead) {
|
|
38
|
+
if (event.tool_name !== "apply_patch" || typeof event.session_id !== "string" || typeof event.turn_id !== "string") return false;
|
|
39
|
+
try {
|
|
40
|
+
const key = createHash("sha256").update(JSON.stringify([event.session_id, event.turn_id])).digest("hex");
|
|
41
|
+
const binding = JSON.parse(await boundedRead(resolve(repositoryRoot, ".local/codex-hook-native/v2", key + ".json"), 65536));
|
|
42
|
+
if (binding.schema_version !== 2 || binding.session_id !== event.session_id || binding.turn_id !== event.turn_id ||
|
|
43
|
+
typeof binding.native_session_id !== "string" || ![binding.native_session_id, binding.parent_session_id].includes(event.session_id) ||
|
|
44
|
+
!Array.isArray(binding.write_scopes) || !binding.write_scopes.length) return false;
|
|
45
|
+
const readRun = async id => {
|
|
46
|
+
const match = typeof id === "string" && /^RUN-(\d{4})-(\d{2})-(\d{2})-[A-Z0-9-]+-[A-Z0-9]{2,16}$/.exec(id);
|
|
47
|
+
if (!match) throw new Error("invalid_run");
|
|
48
|
+
let text;
|
|
49
|
+
for (const directory of [match[1] + "/" + match[2], match[1] + "/" + match[2] + "/" + match[3]]) {
|
|
50
|
+
try {
|
|
51
|
+
const value = await boundedRead(resolve(repositoryRoot, ".agents/records/runs", directory, id + ".jsonl"), 8388608);
|
|
52
|
+
if (text !== undefined) throw new Error("ambiguous_run");
|
|
53
|
+
text = value;
|
|
54
|
+
} catch (error) { if (error.code !== "ENOENT") throw error; }
|
|
55
|
+
}
|
|
56
|
+
if (!text?.endsWith("\n")) throw new Error("incomplete_run");
|
|
57
|
+
const records = text.split(/\r?\n/).filter(Boolean).map(JSON.parse);
|
|
58
|
+
if (records.some((row, i) => row.schema_version !== 2 || row.sequence !== i + 1 || row.run_id !== id ||
|
|
59
|
+
row.type === "run.finished" || row.type === "run.finalization.decided")) throw new Error("inactive_run");
|
|
60
|
+
if (records[0]?.type !== "run.started") throw new Error("invalid_run");
|
|
61
|
+
return records[0];
|
|
62
|
+
};
|
|
63
|
+
const child = await readRun(binding.run_id), parent = await readRun(binding.parent_run_id);
|
|
64
|
+
if (child.client !== "codex-subagent" || child.run_role !== "subagent" || child.run_purpose !== "execution" ||
|
|
65
|
+
!child.execution_eligibility?.includes("delivery") || child.parent_run_id !== parent.run_id ||
|
|
66
|
+
child.client_thread_id !== binding.agent_id || child.client_turn_id !== event.turn_id ||
|
|
67
|
+
parent.agent !== "agent-orchestrator" || parent.run_role !== "orchestrator" || parent.parent_run_id !== null ||
|
|
68
|
+
parent.client_thread_id !== binding.parent_session_id ||
|
|
69
|
+
parent.entrypoint !== "task" || !binding.task_id || !binding.execution_id ||
|
|
70
|
+
child.task_id !== binding.task_id || parent.task_id !== binding.task_id ||
|
|
71
|
+
child.execution_id !== binding.execution_id || parent.execution_id !== binding.execution_id) return false;
|
|
72
|
+
const command = event.tool_input?.command;
|
|
73
|
+
if (typeof command !== "string") return false;
|
|
74
|
+
const scopes = await canonicalScopes(binding.task_id, repositoryRoot, boundedRead);
|
|
75
|
+
if (JSON.stringify(scopes) !== JSON.stringify(binding.write_scopes)) return false;
|
|
76
|
+
const paths = [...command.matchAll(/^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)$/gm)].map(match => match[1].trim());
|
|
77
|
+
for (const path of paths) if (!await isSafePatchPath(resolve(repositoryRoot, path), repositoryRoot)) return false;
|
|
78
|
+
return paths.length > 0 && paths.every(path => {
|
|
79
|
+
const target = resolve(repositoryRoot, path);
|
|
80
|
+
return !authorityPath(relative(repositoryRoot, target)) && inside(target, repositoryRoot) && scopes.some(scope => {
|
|
81
|
+
if (typeof scope !== "string" || !scope || isAbsolute(scope) || scope.split(/[\\/]/).includes("..")) return false;
|
|
82
|
+
const base = resolve(repositoryRoot, scope.replace(/\/\*\*$/, ""));
|
|
83
|
+
return inside(base, repositoryRoot) && inside(target, base);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
} catch { return false; }
|
|
87
|
+
}
|
|
88
|
+
` + CODEX_VALIDATION_RUNTIME_SUPPORT;
|
|
89
|
+
//# sourceMappingURL=codex-native-tool-authority-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-native-tool-authority-template.js","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFzD,GAAG,gCAAgC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,QAouB/B,CAAC"}
|