@fitlab-ai/agent-infra 0.12.0 → 0.12.2

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 (331) hide show
  1. package/README.md +0 -2
  2. package/README.zh-CN.md +0 -2
  3. package/dist/bin/internal-cli.js +2 -17
  4. package/dist/lib/agent-clients/adapter.js +0 -13
  5. package/dist/lib/agent-clients/adapters/antigravity-cli.js +0 -5
  6. package/dist/lib/agent-clients/adapters/claude-code-credentials.js +0 -17
  7. package/dist/lib/agent-clients/adapters/claude-code.js +0 -9
  8. package/dist/lib/agent-clients/adapters/codex.js +0 -52
  9. package/dist/lib/agent-clients/adapters/opencode.js +0 -5
  10. package/dist/lib/agent-clients/adapters/traecli.js +0 -5
  11. package/dist/lib/agent-clients/config.js +19 -54
  12. package/dist/lib/agent-clients/registry.js +1 -12
  13. package/dist/lib/agent-clients/schema.js +0 -18
  14. package/dist/lib/agent-clients/tokens.js +1 -2
  15. package/dist/lib/agent-clients/types.js +0 -1
  16. package/dist/lib/decide.js +2 -0
  17. package/dist/lib/git/worktree-identity.js +1 -9
  18. package/dist/lib/internal/agent-client.js +2 -62
  19. package/dist/lib/internal/cli-route-inventory.js +1 -5
  20. package/dist/lib/internal/manual-validation.js +29 -27
  21. package/dist/lib/internal/platform-comment.js +56 -7
  22. package/dist/lib/internal/task-create.js +1 -1
  23. package/dist/lib/internal/task-event.js +1 -8
  24. package/dist/lib/internal/task-finalization.js +0 -1
  25. package/dist/lib/internal/task-lifecycle.js +2 -2
  26. package/dist/lib/internal/task-operation-registry.js +4 -20
  27. package/dist/lib/internal/task-review.js +4 -4
  28. package/dist/lib/platform/comment-safety.js +1 -7
  29. package/dist/lib/platform/in-label-sync.js +1 -14
  30. package/dist/lib/platform/issue-comments.js +373 -282
  31. package/dist/lib/platform/issue-summary-content.js +112 -0
  32. package/dist/lib/platform/issues.js +1 -1
  33. package/dist/lib/platform/operation-coordinator.js +4 -2
  34. package/dist/lib/platform/pr-change-report.js +176 -30
  35. package/dist/lib/platform/pr-checks.js +2 -8
  36. package/dist/lib/platform/pr-summary-content.js +54 -0
  37. package/dist/lib/platform/pr-summary.js +318 -284
  38. package/dist/lib/platform/provider-validation.js +0 -20
  39. package/dist/lib/platform/pull-requests.js +73 -84
  40. package/dist/lib/platform/releases.js +1 -43
  41. package/dist/lib/platform/summary-content-pipeline.js +18 -0
  42. package/dist/lib/platform/verification-required.js +0 -2
  43. package/dist/lib/platform/verification-sync.js +1 -79
  44. package/dist/lib/process-data/normalize.js +1 -185
  45. package/dist/lib/process-data/privacy.js +1 -16
  46. package/dist/lib/process-data/sources.js +2 -279
  47. package/dist/lib/render.js +0 -12
  48. package/dist/lib/run/index.js +15 -10
  49. package/dist/lib/run/skills.js +0 -3
  50. package/dist/lib/sandbox/commands/create.js +40 -53
  51. package/dist/lib/sandbox/commands/list-running.js +0 -18
  52. package/dist/lib/sandbox/commands/start.js +7 -8
  53. package/dist/lib/sandbox/constants.js +0 -6
  54. package/dist/lib/sandbox/control/client.js +0 -1
  55. package/dist/lib/sandbox/control/container-identity.js +1 -16
  56. package/dist/lib/sandbox/control/executor.js +0 -4
  57. package/dist/lib/sandbox/control/identity-sentinel.js +0 -7
  58. package/dist/lib/sandbox/control/lifecycle.js +21 -37
  59. package/dist/lib/sandbox/control/native-file-lock.js +0 -3
  60. package/dist/lib/sandbox/control/server.js +18 -38
  61. package/dist/lib/sandbox/control/state.js +1 -9
  62. package/dist/lib/sandbox/dockerfile.js +0 -6
  63. package/dist/lib/sandbox/engine.js +0 -14
  64. package/dist/lib/sandbox/engines/docker-exact-discovery.js +1 -4
  65. package/dist/lib/sandbox/engines/wsl2-paths.js +0 -3
  66. package/dist/lib/sandbox/recovery.js +24 -26
  67. package/dist/lib/sandbox/removal.js +67 -518
  68. package/dist/lib/sandbox/task-resolver.js +0 -41
  69. package/dist/lib/sandbox/tools.js +1 -4
  70. package/dist/lib/sandbox/workspace-view.js +1 -2
  71. package/dist/lib/server/display.js +0 -6
  72. package/dist/lib/task/activity-intent.js +45 -40
  73. package/dist/lib/task/activity-log.js +9 -16
  74. package/dist/lib/task/artifact-command.js +1 -1
  75. package/dist/lib/task/artifact-lifecycle.js +61 -63
  76. package/dist/lib/task/artifact-name.js +0 -6
  77. package/dist/lib/task/artifact-operations.js +3 -3
  78. package/dist/lib/task/capabilities.js +4 -5
  79. package/dist/lib/task/commands/log.js +0 -6
  80. package/dist/lib/task/commands/status.js +17 -60
  81. package/dist/lib/task/commit-operation.js +28 -39
  82. package/dist/lib/task/completion-facts.js +56 -43
  83. package/dist/lib/task/control-authority.js +23 -256
  84. package/dist/lib/task/control-recovery.js +3 -5
  85. package/dist/lib/task/create.js +2 -4
  86. package/dist/lib/task/decision-intents.js +8 -9
  87. package/dist/lib/task/delivery-target.js +1 -40
  88. package/dist/lib/task/events.js +84 -107
  89. package/dist/lib/task/finalization.js +60 -15
  90. package/dist/lib/task/ledger-intents.js +1 -1
  91. package/dist/lib/task/lifecycle-execution.js +38 -33
  92. package/dist/lib/task/lifecycle.js +49 -41
  93. package/dist/lib/task/local-artifact-finalization.js +1 -4
  94. package/dist/lib/task/manual-validation-evidence.js +1 -37
  95. package/dist/lib/task/platform-operation-recovery.js +151 -108
  96. package/dist/lib/task/pr-delivery-fact.js +2 -5
  97. package/dist/lib/task/qualification-confirmation.js +5 -7
  98. package/dist/lib/task/resolve-ref.js +1 -25
  99. package/dist/lib/task/review-command.js +2 -2
  100. package/dist/lib/task/review-finalization.js +1 -21
  101. package/dist/lib/task/review-fingerprint.js +0 -4
  102. package/dist/lib/task/secure-fs.js +0 -56
  103. package/dist/lib/task/short-id.js +1 -39
  104. package/dist/lib/task/skill-scope.js +0 -1
  105. package/dist/lib/task/verification-engine.js +58 -282
  106. package/dist/lib/task/verification.js +6 -3
  107. package/dist/lib/task/write.js +11 -1
  108. package/lib/agent-clients/adapter.ts +0 -76
  109. package/lib/agent-clients/adapters/antigravity-cli.ts +0 -5
  110. package/lib/agent-clients/adapters/claude-code-credentials.ts +0 -19
  111. package/lib/agent-clients/adapters/claude-code.ts +0 -9
  112. package/lib/agent-clients/adapters/codex.ts +0 -56
  113. package/lib/agent-clients/adapters/opencode.ts +0 -5
  114. package/lib/agent-clients/adapters/traecli.ts +0 -5
  115. package/lib/agent-clients/config.ts +20 -61
  116. package/lib/agent-clients/registry.ts +1 -34
  117. package/lib/agent-clients/schema.ts +0 -18
  118. package/lib/agent-clients/tokens.ts +1 -2
  119. package/lib/agent-clients/types.ts +0 -15
  120. package/lib/decide.ts +1 -0
  121. package/lib/git/worktree-identity.ts +0 -10
  122. package/lib/internal/agent-client.ts +2 -70
  123. package/lib/internal/cli-route-inventory.ts +1 -4
  124. package/lib/internal/manual-validation.ts +28 -27
  125. package/lib/internal/platform-comment.ts +46 -4
  126. package/lib/internal/task-create.ts +0 -1
  127. package/lib/internal/task-event.ts +1 -5
  128. package/lib/internal/task-finalization.ts +0 -1
  129. package/lib/internal/task-lifecycle.ts +3 -5
  130. package/lib/internal/task-operation-registry.ts +3 -19
  131. package/lib/internal/task-review.ts +4 -4
  132. package/lib/platform/comment-safety.ts +0 -10
  133. package/lib/platform/github-provider.ts +0 -2
  134. package/lib/platform/in-label-sync.ts +0 -16
  135. package/lib/platform/issue-comments.ts +478 -301
  136. package/lib/platform/issue-summary-content.ts +132 -0
  137. package/lib/platform/issues.ts +0 -2
  138. package/lib/platform/operation-coordinator.ts +4 -2
  139. package/lib/platform/pr-change-report.ts +165 -25
  140. package/lib/platform/pr-checks.ts +1 -10
  141. package/lib/platform/pr-review.ts +1 -1
  142. package/lib/platform/pr-summary-content.ts +60 -0
  143. package/lib/platform/pr-summary.ts +364 -257
  144. package/lib/platform/provider-bridge.ts +0 -1
  145. package/lib/platform/provider-loader.ts +1 -5
  146. package/lib/platform/provider-validation.ts +1 -49
  147. package/lib/platform/pull-requests.ts +64 -99
  148. package/lib/platform/releases.ts +1 -40
  149. package/lib/platform/summary-content-pipeline.ts +23 -0
  150. package/lib/platform/verification-required.ts +0 -2
  151. package/lib/platform/verification-sync.ts +0 -94
  152. package/lib/process-data/normalize.ts +1 -186
  153. package/lib/process-data/privacy.ts +2 -19
  154. package/lib/process-data/sources.ts +3 -283
  155. package/lib/render.ts +0 -15
  156. package/lib/run/index.ts +13 -7
  157. package/lib/run/skills.ts +0 -4
  158. package/lib/sandbox/commands/create.ts +37 -74
  159. package/lib/sandbox/commands/list-running.ts +0 -19
  160. package/lib/sandbox/commands/start.ts +7 -10
  161. package/lib/sandbox/constants.ts +0 -8
  162. package/lib/sandbox/control/client.ts +0 -1
  163. package/lib/sandbox/control/container-identity.ts +1 -16
  164. package/lib/sandbox/control/executor.ts +1 -5
  165. package/lib/sandbox/control/identity-sentinel.ts +0 -8
  166. package/lib/sandbox/control/lifecycle.ts +18 -51
  167. package/lib/sandbox/control/native-file-lock.ts +0 -8
  168. package/lib/sandbox/control/protocol.ts +0 -2
  169. package/lib/sandbox/control/server.ts +13 -39
  170. package/lib/sandbox/control/state.ts +1 -10
  171. package/lib/sandbox/dockerfile.ts +0 -11
  172. package/lib/sandbox/engine.ts +0 -17
  173. package/lib/sandbox/engines/docker-exact-discovery.ts +1 -5
  174. package/lib/sandbox/engines/wsl2-paths.ts +0 -4
  175. package/lib/sandbox/recovery.ts +24 -26
  176. package/lib/sandbox/removal.ts +58 -687
  177. package/lib/sandbox/shell.ts +1 -1
  178. package/lib/sandbox/task-resolver.ts +0 -48
  179. package/lib/sandbox/tools.ts +1 -5
  180. package/lib/sandbox/workspace-view.ts +2 -4
  181. package/lib/server/display.ts +0 -14
  182. package/lib/server/process-control.ts +1 -1
  183. package/lib/task/activity-intent.ts +36 -44
  184. package/lib/task/activity-log.ts +9 -22
  185. package/lib/task/artifact-command.ts +1 -1
  186. package/lib/task/artifact-lifecycle.ts +58 -67
  187. package/lib/task/artifact-name.ts +0 -7
  188. package/lib/task/artifact-operations.ts +3 -3
  189. package/lib/task/capabilities.ts +5 -6
  190. package/lib/task/commands/log.ts +0 -7
  191. package/lib/task/commands/status.ts +14 -79
  192. package/lib/task/commit-operation.ts +29 -51
  193. package/lib/task/completion-facts.ts +45 -42
  194. package/lib/task/control-authority.ts +27 -317
  195. package/lib/task/control-recovery.ts +2 -5
  196. package/lib/task/create.ts +2 -5
  197. package/lib/task/decision-intents.ts +5 -5
  198. package/lib/task/delivery-target.ts +0 -40
  199. package/lib/task/events.ts +89 -123
  200. package/lib/task/finalization.ts +52 -15
  201. package/lib/task/ledger-intents.ts +1 -1
  202. package/lib/task/lifecycle-execution.ts +37 -89
  203. package/lib/task/lifecycle.ts +48 -44
  204. package/lib/task/local-artifact-finalization.ts +0 -7
  205. package/lib/task/manual-validation-evidence.ts +1 -47
  206. package/lib/task/platform-operation-recovery.ts +117 -104
  207. package/lib/task/pr-delivery-fact.ts +2 -11
  208. package/lib/task/qualification-confirmation.ts +6 -6
  209. package/lib/task/resolve-ref.ts +0 -23
  210. package/lib/task/review-command.ts +2 -2
  211. package/lib/task/review-finalization.ts +1 -27
  212. package/lib/task/review-fingerprint.ts +0 -8
  213. package/lib/task/secure-fs.ts +0 -42
  214. package/lib/task/short-id.ts +0 -43
  215. package/lib/task/skill-scope.ts +0 -1
  216. package/lib/task/verification-engine.ts +56 -287
  217. package/lib/task/verification.ts +5 -5
  218. package/lib/task/write.ts +12 -1
  219. package/package.json +2 -2
  220. package/templates/.agents/README.en.md +1 -3
  221. package/templates/.agents/README.zh-CN.md +0 -2
  222. package/templates/.agents/rules/README.en.md +0 -1
  223. package/templates/.agents/rules/README.zh-CN.md +0 -1
  224. package/templates/.agents/rules/commit-and-pr.en.md +1 -1
  225. package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -1
  226. package/templates/.agents/rules/no-mid-flow-questions.en.md +0 -10
  227. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +0 -10
  228. package/templates/.agents/rules/pr-sync.en.md +4 -2
  229. package/templates/.agents/rules/pr-sync.zh-CN.md +6 -9
  230. package/templates/.agents/rules/task-management.en.md +3 -3
  231. package/templates/.agents/rules/task-management.zh-CN.md +3 -3
  232. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  233. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  234. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  235. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  236. package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
  237. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
  238. package/templates/.agents/skills/commit/SKILL.en.md +2 -2
  239. package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
  240. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +6 -6
  241. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +6 -6
  242. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  243. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  244. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +2 -2
  245. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +2 -2
  246. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -25
  247. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +11 -26
  248. package/templates/.agents/skills/create-pr/SKILL.en.md +1 -1
  249. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
  250. package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -2
  251. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -2
  252. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
  253. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
  254. package/templates/.agents/skills/create-task/SKILL.en.md +0 -18
  255. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +0 -18
  256. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  257. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  258. package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
  259. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
  260. package/templates/.agents/skills/review-code/SKILL.en.md +5 -5
  261. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
  262. package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
  263. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
  264. package/templates/.agents/skills/review-pr/SKILL.en.md +4 -4
  265. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +4 -4
  266. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
  267. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
  268. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -75
  269. package/templates/.agents/skills/watch-pr/SKILL.en.md +1 -1
  270. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +1 -1
  271. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +3 -3
  272. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +3 -3
  273. package/templates/.agents/templates/task.en.md +1 -0
  274. package/templates/.agents/templates/task.zh-CN.md +1 -0
  275. package/templates/.claude/settings.json +0 -24
  276. package/templates/.codex/hooks.json +0 -50
  277. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +0 -582
  278. package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +0 -114
  279. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +0 -237
  280. package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +0 -443
  281. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +0 -236
  282. package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +0 -292
  283. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +0 -267
  284. package/dist/lib/agent-clients/adapters/codex-orchestration.js +0 -466
  285. package/dist/lib/internal/task-orchestration.js +0 -71
  286. package/dist/lib/platform/verification.js +0 -6
  287. package/dist/lib/run/prompt.js +0 -2
  288. package/dist/lib/sandbox/engines/authority.js +0 -289
  289. package/dist/lib/task/delegation-receipts.js +0 -410
  290. package/dist/lib/task/orchestration.js +0 -1233
  291. package/dist/lib/task/verification-checks.js +0 -9
  292. package/dist/lib/task/workspace-snapshot.js +0 -121
  293. package/dist/lifecycle-build-manifest.json +0 -6
  294. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +0 -688
  295. package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +0 -147
  296. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +0 -349
  297. package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +0 -506
  298. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +0 -385
  299. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +0 -41
  300. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +0 -418
  301. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +0 -354
  302. package/lib/agent-clients/adapters/codex-orchestration.ts +0 -630
  303. package/lib/internal/task-orchestration.ts +0 -74
  304. package/lib/platform/verification.ts +0 -11
  305. package/lib/run/prompt.ts +0 -1
  306. package/lib/sandbox/engines/authority.ts +0 -365
  307. package/lib/task/delegation-receipts.ts +0 -547
  308. package/lib/task/orchestration.ts +0 -1651
  309. package/lib/task/verification-checks.ts +0 -10
  310. package/lib/task/workspace-snapshot.ts +0 -144
  311. package/templates/.agents/hooks/lifecycle-delegation.js +0 -140
  312. package/templates/.agents/rules/lifecycle-orchestration.en.md +0 -44
  313. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +0 -44
  314. package/templates/.agents/skills/run-task/SKILL.en.md +0 -29
  315. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +0 -29
  316. package/templates/.agents/skills/run-task/config/verify.en.json +0 -10
  317. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +0 -10
  318. package/templates/.agents/skills/run-task/reference/host-validation.en.md +0 -24
  319. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +0 -24
  320. package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +0 -6
  321. package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +0 -6
  322. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +0 -6
  323. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +0 -6
  324. package/templates/.claude/commands/run-task.en.md +0 -8
  325. package/templates/.claude/commands/run-task.zh-CN.md +0 -8
  326. package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +0 -3
  327. package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +0 -3
  328. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +0 -3
  329. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +0 -3
  330. package/templates/.opencode/commands/run-task.en.md +0 -11
  331. package/templates/.opencode/commands/run-task.zh-CN.md +0 -11
@@ -1,506 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import crypto from 'node:crypto';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
-
6
- import {
7
- preflightCodexLifecycleEvidence,
8
- resolveCodexTerminal,
9
- resolveCodexThread
10
- } from './app-server.ts';
11
- import { createCodexLifecycleStore } from './store.ts';
12
- import type { CodexLifecycleEvent } from './evidence.ts';
13
- import { resolveTaskRef } from '../../../task/resolve-ref.ts';
14
- import { resolveTaskContext } from '../../../task/resolve-ref.ts';
15
- import { hasSealableOrchestrationDelegation, readRun } from '../../../task/orchestration.ts';
16
- import {
17
- parseCodexLifecycleBinding,
18
- verifyCodexLifecycleTaskBinding
19
- } from './binding.ts';
20
- import type { CodexLifecycleTaskBinding } from './binding.ts';
21
- import {
22
- activateCodexOrchestrationDelegation,
23
- activateCodexSpawnDelegation,
24
- reconcileCodexOrchestrationDelegation,
25
- sealCodexOrchestrationDelegation,
26
- sealCodexParentDelegation
27
- } from '../codex-orchestration.ts';
28
- import { ensureInternalHandlerRoute, internalHandlerRoute } from '../../../internal/cli-route-inventory.ts';
29
-
30
- const USAGE = 'Usage: agent-infra-internal codex-lifecycle <hook-event|resolve-start|resolve-stop|preflight|consume> [options]\n';
31
- const MANAGED_AGENT = /^agent-infra-lifecycle-(executor|reviewer)$/;
32
-
33
- type Parsed = Readonly<{ operation: string; values: Readonly<Record<string, string>> }>;
34
- type UnresolvedHookChild = Omit<Extract<CodexLifecycleEvent, { type: 'hook-child' }>, 'parentThreadId'>;
35
-
36
- function output(value: unknown): void {
37
- process.stdout.write(`${JSON.stringify(value)}\n`);
38
- }
39
-
40
- function failure(code: string, message: string): void {
41
- output({ status: 'failed', changed: false, evidence: null, diagnostics: [], error: { code, message } });
42
- process.exitCode = 1;
43
- }
44
-
45
- function outputBridgeResult(result: Awaited<ReturnType<typeof activateCodexOrchestrationDelegation>>): void {
46
- if (result.error?.code === 'ORCHESTRATION_DELEGATION_MISSING') {
47
- output({ status: 'ignored', changed: false, evidence: null, diagnostics: [], error: null });
48
- return;
49
- }
50
- output(result);
51
- if (result.status !== 'running') process.exitCode = 1;
52
- }
53
-
54
- function parse(args: string[]): Parsed | null {
55
- if (args[0] === '--help' || args[0] === '-h') {
56
- process.stdout.write(USAGE);
57
- return null;
58
- }
59
- const operation = args[0];
60
- if (!operation) {
61
- failure('CODEX_LIFECYCLE_PAYLOAD_INVALID', 'operation is required');
62
- return null;
63
- }
64
- const allowed = {
65
- 'hook-event': ['--event', '--bridge'],
66
- 'resolve-start': ['--child-id'],
67
- 'resolve-stop': ['--child-id'],
68
- preflight: ['--format', '--session-id', '--turn-id', '--tool-use-id'],
69
- consume: ['--child-id', '--consumer']
70
- }[operation];
71
- if (!allowed) {
72
- failure('CODEX_LIFECYCLE_PAYLOAD_INVALID', 'unknown operation');
73
- return null;
74
- }
75
- const values: Record<string, string> = {};
76
- for (let index = 1; index < args.length; index += 1) {
77
- const flag = args[index]!;
78
- if (!allowed.includes(flag) || Object.hasOwn(values, flag)) {
79
- failure('CODEX_LIFECYCLE_PAYLOAD_INVALID', `invalid or duplicate option '${flag}'`);
80
- return null;
81
- }
82
- const value = args[++index];
83
- if (!value || value.startsWith('--')) {
84
- failure('CODEX_LIFECYCLE_PAYLOAD_INVALID', `option '${flag}' requires a value`);
85
- return null;
86
- }
87
- values[flag] = value;
88
- }
89
- return Object.freeze({ operation, values: Object.freeze(values) });
90
- }
91
-
92
- function cliVersion(): string {
93
- const result = spawnSync('codex', ['--version'], { encoding: 'utf8' });
94
- const version = /codex-cli\s+(\d+\.\d+\.\d+)/.exec(result.stdout ?? '')?.[1];
95
- if (result.status !== 0 || !version) throw new Error('Codex CLI version is unavailable');
96
- return version;
97
- }
98
-
99
- function hookDefinitionHash(): string {
100
- const file = path.join(process.cwd(), '.codex', 'hooks.json');
101
- return crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
102
- }
103
-
104
- function resolveLifecycleTaskContext() {
105
- const taskId = process.env.AGENT_INFRA_TASK_ID;
106
- const context = taskId
107
- ? resolveTaskRef(taskId, { repoRoot: process.cwd() })
108
- : resolveTaskContext(undefined, { repoRoot: process.cwd() });
109
- if (!context.ok) throw new Error(`${context.code}: ${context.message}`);
110
- return context;
111
- }
112
-
113
- function verifyPendingBinding(
114
- binding: CodexLifecycleTaskBinding,
115
- nativeAgent: string,
116
- expected: Readonly<{ requestedModel?: string; requestedReasoningEffort?: string }> = {}
117
- ) {
118
- const resolved = resolveLifecycleTaskContext();
119
- const run = readRun(resolved.taskDir);
120
- if (!run) throw new Error('Codex lifecycle task binding has no current orchestration run');
121
- verifyCodexLifecycleTaskBinding(binding, run, nativeAgent, expected);
122
- return { resolved, run };
123
- }
124
-
125
- function verifyStoredBinding(
126
- taskId: string,
127
- binding: CodexLifecycleTaskBinding,
128
- nativeAgent: string
129
- ): void {
130
- const resolved = resolveTaskRef(taskId, { repoRoot: process.cwd() });
131
- if (!resolved.ok) throw new Error(`${resolved.code}: ${resolved.message}`);
132
- const run = readRun(resolved.taskDir);
133
- const receipt = run?.pendingDelegation;
134
- if (!receipt || run?.status !== 'running'
135
- || receipt.id !== binding.receiptId
136
- || receipt.runId !== binding.runId
137
- || receipt.client !== 'codex'
138
- || receipt.role !== nativeRole(nativeAgent)) {
139
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: stored task receipt is not the current pending lifecycle event');
140
- }
141
- }
142
-
143
- function sameTaskBinding(left: CodexLifecycleTaskBinding | null | undefined, right: CodexLifecycleTaskBinding): boolean {
144
- return left?.runId === right.runId && left.receiptId === right.receiptId;
145
- }
146
-
147
- function nativeRole(nativeAgent: string): string | null {
148
- const match = /^agent-infra-lifecycle-(executor|reviewer)$/u.exec(nativeAgent);
149
- return match?.[1] ?? null;
150
- }
151
-
152
- function taskScopedStore(taskId: string) {
153
- return createCodexLifecycleStore({
154
- repoRoot: process.cwd(),
155
- taskId,
156
- cliVersion: cliVersion()
157
- });
158
- }
159
-
160
- async function readStdin(): Promise<unknown> {
161
- let input = '';
162
- process.stdin.setEncoding('utf8');
163
- for await (const chunk of process.stdin) {
164
- input += chunk;
165
- if (Buffer.byteLength(input) > 64 * 1024) throw new Error('Codex lifecycle input exceeds 64 KiB');
166
- }
167
- return JSON.parse(input || '{}') as unknown;
168
- }
169
-
170
- function recordFromPayload(phase: string, payload: unknown, taskBinding?: CodexLifecycleTaskBinding): CodexLifecycleEvent | UnresolvedHookChild | null {
171
- if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
172
- throw new Error('Codex lifecycle hook payload must be an object');
173
- }
174
- const value = payload as Record<string, unknown>;
175
- const text = (key: string) => typeof value[key] === 'string' ? value[key] as string : '';
176
- if (!MANAGED_AGENT.test(text('nativeAgent'))) return null;
177
- if (phase === 'pre-tool') return {
178
- type: 'hook-spawn',
179
- sessionId: text('sessionId'),
180
- turnId: text('turnId'),
181
- toolUseId: text('toolUseId'),
182
- nativeAgent: text('nativeAgent'),
183
- ...(text('requestedModel') ? { requestedModel: text('requestedModel') } : {}),
184
- ...(text('requestedReasoningEffort') ? { requestedReasoningEffort: text('requestedReasoningEffort') } : {}),
185
- hookDefinitionHash: text('hookDefinitionHash'),
186
- ...(taskBinding ? { taskBinding } : {})
187
- };
188
- if (phase === 'subagent-start') return {
189
- type: 'hook-child',
190
- sessionId: text('sessionId'),
191
- turnId: text('turnId'),
192
- childThreadId: text('childThreadId'),
193
- nativeAgent: text('nativeAgent'),
194
- source: 'hook'
195
- };
196
- if (phase === 'subagent-stop') return {
197
- type: 'hook-stop',
198
- sessionId: text('sessionId'),
199
- turnId: text('turnId'),
200
- childThreadId: text('childThreadId'),
201
- nativeAgent: text('nativeAgent')
202
- };
203
- if (phase === 'post-tool') return null;
204
- throw new Error(`unknown Codex lifecycle hook phase '${phase}'`);
205
- }
206
-
207
- function payloadText(payload: unknown, key: string): string {
208
- return payload && typeof payload === 'object' && !Array.isArray(payload)
209
- && typeof (payload as Record<string, unknown>)[key] === 'string'
210
- ? (payload as Record<string, string>)[key]!
211
- : '';
212
- }
213
-
214
- function resolveHookTaskContext(phase: string, toolName: string, payload: unknown) {
215
- const spawnName = payloadText(payload, 'taskName');
216
- const needsSpawnBinding = phase === 'pre-tool' || (phase === 'post-tool' && toolName === 'collaborationspawn_agent');
217
- const spawnBinding = needsSpawnBinding ? parseCodexLifecycleBinding(spawnName) : null;
218
- if (needsSpawnBinding && !spawnBinding) {
219
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISSING: task_name must carry the prepared task binding');
220
- }
221
- const nativeAgent = payloadText(payload, 'nativeAgent');
222
- const taskContext = spawnBinding
223
- ? verifyPendingBinding(spawnBinding.binding, nativeAgent, {
224
- requestedModel: payloadText(payload, 'requestedModel') || undefined,
225
- requestedReasoningEffort: payloadText(payload, 'requestedReasoningEffort') || undefined
226
- }).resolved
227
- : resolveLifecycleTaskContext();
228
- const store = taskScopedStore(taskContext.taskId);
229
- if (spawnBinding) verifyStoredBinding(taskContext.taskId, spawnBinding.binding, nativeAgent);
230
- return { spawnBinding, nativeAgent, taskContext, store };
231
- }
232
-
233
- function currentHookTaskBinding(
234
- taskDir: string,
235
- taskId: string,
236
- spawnBinding: ReturnType<typeof parseCodexLifecycleBinding>,
237
- nativeAgent: string
238
- ) {
239
- if (!spawnBinding) {
240
- const run = readRun(taskDir);
241
- const receipt = run?.pendingDelegation;
242
- if (!receipt || receipt.client !== 'codex' || receipt.role !== nativeRole(nativeAgent)) {
243
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: no matching pending task receipt');
244
- }
245
- verifyStoredBinding(taskId, { taskId: receipt.taskId, runId: receipt.runId, receiptId: receipt.id }, nativeAgent);
246
- }
247
- const receipt = readRun(taskDir)?.pendingDelegation;
248
- return receipt && { taskId: receipt.taskId, runId: receipt.runId, receiptId: receipt.id };
249
- }
250
-
251
- function validateHookStopIdentity(
252
- store: ReturnType<typeof taskScopedStore>,
253
- event: Extract<CodexLifecycleEvent, { type: 'hook-stop' }>,
254
- currentBinding: ReturnType<typeof currentHookTaskBinding>
255
- ): void {
256
- const record = store.read(event.childThreadId);
257
- const child = record.state.child;
258
- if (!currentBinding || !sameTaskBinding(record.taskBinding, currentBinding)
259
- || !child
260
- || child.sessionId !== event.sessionId
261
- || child.turnId !== event.turnId
262
- || child.childThreadId !== event.childThreadId
263
- || child.nativeAgent !== event.nativeAgent) {
264
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: stop event does not match the current task receipt and child');
265
- }
266
- }
267
-
268
- function matchingHookChildSpawns(
269
- store: ReturnType<typeof taskScopedStore>,
270
- binding: ReturnType<typeof currentHookTaskBinding>,
271
- event: UnresolvedHookChild
272
- ) {
273
- return binding ? store.findByTaskBinding(binding).filter((record) =>
274
- record.state.spawn?.sessionId === event.sessionId
275
- && record.state.spawn?.nativeAgent === event.nativeAgent
276
- ) : [];
277
- }
278
-
279
- async function applyHookChildEvent(
280
- event: UnresolvedHookChild,
281
- currentBinding: NonNullable<ReturnType<typeof currentHookTaskBinding>>,
282
- taskContext: ReturnType<typeof resolveLifecycleTaskContext>,
283
- store: ReturnType<typeof taskScopedStore>,
284
- bridge: boolean,
285
- resolved?: Awaited<ReturnType<typeof resolveCodexThread>>
286
- ): Promise<void> {
287
- const candidates = matchingHookChildSpawns(store, currentBinding, event);
288
- if (candidates.length !== 1) {
289
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: child event has no unique spawn for the current task receipt');
290
- }
291
- const childResolution = resolved ?? await resolveCodexThread(event.childThreadId);
292
- verifyStoredBinding(taskContext.taskId, currentBinding, event.nativeAgent);
293
- const latestCandidates = matchingHookChildSpawns(store, currentBinding, event);
294
- if (latestCandidates.length !== 1 || latestCandidates[0]!.revision !== candidates[0]!.revision) {
295
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: task receipt spawn became ambiguous during child resolution');
296
- }
297
- if (childResolution.resolution.thread.childThreadId !== event.childThreadId
298
- || childResolution.resolution.thread.parentThreadId !== event.sessionId
299
- || childResolution.resolution.thread.nativeAgent !== event.nativeAgent) {
300
- throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: resolved child does not match the current spawn');
301
- }
302
- verifyStoredBinding(taskContext.taskId, currentBinding, event.nativeAgent);
303
- const spawn = latestCandidates[0]!.state.spawn;
304
- if (!spawn) throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: current spawn record is missing');
305
- const result = store.applyToSpawn({
306
- sessionId: spawn.sessionId, turnId: spawn.turnId, toolUseId: spawn.toolUseId, taskBinding: currentBinding
307
- }, { ...event, parentThreadId: childResolution.resolution.thread.parentThreadId }, latestCandidates[0]!.revision);
308
- if (bridge) {
309
- outputBridgeResult(await activateCodexOrchestrationDelegation(event.childThreadId, {
310
- store, orchestrationOptions: { repoRoot: process.cwd(), taskId: taskContext.taskId },
311
- resolveThread: async () => childResolution
312
- }));
313
- return;
314
- }
315
- output({ status: result.state.status, changed: true, evidence: result.state, diagnostics: childResolution.diagnostics, error: result.state.error });
316
- if (result.state.status === 'invalid') process.exitCode = 1;
317
- }
318
-
319
- async function handleBridgePostTool(
320
- toolName: string,
321
- payload: unknown,
322
- nativeAgent: string,
323
- taskId: string,
324
- store: ReturnType<typeof taskScopedStore>
325
- ): Promise<void> {
326
- const orchestrationOptions = { repoRoot: process.cwd(), taskId };
327
- if (toolName === 'collaborationspawn_agent') {
328
- if (!MANAGED_AGENT.test(nativeAgent)) {
329
- output({ status: 'ignored', changed: false, evidence: null, diagnostics: [], error: null });
330
- return;
331
- }
332
- const requestedModel = payloadText(payload, 'requestedModel');
333
- const requestedReasoningEffort = payloadText(payload, 'requestedReasoningEffort');
334
- const bridged = await activateCodexSpawnDelegation({
335
- sessionId: payloadText(payload, 'sessionId'), turnId: payloadText(payload, 'turnId'),
336
- toolUseId: payloadText(payload, 'toolUseId'), transcriptPath: payloadText(payload, 'transcriptPath'),
337
- nativeAgent, taskName: payloadText(payload, 'taskName'),
338
- ...(requestedModel ? { requestedModel } : {}),
339
- ...(requestedReasoningEffort ? { requestedReasoningEffort } : {})
340
- }, { store, orchestrationOptions });
341
- outputBridgeResult(bridged);
342
- return;
343
- }
344
- if (toolName === 'collaborationwait_agent') {
345
- outputBridgeResult(await sealCodexParentDelegation(payloadText(payload, 'sessionId'), { store, orchestrationOptions }));
346
- return;
347
- }
348
- output({ status: 'ignored', changed: false, evidence: null, diagnostics: [], error: null });
349
- }
350
-
351
- async function sealConsumedHookStop(
352
- event: Extract<CodexLifecycleEvent, { type: 'hook-stop' }>,
353
- store: ReturnType<typeof taskScopedStore>,
354
- taskId: string
355
- ): Promise<void> {
356
- const result = await sealCodexOrchestrationDelegation(event.childThreadId, {
357
- store, orchestrationOptions: { repoRoot: process.cwd(), taskId }
358
- });
359
- outputBridgeResult(result);
360
- }
361
-
362
- function handleMissingHookEvent(phase: string, bridge: boolean, payload: unknown, taskId: string): void {
363
- if (phase === 'post-tool' && bridge) {
364
- const value = payload as Record<string, unknown>;
365
- outputBridgeResult(reconcileCodexOrchestrationDelegation(String(value.childThreadId ?? ''), {
366
- orchestrationOptions: { repoRoot: process.cwd(), taskId }
367
- }));
368
- return;
369
- }
370
- output({ status: 'ignored', changed: false, evidence: null, diagnostics: [], error: null });
371
- }
372
-
373
- async function handlePreflight(parsed: Parsed): Promise<void> {
374
- const format = parsed.values['--format'] ?? 'json';
375
- if (!['text', 'json'].includes(format)) throw new Error("format must be 'text' or 'json'");
376
- const runtimeFields = [parsed.values['--session-id'], parsed.values['--turn-id'], parsed.values['--tool-use-id']];
377
- if (runtimeFields.some(Boolean) && !runtimeFields.every(Boolean)) {
378
- throw new Error('preflight runtime identity requires --session-id, --turn-id, and --tool-use-id together');
379
- }
380
- const runtimeIdentity = runtimeFields.every(Boolean)
381
- ? { sessionId: runtimeFields[0]!, turnId: runtimeFields[1]!, toolUseId: runtimeFields[2]! }
382
- : undefined;
383
- const result = await preflightCodexLifecycleEvidence(process.cwd(), runtimeIdentity);
384
- if (format === 'text') {
385
- process.stdout.write(`Codex lifecycle static preflight: ready\nCLI: ${result.cliVersion}\nRuntime hook liveness: ${result.runtimeLiveness ? 'observed' : 'not-yet-observed'}\n`);
386
- } else output({ status: 'ready', changed: false, evidence: result, diagnostics: result.diagnostics, error: null });
387
- }
388
-
389
- async function codexLifecycle(args: string[] = []): Promise<void> {
390
- if (!ensureInternalHandlerRoute('codex-lifecycle', args)) return;
391
- const parsed = parse(args);
392
- if (!parsed || process.exitCode) return;
393
- try {
394
- if (internalHandlerRoute('codex-lifecycle', 'preflight', parsed.operation)) {
395
- await handlePreflight(parsed);
396
- return;
397
- }
398
-
399
- if (internalHandlerRoute('codex-lifecycle', 'hook-event', parsed.operation)) {
400
- const phase = parsed.values['--event'];
401
- if (!phase || !['pre-tool', 'subagent-start', 'post-tool', 'subagent-stop'].includes(phase)) {
402
- throw new Error('hook-event requires a known --event');
403
- }
404
- if (parsed.values['--bridge'] !== undefined && parsed.values['--bridge'] !== 'true') {
405
- throw new Error("hook-event --bridge must be 'true'");
406
- }
407
- const payload = await readStdin();
408
- const toolName = payloadText(payload, 'toolName');
409
- const hookContext = resolveHookTaskContext(phase, toolName, payload);
410
- const { spawnBinding, nativeAgent, taskContext, store } = hookContext;
411
- if (phase === 'post-tool' && parsed.values['--bridge'] === 'true') {
412
- await handleBridgePostTool(toolName, payload, nativeAgent, taskContext.taskId, store);
413
- return;
414
- }
415
- const event = recordFromPayload(phase, payload, spawnBinding?.binding);
416
- if (!event) {
417
- handleMissingHookEvent(phase, parsed.values['--bridge'] === 'true', payload, taskContext.taskId);
418
- return;
419
- }
420
- const currentBinding = currentHookTaskBinding(taskContext.taskDir, taskContext.taskId, spawnBinding, nativeAgent);
421
- if (event.type === 'hook-stop') {
422
- validateHookStopIdentity(store, event, currentBinding);
423
- }
424
- if (parsed.values['--bridge'] === 'true' && event.type === 'hook-stop'
425
- && store.read(event.childThreadId).consumer) {
426
- await sealConsumedHookStop(event, store, taskContext.taskId);
427
- return;
428
- }
429
- if (event.type === 'hook-child') {
430
- await applyHookChildEvent(event, currentBinding!, taskContext, store, parsed.values['--bridge'] === 'true');
431
- return;
432
- }
433
- if (!currentBinding) throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: current task receipt is missing');
434
- verifyStoredBinding(taskContext.taskId, currentBinding, nativeAgent);
435
- const result = store.apply(event);
436
- if (parsed.values['--bridge'] === 'true' && event.type === 'hook-stop') {
437
- if (!hasSealableOrchestrationDelegation('codex', event.childThreadId, { repoRoot: process.cwd(), taskId: taskContext.taskId })) {
438
- output({ status: 'ignored', changed: false, evidence: null, diagnostics: [], error: null });
439
- return;
440
- }
441
- output({
442
- status: result.state.status,
443
- changed: true,
444
- evidence: result.state,
445
- diagnostics: [],
446
- error: result.state.error
447
- });
448
- return;
449
- }
450
- output({ status: result.state.status, changed: true, evidence: result.state, diagnostics: [], error: result.state.error });
451
- if (result.state.status === 'invalid') process.exitCode = 1;
452
- return;
453
- }
454
-
455
- const childThreadId = parsed.values['--child-id'];
456
- if (!childThreadId) throw new Error(`operation '${parsed.operation}' requires --child-id`);
457
- const taskContext = resolveLifecycleTaskContext();
458
- const store = taskScopedStore(taskContext.taskId);
459
- const existing = store.read(childThreadId);
460
- if (!existing.taskBinding) throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISSING: stored lifecycle identity has no task binding');
461
- verifyStoredBinding(
462
- taskContext.taskId,
463
- existing.taskBinding,
464
- existing.state.startEvidence?.nativeAgent ?? existing.state.spawn?.nativeAgent ?? ''
465
- );
466
- if (internalHandlerRoute('codex-lifecycle', 'resolve-start', parsed.operation)) {
467
- if (store.read(childThreadId).state.spawn?.hookDefinitionHash !== hookDefinitionHash()) {
468
- throw new Error('Codex lifecycle hook definition hash is stale');
469
- }
470
- const resolved = await resolveCodexThread(childThreadId);
471
- verifyStoredBinding(taskContext.taskId, existing.taskBinding, existing.state.startEvidence?.nativeAgent ?? existing.state.spawn?.nativeAgent ?? '');
472
- let latest = store.apply(resolved.resolution.thread);
473
- for (const reroute of resolved.reroutes) latest = store.apply(reroute);
474
- latest = store.apply(resolved.resolution.settings);
475
- output({ status: latest.state.status, changed: true, evidence: latest.state.startEvidence, diagnostics: resolved.diagnostics, error: latest.state.error });
476
- if (latest.state.status !== 'start-ready') process.exitCode = 1;
477
- return;
478
- }
479
- if (internalHandlerRoute('codex-lifecycle', 'resolve-stop', parsed.operation)) {
480
- const stopTurnId = store.read(childThreadId).state.stop?.turnId;
481
- if (!stopTurnId) throw new Error('Codex lifecycle stop hook is not available');
482
- const terminal = await resolveCodexTerminal(childThreadId, stopTurnId);
483
- verifyStoredBinding(taskContext.taskId, existing.taskBinding, existing.state.startEvidence?.nativeAgent ?? existing.state.spawn?.nativeAgent ?? '');
484
- const latest = store.apply(terminal);
485
- if (latest.state.status !== 'stop-ready') {
486
- throw new Error(`Codex lifecycle stop evidence is not ready (status=${latest.state.status})`);
487
- }
488
- output({ status: latest.state.status, changed: true, evidence: latest.state.stopEvidence, diagnostics: [], error: latest.state.error });
489
- return;
490
- }
491
- if (internalHandlerRoute('codex-lifecycle', 'consume', parsed.operation)) {
492
- const consumer = parsed.values['--consumer'];
493
- if (!consumer) throw new Error('consume requires --consumer');
494
- verifyStoredBinding(taskContext.taskId, existing.taskBinding, existing.state.startEvidence?.nativeAgent ?? existing.state.spawn?.nativeAgent ?? '');
495
- const consumed = store.consume(childThreadId, consumer, hookDefinitionHash());
496
- output({ status: 'consumed', changed: true, evidence: {
497
- start: consumed.state.startEvidence,
498
- stop: consumed.state.stopEvidence
499
- }, diagnostics: [], error: null });
500
- }
501
- } catch (error) {
502
- failure('CODEX_LIFECYCLE_FAILED', error instanceof Error ? error.message : String(error));
503
- }
504
- }
505
-
506
- export { codexLifecycle };