@zaip-ai/cli 4.2.0 → 4.4.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.
Files changed (178) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +3 -1
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/services/adapters.d.ts +2 -2
  5. package/dist/services/adapters.d.ts.map +1 -1
  6. package/dist/services/adapters.js +24 -70
  7. package/dist/services/adapters.js.map +1 -1
  8. package/dist/services/adapters.test.js +5 -1
  9. package/dist/services/adapters.test.js.map +1 -1
  10. package/dist/services/agent-adapters.d.ts.map +1 -1
  11. package/dist/services/agent-adapters.js +3 -7
  12. package/dist/services/agent-adapters.js.map +1 -1
  13. package/dist/services/agent-adapters.test.js +43 -11
  14. package/dist/services/agent-adapters.test.js.map +1 -1
  15. package/dist/services/codex-config-overlay.d.ts +6 -0
  16. package/dist/services/codex-config-overlay.d.ts.map +1 -0
  17. package/dist/services/codex-config-overlay.js +161 -0
  18. package/dist/services/codex-config-overlay.js.map +1 -0
  19. package/dist/services/codex-config-template.js +2 -2
  20. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  21. package/dist/services/codex-conversation-lifecycle-hook.js +38 -14
  22. package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
  23. package/dist/services/codex-hook-activation.d.ts +4 -0
  24. package/dist/services/codex-hook-activation.d.ts.map +1 -0
  25. package/dist/services/codex-hook-activation.js +64 -0
  26. package/dist/services/codex-hook-activation.js.map +1 -0
  27. package/dist/services/codex-model-policy.d.ts +4 -0
  28. package/dist/services/codex-model-policy.d.ts.map +1 -0
  29. package/dist/services/codex-model-policy.js +24 -0
  30. package/dist/services/codex-model-policy.js.map +1 -0
  31. package/dist/services/codex-native-tool-authority-template.d.ts +2 -0
  32. package/dist/services/codex-native-tool-authority-template.d.ts.map +1 -0
  33. package/dist/services/codex-native-tool-authority-template.js +89 -0
  34. package/dist/services/codex-native-tool-authority-template.js.map +1 -0
  35. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  36. package/dist/services/codex-pre-tool-hook-template.js +59 -86
  37. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  38. package/dist/services/codex-pre-tool-hook-template.test.js +200 -1
  39. package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
  40. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  41. package/dist/services/codex-pre-tool-support-template.js +303 -12
  42. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  43. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  44. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  45. package/dist/services/codex-subagent-hook-template.js +11 -4
  46. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  47. package/dist/services/codex-validation-runtime-template.d.ts +3 -0
  48. package/dist/services/codex-validation-runtime-template.d.ts.map +1 -0
  49. package/dist/services/codex-validation-runtime-template.js +18 -0
  50. package/dist/services/codex-validation-runtime-template.js.map +1 -0
  51. package/dist/services/codex-windows-hook-command.js +1 -1
  52. package/dist/services/codex-windows-hook-command.js.map +1 -1
  53. package/dist/services/codex-windows-hook-command.test.js +22 -0
  54. package/dist/services/codex-windows-hook-command.test.js.map +1 -1
  55. package/dist/services/global-codex-config-fixtures.d.ts +12 -0
  56. package/dist/services/global-codex-config-fixtures.d.ts.map +1 -0
  57. package/dist/services/global-codex-config-fixtures.js +38 -0
  58. package/dist/services/global-codex-config-fixtures.js.map +1 -0
  59. package/dist/services/global-codex-config-migration.test.d.ts +2 -0
  60. package/dist/services/global-codex-config-migration.test.d.ts.map +1 -0
  61. package/dist/services/global-codex-config-migration.test.js +301 -0
  62. package/dist/services/global-codex-config-migration.test.js.map +1 -0
  63. package/dist/services/global-codex-config-transaction.d.ts +15 -0
  64. package/dist/services/global-codex-config-transaction.d.ts.map +1 -0
  65. package/dist/services/global-codex-config-transaction.js +89 -0
  66. package/dist/services/global-codex-config-transaction.js.map +1 -0
  67. package/dist/services/global-codex-config-transaction.test.d.ts +2 -0
  68. package/dist/services/global-codex-config-transaction.test.d.ts.map +1 -0
  69. package/dist/services/global-codex-config-transaction.test.js +145 -0
  70. package/dist/services/global-codex-config-transaction.test.js.map +1 -0
  71. package/dist/services/global-codex-config.d.ts +10 -11
  72. package/dist/services/global-codex-config.d.ts.map +1 -1
  73. package/dist/services/global-codex-config.js +225 -107
  74. package/dist/services/global-codex-config.js.map +1 -1
  75. package/dist/services/global-codex-config.test.js +6 -6
  76. package/dist/services/global-codex-config.test.js.map +1 -1
  77. package/dist/services/hook-readiness.d.ts +7 -0
  78. package/dist/services/hook-readiness.d.ts.map +1 -0
  79. package/dist/services/hook-readiness.js +17 -0
  80. package/dist/services/hook-readiness.js.map +1 -0
  81. package/dist/services/install-agents-template.d.ts.map +1 -1
  82. package/dist/services/install-agents-template.js +12 -18
  83. package/dist/services/install-agents-template.js.map +1 -1
  84. package/dist/services/logger.d.ts +2 -0
  85. package/dist/services/logger.d.ts.map +1 -1
  86. package/dist/services/logger.js +15 -1
  87. package/dist/services/logger.js.map +1 -1
  88. package/dist/services/logger.test.js +3 -0
  89. package/dist/services/logger.test.js.map +1 -1
  90. package/dist/services/managed-adapter.d.ts +6 -0
  91. package/dist/services/managed-adapter.d.ts.map +1 -0
  92. package/dist/services/managed-adapter.js +63 -0
  93. package/dist/services/managed-adapter.js.map +1 -0
  94. package/dist/services/render-framework-lock.d.ts +6 -0
  95. package/dist/services/render-framework-lock.d.ts.map +1 -0
  96. package/dist/services/render-framework-lock.js +20 -0
  97. package/dist/services/render-framework-lock.js.map +1 -0
  98. package/dist/types.d.ts +2 -0
  99. package/dist/types.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/templates/.agents/README.md +8 -0
  102. package/templates/.agents/config/agents/discovery.json +1 -1
  103. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +1 -2
  104. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -2
  105. package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -2
  106. package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +1 -2
  107. package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -2
  108. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -2
  109. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +1 -2
  110. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -2
  111. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -2
  112. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -2
  113. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +1 -2
  114. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -2
  115. package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -2
  116. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -2
  117. package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -2
  118. package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +1 -2
  119. package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -2
  120. package/templates/.agents/dashboard/.zaip-managed.json +40 -32
  121. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-DlN5EMmD.js → DashboardHelpDialog-CkQ_y8kg.js} +60 -1
  122. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BRdoeTWk.js → ProjectSettingsPage-doIMhei7.js} +1 -1
  123. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-B_5u4Xnp.js → TraceabilityWorkspace-C_4ftjyB.js} +1 -1
  124. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-C4rLXrz_.js → index-Rbmpz4UO.js} +2 -2
  125. package/templates/.agents/dashboard/apps/frontend/dist/index.html +1 -1
  126. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  127. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  128. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  129. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  130. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  131. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  132. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  133. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +177 -177
  134. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +135 -135
  135. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  136. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +177 -177
  137. package/templates/.agents/dashboard/packages/local-runtime/src/server-operation-detail.test.ts +106 -0
  138. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +0 -13
  139. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +17 -230
  140. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-fixture.test-support.ts +239 -0
  141. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +28 -8
  142. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  143. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  144. package/templates/.agents/design/.zaip-managed.json +3 -3
  145. package/templates/.agents/design/apps/catalog/package.json +1 -1
  146. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  147. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  148. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  149. package/templates/.agents/requirements/comparative-audit.md +1 -1
  150. package/templates/.agents/requirements/context-engine.md +1 -1
  151. package/templates/.agents/requirements/cost-observability.md +1 -1
  152. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  153. package/templates/.agents/requirements/data-export.md +1 -1
  154. package/templates/.agents/requirements/design-system.md +1 -1
  155. package/templates/.agents/requirements/execution-engine.md +1 -1
  156. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  157. package/templates/.agents/requirements/model-orchestration.md +1 -1
  158. package/templates/.agents/requirements/public-distribution.md +1 -1
  159. package/templates/.agents/requirements/software-architecture.md +1 -1
  160. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  161. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  162. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  163. package/templates/.agents/rules/astra-diagnostic.md +1 -1
  164. package/templates/.agents/runtime/VERSION +1 -1
  165. package/templates/.agents/runtime/bin/zaip.mjs +654 -199
  166. package/templates/.agents/runtime/checksums.sha256 +5 -5
  167. package/templates/.agents/runtime/manifest.json +1 -1
  168. package/templates/.agents/runtime/provenance.json +4 -4
  169. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  170. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
  171. package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +26 -0
  172. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +2 -0
  173. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +31 -1
  174. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +26 -1
  175. package/templates/.agents/skills/zaip-skill-task/references/commit-policy.md +8 -1
  176. package/templates/.agents/zaip-aios/VERSION +1 -1
  177. package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +52 -1
  178. package/templates/template-manifest.json +95 -87
@@ -0,0 +1,161 @@
1
+ import { createHash } from "node:crypto";
2
+ const HEADER = /^# zaip-managed generated-do-not-edit source=codex-config [^\r\n]*\r?\n/;
3
+ const BEGIN = "# zaip-managed begin agent-registrations";
4
+ const END = "# zaip-managed end agent-registrations";
5
+ /** Locate only real TOML headers/comments, never text inside multiline strings. */
6
+ function lines(text) {
7
+ const result = [];
8
+ let multiline = null;
9
+ let start = 0;
10
+ for (const raw of text.match(/[^\n]*(?:\n|$)/g) ?? []) {
11
+ if (!raw)
12
+ continue;
13
+ result.push({ text: raw.trim(), start, end: start + raw.length, outside: multiline === null });
14
+ for (let i = 0; i < raw.length; i++) {
15
+ if (multiline !== null) {
16
+ if (multiline === '"""' && raw[i] === "\\") {
17
+ i++;
18
+ continue;
19
+ }
20
+ if (raw.startsWith(multiline, i)) {
21
+ i += 2;
22
+ multiline = null;
23
+ }
24
+ }
25
+ else if (raw[i] === "#")
26
+ break;
27
+ else if (raw[i] === '"' || raw[i] === "'") {
28
+ const quote = raw[i];
29
+ if (raw.startsWith(quote.repeat(3), i)) {
30
+ multiline = quote.repeat(3);
31
+ i += 2;
32
+ }
33
+ else
34
+ for (i++; i < raw.length; i++) {
35
+ if (quote === '"' && raw[i] === "\\")
36
+ i++;
37
+ else if (raw[i] === quote)
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ start += raw.length;
43
+ }
44
+ return result;
45
+ }
46
+ function sections(text) {
47
+ const headers = lines(text).filter((line) => line.outside && /^\[.+\]\s*(?:#.*)?$/.test(line.text));
48
+ return headers.map((line, index) => {
49
+ const end = headers[index + 1]?.start ?? text.length;
50
+ return { header: line.text.replace(/\s+#.*$/, ""), start: line.start, end, text: text.slice(line.start, end) };
51
+ });
52
+ }
53
+ function registrationRange(text) {
54
+ const source = lines(text).filter((line) => line.outside);
55
+ const starts = source.filter((line) => line.text === BEGIN);
56
+ const ends = source.filter((line) => line.text === END);
57
+ if (!starts.length && !ends.length)
58
+ return null;
59
+ if (starts.length !== 1 || ends.length !== 1 || (starts[0]?.start ?? 0) >= (ends[0]?.start ?? 0)) {
60
+ throw new Error("Ambiguous managed Codex agent registration block");
61
+ }
62
+ return { start: starts[0]?.start ?? 0, end: ends[0]?.end ?? text.length };
63
+ }
64
+ function managedHook(section) {
65
+ return lines(section.text).some((line) => line.outside &&
66
+ /^command\s*=/.test(line.text) &&
67
+ /[\\/]zaip-(?:pre-tool-use|conversation-lifecycle|subagent-lifecycle)\.mjs/.test(line.text));
68
+ }
69
+ /** Refresh owned hook entries, retaining third-party entries even in the same hook group. */
70
+ function refreshHooks(current, generated) {
71
+ const expected = sections(generated);
72
+ const replacements = new Map();
73
+ for (let i = 0; i < expected.length; i++) {
74
+ const section = expected[i];
75
+ if (section && /^\[\[hooks\.[\w]+\]\]$/.test(section.header) &&
76
+ expected[i + 1] && managedHook(expected[i + 1])) {
77
+ replacements.set(section.header, section.text + expected[i + 1]?.text);
78
+ }
79
+ }
80
+ const source = sections(current);
81
+ const changes = [];
82
+ const seen = new Set();
83
+ for (let i = 0; i < source.length; i++) {
84
+ const parent = source[i];
85
+ if (!parent || !replacements.has(parent.header))
86
+ continue;
87
+ const childHeader = `${parent.header.slice(0, -2)}.hooks]]`;
88
+ const children = [];
89
+ while (source[i + 1]?.header === childHeader)
90
+ children.push(source[++i]);
91
+ const owned = children.filter(managedHook);
92
+ if (!owned.length)
93
+ continue;
94
+ const thirdParty = children.filter((child) => !managedHook(child));
95
+ const replacement = seen.has(parent.header) ? "" : replacements.get(parent.header) ?? "";
96
+ seen.add(parent.header);
97
+ changes.push({ start: parent.start, end: children.at(-1)?.end ?? parent.end,
98
+ text: (thirdParty.length ? parent.text + thirdParty.map((child) => child.text).join("") : "") + replacement });
99
+ }
100
+ for (const change of changes.reverse())
101
+ current = current.slice(0, change.start) + change.text + current.slice(change.end);
102
+ const missing = [...replacements].filter(([header]) => !seen.has(header)).map(([, text]) => text);
103
+ if (missing.length)
104
+ current = `${current.trimEnd()}\n\n${missing.join("")}`;
105
+ return current;
106
+ }
107
+ function enableHooks(current) {
108
+ const section = sections(current).find((section) => section.header === "[features]");
109
+ if (!section)
110
+ return `${current.trimEnd()}\n\n[features]\nhooks = true\n`;
111
+ const setting = lines(section.text).find((line) => line.outside && /^hooks\s*=/.test(line.text));
112
+ if (setting) {
113
+ if (!/^hooks\s*=\s*true\s*(?:#.*)?$/.test(setting.text)) {
114
+ throw new Error("Codex hooks are explicitly disabled or ambiguous; preserve the user's setting and resolve it before installing ZAIP hooks");
115
+ }
116
+ return current;
117
+ }
118
+ const newline = current.indexOf("\n", section.start);
119
+ const headerEnd = newline === -1 ? current.length : newline + 1;
120
+ return current.slice(0, headerEnd) + (newline === -1 ? "\n" : "") + "hooks = true\n" + current.slice(headerEnd);
121
+ }
122
+ /** A whole-file marker proves ownership only while its checksum still matches. */
123
+ export function isUnchangedCodexConfig(content) {
124
+ const header = content.match(HEADER)?.[0];
125
+ const digest = header?.match(/\bsha256=([a-f0-9]{64})\b/)?.[1];
126
+ return header !== undefined && digest !== undefined &&
127
+ createHash("sha256").update(content.slice(header.length)).digest("hex") === digest;
128
+ }
129
+ export function reconcileCodexConfig(current, generated, registerAgents = true) {
130
+ if (isUnchangedCodexConfig(current))
131
+ return generated;
132
+ const marked = HEADER.test(current);
133
+ // An overlay must not retain a generated-do-not-edit/checksum claim about user content.
134
+ let result = current.replace(HEADER, "");
135
+ const existingRange = registrationRange(result);
136
+ const expectedRange = registrationRange(generated);
137
+ if (expectedRange && (marked || registerAgents || existingRange)) {
138
+ const block = generated.slice(expectedRange.start, expectedRange.end);
139
+ if (existingRange)
140
+ result = result.slice(0, existingRange.start) + block + result.slice(existingRange.end);
141
+ else {
142
+ const ownedHeaders = new Set(sections(block).map((section) => section.header));
143
+ for (const section of sections(result).reverse()) {
144
+ if (ownedHeaders.has(section.header))
145
+ result = result.slice(0, section.start) + result.slice(section.end);
146
+ }
147
+ result = `${result.trimEnd()}\n\n${block}`;
148
+ }
149
+ }
150
+ return enableHooks(refreshHooks(result, generated));
151
+ }
152
+ /** Read-only checks classify an invalid overlay as drift instead of aborting doctor JSON. */
153
+ export function isReconciledCodexConfig(current, generated, registerAgents = true) {
154
+ try {
155
+ return reconcileCodexConfig(current, generated, registerAgents) === current;
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ }
161
+ //# sourceMappingURL=codex-config-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-config-overlay.js","sourceRoot":"","sources":["../../src/services/codex-config-overlay.ts"],"names":[],"mappings":"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"}
@@ -94,7 +94,7 @@ matcher = "*"
94
94
  type = "command"
95
95
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
96
96
  command_windows = '''${codexWindowsHookCommand("zaip-subagent-lifecycle.mjs")}'''
97
- timeout = 3
97
+ timeout = 10
98
98
  statusMessage = "Attributing ZAIP subagent Run"
99
99
 
100
100
  [[hooks.SubagentStop]]
@@ -104,7 +104,7 @@ matcher = "*"
104
104
  type = "command"
105
105
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
106
106
  command_windows = '''${codexWindowsHookCommand("zaip-subagent-lifecycle.mjs")}'''
107
- timeout = 3
107
+ timeout = 10
108
108
  statusMessage = "Finalizing ZAIP subagent Run"
109
109
  `;
110
110
  //# sourceMappingURL=codex-config-template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-conversation-lifecycle-hook.d.ts","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,QA8M7C,CAAC"}
1
+ {"version":3,"file":"codex-conversation-lifecycle-hook.d.ts","sourceRoot":"","sources":["../../src/services/codex-conversation-lifecycle-hook.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,QAsO7C,CAAC"}
@@ -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
- const deadline = Date.now() + 8000;
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
- const result = { hookSpecificOutput: { hookEventName: "Stop" } };
20
- // One continuation at most. Persistent failures remain an explicit durable pending event.
21
- if (pending && event?.stop_hook_active !== true) Object.assign(result, { decision: "block", reason: receipt?.error === "owned_task_active" ? "ZAIP Task remains marked executing or verifying after Stop reconciliation; this does not prove a live worker. Inspect every launched process by fresh PID/session status, collect terminal exit and output, and either recover the lifecycle or report the concrete blocker. Never claim a process is still running from stale state." : receipt?.error === "owned_task_recoverable" ? "ZAIP Task " + receipt.recovery.task_id + " has a frozen recovery ledger. Observed attempts=" + receipt.recovery.progress.attempts + ", replans=" + (receipt.recovery.progress.total_replans ?? "unknown") + "; next ledger operation=" + receipt.recovery.operation + ". Evaluate the concrete blocker and perform only this authorized canonical operation in this turn. The hook did not dispatch an agent or prove the operation completed. Do not claim three replans without three observed ledger entries." : receipt?.error === "owned_task_unmetered" ? "ZAIP Task " + receipt.recovery.task_id + " is blocked without a frozen recovery ledger. The Stop hook cannot guarantee three replans or dispatch a model. Check the legacy policy and observed attempts, then report the concrete blocker and the missing enforcement honestly; never claim an unobserved replan." : "ZAIP closure or telemetry is pending. Retry this exact turn using its durable Stop receipt; do not report Task completion before canonical closure." });
22
- writeSync(1, JSON.stringify(result) + "\n");
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)).toLowerCase() !== resolve(path).toLowerCase()) throw new Error("transcript_unsafe");
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 readBytes = 0, scanOffset = offset, lineOffset = offset, lineBytes = 0, lineParts = [];
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
- receipt.event = { hook_event_name: "Stop", cwd: root, session_id: session, turn_id: turn, transcript_path: text(event.transcript_path), stop_hook_active: true };
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(text(event.transcript_path)); if (status) break; }
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"], text(event.transcript_path));
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], text(event.transcript_path));
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], text(event.transcript_path));
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"], text(event.transcript_path));
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8M1D,CAAC"}
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,4 @@
1
+ import type { GuidanceAgent } from "./agent-adapters.js";
2
+ export declare function codexModelInstructions(agent: GuidanceAgent): readonly string[];
3
+ export declare function codexModelConfig(agent: GuidanceAgent): string;
4
+ //# sourceMappingURL=codex-model-policy.d.ts.map
@@ -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,2 @@
1
+ export declare const CODEX_NATIVE_TOOL_AUTHORITY_HOOK: string;
2
+ //# sourceMappingURL=codex-native-tool-authority-template.d.ts.map
@@ -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,QA+vB/B,CAAC"}
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"}