@zaip-ai/cli 4.0.0 → 4.1.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 (72) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.d.ts.map +1 -1
  3. package/dist/services/adapters.js +11 -6
  4. package/dist/services/adapters.js.map +1 -1
  5. package/dist/services/codex-config-template.d.ts +2 -2
  6. package/dist/services/codex-config-template.d.ts.map +1 -1
  7. package/dist/services/codex-config-template.js +4 -3
  8. package/dist/services/codex-config-template.js.map +1 -1
  9. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  10. package/dist/services/codex-pre-tool-hook-template.js +10 -11
  11. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  12. package/dist/services/codex-pre-tool-hook-template.test.d.ts +2 -0
  13. package/dist/services/codex-pre-tool-hook-template.test.d.ts.map +1 -0
  14. package/dist/services/codex-pre-tool-hook-template.test.js +33 -0
  15. package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -0
  16. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  17. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  18. package/dist/services/codex-subagent-hook-template.js +3 -0
  19. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  20. package/dist/services/codex-windows-hook-command.d.ts +3 -0
  21. package/dist/services/codex-windows-hook-command.d.ts.map +1 -0
  22. package/dist/services/codex-windows-hook-command.js +10 -0
  23. package/dist/services/codex-windows-hook-command.js.map +1 -0
  24. package/dist/services/codex-windows-hook-command.test.d.ts +2 -0
  25. package/dist/services/codex-windows-hook-command.test.d.ts.map +1 -0
  26. package/dist/services/codex-windows-hook-command.test.js +44 -0
  27. package/dist/services/codex-windows-hook-command.test.js.map +1 -0
  28. package/dist/services/global-codex-config.d.ts.map +1 -1
  29. package/dist/services/global-codex-config.js +27 -13
  30. package/dist/services/global-codex-config.js.map +1 -1
  31. package/dist/services/global-codex-config.test.js +27 -2
  32. package/dist/services/global-codex-config.test.js.map +1 -1
  33. package/package.json +1 -1
  34. package/templates/.agents/config/agents/discovery.json +1 -1
  35. package/templates/.agents/dashboard/.zaip-managed.json +11 -11
  36. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  37. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  38. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  39. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  40. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  41. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  42. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  43. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  44. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  45. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  46. package/templates/.agents/design/.zaip-managed.json +3 -3
  47. package/templates/.agents/design/apps/catalog/package.json +1 -1
  48. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  49. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  50. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  51. package/templates/.agents/requirements/comparative-audit.md +1 -1
  52. package/templates/.agents/requirements/context-engine.md +1 -1
  53. package/templates/.agents/requirements/cost-observability.md +1 -1
  54. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  55. package/templates/.agents/requirements/data-export.md +1 -1
  56. package/templates/.agents/requirements/design-system.md +1 -1
  57. package/templates/.agents/requirements/execution-engine.md +1 -1
  58. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  59. package/templates/.agents/requirements/model-orchestration.md +1 -1
  60. package/templates/.agents/requirements/public-distribution.md +1 -1
  61. package/templates/.agents/requirements/software-architecture.md +1 -1
  62. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  63. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  64. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  65. package/templates/.agents/runtime/VERSION +1 -1
  66. package/templates/.agents/runtime/bin/zaip.mjs +23 -21
  67. package/templates/.agents/runtime/checksums.sha256 +5 -5
  68. package/templates/.agents/runtime/manifest.json +1 -1
  69. package/templates/.agents/runtime/provenance.json +4 -4
  70. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  71. package/templates/.agents/zaip-aios/VERSION +1 -1
  72. package/templates/template-manifest.json +42 -42
@@ -1,5 +1,5 @@
1
1
  import { type PublicAgentCatalog } from "./agent-adapters.js";
2
- export declare const ADAPTERS_VERSION = "4.0.0";
2
+ export declare const ADAPTERS_VERSION = "4.1.0";
3
3
  export interface AdapterFile {
4
4
  path: string;
5
5
  content: string;
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/services/adapters.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,qBAAqB,CAAC;AAK7B,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAuLD,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,SAAS,WAAW,EAAE,CAoDxB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC,CAYD;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,UAAQ,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAyB7D;AASD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAuBvE"}
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/services/adapters.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,qBAAqB,CAAC;AAM7B,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAuLD,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,SAAS,WAAW,EAAE,CAqDxB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC,CAYD;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,UAAQ,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAyB7D;AASD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAuBvE"}
@@ -5,8 +5,9 @@ import { CODEX_CONVERSATION_LIFECYCLE_HOOK, CODEX_PRE_TOOL_HOOK, CODEX_SUBAGENT_
5
5
  import { codexAgentConfig, parsePublicAgentCatalog, publicAgentAdapterFiles, } from "./agent-adapters.js";
6
6
  import { formatAgentDiscovery, serializeAgentDiscovery } from "./agent-discovery.js";
7
7
  import { CODEX_GITHUB_DEPLOY_RULES, CODEX_SECURITY_RULES } from "./codex-rules.js";
8
+ import { codexWindowsHookCommand } from "./codex-windows-hook-command.js";
8
9
  import { applyTransactionalChanges, assertSafeDestination } from "./transactional-files.js";
9
- export const ADAPTERS_VERSION = "4.0.0";
10
+ export const ADAPTERS_VERSION = "4.1.0";
10
11
  const ROOT_GUIDANCE = `# ZAIP-AIOS
11
12
 
12
13
  Read \`.agents/config/project.yaml\` first. Apply ZAIP only for literal boolean \`zaip.enabled: true\`, except framework maintenance or \`zaip enable\`. \`AGENTS.md\` is a bootstrap; canonical guidance lives in \`.agents/\`.
@@ -121,7 +122,7 @@ matcher = "^(Bash|shell_command|exec_command|apply_patch|Edit|Write)$"
121
122
  [[hooks.PreToolUse.hooks]]
122
123
  type = "command"
123
124
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-pre-tool-use.mjs"'''
124
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-pre-tool-use.mjs')"'''
125
+ command_windows = '''__ZAIP_WINDOWS_PRE_TOOL_HOOK__'''
125
126
  timeout = 10
126
127
  statusMessage = "Applying ZAIP workspace safety policy"
127
128
 
@@ -132,7 +133,7 @@ matcher = "*"
132
133
  type = "command"
133
134
  async = false
134
135
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-conversation-lifecycle.mjs"'''
135
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-conversation-lifecycle.mjs')"'''
136
+ command_windows = '''__ZAIP_WINDOWS_CONVERSATION_HOOK__'''
136
137
  timeout = 10
137
138
  statusMessage = "Reconciling ZAIP task closure and telemetry"
138
139
 
@@ -155,7 +156,7 @@ matcher = "*"
155
156
  [[hooks.SubagentStart.hooks]]
156
157
  type = "command"
157
158
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
158
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')"'''
159
+ command_windows = '''__ZAIP_WINDOWS_SUBAGENT_HOOK__'''
159
160
  timeout = 3
160
161
  statusMessage = "Attributing ZAIP subagent Run"
161
162
 
@@ -165,7 +166,7 @@ matcher = "*"
165
166
  [[hooks.SubagentStop.hooks]]
166
167
  type = "command"
167
168
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
168
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')"'''
169
+ command_windows = '''__ZAIP_WINDOWS_SUBAGENT_HOOK__'''
169
170
  timeout = 3
170
171
  statusMessage = "Finalizing ZAIP subagent Run"
171
172
  `;
@@ -179,7 +180,11 @@ const CLAUDE_SETTINGS = `{
179
180
  }
180
181
  `;
181
182
  export function adapterFiles(workspaceRoot, catalog) {
182
- const codexConfig = CODEX_CONFIG.replaceAll(CODEX_WORKSPACE_ROOT_PLACEHOLDER, JSON.stringify(resolve(workspaceRoot)));
183
+ const codexConfig = CODEX_CONFIG
184
+ .replaceAll(CODEX_WORKSPACE_ROOT_PLACEHOLDER, JSON.stringify(resolve(workspaceRoot)))
185
+ .replaceAll("__ZAIP_WINDOWS_PRE_TOOL_HOOK__", codexWindowsHookCommand("zaip-pre-tool-use.mjs", workspaceRoot))
186
+ .replaceAll("__ZAIP_WINDOWS_CONVERSATION_HOOK__", codexWindowsHookCommand("zaip-conversation-lifecycle.mjs", workspaceRoot))
187
+ .replaceAll("__ZAIP_WINDOWS_SUBAGENT_HOOK__", codexWindowsHookCommand("zaip-subagent-lifecycle.mjs", workspaceRoot));
183
188
  return [
184
189
  ...(catalog === undefined
185
190
  ? []
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/services/adapters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/services/adapters.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export declare const CODEX_WORKSPACE_ROOT_PLACEHOLDER = "__ZAIP_WORKSPACE_ROOT_TOML__";
2
- export declare const CODEX_PRE_TOOL_USE_HOOK = "[[hooks.PreToolUse]]\nmatcher = \"^(Bash|shell_command|exec_command|apply_patch|Edit|Write)$\"\n\n[[hooks.PreToolUse.hooks]]\ntype = \"command\"\ncommand = '''node \"$(git rev-parse --show-toplevel)/.codex/hooks/zaip-pre-tool-use.mjs\"'''\ncommand_windows = '''powershell -NoProfile -NonInteractive -Command \"$git = Join-Path __ZAIP_WORKSPACE_ROOT_TOML__ '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-pre-tool-use.mjs')\"'''\ntimeout = 10\nstatusMessage = \"Applying ZAIP workspace safety policy\"";
3
- export declare const CODEX_CONFIG = "project_doc_fallback_filenames = [\"AGENTS.md\"]\napproval_policy = \"never\"\ndefault_permissions = \"zaip-aios-full-access\"\nallow_login_shell = true\nweb_search = \"live\"\ndeveloper_instructions = \"\"\"\nThe default full-access profile permits unrestricted development. Follow the user's current request.\n\"\"\"\n\n[permissions.zaip-aios-security]\ndescription = \"Zaip AIOS workspace-only development with security. (low risk)\"\n\n[permissions.zaip-aios-security.filesystem]\n\":minimal\" = \"read\"\n\"~/.ssh\" = \"write\"\n\n[permissions.zaip-aios-security.filesystem.__ZAIP_WORKSPACE_ROOT_TOML__]\n\".\" = \"write\"\n\".git\" = \"write\"\n\".agents\" = \"write\"\n\".codex\" = \"write\"\n\n[permissions.zaip-aios-security.network]\nenabled = true\nmode = \"limited\"\n\n[permissions.zaip-aios-security.network.domains]\n\"github.com\" = \"allow\"\n\n[permissions.zaip-aios-full-access]\ndescription = \"Zaip AIOS unrestricted full access. (higher risk)\"\n\n[permissions.zaip-aios-full-access.filesystem]\n\":root\" = \"write\"\n\n[permissions.zaip-aios-full-access.network]\nenabled = true\nmode = \"full\"\n\n[permissions.zaip-aios-full-access.network.domains]\n\"*\" = \"allow\"\n\n[shell_environment_policy]\ninherit = \"all\"\nignore_default_excludes = true\nexclude = []\ninclude_only = []\nexperimental_use_profile = false\n\n[shell_environment_policy.set]\nBROWSER_USE_AVAILABLE_BACKENDS = \"chrome,iab\"\n\n[plugins.\"browser@openai-bundled\"]\nenabled = true\n\n[plugins.\"computer-use@openai-bundled\"]\nenabled = true\n\n[features]\nhooks = true\nunified_exec = false\njs_repl = true\n\n[[hooks.PreToolUse]]\nmatcher = \"^(Bash|shell_command|exec_command|apply_patch|Edit|Write)$\"\n\n[[hooks.PreToolUse.hooks]]\ntype = \"command\"\ncommand = '''node \"$(git rev-parse --show-toplevel)/.codex/hooks/zaip-pre-tool-use.mjs\"'''\ncommand_windows = '''powershell -NoProfile -NonInteractive -Command \"$git = Join-Path __ZAIP_WORKSPACE_ROOT_TOML__ '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-pre-tool-use.mjs')\"'''\ntimeout = 10\nstatusMessage = \"Applying ZAIP workspace safety policy\"\n\n[apps._default]\ndestructive_enabled = true\nopen_world_enabled = true\ndefault_tools_approval_mode = \"approve\"\n\n[mcp_servers.openaiDeveloperDocs]\nurl = \"https://developers.openai.com/mcp\"\nenabled = true\nenabled_tools = [\"search_openai_docs\", \"fetch_openai_doc\", \"list_openai_docs\", \"get_openapi_spec\", \"list_api_endpoints\"]\ndefault_tools_approval_mode = \"approve\"\nstartup_timeout_sec = 20\ntool_timeout_sec = 60\n\n[[hooks.SubagentStart]]\nmatcher = \"*\"\n\n[[hooks.SubagentStart.hooks]]\ntype = \"command\"\ncommand = '''node \"$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs\"'''\ncommand_windows = '''powershell -NoProfile -NonInteractive -Command \"$git = Join-Path __ZAIP_WORKSPACE_ROOT_TOML__ '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')\"'''\ntimeout = 3\nstatusMessage = \"Attributing ZAIP subagent Run\"\n\n[[hooks.SubagentStop]]\nmatcher = \"*\"\n\n[[hooks.SubagentStop.hooks]]\ntype = \"command\"\ncommand = '''node \"$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs\"'''\ncommand_windows = '''powershell -NoProfile -NonInteractive -Command \"$git = Join-Path __ZAIP_WORKSPACE_ROOT_TOML__ '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')\"'''\ntimeout = 3\nstatusMessage = \"Finalizing ZAIP subagent Run\"\n";
2
+ export declare const CODEX_PRE_TOOL_USE_HOOK: string;
3
+ export declare const CODEX_CONFIG: string;
4
4
  //# sourceMappingURL=codex-config-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-config-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-config-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,iCAAiC,CAAC;AAE/E,eAAO,MAAM,uBAAuB,+mBAQoB,CAAC;AAEzD,eAAO,MAAM,YAAY,4uHAiGxB,CAAC"}
1
+ {"version":3,"file":"codex-config-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-config-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gCAAgC,iCAAiC,CAAC;AAE/E,eAAO,MAAM,uBAAuB,QAQoB,CAAC;AAEzD,eAAO,MAAM,YAAY,QAiGxB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { codexWindowsHookCommand } from "./codex-windows-hook-command.js";
1
2
  export const CODEX_WORKSPACE_ROOT_PLACEHOLDER = "__ZAIP_WORKSPACE_ROOT_TOML__";
2
3
  export const CODEX_PRE_TOOL_USE_HOOK = `[[hooks.PreToolUse]]
3
4
  matcher = "^(Bash|shell_command|exec_command|apply_patch|Edit|Write)$"
@@ -5,7 +6,7 @@ matcher = "^(Bash|shell_command|exec_command|apply_patch|Edit|Write)$"
5
6
  [[hooks.PreToolUse.hooks]]
6
7
  type = "command"
7
8
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-pre-tool-use.mjs"'''
8
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-pre-tool-use.mjs')"'''
9
+ command_windows = '''${codexWindowsHookCommand("zaip-pre-tool-use.mjs")}'''
9
10
  timeout = 10
10
11
  statusMessage = "Applying ZAIP workspace safety policy"`;
11
12
  export const CODEX_CONFIG = `project_doc_fallback_filenames = ["AGENTS.md"]
@@ -92,7 +93,7 @@ matcher = "*"
92
93
  [[hooks.SubagentStart.hooks]]
93
94
  type = "command"
94
95
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
95
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')"'''
96
+ command_windows = '''${codexWindowsHookCommand("zaip-subagent-lifecycle.mjs")}'''
96
97
  timeout = 3
97
98
  statusMessage = "Attributing ZAIP subagent Run"
98
99
 
@@ -102,7 +103,7 @@ matcher = "*"
102
103
  [[hooks.SubagentStop.hooks]]
103
104
  type = "command"
104
105
  command = '''node "$(git rev-parse --show-toplevel)/.codex/hooks/zaip-subagent-lifecycle.mjs"'''
105
- command_windows = '''powershell -NoProfile -NonInteractive -Command "$git = Join-Path ${CODEX_WORKSPACE_ROOT_PLACEHOLDER} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git)) { $git = 'git' }; $root = & $git rev-parse --show-toplevel; node (Join-Path $root '.codex/hooks/zaip-subagent-lifecycle.mjs')"'''
106
+ command_windows = '''${codexWindowsHookCommand("zaip-subagent-lifecycle.mjs")}'''
106
107
  timeout = 3
107
108
  statusMessage = "Finalizing ZAIP subagent Run"
108
109
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"codex-config-template.js","sourceRoot":"","sources":["../../src/services/codex-config-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAE/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;wFAMiD,gCAAgC;;wDAEhE,CAAC;AAEzD,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;6CAgBiB,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+C3E,uBAAuB;;;;;;;;;;;;;;;;;;;;;wFAqB+D,gCAAgC;;;;;;;;;;wFAUhC,gCAAgC;;;CAGvH,CAAC"}
1
+ {"version":3,"file":"codex-config-template.js","sourceRoot":"","sources":["../../src/services/codex-config-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAE/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;uBAMhB,uBAAuB,CAAC,uBAAuB,CAAC;;wDAEf,CAAC;AAEzD,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;6CAgBiB,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+C3E,uBAAuB;;;;;;;;;;;;;;;;;;;;;uBAqBF,uBAAuB,CAAC,6BAA6B,CAAC;;;;;;;;;;uBAUtD,uBAAuB,CAAC,6BAA6B,CAAC;;;CAG5E,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+xB/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,QA8xB/B,CAAC"}
@@ -10,20 +10,13 @@ const execute = promisify(execFile);
10
10
  const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
11
11
  const deletionCommandPattern = /\b(?:Remove-Item|rm|rmdir|rd|del|erase)\b/i;
12
12
  const allowedExplicitNetworkHosts = new Set([
13
- "127.0.0.1",
14
- "api.github.com",
15
- "github.com",
16
- "localhost",
17
- "objects.githubusercontent.com",
18
- "::1",
13
+ "127.0.0.1", "api.github.com", "github.com", "localhost", "objects.githubusercontent.com", "::1",
19
14
  ]);
20
15
  const networkClientPattern = /\b(?:curl|wget|Invoke-WebRequest|Invoke-RestMethod|iwr|irm)\b/i;
21
16
  const cloudRunnerScript = ".agents/tools/cloud-runner.mjs";
22
17
  const cloudContractPath = ".agents/config/autonomous-cloud-contract.json";
23
18
  const cloudOperationProviders = new Map([
24
- ["cloudflare:dns:read", "cloudflare"],
25
- ["cloudflare:dns:create", "cloudflare"],
26
- ["cloudflare:dns:edit", "cloudflare"],
19
+ ["cloudflare:dns:read", "cloudflare"], ["cloudflare:dns:create", "cloudflare"], ["cloudflare:dns:edit", "cloudflare"],
27
20
  ["hostinger:vps:read", "hostinger"],
28
21
  ["hostinger:ssh:read", "hostinger"],
29
22
  ["hostinger:ssh:configure", "hostinger"],
@@ -101,7 +94,7 @@ const destructivePatterns = [
101
94
  reason: "OS persistence and service changes are blocked.",
102
95
  },
103
96
  {
104
- pattern: /\b(?:diskpart|format(?:\.com)?|bcdedit|fsutil|takeown|icacls|Set-Acl|chmod|chown)\b|\bcipher\s+\/w\b/i,
97
+ pattern: /\b(?:diskpart|bcdedit|fsutil|takeown|icacls|Set-Acl|chmod|chown)\b|(?:^|[\s;&|"'(])format(?:\.com)?\b|\bcipher\s+\/w\b/i,
105
98
  reason: "Disk, boot, ownership, and access-control changes are blocked.",
106
99
  },
107
100
  {
@@ -777,7 +770,13 @@ if (typeof event.cwd !== "string" || !isWithinRepository(event.cwd)) {
777
770
  deny("Tool execution outside the ZAIP-AIOS repository is blocked.");
778
771
  }
779
772
 
780
- const command = event?.tool_input?.command;
773
+ const toolInput = event?.tool_input;
774
+ const commandFromCmd = toolInput?.cmd;
775
+ const commandFromCommand = toolInput?.command;
776
+ if (typeof commandFromCmd === "string" && typeof commandFromCommand === "string" && commandFromCmd !== commandFromCommand) {
777
+ deny("Conflicting tool commands were rejected.");
778
+ }
779
+ const command = typeof commandFromCmd === "string" ? commandFromCmd : commandFromCommand;
781
780
  if (typeof command !== "string") deny("A matched tool call without a command was rejected.");
782
781
 
783
782
  if (requiresOrchestratorRun(event, command) && !(await hasCurrentTaskOrchestratorRun(event))) {
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+xB5C,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8xB5C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codex-pre-tool-hook-template.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-pre-tool-hook-template.test.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, expect, it } from "vitest";
6
+ import { CODEX_PRE_TOOL_HOOK } from "./codex-pre-tool-hook-template.js";
7
+ const roots = [];
8
+ afterEach(async () => {
9
+ await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
10
+ });
11
+ it("uses tool_input.cmd, rejects conflicting commands, and keeps read-only git formatting", async () => {
12
+ const root = await mkdtemp(join(tmpdir(), "zaip-cli-pre-tool-"));
13
+ roots.push(root);
14
+ const hookPath = join(root, ".codex", "hooks", "zaip-pre-tool-use.mjs");
15
+ await mkdir(join(root, ".codex", "hooks"), { recursive: true });
16
+ await writeFile(hookPath, CODEX_PRE_TOOL_HOOK);
17
+ const invoke = (tool_input) => spawnSync(process.execPath, [hookPath], {
18
+ cwd: root,
19
+ encoding: "utf8",
20
+ input: JSON.stringify({ cwd: root, tool_name: "exec_command", tool_input }),
21
+ });
22
+ const allowed = invoke({ cmd: "git log -1 --format='%H %s'" });
23
+ expect(allowed.status).toBe(0);
24
+ expect(allowed.stdout).toBe("");
25
+ const denied = invoke({ cmd: "git status", command: "git reset --hard" });
26
+ expect(denied.status).toBe(0);
27
+ expect(JSON.parse(denied.stdout).hookSpecificOutput.permissionDecision).toBe("deny");
28
+ const diskDenied = invoke({ cmd: "format" + " C:" });
29
+ expect(JSON.parse(diskDenied.stdout).hookSpecificOutput.permissionDecision).toBe("deny");
30
+ const nestedDiskDenied = invoke({ cmd: "cmd /c " + "format" + " C:" });
31
+ expect(JSON.parse(nestedDiskDenied.stdout).hookSpecificOutput.permissionDecision).toBe("deny");
32
+ });
33
+ //# sourceMappingURL=codex-pre-tool-hook-template.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-pre-tool-hook-template.test.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const CODEX_SUBAGENT_LIFECYCLE_HOOK = "import { existsSync } from \"node:fs\";\nimport { promises as fs } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { dirname, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst hookPath = fileURLToPath(import.meta.url);\nconst repositoryRoot = resolve(dirname(hookPath), \"..\", \"..\");\nconst diagnosticPath = resolve(\n repositoryRoot,\n \".agents\",\n \"local\",\n \"hooks\",\n \"subagent-lifecycle.ndjson\",\n);\nconst pendingRoot = resolve(repositoryRoot, \".local\", \"hooks\", \"subagent-pending\");\n\nif (process.argv[2] === \"--capture-runner\") {\n await runCaptureRunner(process.argv[3]);\n process.exit(0);\n}\nif (process.argv[2] === \"--replay-pending\") {\n const files = await fs.readdir(pendingRoot).catch(() => []);\n let replayed = 0;\n for (const file of files.filter((name) => /^[a-f0-9]{64}\\.json$/.test(name)).slice(0, 256)) {\n const path = resolve(pendingRoot, file);\n const receipt = await fs.readFile(path, \"utf8\").then(JSON.parse).catch(() => null);\n if (receipt?.state === \"pending\" && Array.isArray(receipt.capture_arguments)) { await runCaptureRunner(path, true); if (++replayed >= 3) break; }\n }\n process.exit(0);\n}\n\nlet raw = \"\";\nfor await (const chunk of process.stdin) raw += chunk;\n\ntry {\n const event = JSON.parse(raw);\n const cwd = text(event.cwd);\n const scoped = cwd === null ? \"..\" : relative(repositoryRoot, resolve(cwd));\n if (cwd === null || scoped.startsWith(\"..\")) process.exit(0);\n const eventName = text(event.hook_event_name);\n const lifecycleEvent =\n eventName === \"SubagentStart\" ? \"start\" : eventName === \"SubagentStop\" ? \"stop\" : null;\n const session = text(event.session_id);\n const turn = text(event.turn_id);\n const agentId = text(event.agent_id);\n const agentType = text(event.agent_type);\n const model = text(event.model);\n const reasoningEffort = reasoningEffortValue(\n event.model_reasoning_effort ?? event.reasoning_effort,\n );\n const parentAgentId = text(event.parent_agent_id ?? event.parent_id);\n const parentRunId = text(event.parent_run_id ?? event.root_run_id);\n const status = terminalStatus(event.status);\n const required = [lifecycleEvent, session, turn, agentId, agentType];\n if (lifecycleEvent === null) {\n await diagnostic(\"ignored_unrecognized_event\", { eventName });\n process.exit(0);\n }\n const terminalFallback =\n lifecycleEvent === \"stop\" &&\n status !== null &&\n agentId !== null &&\n parentAgentId !== null &&\n parentRunId !== null &&\n (session === null || turn === null);\n if (\n (!terminalFallback && required.some((value) => value === null)) ||\n (lifecycleEvent === \"start\" && model === null) ||\n (lifecycleEvent === \"stop\" && status === null)\n ) {\n await fs.mkdir(pendingRoot, { recursive: true });\n const identity = JSON.stringify({ eventName, session, turn, agentId, agentType, parentAgentId, parentRunId });\n const pending = resolve(pendingRoot, createHash(\"sha256\").update(identity).digest(\"hex\") + \".json\");\n await atomicSave(pending, { schema_version: 1, state: \"pending\", last_error: \"incomplete_host_metadata\", identity: JSON.parse(identity), recovery: \"Capture observed native metadata manually; never infer completed status.\" });\n await diagnostic(\"ignored_incomplete_event\", {\n eventName,\n session,\n turn,\n agentId,\n agentType,\n missing_model: lifecycleEvent === \"start\" && model === null,\n });\n process.exit(0);\n }\n const candidates = [\n resolve(repositoryRoot, \".agents\", \"runtime\", \"bin\", \"zaip.mjs\"),\n resolve(repositoryRoot, \"packages\", \"cli\", \"dist\", \"index.js\"),\n ];\n const cli = candidates.find(existsSync);\n if (cli === undefined) {\n await diagnostic(\"cli_not_found\", { eventName, candidates });\n process.exit(0);\n }\n const captureArguments = terminalFallback\n ? [\n \"subagent\",\n \"capture-terminal\",\n \"--parent-agent-id\",\n parentAgentId,\n \"--parent-run-id\",\n parentRunId,\n \"--agent-id\",\n agentId,\n \"--agent-type\",\n agentType,\n \"--status\",\n status,\n \"--json\",\n ]\n : [\n \"subagent\",\n \"capture\",\n \"--event\",\n lifecycleEvent,\n \"--session\",\n session,\n \"--turn\",\n turn,\n \"--agent-id\",\n agentId,\n \"--agent-type\",\n agentType,\n ...(model === null ? [] : [\"--model\", model]),\n ...(reasoningEffort === null ? [] : [\"--reasoning-effort\", reasoningEffort]),\n ...(parentAgentId === null ? [] : [\"--parent-agent-id\", parentAgentId]),\n ...(lifecycleEvent !== \"stop\" || status === null ? [] : [\"--status\", status]),\n \"--json\",\n ];\n const pending = await persistPending(cli, captureArguments);\n const receipt = await fs.readFile(pending, \"utf8\").then(JSON.parse);\n if (receipt.state !== \"acknowledged\") {\n const runner = spawn(\n process.execPath,\n [hookPath, \"--capture-runner\", pending],\n {\n cwd: repositoryRoot,\n detached: true,\n windowsHide: true,\n stdio: \"ignore\",\n },\n );\n runner.once(\"error\", (error) =>\n diagnostic(\"runner_spawn_failed\", { eventName, error: error.message }),\n );\n runner.unref();\n }\n if (lifecycleEvent === \"start\") {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"SubagentStart\",\n additionalContext:\n \"ZAIP Codex delegation policy: a Sub-Run is only a native collaboration subagent. Do not use create_thread or fork_thread as a Sub-Run, fallback, retry, or delegation proof; those create independent chats and require an explicit user request. If native delegation is unavailable, report the limitation rather than create an independent chat. A catalog name, task_name, title, or prompt is not native ancestry. Before retrying the same bounded dispatch, await or reuse its pending native child; capture only ancestry observed from native host spawn/terminal results or SubagentStart/SubagentStop events, and work only as a cataloged zaip-agent-NOME identity. Delegation is recursive; do not use default, worker, explorer, or ad-hoc agent types.\",\n },\n }));\n }\n} catch (error) {\n await diagnostic(\"hook_exception\", {\n error: error instanceof Error ? error.message : String(error),\n });\n}\n\nasync function atomicSave(path, value) {\n const temporary = path + \".tmp-\" + randomUUID();\n await fs.writeFile(temporary, JSON.stringify(value), { flag: \"wx\", mode: 0o600 });\n for (let retry = 0; ; retry++) {\n try { await fs.rename(temporary, path); break; }\n catch (error) { if (![\"EPERM\", \"EACCES\", \"EBUSY\"].includes(error.code) || retry >= 5) throw error; await new Promise(done => setTimeout(done, 20 * (retry + 1))); }\n }\n}\n\nasync function runCaptureRunner(receiptPath, replay = false) {\n if (typeof receiptPath !== \"string\" || dirname(resolve(receiptPath)) !== pendingRoot) return;\n const lockPath = receiptPath + \".lock\";\n let lease;\n try {\n lease = await fs.open(lockPath, \"wx\");\n await lease.writeFile(JSON.stringify({ pid: process.pid }));\n } catch (error) {\n if (error.code !== \"EEXIST\") return;\n const owner = await fs.readFile(lockPath, \"utf8\").then(JSON.parse).catch(() => null);\n if (!Number.isSafeInteger(owner?.pid) || owner.pid <= 0) return;\n try { process.kill(owner.pid, 0); return; } catch (failure) { if (failure.code !== \"ESRCH\") return; }\n // Serialize stale lock recovery so two recovering workers cannot remove a new lease.\n let recovery;\n try { recovery = await fs.open(lockPath + \".recover\", \"wx\"); } catch { return; }\n try {\n const current = await fs.readFile(lockPath, \"utf8\").then(JSON.parse).catch(() => null);\n if (current?.pid !== owner.pid) return;\n await fs.unlink(lockPath);\n lease = await fs.open(lockPath, \"wx\");\n await lease.writeFile(JSON.stringify({ pid: process.pid }));\n } finally { await recovery.close(); await fs.unlink(lockPath + \".recover\").catch(() => {}); }\n if (!lease) return;\n }\n try {\n const receipt = await fs.readFile(receiptPath, \"utf8\").then(JSON.parse);\n if (receipt.schema_version !== 1 || receipt.state === \"acknowledged\" || (!replay && receipt.attempts >= 3)) return;\n const cli = receipt.cli, args = receipt.capture_arguments;\n const allowedCli = [resolve(repositoryRoot, \".agents/runtime/bin/zaip.mjs\"), resolve(repositoryRoot, \"packages/cli/dist/index.js\")];\n if (!allowedCli.includes(cli) || !Array.isArray(args) || !args.every(x => typeof x === \"string\") || args[0] !== \"subagent\" || ![\"capture\", \"capture-terminal\"].includes(args[1])) return;\n const digest = createHash(\"sha256\").update(JSON.stringify({ cli, arguments: args })).digest(\"hex\");\n if (resolve(pendingRoot, digest + \".json\") !== resolve(receiptPath)) return;\n const value = flag => args[args.indexOf(flag) + 1];\n const stop = args[1] === \"capture-terminal\" || value(\"--event\") === \"stop\";\n if (stop && ![\"completed\", \"failed\", \"cancelled\"].includes(value(\"--status\"))) return;\n for (let retry = 0; retry < 3; retry++) {\n receipt.attempts = (receipt.attempts ?? 0) + 1;\n receipt.updated_at = new Date().toISOString();\n await atomicSave(receiptPath, receipt);\n const outcome = await capture(cli, args);\n let result;\n try { result = JSON.parse(outcome.stdout); } catch { result = null; }\n const runId = result?.run?.run_id ?? result?.run?.id;\n const status = result?.status ?? result?.run?.status;\n if (outcome.code === 0 && result?.captured === true && typeof runId === \"string\" && runId.startsWith(\"RUN-\") && (!stop || status === value(\"--status\"))) {\n receipt.state = \"acknowledged\";\n receipt.run_id = runId;\n receipt.acknowledged_at = new Date().toISOString();\n delete receipt.last_error;\n await atomicSave(receiptPath, receipt);\n return;\n }\n receipt.last_error = outcome.error ?? (outcome.code === 0 ? \"capture_not_confirmed\" : \"capture_exit_nonzero\");\n await atomicSave(receiptPath, receipt);\n if (retry < 2) await new Promise(done => setTimeout(done, 250 * (retry + 1)));\n }\n await persistDiagnostic(\"capture_pending\", { receipt: receiptPath, attempts: receipt.attempts, error: receipt.last_error });\n } catch (error) {\n await persistDiagnostic(\"runner_exception\", { error: error instanceof Error ? error.message : String(error) });\n } finally {\n await lease?.close();\n await fs.unlink(lockPath).catch(() => {});\n }\n}\n\nasync function capture(cli, args) {\n const child = spawn(process.execPath, [cli, ...args], { cwd: repositoryRoot, windowsHide: true, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\", overflow = false;\n child.stdout.on(\"data\", chunk => { stdout += String(chunk); if (stdout.length > 262144) { overflow = true; stdout = \"\"; child.kill(); } });\n child.stderr.resume();\n return await new Promise(done => {\n let settled = false;\n const finish = result => { if (settled) return; settled = true; clearTimeout(timer); done({ ...result, stdout: overflow ? \"\" : stdout }); };\n const timer = setTimeout(() => { child.kill(); finish({ error: \"capture_timeout\" }); }, 15000);\n child.once(\"error\", () => finish({ error: \"capture_spawn_failed\" }));\n child.once(\"close\", code => finish({ code }));\n });\n}\n\nasync function persistPending(cli, captureArguments) {\n const identity = JSON.stringify({ cli, arguments: captureArguments });\n const digest = createHash(\"sha256\").update(identity).digest(\"hex\");\n const path = resolve(pendingRoot, digest + \".json\");\n await fs.mkdir(pendingRoot, { recursive: true });\n const receipt = { schema_version: 1, state: \"pending\", cli, capture_arguments: captureArguments, attempts: 0, created_at: new Date().toISOString() };\n // Publish a complete immutable initial receipt without overwriting another worker's acknowledgement.\n const temporary = path + \".tmp-\" + randomUUID();\n await fs.writeFile(temporary, JSON.stringify(receipt), { flag: \"wx\", mode: 0o600 });\n try { await fs.link(temporary, path); } catch (error) { if (error.code !== \"EEXIST\") throw error; }\n finally { await fs.unlink(temporary); }\n return path;\n}\n\nasync function persistDiagnostic(code, detail) {\n const line = `${JSON.stringify({\n source: \"zaip-subagent-lifecycle-runner\",\n code,\n occurred_at: new Date().toISOString(),\n detail,\n })}\\n`;\n await fs.mkdir(dirname(diagnosticPath), { recursive: true });\n const size = await fs.stat(diagnosticPath).then((entry) => entry.size).catch(() => 0);\n if (size + Buffer.byteLength(line) > 262_144) {\n await fs.writeFile(diagnosticPath, \"\", \"utf8\");\n }\n await fs.appendFile(diagnosticPath, line, \"utf8\");\n}\n\nasync function diagnostic(code, detail) {\n await persistDiagnostic(code, detail);\n process.stderr.write(\n `${JSON.stringify({ source: \"zaip-subagent-lifecycle\", code, detail })}\\n`,\n );\n}\n\nfunction text(value) {\n if (typeof value !== \"string\") return null;\n const normalized = value.trim();\n return normalized.length > 0 && normalized.length <= 200 ? normalized : null;\n}\n\nfunction reasoningEffortValue(value) {\n const normalized = text(value);\n return [\"low\", \"medium\", \"high\", \"xhigh\"].includes(normalized) ? normalized : null;\n}\n\nfunction terminalStatus(value) {\n const normalized = text(value);\n return [\"completed\", \"failed\", \"cancelled\"].includes(normalized) ? normalized : null;\n}\n";
1
+ export declare const CODEX_SUBAGENT_LIFECYCLE_HOOK = "import { existsSync } from \"node:fs\";\nimport { promises as fs } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { dirname, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst hookPath = fileURLToPath(import.meta.url);\nconst repositoryRoot = resolve(dirname(hookPath), \"..\", \"..\");\nconst diagnosticPath = resolve(\n repositoryRoot,\n \".agents\",\n \"local\",\n \"hooks\",\n \"subagent-lifecycle.ndjson\",\n);\nconst pendingRoot = resolve(repositoryRoot, \".local\", \"hooks\", \"subagent-pending\");\n\nif (process.argv[2] === \"--capture-runner\") {\n await runCaptureRunner(process.argv[3]);\n process.exit(0);\n}\nif (process.argv[2] === \"--replay-pending\") {\n const files = await fs.readdir(pendingRoot).catch(() => []);\n let replayed = 0;\n for (const file of files.filter((name) => /^[a-f0-9]{64}\\.json$/.test(name)).slice(0, 256)) {\n const path = resolve(pendingRoot, file);\n const receipt = await fs.readFile(path, \"utf8\").then(JSON.parse).catch(() => null);\n if (receipt?.state === \"pending\" && Array.isArray(receipt.capture_arguments)) { await runCaptureRunner(path, true); if (++replayed >= 3) break; }\n }\n process.exit(0);\n}\n\nlet raw = \"\";\nfor await (const chunk of process.stdin) raw += chunk;\n\ntry {\n const event = JSON.parse(raw);\n const cwd = text(event.cwd);\n const scoped = cwd === null ? \"..\" : relative(repositoryRoot, resolve(cwd));\n if (cwd === null || scoped.startsWith(\"..\")) process.exit(0);\n const eventName = text(event.hook_event_name);\n const lifecycleEvent =\n eventName === \"SubagentStart\" ? \"start\" : eventName === \"SubagentStop\" ? \"stop\" : null;\n const session = text(event.session_id);\n const turn = text(event.turn_id);\n const agentId = text(event.agent_id);\n const agentType = text(event.agent_type);\n const model = text(event.model);\n const reasoningEffort = reasoningEffortValue(\n event.model_reasoning_effort ?? event.reasoning_effort,\n );\n const parentAgentId = text(event.parent_agent_id ?? event.parent_id);\n const parentRunId = text(event.parent_run_id ?? event.root_run_id);\n const status = terminalStatus(event.status);\n const required = [lifecycleEvent, session, turn, agentId, agentType];\n if (lifecycleEvent === null) {\n await diagnostic(\"ignored_unrecognized_event\", { eventName });\n process.exit(0);\n }\n const terminalFallback =\n lifecycleEvent === \"stop\" &&\n status !== null &&\n agentId !== null &&\n parentAgentId !== null &&\n parentRunId !== null &&\n (session === null || turn === null);\n if (\n (!terminalFallback && required.some((value) => value === null)) ||\n (lifecycleEvent === \"start\" && model === null) ||\n (lifecycleEvent === \"stop\" && status === null)\n ) {\n await fs.mkdir(pendingRoot, { recursive: true });\n const identity = JSON.stringify({ eventName, session, turn, agentId, agentType, parentAgentId, parentRunId });\n const pending = resolve(pendingRoot, createHash(\"sha256\").update(identity).digest(\"hex\") + \".json\");\n await atomicSave(pending, { schema_version: 1, state: \"pending\", last_error: \"incomplete_host_metadata\", identity: JSON.parse(identity), recovery: \"Capture observed native metadata manually; never infer completed status.\" });\n await diagnostic(\"ignored_incomplete_event\", {\n eventName,\n session,\n turn,\n agentId,\n agentType,\n missing_model: lifecycleEvent === \"start\" && model === null,\n });\n process.exit(0);\n }\n const candidates = [\n resolve(repositoryRoot, \".agents\", \"runtime\", \"bin\", \"zaip.mjs\"),\n resolve(repositoryRoot, \"packages\", \"cli\", \"dist\", \"index.js\"),\n ];\n const cli = candidates.find(existsSync);\n if (cli === undefined) {\n await diagnostic(\"cli_not_found\", { eventName, candidates });\n process.exit(0);\n }\n const captureArguments = terminalFallback\n ? [\n \"subagent\",\n \"capture-terminal\",\n \"--parent-agent-id\",\n parentAgentId,\n \"--parent-run-id\",\n parentRunId,\n \"--agent-id\",\n agentId,\n \"--agent-type\",\n agentType,\n \"--status\",\n status,\n \"--json\",\n ]\n : [\n \"subagent\",\n \"capture\",\n \"--event\",\n lifecycleEvent,\n \"--session\",\n session,\n \"--turn\",\n turn,\n \"--agent-id\",\n agentId,\n \"--agent-type\",\n agentType,\n ...(model === null ? [] : [\"--model\", model]),\n ...(reasoningEffort === null ? [] : [\"--reasoning-effort\", reasoningEffort]),\n ...(parentAgentId === null ? [] : [\"--parent-agent-id\", parentAgentId]),\n ...(lifecycleEvent !== \"stop\" || status === null ? [] : [\"--status\", status]),\n \"--json\",\n ];\n const pending = await persistPending(cli, captureArguments);\n const receipt = await fs.readFile(pending, \"utf8\").then(JSON.parse);\n if (receipt.state !== \"acknowledged\") {\n const runner = spawn(\n process.execPath,\n [hookPath, \"--capture-runner\", pending],\n {\n cwd: repositoryRoot,\n detached: true,\n windowsHide: true,\n stdio: \"ignore\",\n },\n );\n runner.once(\"error\", (error) =>\n diagnostic(\"runner_spawn_failed\", { eventName, error: error.message }),\n );\n runner.unref();\n }\n if (lifecycleEvent === \"start\") {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"SubagentStart\",\n additionalContext:\n \"ZAIP Codex delegation policy: a Sub-Run is only a native collaboration subagent. Do not use create_thread or fork_thread as a Sub-Run, fallback, retry, or delegation proof; those create independent chats and require an explicit user request. If native delegation is unavailable, report the limitation rather than create an independent chat. A catalog name, task_name, title, or prompt is not native ancestry. Before retrying the same bounded dispatch, await or reuse its pending native child; capture only ancestry observed from native host spawn/terminal results or SubagentStart/SubagentStop events, and work only as a cataloged zaip-agent-NOME identity. Delegation is recursive; do not use default, worker, explorer, or ad-hoc agent types.\",\n },\n }));\n } else {\n // Codex expects one JSON object on stdout for SubagentStop as well.\n process.stdout.write(JSON.stringify({}));\n }\n} catch (error) {\n await diagnostic(\"hook_exception\", {\n error: error instanceof Error ? error.message : String(error),\n });\n}\n\nasync function atomicSave(path, value) {\n const temporary = path + \".tmp-\" + randomUUID();\n await fs.writeFile(temporary, JSON.stringify(value), { flag: \"wx\", mode: 0o600 });\n for (let retry = 0; ; retry++) {\n try { await fs.rename(temporary, path); break; }\n catch (error) { if (![\"EPERM\", \"EACCES\", \"EBUSY\"].includes(error.code) || retry >= 5) throw error; await new Promise(done => setTimeout(done, 20 * (retry + 1))); }\n }\n}\n\nasync function runCaptureRunner(receiptPath, replay = false) {\n if (typeof receiptPath !== \"string\" || dirname(resolve(receiptPath)) !== pendingRoot) return;\n const lockPath = receiptPath + \".lock\";\n let lease;\n try {\n lease = await fs.open(lockPath, \"wx\");\n await lease.writeFile(JSON.stringify({ pid: process.pid }));\n } catch (error) {\n if (error.code !== \"EEXIST\") return;\n const owner = await fs.readFile(lockPath, \"utf8\").then(JSON.parse).catch(() => null);\n if (!Number.isSafeInteger(owner?.pid) || owner.pid <= 0) return;\n try { process.kill(owner.pid, 0); return; } catch (failure) { if (failure.code !== \"ESRCH\") return; }\n // Serialize stale lock recovery so two recovering workers cannot remove a new lease.\n let recovery;\n try { recovery = await fs.open(lockPath + \".recover\", \"wx\"); } catch { return; }\n try {\n const current = await fs.readFile(lockPath, \"utf8\").then(JSON.parse).catch(() => null);\n if (current?.pid !== owner.pid) return;\n await fs.unlink(lockPath);\n lease = await fs.open(lockPath, \"wx\");\n await lease.writeFile(JSON.stringify({ pid: process.pid }));\n } finally { await recovery.close(); await fs.unlink(lockPath + \".recover\").catch(() => {}); }\n if (!lease) return;\n }\n try {\n const receipt = await fs.readFile(receiptPath, \"utf8\").then(JSON.parse);\n if (receipt.schema_version !== 1 || receipt.state === \"acknowledged\" || (!replay && receipt.attempts >= 3)) return;\n const cli = receipt.cli, args = receipt.capture_arguments;\n const allowedCli = [resolve(repositoryRoot, \".agents/runtime/bin/zaip.mjs\"), resolve(repositoryRoot, \"packages/cli/dist/index.js\")];\n if (!allowedCli.includes(cli) || !Array.isArray(args) || !args.every(x => typeof x === \"string\") || args[0] !== \"subagent\" || ![\"capture\", \"capture-terminal\"].includes(args[1])) return;\n const digest = createHash(\"sha256\").update(JSON.stringify({ cli, arguments: args })).digest(\"hex\");\n if (resolve(pendingRoot, digest + \".json\") !== resolve(receiptPath)) return;\n const value = flag => args[args.indexOf(flag) + 1];\n const stop = args[1] === \"capture-terminal\" || value(\"--event\") === \"stop\";\n if (stop && ![\"completed\", \"failed\", \"cancelled\"].includes(value(\"--status\"))) return;\n for (let retry = 0; retry < 3; retry++) {\n receipt.attempts = (receipt.attempts ?? 0) + 1;\n receipt.updated_at = new Date().toISOString();\n await atomicSave(receiptPath, receipt);\n const outcome = await capture(cli, args);\n let result;\n try { result = JSON.parse(outcome.stdout); } catch { result = null; }\n const runId = result?.run?.run_id ?? result?.run?.id;\n const status = result?.status ?? result?.run?.status;\n if (outcome.code === 0 && result?.captured === true && typeof runId === \"string\" && runId.startsWith(\"RUN-\") && (!stop || status === value(\"--status\"))) {\n receipt.state = \"acknowledged\";\n receipt.run_id = runId;\n receipt.acknowledged_at = new Date().toISOString();\n delete receipt.last_error;\n await atomicSave(receiptPath, receipt);\n return;\n }\n receipt.last_error = outcome.error ?? (outcome.code === 0 ? \"capture_not_confirmed\" : \"capture_exit_nonzero\");\n await atomicSave(receiptPath, receipt);\n if (retry < 2) await new Promise(done => setTimeout(done, 250 * (retry + 1)));\n }\n await persistDiagnostic(\"capture_pending\", { receipt: receiptPath, attempts: receipt.attempts, error: receipt.last_error });\n } catch (error) {\n await persistDiagnostic(\"runner_exception\", { error: error instanceof Error ? error.message : String(error) });\n } finally {\n await lease?.close();\n await fs.unlink(lockPath).catch(() => {});\n }\n}\n\nasync function capture(cli, args) {\n const child = spawn(process.execPath, [cli, ...args], { cwd: repositoryRoot, windowsHide: true, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\", overflow = false;\n child.stdout.on(\"data\", chunk => { stdout += String(chunk); if (stdout.length > 262144) { overflow = true; stdout = \"\"; child.kill(); } });\n child.stderr.resume();\n return await new Promise(done => {\n let settled = false;\n const finish = result => { if (settled) return; settled = true; clearTimeout(timer); done({ ...result, stdout: overflow ? \"\" : stdout }); };\n const timer = setTimeout(() => { child.kill(); finish({ error: \"capture_timeout\" }); }, 15000);\n child.once(\"error\", () => finish({ error: \"capture_spawn_failed\" }));\n child.once(\"close\", code => finish({ code }));\n });\n}\n\nasync function persistPending(cli, captureArguments) {\n const identity = JSON.stringify({ cli, arguments: captureArguments });\n const digest = createHash(\"sha256\").update(identity).digest(\"hex\");\n const path = resolve(pendingRoot, digest + \".json\");\n await fs.mkdir(pendingRoot, { recursive: true });\n const receipt = { schema_version: 1, state: \"pending\", cli, capture_arguments: captureArguments, attempts: 0, created_at: new Date().toISOString() };\n // Publish a complete immutable initial receipt without overwriting another worker's acknowledgement.\n const temporary = path + \".tmp-\" + randomUUID();\n await fs.writeFile(temporary, JSON.stringify(receipt), { flag: \"wx\", mode: 0o600 });\n try { await fs.link(temporary, path); } catch (error) { if (error.code !== \"EEXIST\") throw error; }\n finally { await fs.unlink(temporary); }\n return path;\n}\n\nasync function persistDiagnostic(code, detail) {\n const line = `${JSON.stringify({\n source: \"zaip-subagent-lifecycle-runner\",\n code,\n occurred_at: new Date().toISOString(),\n detail,\n })}\\n`;\n await fs.mkdir(dirname(diagnosticPath), { recursive: true });\n const size = await fs.stat(diagnosticPath).then((entry) => entry.size).catch(() => 0);\n if (size + Buffer.byteLength(line) > 262_144) {\n await fs.writeFile(diagnosticPath, \"\", \"utf8\");\n }\n await fs.appendFile(diagnosticPath, line, \"utf8\");\n}\n\nasync function diagnostic(code, detail) {\n await persistDiagnostic(code, detail);\n process.stderr.write(\n `${JSON.stringify({ source: \"zaip-subagent-lifecycle\", code, detail })}\\n`,\n );\n}\n\nfunction text(value) {\n if (typeof value !== \"string\") return null;\n const normalized = value.trim();\n return normalized.length > 0 && normalized.length <= 200 ? normalized : null;\n}\n\nfunction reasoningEffortValue(value) {\n const normalized = text(value);\n return [\"low\", \"medium\", \"high\", \"xhigh\"].includes(normalized) ? normalized : null;\n}\n\nfunction terminalStatus(value) {\n const normalized = text(value);\n return [\"completed\", \"failed\", \"cancelled\"].includes(normalized) ? normalized : null;\n}\n";
2
2
  //# sourceMappingURL=codex-subagent-hook-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-subagent-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-subagent-hook-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,sqbA8SzC,CAAC"}
1
+ {"version":3,"file":"codex-subagent-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-subagent-hook-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,2ybAiTzC,CAAC"}
@@ -154,6 +154,9 @@ try {
154
154
  "ZAIP Codex delegation policy: a Sub-Run is only a native collaboration subagent. Do not use create_thread or fork_thread as a Sub-Run, fallback, retry, or delegation proof; those create independent chats and require an explicit user request. If native delegation is unavailable, report the limitation rather than create an independent chat. A catalog name, task_name, title, or prompt is not native ancestry. Before retrying the same bounded dispatch, await or reuse its pending native child; capture only ancestry observed from native host spawn/terminal results or SubagentStart/SubagentStop events, and work only as a cataloged zaip-agent-NOME identity. Delegation is recursive; do not use default, worker, explorer, or ad-hoc agent types.",
155
155
  },
156
156
  }));
157
+ } else {
158
+ // Codex expects one JSON object on stdout for SubagentStop as well.
159
+ process.stdout.write(JSON.stringify({}));
157
160
  }
158
161
  } catch (error) {
159
162
  await diagnostic("hook_exception", {
@@ -1 +1 @@
1
- {"version":3,"file":"codex-subagent-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-subagent-hook-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8S5C,CAAC"}
1
+ {"version":3,"file":"codex-subagent-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-subagent-hook-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiT5C,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Encode PowerShell before TOML and cmd.exe parse the hook command. */
2
+ export declare function codexWindowsHookCommand(hook: string, workspaceRoot?: string): string;
3
+ //# sourceMappingURL=codex-windows-hook-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-windows-hook-command.d.ts","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAKpF"}
@@ -0,0 +1,10 @@
1
+ import { resolve } from "node:path";
2
+ /** Encode PowerShell before TOML and cmd.exe parse the hook command. */
3
+ export function codexWindowsHookCommand(hook, workspaceRoot) {
4
+ if (!/^zaip-[a-z-]+\.mjs$/.test(hook))
5
+ throw new Error(`Invalid ZAIP hook name: ${hook}`);
6
+ const literalRoot = workspaceRoot === undefined ? "(Get-Location)" : `'${resolve(workspaceRoot).replaceAll("'", "''")}'`;
7
+ const script = `$git = Join-Path ${literalRoot} '.local\\git\\cmd\\git.exe'; if (!(Test-Path -LiteralPath $git -PathType Leaf)) { $git = (Get-Command git -ErrorAction SilentlyContinue).Source }; if (!$git) { exit 0 }; $root = & $git rev-parse --show-toplevel 2>$null; if ($LASTEXITCODE -ne 0 -or !$root) { exit 0 }; $hook = Join-Path $root '.codex/hooks/${hook}'; if (!(Test-Path -LiteralPath $hook -PathType Leaf)) { exit 0 }; & node $hook; exit $LASTEXITCODE`;
8
+ return `powershell -NoProfile -NonInteractive -EncodedCommand ${Buffer.from(script, "utf16le").toString("base64")}`;
9
+ }
10
+ //# sourceMappingURL=codex-windows-hook-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-windows-hook-command.js","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,wEAAwE;AACxE,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,aAAsB;IAC1E,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAC1F,MAAM,WAAW,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IACzH,MAAM,MAAM,GAAG,oBAAoB,WAAW,sTAAsT,IAAI,qGAAqG,CAAC;IAC9c,OAAO,yDAAyD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACtH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codex-windows-hook-command.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-windows-hook-command.test.d.ts","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, describe, expect, it } from "vitest";
6
+ import { codexWindowsHookCommand } from "./codex-windows-hook-command.js";
7
+ const roots = [];
8
+ afterEach(async () => {
9
+ await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
10
+ });
11
+ describe.skipIf(process.platform !== "win32")("Codex Windows hook command", () => {
12
+ it("passes stdin and JSON stdout through cmd.exe from a path with spaces", async () => {
13
+ const root = await mkdtemp(join(tmpdir(), "zaip hook workspace "));
14
+ roots.push(root);
15
+ const init = spawnSync("git", ["init", "-q"], { cwd: root, encoding: "utf8" });
16
+ expect(init.status).toBe(0);
17
+ const hooks = join(root, ".codex", "hooks");
18
+ await mkdir(hooks, { recursive: true });
19
+ await writeFile(join(hooks, "zaip-pre-tool-use.mjs"), 'let value = ""; for await (const chunk of process.stdin) value += chunk; process.stdout.write(JSON.stringify({input: JSON.parse(value)}));\n');
20
+ const command = codexWindowsHookCommand("zaip-pre-tool-use.mjs");
21
+ const result = spawnSync("cmd.exe", ["/d", "/s", "/c", command], {
22
+ cwd: root,
23
+ input: JSON.stringify({ hook_event_name: "PreToolUse", tool_input: { cmd: "git status" } }),
24
+ encoding: "utf8",
25
+ });
26
+ expect(result.status).toBe(0);
27
+ expect(JSON.parse(result.stdout)).toEqual({
28
+ input: { hook_event_name: "PreToolUse", tool_input: { cmd: "git status" } },
29
+ });
30
+ });
31
+ it("exits successfully outside a repository or when its hook is absent", async () => {
32
+ const root = await mkdtemp(join(tmpdir(), "zaip hook absent "));
33
+ roots.push(root);
34
+ const command = codexWindowsHookCommand("zaip-subagent-lifecycle.mjs");
35
+ const result = spawnSync("cmd.exe", ["/d", "/s", "/c", command], {
36
+ cwd: root,
37
+ input: "{}",
38
+ encoding: "utf8",
39
+ });
40
+ expect(result.status).toBe(0);
41
+ expect(result.stdout).toBe("");
42
+ });
43
+ });
44
+ //# sourceMappingURL=codex-windows-hook-command.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-windows-hook-command.test.js","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"global-codex-config.d.ts","sourceRoot":"","sources":["../../src/services/global-codex-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAM1E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,SAAS,CAAC;CAC7B;AAYD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,SAAsD,EAC/D,UAAU,SAAiD,EAC3D,UAAU,GAAE,2BAA4C,GACvD,OAAO,CAAC,uBAAuB,CAAC,CAuClC;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAY1D;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,gBAAgB,GAAE,SAAS,MAAM,EAAO,GACvC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CASA"}
1
+ {"version":3,"file":"global-codex-config.d.ts","sourceRoot":"","sources":["../../src/services/global-codex-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAM1E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,SAAS,CAAC;CAC7B;AAgBD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,SAAsD,EAC/D,UAAU,SAAiD,EAC3D,UAAU,GAAE,2BAA4C,GACvD,OAAO,CAAC,uBAAuB,CAAC,CAuClC;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAY1D;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,gBAAgB,GAAE,SAAS,MAAM,EAAO,GACvC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CASA"}
@@ -6,11 +6,15 @@ import { CODEX_PRE_TOOL_USE_HOOK } from "./codex-config-template.js";
6
6
  const nodeFileSystem = { mkdir, readFile, rename, rm, writeFile };
7
7
  const ANY_TOML_TABLE = /^\[\[?[^\]\r\n]+\]\]?(?:\r?\n|$)/;
8
8
  const AGENT_TABLE = /^\[agents\."([^"]+)"\](?:\r?\n|$)/;
9
- const PRE_TOOL_USE_TABLE = /^\[\[hooks\.PreToolUse\]\](?:\r?\n|$)/;
10
- const PRE_TOOL_USE_CHILD_TABLE = /^\[\[hooks\.PreToolUse\.[^\]]+\]\](?:\r?\n|$)/;
9
+ const HOOK_TABLE = /^\[\[hooks\.(PreToolUse|Stop|SubagentStart|SubagentStop)\]\](?:\r?\n|$)/;
11
10
  const ZAIP_HOOK_SIGNATURES = [
12
11
  ".codex/hooks/zaip-pre-tool-use.mjs",
12
+ ".codex/hooks/zaip-conversation-lifecycle.mjs",
13
+ ".codex/hooks/zaip-subagent-lifecycle.mjs",
13
14
  'statusMessage = "Applying ZAIP workspace safety policy"',
15
+ 'statusMessage = "Reconciling ZAIP task closure and telemetry"',
16
+ 'statusMessage = "Attributing ZAIP subagent Run"',
17
+ 'statusMessage = "Finalizing ZAIP subagent Run"',
14
18
  ];
15
19
  /**
16
20
  * Removes only catalog-declared legacy Codex identity aliases and installs the
@@ -59,7 +63,7 @@ export async function reconcileGlobalCodexConfig(codexHome = process.env.CODEX_H
59
63
  }
60
64
  }
61
65
  export function installSecurityHook(config) {
62
- const zaipHookSpans = zaipSecurityHookSpans(config);
66
+ const zaipHookSpans = zaipOwnedHookSpans(config);
63
67
  if (zaipHookSpans.length === 1 && normalizeNewlines(config).includes(CODEX_PRE_TOOL_USE_HOOK)) {
64
68
  return config;
65
69
  }
@@ -100,7 +104,7 @@ function legacyAgentTableSpans(config, legacyAgentNames) {
100
104
  }
101
105
  return tables.flatMap((table, index) => table.legacy ? [{ start: table.start, end: tables[index + 1]?.start ?? config.length }] : []);
102
106
  }
103
- function zaipSecurityHookSpans(config) {
107
+ function zaipOwnedHookSpans(config) {
104
108
  const tables = [];
105
109
  let offset = 0;
106
110
  let inMultilineBasic = false;
@@ -121,16 +125,26 @@ function zaipSecurityHookSpans(config) {
121
125
  offset += text.length;
122
126
  }
123
127
  return tables.flatMap((table, index) => {
124
- if (!PRE_TOOL_USE_TABLE.test(table.text))
128
+ const eventName = HOOK_TABLE.exec(table.text)?.[1];
129
+ if (eventName === undefined)
125
130
  return [];
126
- const nextBoundary = tables
127
- .slice(index + 1)
128
- .find((candidate) => !PRE_TOOL_USE_CHILD_TABLE.test(candidate.text));
129
- const end = nextBoundary?.start ?? config.length;
130
- const content = config.slice(table.start, end);
131
- return ZAIP_HOOK_SIGNATURES.some((signature) => content.includes(signature))
132
- ? [{ start: table.start, end }]
133
- : [];
131
+ const childTable = new RegExp(`^\\[\\[hooks\\.${eventName}\\.[^\\]]+\\]\\]`);
132
+ let boundary = index + 1;
133
+ while (boundary < tables.length && childTable.test(tables[boundary].text))
134
+ boundary += 1;
135
+ const end = tables[boundary]?.start ?? config.length;
136
+ const children = tables.slice(index + 1, boundary).map((child, childIndex, siblings) => ({
137
+ start: child.start,
138
+ end: siblings[childIndex + 1]?.start ?? end,
139
+ }));
140
+ const isZaip = (span) => ZAIP_HOOK_SIGNATURES.some((signature) => config.slice(span.start, span.end).includes(signature));
141
+ if (children.length === 0)
142
+ return isZaip({ start: table.start, end }) ? [{ start: table.start, end }] : [];
143
+ const owned = children.filter(isZaip);
144
+ if (owned.length === children.length)
145
+ return [{ start: table.start, end }];
146
+ // An event can contain user and ZAIP hooks. Keep the event matcher and every user child intact.
147
+ return owned;
134
148
  });
135
149
  }
136
150
  async function catalogedCodexAliases(sourcePath, filesystem) {