@fitlab-ai/agent-infra 0.9.13 → 0.9.15

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 (428) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/cli.ts +26 -9
  4. package/bin/internal-cli.sh +45 -0
  5. package/dist/bin/cli.js +173 -157
  6. package/dist/bin/internal-cli.js +126 -42
  7. package/dist/lib/agent-client.js +5 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
  10. package/dist/lib/defaults.json +103 -103
  11. package/dist/lib/fs/durable-write.js +37 -0
  12. package/dist/lib/fs/file-lock.js +111 -0
  13. package/dist/lib/host-control/audit.js +19 -0
  14. package/dist/lib/host-control/client.js +142 -0
  15. package/dist/lib/host-control/command.js +49 -0
  16. package/dist/lib/host-control/path.js +160 -0
  17. package/dist/lib/host-control/secure-fs.js +140 -0
  18. package/dist/lib/host-control/server.js +159 -0
  19. package/dist/lib/host-control/service.js +112 -0
  20. package/dist/lib/init.js +11 -2
  21. package/dist/lib/internal/agent-client.js +5 -2
  22. package/dist/lib/internal/cli-route-inventory.js +154 -0
  23. package/dist/lib/internal/codex-lifecycle.js +15 -12
  24. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  25. package/dist/lib/internal/demo-promotion.js +322 -0
  26. package/dist/lib/internal/demo-transcript.js +454 -0
  27. package/dist/lib/internal/git-workflow.js +10 -6
  28. package/dist/lib/internal/host-control.js +28 -0
  29. package/dist/lib/internal/manual-validation.js +322 -0
  30. package/dist/lib/internal/platform-checks.js +16 -4
  31. package/dist/lib/internal/platform-comment.js +16 -4
  32. package/dist/lib/internal/platform-context.js +4 -1
  33. package/dist/lib/internal/platform-issue.js +12 -4
  34. package/dist/lib/internal/platform-metadata.js +88 -0
  35. package/dist/lib/internal/platform-pr-review.js +16 -3
  36. package/dist/lib/internal/platform-pr.js +42 -14
  37. package/dist/lib/internal/platform-release-notes.js +6 -3
  38. package/dist/lib/internal/platform-security.js +93 -0
  39. package/dist/lib/internal/pr-review-grade.js +14 -3
  40. package/dist/lib/internal/release-workflow.js +82 -89
  41. package/dist/lib/internal/sandbox-control.js +171 -7
  42. package/dist/lib/internal/task-activity.js +13 -4
  43. package/dist/lib/internal/task-artifact.js +19 -107
  44. package/dist/lib/internal/task-context.js +4 -1
  45. package/dist/lib/internal/task-create.js +48 -14
  46. package/dist/lib/internal/task-delivery.js +4 -1
  47. package/dist/lib/internal/task-event.js +38 -35
  48. package/dist/lib/internal/task-finalization.js +4 -1
  49. package/dist/lib/internal/task-invalidation.js +4 -1
  50. package/dist/lib/internal/task-ledger.js +12 -1
  51. package/dist/lib/internal/task-lifecycle.js +4 -1
  52. package/dist/lib/internal/task-operation-registry.js +519 -0
  53. package/dist/lib/internal/task-orchestration.js +12 -0
  54. package/dist/lib/internal/task-override.js +10 -3
  55. package/dist/lib/internal/task-qualification.js +90 -0
  56. package/dist/lib/internal/task-review.js +10 -52
  57. package/dist/lib/internal/task-short-id.js +11 -1
  58. package/dist/lib/internal/task-snapshot.js +4 -1
  59. package/dist/lib/internal/task-validate.js +37 -12
  60. package/dist/lib/internal/task-verify.js +5 -1
  61. package/dist/lib/internal/task-warning.js +8 -1
  62. package/dist/lib/owned-path.js +33 -0
  63. package/dist/lib/platform/check-status.js +11 -0
  64. package/dist/lib/platform/comment-safety.js +229 -0
  65. package/dist/lib/platform/completion-backfill.js +1 -1
  66. package/dist/lib/platform/github-data.js +241 -0
  67. package/dist/lib/platform/github-provider.js +248 -26
  68. package/dist/lib/platform/issue-comments.js +146 -34
  69. package/dist/lib/platform/issues.js +1 -179
  70. package/dist/lib/platform/pr-change-report.js +6 -12
  71. package/dist/lib/platform/pr-checks.js +12 -65
  72. package/dist/lib/platform/pr-summary.js +83 -10
  73. package/dist/lib/platform/provider-contract.d.ts +67 -1
  74. package/dist/lib/platform/provider-contract.js +6 -2
  75. package/dist/lib/platform/provider-validation.js +76 -3
  76. package/dist/lib/platform/pull-requests.js +117 -275
  77. package/dist/lib/platform/repository-metadata.js +377 -0
  78. package/dist/lib/platform/security-alerts.js +155 -0
  79. package/dist/lib/platform/snapshots.js +2 -0
  80. package/dist/lib/platform/verification-sync.js +154 -162
  81. package/dist/lib/process-data/index.js +7 -0
  82. package/dist/lib/release/workflow.js +1 -1
  83. package/dist/lib/run/index.js +5 -0
  84. package/dist/lib/sandbox/commands/control-status.js +22 -0
  85. package/dist/lib/sandbox/commands/create.js +39 -8
  86. package/dist/lib/sandbox/commands/ls.js +5 -0
  87. package/dist/lib/sandbox/commands/rm.js +3 -807
  88. package/dist/lib/sandbox/commands/show.js +16 -0
  89. package/dist/lib/sandbox/control/audit.js +203 -0
  90. package/dist/lib/sandbox/control/client.js +125 -12
  91. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  92. package/dist/lib/sandbox/control/container-identity.js +28 -31
  93. package/dist/lib/sandbox/control/executor.js +233 -34
  94. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  95. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  96. package/dist/lib/sandbox/control/lifecycle.js +656 -128
  97. package/dist/lib/sandbox/control/native-file-lock.js +85 -0
  98. package/dist/lib/sandbox/control/protocol.js +55 -4
  99. package/dist/lib/sandbox/control/server.js +720 -79
  100. package/dist/lib/sandbox/control/state.js +63 -3
  101. package/dist/lib/sandbox/control/task-view.js +183 -0
  102. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  103. package/dist/lib/sandbox/control/workflow-executor.js +99 -0
  104. package/dist/lib/sandbox/engines/authority.js +289 -0
  105. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  106. package/dist/lib/sandbox/index.js +7 -2
  107. package/dist/lib/sandbox/recovery.js +49 -5
  108. package/dist/lib/sandbox/removal.js +1717 -0
  109. package/dist/lib/sandbox/task-cleanup.js +217 -0
  110. package/dist/lib/sandbox/workspace-view.js +15 -15
  111. package/dist/lib/sandbox/worktree-safety.js +4 -1
  112. package/dist/lib/server/index.js +8 -0
  113. package/dist/lib/task/activity-intent.js +2 -1
  114. package/dist/lib/task/activity-log.js +30 -24
  115. package/dist/lib/task/artifact-command.js +101 -0
  116. package/dist/lib/task/artifact-lifecycle.js +71 -40
  117. package/dist/lib/task/artifact-name.js +36 -0
  118. package/dist/lib/task/artifact-operations.js +474 -0
  119. package/dist/lib/task/artifact-receipts.js +3 -15
  120. package/dist/lib/task/artifact-repair-intent.js +130 -0
  121. package/dist/lib/task/artifact-schema.js +127 -0
  122. package/dist/lib/task/capabilities.js +83 -19
  123. package/dist/lib/task/codex-orchestration.js +71 -25
  124. package/dist/lib/task/commit-identity.js +28 -0
  125. package/dist/lib/task/commit-operation.js +2 -16
  126. package/dist/lib/task/control-authority.js +375 -5
  127. package/dist/lib/task/control-recovery.js +128 -0
  128. package/dist/lib/task/create-service.js +103 -4
  129. package/dist/lib/task/create.js +80 -2
  130. package/dist/lib/task/decision-details.js +2 -46
  131. package/dist/lib/task/events.js +306 -76
  132. package/dist/lib/task/finalization-state.js +9 -0
  133. package/dist/lib/task/human-override.js +3 -6
  134. package/dist/lib/task/implementation-inputs.js +3 -3
  135. package/dist/lib/task/index.js +11 -3
  136. package/dist/lib/task/intermediate-cleanup.js +383 -0
  137. package/dist/lib/task/invalidation.js +18 -65
  138. package/dist/lib/task/ledger-intents.js +7 -22
  139. package/dist/lib/task/ledger.js +1 -3
  140. package/dist/lib/task/lifecycle.js +19 -1
  141. package/dist/lib/task/local-artifact-finalization.js +190 -290
  142. package/dist/lib/task/manual-validation-completion.js +26 -0
  143. package/dist/lib/task/manual-validation-evidence.js +130 -0
  144. package/dist/lib/task/manual-validation-receipt.js +101 -0
  145. package/dist/lib/task/manual-validation-shared.js +40 -0
  146. package/dist/lib/task/manual-validation-transaction.js +243 -0
  147. package/dist/lib/task/markdown.js +47 -0
  148. package/dist/lib/task/orchestration.js +206 -69
  149. package/dist/lib/task/qualification-audit.js +476 -0
  150. package/dist/lib/task/qualification-confirmation.js +109 -0
  151. package/dist/lib/task/qualification-intents.js +148 -0
  152. package/dist/lib/task/review-artifacts.js +23 -40
  153. package/dist/lib/task/review-command.js +25 -0
  154. package/dist/lib/task/review-finalization.js +146 -97
  155. package/dist/lib/task/review-fingerprint.js +2 -2
  156. package/dist/lib/task/sections.js +34 -54
  157. package/dist/lib/task/verification-config.js +11 -0
  158. package/dist/lib/task/verification-engine.js +170 -327
  159. package/dist/lib/task/verification.js +1 -1
  160. package/dist/lib/task/workflow-command.js +17 -0
  161. package/dist/lib/task/workflow-warning-intents.js +0 -16
  162. package/dist/lib/task/workflow-warnings.js +28 -2
  163. package/dist/lib/update.js +2 -0
  164. package/dist/lifecycle-build-manifest.json +3 -3
  165. package/lib/agent-client.ts +9 -0
  166. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  167. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
  168. package/lib/fs/durable-write.ts +29 -0
  169. package/lib/fs/file-lock.ts +113 -0
  170. package/lib/host-control/audit.ts +22 -0
  171. package/lib/host-control/client.ts +172 -0
  172. package/lib/host-control/command.ts +60 -0
  173. package/lib/host-control/path.ts +167 -0
  174. package/lib/host-control/secure-fs.ts +135 -0
  175. package/lib/host-control/server.ts +180 -0
  176. package/lib/host-control/service.ts +133 -0
  177. package/lib/init.ts +15 -2
  178. package/lib/internal/agent-client.ts +4 -2
  179. package/lib/internal/cli-route-inventory.ts +142 -0
  180. package/lib/internal/codex-lifecycle.ts +14 -12
  181. package/lib/internal/codex-sandbox-controller.ts +7 -2
  182. package/lib/internal/demo-promotion.ts +354 -0
  183. package/lib/internal/demo-transcript.ts +419 -0
  184. package/lib/internal/git-workflow.ts +9 -6
  185. package/lib/internal/host-control.ts +28 -0
  186. package/lib/internal/manual-validation.ts +306 -0
  187. package/lib/internal/platform-checks.ts +12 -4
  188. package/lib/internal/platform-comment.ts +12 -4
  189. package/lib/internal/platform-context.ts +3 -1
  190. package/lib/internal/platform-issue.ts +11 -4
  191. package/lib/internal/platform-metadata.ts +70 -0
  192. package/lib/internal/platform-pr-review.ts +14 -3
  193. package/lib/internal/platform-pr.ts +38 -14
  194. package/lib/internal/platform-release-notes.ts +5 -3
  195. package/lib/internal/platform-security.ts +83 -0
  196. package/lib/internal/pr-review-grade.ts +10 -3
  197. package/lib/internal/release-workflow.ts +91 -87
  198. package/lib/internal/sandbox-control.ts +181 -6
  199. package/lib/internal/task-activity.ts +12 -4
  200. package/lib/internal/task-artifact.ts +15 -79
  201. package/lib/internal/task-context.ts +3 -1
  202. package/lib/internal/task-create.ts +76 -15
  203. package/lib/internal/task-delivery.ts +3 -1
  204. package/lib/internal/task-event.ts +21 -10
  205. package/lib/internal/task-finalization.ts +3 -1
  206. package/lib/internal/task-invalidation.ts +3 -1
  207. package/lib/internal/task-ledger.ts +11 -1
  208. package/lib/internal/task-lifecycle.ts +3 -1
  209. package/lib/internal/task-operation-registry.ts +590 -0
  210. package/lib/internal/task-orchestration.ts +12 -0
  211. package/lib/internal/task-override.ts +9 -3
  212. package/lib/internal/task-qualification.ts +61 -0
  213. package/lib/internal/task-review.ts +7 -50
  214. package/lib/internal/task-short-id.ts +10 -1
  215. package/lib/internal/task-snapshot.ts +3 -1
  216. package/lib/internal/task-validate.ts +32 -12
  217. package/lib/internal/task-verify.ts +4 -1
  218. package/lib/internal/task-warning.ts +7 -1
  219. package/lib/owned-path.ts +26 -0
  220. package/lib/platform/check-status.ts +9 -0
  221. package/lib/platform/comment-safety.ts +255 -0
  222. package/lib/platform/completion-backfill.ts +1 -1
  223. package/lib/platform/github-data.ts +322 -0
  224. package/lib/platform/github-provider.ts +244 -27
  225. package/lib/platform/issue-comments.ts +159 -35
  226. package/lib/platform/issues.ts +4 -245
  227. package/lib/platform/pr-change-report.ts +6 -12
  228. package/lib/platform/pr-checks.ts +13 -77
  229. package/lib/platform/pr-summary.ts +88 -11
  230. package/lib/platform/provider-contract.ts +78 -3
  231. package/lib/platform/provider-validation.ts +85 -3
  232. package/lib/platform/pull-requests.ts +129 -348
  233. package/lib/platform/repository-metadata.ts +453 -0
  234. package/lib/platform/security-alerts.ts +191 -0
  235. package/lib/platform/snapshots.ts +53 -0
  236. package/lib/platform/verification-sync.ts +171 -177
  237. package/lib/process-data/index.ts +7 -0
  238. package/lib/release/workflow.ts +3 -3
  239. package/lib/run/index.ts +5 -0
  240. package/lib/sandbox/commands/control-status.ts +26 -0
  241. package/lib/sandbox/commands/create.ts +53 -12
  242. package/lib/sandbox/commands/ls.ts +7 -0
  243. package/lib/sandbox/commands/rm.ts +3 -996
  244. package/lib/sandbox/commands/show.ts +16 -0
  245. package/lib/sandbox/control/audit.ts +253 -0
  246. package/lib/sandbox/control/client.ts +150 -13
  247. package/lib/sandbox/control/completed-reentry.ts +98 -0
  248. package/lib/sandbox/control/container-identity.ts +27 -43
  249. package/lib/sandbox/control/executor.ts +262 -37
  250. package/lib/sandbox/control/finalization-response.ts +29 -0
  251. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  252. package/lib/sandbox/control/lifecycle.ts +672 -18
  253. package/lib/sandbox/control/native-file-lock.ts +108 -0
  254. package/lib/sandbox/control/protocol.ts +80 -8
  255. package/lib/sandbox/control/server.ts +779 -82
  256. package/lib/sandbox/control/state.ts +84 -3
  257. package/lib/sandbox/control/task-view.ts +240 -0
  258. package/lib/sandbox/control/task-workflow.ts +95 -0
  259. package/lib/sandbox/control/workflow-executor.ts +102 -0
  260. package/lib/sandbox/engines/authority.ts +365 -0
  261. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  262. package/lib/sandbox/index.ts +9 -2
  263. package/lib/sandbox/recovery.ts +49 -6
  264. package/lib/sandbox/removal.ts +2144 -0
  265. package/lib/sandbox/task-cleanup.ts +209 -0
  266. package/lib/sandbox/workspace-view.ts +26 -18
  267. package/lib/sandbox/worktree-safety.ts +4 -1
  268. package/lib/server/index.ts +10 -0
  269. package/lib/task/activity-intent.ts +2 -2
  270. package/lib/task/activity-log.ts +27 -19
  271. package/lib/task/artifact-command.ts +104 -0
  272. package/lib/task/artifact-lifecycle.ts +66 -39
  273. package/lib/task/artifact-name.ts +55 -0
  274. package/lib/task/artifact-operations.ts +580 -0
  275. package/lib/task/artifact-receipts.ts +3 -14
  276. package/lib/task/artifact-repair-intent.ts +152 -0
  277. package/lib/task/artifact-schema.ts +163 -0
  278. package/lib/task/capabilities.ts +82 -22
  279. package/lib/task/codex-orchestration.ts +85 -24
  280. package/lib/task/commit-identity.ts +31 -0
  281. package/lib/task/commit-operation.ts +2 -16
  282. package/lib/task/control-authority.ts +513 -6
  283. package/lib/task/control-recovery.ts +174 -0
  284. package/lib/task/create-service.ts +131 -6
  285. package/lib/task/create.ts +83 -1
  286. package/lib/task/decision-details.ts +3 -71
  287. package/lib/task/events.ts +292 -75
  288. package/lib/task/finalization-state.ts +11 -0
  289. package/lib/task/human-override.ts +3 -8
  290. package/lib/task/implementation-inputs.ts +3 -3
  291. package/lib/task/index.ts +16 -3
  292. package/lib/task/intermediate-cleanup.ts +455 -0
  293. package/lib/task/invalidation.ts +18 -62
  294. package/lib/task/ledger-intents.ts +7 -24
  295. package/lib/task/ledger.ts +1 -3
  296. package/lib/task/lifecycle.ts +17 -1
  297. package/lib/task/local-artifact-finalization.ts +223 -388
  298. package/lib/task/manual-validation-completion.ts +40 -0
  299. package/lib/task/manual-validation-evidence.ts +209 -0
  300. package/lib/task/manual-validation-receipt.ts +152 -0
  301. package/lib/task/manual-validation-shared.ts +50 -0
  302. package/lib/task/manual-validation-transaction.ts +304 -0
  303. package/lib/task/markdown.ts +70 -0
  304. package/lib/task/orchestration.ts +191 -68
  305. package/lib/task/qualification-audit.ts +588 -0
  306. package/lib/task/qualification-confirmation.ts +117 -0
  307. package/lib/task/qualification-intents.ts +150 -0
  308. package/lib/task/review-artifacts.ts +21 -41
  309. package/lib/task/review-command.ts +23 -0
  310. package/lib/task/review-finalization.ts +154 -153
  311. package/lib/task/review-fingerprint.ts +2 -2
  312. package/lib/task/sections.ts +33 -52
  313. package/lib/task/verification-config.ts +12 -0
  314. package/lib/task/verification-engine.ts +165 -370
  315. package/lib/task/verification-types.ts +17 -0
  316. package/lib/task/verification.ts +1 -1
  317. package/lib/task/workflow-command.ts +18 -0
  318. package/lib/task/workflow-warning-intents.ts +0 -13
  319. package/lib/task/workflow-warnings.ts +21 -2
  320. package/lib/update.ts +6 -0
  321. package/package.json +7 -2
  322. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  323. package/templates/.agents/rules/README.en.md +2 -0
  324. package/templates/.agents/rules/README.zh-CN.md +2 -0
  325. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  326. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  327. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  328. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  329. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  330. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  331. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  332. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  333. package/templates/.agents/rules/security-alerts.en.md +8 -8
  334. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  335. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  336. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  337. package/templates/.agents/scripts/package.json +3 -0
  338. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  339. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  340. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  341. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  342. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  343. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  344. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  345. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  346. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  347. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  348. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  349. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  350. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  351. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  352. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  353. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  354. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  355. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  356. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  357. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  358. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +37 -21
  359. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
  360. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  361. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  362. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
  363. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
  364. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  365. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  366. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
  367. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
  368. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  369. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  370. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  371. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  372. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  373. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  374. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  375. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  376. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  377. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  378. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  379. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  380. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  381. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  382. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  383. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  384. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  385. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  386. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  387. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  388. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  389. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  390. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  391. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  392. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  393. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  394. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  395. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  396. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  397. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  398. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  399. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  400. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  401. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  402. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  403. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  404. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  405. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  406. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +25 -4
  407. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
  408. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  409. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  410. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
  411. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
  412. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  413. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  414. package/templates/.agents/skills/test/SKILL.en.md +29 -7
  415. package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
  416. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  417. package/templates/.agents/templates/task.en.md +6 -0
  418. package/templates/.agents/templates/task.zh-CN.md +6 -0
  419. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  420. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  421. package/dist/lib/platform/adapters.js +0 -56
  422. package/lib/platform/adapters.ts +0 -197
  423. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  424. package/templates/.agents/scripts/security-alerts.sh +0 -31
  425. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  426. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  427. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  428. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -1,112 +1,78 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import crypto from 'node:crypto';
4
3
  import { spawnSync } from 'node:child_process';
5
4
  import semver from 'semver';
6
5
  import { commitExplicitPaths, inspectGitWorkflow, pushGitRefs } from '../git/workflow.js';
7
6
  import { inspectPlatformRelease, reconcileReleaseMilestones } from '../platform/releases.js';
8
7
  import { inspectHomebrewChannel, inspectNpmChannel } from '../release/channels.js';
9
8
  import { releaseSnapshot } from '../release/workflow.js';
10
- function command(cwd, executable, args) {
11
- return spawnSync(executable, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
9
+ import { collectDemoTranscript } from './demo-transcript.js';
10
+ import { createDemoPromotion, promoteDemoAssets, recoverDemoPromotion } from './demo-promotion.js';
11
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
12
+ function command(cwd, executable, args, options = {}) {
13
+ return spawnSync(executable, args, {
14
+ cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, ...options.env }
15
+ });
12
16
  }
13
- // The tape is the canonical init interaction contract. Do not hash all of
14
- // lib/init.ts: non-visual config serialization changes must not re-record it.
15
- const DEMO_INPUT_PATHS = [
16
- 'assets/demo-init.tape',
17
- 'scripts/demo-regen.sh',
18
- 'scripts/normalize-gif-duration.py',
19
- 'bin/cli.ts',
20
- 'lib/log.ts',
21
- 'lib/prompt.ts',
22
- 'lib/paths.ts',
23
- 'lib/render.ts',
24
- 'lib/sandbox/engines/'
25
- ];
26
- const DEMO_DIGEST_PATH = 'assets/demo-init.inputs.sha256';
17
+ const DEMO_DIGEST_PATH = 'assets/demo-init.transcript.sha256';
27
18
  const DEMO_OUTPUT_PATH = 'assets/demo-init.gif';
28
19
  const DEMO_MAX_BYTES = 4 * 1024 * 1024;
29
- function demoInputFiles(cwd) {
30
- const files = new Set();
31
- for (const input of DEMO_INPUT_PATHS) {
32
- if (input.endsWith('/')) {
33
- const listed = command(cwd, 'git', ['ls-files', '--', input]);
34
- if (listed.status !== 0)
35
- throw new Error(String(listed.stderr || `Unable to list ${input}`));
36
- const directoryFiles = String(listed.stdout).split('\n').filter(Boolean);
37
- if (!directoryFiles.length)
38
- throw new Error(`Canonical demo input directory is empty: ${input}`);
39
- for (const file of directoryFiles)
40
- files.add(file.replaceAll('\\', '/'));
41
- }
42
- else {
43
- files.add(input);
44
- }
45
- }
46
- const sorted = [...files].sort((left, right) => Buffer.from(left).compare(Buffer.from(right)));
47
- if (!sorted.length)
48
- throw new Error('Canonical demo input set is empty');
49
- for (const file of sorted) {
50
- const absolute = path.join(cwd, file);
51
- if (!fs.statSync(absolute).isFile())
52
- throw new Error(`Canonical demo input is not a file: ${file}`);
53
- }
54
- return sorted;
55
- }
56
- function computeDemoInputDigest(cwd) {
57
- const hash = crypto.createHash('sha256');
58
- for (const file of demoInputFiles(cwd)) {
59
- const bytes = fs.readFileSync(path.join(cwd, file));
60
- hash.update(file);
61
- hash.update('\0');
62
- hash.update(String(bytes.byteLength));
63
- hash.update('\0');
64
- hash.update(bytes);
65
- hash.update('\0');
66
- }
67
- return hash.digest('hex');
68
- }
69
20
  function validGif(filePath) {
70
21
  if (!fs.existsSync(filePath))
71
22
  return false;
72
23
  const header = fs.readFileSync(filePath).subarray(0, 6).toString('ascii');
73
24
  return header === 'GIF87a' || header === 'GIF89a';
74
25
  }
75
- function writeDigestAtomically(cwd, digest) {
76
- const target = path.join(cwd, DEMO_DIGEST_PATH);
77
- const temporary = `${target}.tmp-${process.pid}`;
78
- fs.writeFileSync(temporary, `${digest}\n`);
79
- fs.renameSync(temporary, target);
80
- }
81
- function runOptionalDemo(cwd, run = command) {
82
- let digest;
83
- try {
84
- digest = computeDemoInputDigest(cwd);
26
+ async function runOptionalDemo(cwd, run = command, collect = collectDemoTranscript) {
27
+ const recovery = recoverDemoPromotion(cwd);
28
+ if (recovery?.status === 'failed') {
29
+ return { status: 'failed', reasonCode: recovery.code === 'DEMO_PROMOTION_CLEANUP_FAILED' ? recovery.code : 'DEMO_PROMOTION_RECOVERY_REQUIRED', message: recovery.message, outputPath: null };
85
30
  }
86
- catch (error) {
87
- return { status: 'failed', reasonCode: 'DEMO_DIGEST_FAILED', message: String(error), outputPath: null };
31
+ const transcript = await collect(cwd);
32
+ if (transcript.status === 'failed') {
33
+ return { status: 'failed', reasonCode: transcript.reasonCode, message: transcript.message, outputPath: null };
88
34
  }
89
35
  const digestPath = path.join(cwd, DEMO_DIGEST_PATH);
90
36
  const priorDigest = fs.existsSync(digestPath) ? fs.readFileSync(digestPath, 'utf8').trim() : '';
91
- if (/^[0-9a-f]{64}$/.test(priorDigest) && priorDigest === digest) {
92
- return { status: 'skipped', reasonCode: 'DEMO_INPUTS_UNCHANGED', message: null, outputPath: null };
37
+ if (/^[0-9a-f]{64}$/.test(priorDigest) && priorDigest === transcript.sha256) {
38
+ return { status: 'skipped', reasonCode: 'DEMO_TRANSCRIPT_UNCHANGED', message: null, outputPath: null };
93
39
  }
40
+ const promotion = createDemoPromotion(cwd, transcript.transcript);
41
+ const discardPromotion = () => fs.rmSync(promotion.directory, { recursive: true, force: true });
94
42
  const lfs = run(cwd, 'git', ['lfs', 'version']);
95
43
  if (lfs.status !== 0) {
44
+ discardPromotion();
96
45
  return { status: 'failed', reasonCode: 'GIT_LFS_MISSING', message: String(lfs.stderr || lfs.stdout), outputPath: null };
97
46
  }
98
47
  const lfsAttribute = run(cwd, 'git', ['check-attr', 'filter', '--', DEMO_OUTPUT_PATH]);
99
48
  if (lfsAttribute.status !== 0 || !String(lfsAttribute.stdout).trim().endsWith(': lfs')) {
49
+ discardPromotion();
100
50
  return { status: 'failed', reasonCode: 'GIT_LFS_MISSING', message: `${DEMO_OUTPUT_PATH} is not tracked by Git LFS`, outputPath: null };
101
51
  }
102
52
  const vhs = run(cwd, 'vhs', ['--version']);
103
- if (vhs.status !== 0)
104
- return { status: 'skipped', reasonCode: 'VHS_MISSING', message: null, outputPath: null };
53
+ if (vhs.status !== 0) {
54
+ discardPromotion();
55
+ return {
56
+ status: 'failed',
57
+ reasonCode: 'VHS_MISSING',
58
+ message: String(vhs.stderr || vhs.stdout) || 'VHS is required to record the changed demo transcript',
59
+ outputPath: null
60
+ };
61
+ }
105
62
  const ffmpeg = run(cwd, 'ffmpeg', ['-version']);
106
- if (ffmpeg.status !== 0)
107
- return { status: 'skipped', reasonCode: 'FFMPEG_MISSING', message: null, outputPath: null };
108
- const demo = run(cwd, 'npm', ['run', 'demo:regen']);
63
+ if (ffmpeg.status !== 0) {
64
+ discardPromotion();
65
+ return {
66
+ status: 'failed',
67
+ reasonCode: 'FFMPEG_MISSING',
68
+ message: String(ffmpeg.stderr || ffmpeg.stdout) || 'ffmpeg is required to record the changed demo transcript',
69
+ outputPath: null
70
+ };
71
+ }
72
+ const stagedOutputPath = path.relative(cwd, promotion.staging.gif).replaceAll(path.sep, '/');
73
+ const demo = run(cwd, 'npm', ['run', 'demo:regen'], { env: { DEMO_OUTPUT_PATH: stagedOutputPath } });
109
74
  if (demo.status !== 0) {
75
+ discardPromotion();
110
76
  return {
111
77
  status: 'failed',
112
78
  reasonCode: 'DEMO_COMMAND_FAILED',
@@ -115,7 +81,8 @@ function runOptionalDemo(cwd, run = command) {
115
81
  };
116
82
  }
117
83
  const outputPath = DEMO_OUTPUT_PATH;
118
- if (!fs.existsSync(path.join(cwd, outputPath))) {
84
+ if (!fs.existsSync(promotion.staging.gif)) {
85
+ discardPromotion();
119
86
  return {
120
87
  status: 'failed',
121
88
  reasonCode: 'DEMO_OUTPUT_MISSING',
@@ -123,18 +90,24 @@ function runOptionalDemo(cwd, run = command) {
123
90
  outputPath: null
124
91
  };
125
92
  }
126
- const absoluteOutput = path.join(cwd, outputPath);
93
+ const absoluteOutput = promotion.staging.gif;
127
94
  if (!validGif(absoluteOutput)) {
95
+ discardPromotion();
128
96
  return { status: 'failed', reasonCode: 'DEMO_OUTPUT_INVALID', message: `${outputPath} is not a GIF`, outputPath: null };
129
97
  }
130
98
  if (fs.statSync(absoluteOutput).size > DEMO_MAX_BYTES) {
99
+ discardPromotion();
131
100
  return { status: 'failed', reasonCode: 'DEMO_OUTPUT_TOO_LARGE', message: `${outputPath} exceeds 4 MiB`, outputPath: null };
132
101
  }
133
- const pointer = run(cwd, 'git', ['lfs', 'pointer', `--file=${outputPath}`]);
102
+ const pointer = run(cwd, 'git', ['lfs', 'pointer', `--file=${stagedOutputPath}`]);
134
103
  if (pointer.status !== 0 || !String(pointer.stdout).includes(`size ${fs.statSync(absoluteOutput).size}`)) {
104
+ discardPromotion();
135
105
  return { status: 'failed', reasonCode: 'DEMO_OUTPUT_INVALID', message: 'Git LFS could not produce a matching pointer', outputPath: null };
136
106
  }
137
- writeDigestAtomically(cwd, digest);
107
+ const promoted = promoteDemoAssets(cwd, promotion.staging, `${process.pid}-${Date.now()}`);
108
+ if (promoted.status === 'failed') {
109
+ return { status: 'failed', reasonCode: promoted.code ?? 'DEMO_PROMOTION_FAILED', message: promoted.message, outputPath: null };
110
+ }
138
111
  return { status: 'recorded', reasonCode: null, message: null, outputPath };
139
112
  }
140
113
  function git(cwd, args, run = command, trim = true) {
@@ -188,7 +161,7 @@ function inspectPostReleaseFacts(cwd, commit, run = command) {
188
161
  remoteHead,
189
162
  newVersion,
190
163
  changedPaths,
191
- demoInputSha256: digest && /^[0-9a-f]{64}$/.test(digest) ? digest : null,
164
+ demoTranscriptSha256: digest && /^[0-9a-f]{64}$/.test(digest) ? digest : null,
192
165
  worktree: snapshot?.worktree ?? [],
193
166
  staged: snapshot?.staged ?? []
194
167
  };
@@ -295,13 +268,21 @@ async function releaseWorkflow(args = []) {
295
268
  const version = String(rawVersion || '').replace(/^v/, '');
296
269
  const cwdIndex = rest.indexOf('--cwd');
297
270
  const cwd = path.resolve(cwdIndex >= 0 && rest[cwdIndex + 1] ? rest[cwdIndex + 1] : process.cwd());
298
- if (!['inspect', 'prepare', 'publish', 'post-prepare', 'post-publish'].includes(action || '') || !semver.valid(version)) {
271
+ if (![
272
+ internalHandlerRoute('release-workflow', 'inspect', action || ''),
273
+ internalHandlerRoute('release-workflow', 'prepare', action || ''),
274
+ internalHandlerRoute('release-workflow', 'publish', action || ''),
275
+ internalHandlerRoute('release-workflow', 'post-prepare', action || ''),
276
+ internalHandlerRoute('release-workflow', 'post-publish', action || '')
277
+ ].some(Boolean) || !semver.valid(version)) {
299
278
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'RELEASE_INPUT_INVALID', message: 'Usage: release-workflow inspect|prepare|publish|post-prepare|post-publish <version>' } })}\n`);
300
279
  process.exitCode = 1;
301
280
  return;
302
281
  }
282
+ if (!ensureInternalHandlerRoute('release-workflow', args))
283
+ return;
303
284
  const before = releaseSnapshot(version, await inspectFacts(cwd, version));
304
- if (action === 'inspect') {
285
+ if (internalHandlerRoute('release-workflow', 'inspect', action || '')) {
305
286
  process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`);
306
287
  return;
307
288
  }
@@ -310,10 +291,11 @@ async function releaseWorkflow(args = []) {
310
291
  process.exitCode = 1;
311
292
  return;
312
293
  }
313
- if (action === 'prepare') {
294
+ if (internalHandlerRoute('release-workflow', 'prepare', action || '')) {
314
295
  if (before.phase !== 'unprepared') {
315
296
  const milestones = await reconcileReleaseMilestones(version, { cwd });
316
- process.stdout.write(`${JSON.stringify({ ...milestones, snapshot: before })}\n`);
297
+ const snapshot = releaseSnapshot(version, await inspectFacts(cwd, version));
298
+ process.stdout.write(`${JSON.stringify({ ...milestones, snapshot })}\n`);
317
299
  process.exitCode = milestones.status === 'failed' ? 1 : milestones.status === 'blocked' ? 2 : 0;
318
300
  return;
319
301
  }
@@ -363,7 +345,7 @@ async function releaseWorkflow(args = []) {
363
345
  process.exitCode = failed ? 1 : blocked ? 2 : 0;
364
346
  return;
365
347
  }
366
- if (action === 'publish') {
348
+ if (internalHandlerRoute('release-workflow', 'publish', action || '')) {
367
349
  if (!before.facts.localTag || !['prepared', 'partially-published'].includes(before.phase)) {
368
350
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_PHASE_INVALID', message: `Cannot publish from ${before.phase}` } })}\n`);
369
351
  process.exitCode = 1;
@@ -376,7 +358,7 @@ async function releaseWorkflow(args = []) {
376
358
  process.exitCode = result.status === 'failed' ? 1 : result.status === 'degraded' ? 2 : 0;
377
359
  return;
378
360
  }
379
- if (action === 'post-publish') {
361
+ if (internalHandlerRoute('release-workflow', 'post-publish', action || '')) {
380
362
  const expectedValues = optionValues(rest, '--expected-sha256');
381
363
  if (expectedValues.length !== 1 || !/^sha256:[0-9a-f]{64}$/.test(expectedValues[0])) {
382
364
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_INPUT_INVALID', message: 'post-publish requires one --expected-sha256 sha256:<64 hex>' } })}\n`);
@@ -415,6 +397,11 @@ async function releaseWorkflow(args = []) {
415
397
  process.exitCode = blocked ? 2 : 1;
416
398
  return;
417
399
  }
400
+ if (!internalHandlerRoute('release-workflow', 'post-prepare', action || '')) {
401
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_INPUT_INVALID', message: 'release-workflow action is not registered' } })}\n`);
402
+ process.exitCode = 1;
403
+ return;
404
+ }
418
405
  if (before.phase === 'complete') {
419
406
  process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`);
420
407
  return;
@@ -432,6 +419,12 @@ async function releaseWorkflow(args = []) {
432
419
  process.exitCode = before.facts.smoke === 'failed' ? 1 : 2;
433
420
  return;
434
421
  }
422
+ const recovery = recoverDemoPromotion(cwd);
423
+ if (recovery?.status === 'failed') {
424
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: true, snapshot: before, error: { code: recovery.code, message: recovery.message } })}\n`);
425
+ process.exitCode = 1;
426
+ return;
427
+ }
435
428
  const worktreeError = inspectPostWorktree(cwd);
436
429
  if (worktreeError) {
437
430
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: worktreeError })}\n`);
@@ -444,7 +437,7 @@ async function releaseWorkflow(args = []) {
444
437
  process.exitCode = 1;
445
438
  return;
446
439
  }
447
- const demo = runOptionalDemo(cwd);
440
+ const demo = await runOptionalDemo(cwd);
448
441
  if (demo.status === 'failed') {
449
442
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: true, snapshot: before, demo, error: { code: 'RELEASE_POST_DEMO_FAILED', message: demo.message } })}\n`);
450
443
  process.exitCode = 1;
@@ -473,5 +466,5 @@ async function releaseWorkflow(args = []) {
473
466
  }
474
467
  process.stdout.write(`${JSON.stringify({ status: 'applied', changed: true, demo, snapshot, error: null })}\n`);
475
468
  }
476
- export { changedPaths, computeDemoInputDigest, inspectFacts, inspectLocalReleaseFacts, inspectPostReleaseFacts, inspectPostWorktree, releaseSmokeStatus, releaseWorkflow, runOptionalDemo };
469
+ export { changedPaths, inspectFacts, inspectLocalReleaseFacts, inspectPostReleaseFacts, inspectPostWorktree, releaseSmokeStatus, releaseWorkflow, runOptionalDemo };
477
470
  //# sourceMappingURL=release-workflow.js.map
@@ -1,8 +1,106 @@
1
- import { recoverSandboxControl, requestSandboxControl, requestSandboxTaskFinalization, requestSandboxTaskControl, SandboxControlClientError } from '../sandbox/control/client.js';
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { recoverSandboxControl, requestSandboxControl, requestSandboxTaskFinalization, requestSandboxTaskControl, requestSandboxTaskWorkflow, resolveVisibleActiveShortId, SandboxControlClientError } from '../sandbox/control/client.js';
2
5
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
3
6
  import { serveSandboxControl } from '../sandbox/control/server.js';
4
7
  import { runSandboxControlExecutor } from '../sandbox/control/executor.js';
5
8
  import { controllerProofFromContext, verifyCodexSandboxControllerContextWithWarnings } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.js';
9
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
10
+ import { parseTaskCreateResult, taskCreateExitCode } from '../task/create-service.js';
11
+ import { createTaskWorkflowRequest } from '../sandbox/control/task-workflow.js';
12
+ import { computeLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.js';
13
+ import { routeOrchestration } from '../task/orchestration.js';
14
+ import { parseArtifactName } from '../task/artifact-name.js';
15
+ function valueAfter(args, flag) {
16
+ for (let index = 0; index < args.length; index += 1) {
17
+ if (args[index] === flag)
18
+ return args[index + 1];
19
+ if (args[index]?.startsWith(`${flag}=`))
20
+ return args[index].slice(flag.length + 1);
21
+ }
22
+ return undefined;
23
+ }
24
+ function withoutValue(args, flag) {
25
+ const result = [];
26
+ for (let index = 0; index < args.length; index += 1) {
27
+ if (args[index] === flag) {
28
+ index += 1;
29
+ continue;
30
+ }
31
+ if (args[index]?.startsWith(`${flag}=`))
32
+ continue;
33
+ result.push(args[index]);
34
+ }
35
+ return result;
36
+ }
37
+ function lifecycleIds(authorityRef, taskId) {
38
+ const digest = (label) => createHash('sha256')
39
+ .update(`${label}\0${taskId}\0${authorityRef}`, 'utf8')
40
+ .digest('hex');
41
+ return { operationId: digest('operation'), lifecycleRequestId: digest('lifecycle-request') };
42
+ }
43
+ function lifecycleAuthorityIdentity(authorityRef, taskId, requestId, phase, family, artifact, round) {
44
+ const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
45
+ if (!authorityRef || !contextPath)
46
+ return undefined;
47
+ const routed = verifyCodexSandboxControllerContextWithWarnings(contextPath, { repoRoot: process.cwd() });
48
+ const buildIdentity = computeLifecycleBuildIdentity(process.cwd());
49
+ const hookDefinitionHash = createHash('sha256')
50
+ .update(readFileSync(path.join(process.cwd(), '.codex', 'hooks.json')))
51
+ .digest('hex');
52
+ const ids = lifecycleIds(authorityRef, taskId);
53
+ return {
54
+ version: 1,
55
+ requestId,
56
+ operationId: ids.operationId,
57
+ phase,
58
+ taskId,
59
+ family,
60
+ artifact,
61
+ round,
62
+ lifecycleRequestId: ids.lifecycleRequestId,
63
+ authorityRef,
64
+ expectedControlGeneration: routed.context.controlGeneration,
65
+ expectedControllerInstanceDigest: routed.context.controllerInstanceDigest,
66
+ expectedBuildIdentityDigest: createHash('sha256').update(JSON.stringify(buildIdentity)).digest('hex'),
67
+ expectedHookDefinitionHash: hookDefinitionHash
68
+ };
69
+ }
70
+ function lifecycleAuthoritySelector(args) {
71
+ if (!isCanonicalCodexPrepare(args))
72
+ return undefined;
73
+ const authorityRef = valueAfter(args, '--capability-ref');
74
+ const taskId = args[0];
75
+ if (!authorityRef || !taskId)
76
+ return undefined;
77
+ const routed = routeOrchestration(taskId);
78
+ if (!routed.next || !['analysis', 'plan', 'code'].includes(routed.next.stage))
79
+ return undefined;
80
+ return lifecycleAuthorityIdentity(authorityRef, taskId, randomUUID(), 'orchestration.prepare', routed.next.stage === 'analysis' ? 'analysis' : routed.next.stage === 'plan' ? 'plan' : 'code', routed.next.artifact, routed.next.round);
81
+ }
82
+ function lifecycleWorkflowAuthoritySelector(originalArgs, workflow) {
83
+ const authorityRef = valueAfter(originalArgs, '--capability-ref');
84
+ if (!authorityRef)
85
+ return undefined;
86
+ if (workflow.operation === 'artifact-finalize-local') {
87
+ const family = valueAfter(workflow.args, '--family');
88
+ const artifact = valueAfter(workflow.args, '--artifact');
89
+ const parsed = artifact ? parseArtifactName(artifact) : null;
90
+ if ((family !== 'analysis' && family !== 'plan' && family !== 'code')
91
+ || !parsed || parsed.family !== family)
92
+ return undefined;
93
+ return lifecycleAuthorityIdentity(authorityRef, workflow.taskId, workflow.id, 'artifact.finalize-local', family, artifact, parsed.round);
94
+ }
95
+ if (workflow.operation !== 'event')
96
+ return undefined;
97
+ const completed = /^(analysis|plan|code)\.completed$/u.exec(workflow.args[1] ?? '');
98
+ const artifact = valueAfter(workflow.args, '--artifact');
99
+ const parsed = artifact ? parseArtifactName(artifact) : null;
100
+ if (!completed || !parsed || parsed.family !== completed[1])
101
+ return undefined;
102
+ return lifecycleAuthorityIdentity(authorityRef, workflow.taskId, workflow.id, 'task-event.completed', completed[1], artifact, parsed.round);
103
+ }
6
104
  function isCanonicalCodexPrepare(args) {
7
105
  if (args[1] !== 'prepare')
8
106
  return false;
@@ -28,6 +126,19 @@ function writeClientError(error) {
28
126
  if (error.requestId)
29
127
  process.stderr.write(`SANDBOX_CONTROL_REQUEST_ID: ${error.requestId}\n`);
30
128
  }
129
+ function recoveredExitCode(response) {
130
+ if (response.phase !== 'completed')
131
+ return response.exitCode ?? 1;
132
+ try {
133
+ const result = parseTaskCreateResult(JSON.parse(response.stdout));
134
+ if (result.control?.requestId === response.id)
135
+ return taskCreateExitCode(result);
136
+ }
137
+ catch {
138
+ // Other control families use their own result envelopes.
139
+ }
140
+ return response.exitCode ?? 1;
141
+ }
31
142
  function sandboxFinalizationClient(args) {
32
143
  if (args.length !== 4 || !args[0] || args[1] !== 'complete' || args[2] !== '--agent' || !args[3]) {
33
144
  const error = { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'task ref, complete intent, and --agent are required', retryable: false };
@@ -71,8 +182,10 @@ function sandboxFinalizationClient(args) {
71
182
  process.exitCode = response.exitCode ?? 1;
72
183
  }
73
184
  async function sandboxControl(args) {
185
+ if (!ensureInternalHandlerRoute('sandbox-control', args))
186
+ return;
74
187
  const [operation, ...rest] = args;
75
- if (operation === 'serve') {
188
+ if (internalHandlerRoute('sandbox-control', 'serve', operation ?? '')) {
76
189
  const manifestIndex = rest.indexOf('--manifest');
77
190
  const manifest = manifestIndex >= 0 ? rest[manifestIndex + 1] : undefined;
78
191
  if (!manifest)
@@ -90,7 +203,7 @@ async function sandboxControl(args) {
90
203
  }
91
204
  return;
92
205
  }
93
- if (operation === 'execute') {
206
+ if (internalHandlerRoute('sandbox-control', 'execute', operation ?? '')) {
94
207
  const requestIndex = rest.indexOf('--request');
95
208
  const nonceIndex = rest.indexOf('--nonce');
96
209
  const request = requestIndex >= 0 ? rest[requestIndex + 1] : undefined;
@@ -100,7 +213,7 @@ async function sandboxControl(args) {
100
213
  await runSandboxControlExecutor(request, nonce);
101
214
  return;
102
215
  }
103
- if (operation === 'recover') {
216
+ if (internalHandlerRoute('sandbox-control', 'recover', operation ?? '')) {
104
217
  if (rest.length !== 1 || !rest[0])
105
218
  throw new Error('sandbox-control recover requires <request-id>');
106
219
  let response;
@@ -118,15 +231,60 @@ async function sandboxControl(args) {
118
231
  process.stderr.write(response.stderr);
119
232
  process.exitCode = response.phase === 'rejected'
120
233
  ? response.error?.retryable ? 75 : 1
121
- : response.exitCode ?? 1;
234
+ : recoveredExitCode(response);
122
235
  return;
123
236
  }
124
- if (operation === 'client') {
237
+ if (internalHandlerRoute('sandbox-control', 'client', operation ?? '')) {
125
238
  const [family = '', ...commandArgs] = rest;
126
239
  if (family === 'task-finalization') {
127
240
  sandboxFinalizationClient(commandArgs);
128
241
  return;
129
242
  }
243
+ if (family === 'task-workflow') {
244
+ const command = commandArgs[0];
245
+ const taskId = process.env.AGENT_INFRA_TASK_ID;
246
+ const generation = process.env.AGENT_INFRA_CONTROL_GENERATION;
247
+ if (!command || !taskId || !generation) {
248
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SANDBOX_CONTROL_REQUEST_INVALID', message: 'task-workflow requires a bound task and generation' } })}\n`);
249
+ process.exitCode = 1;
250
+ return;
251
+ }
252
+ let workflow;
253
+ try {
254
+ const args = withoutValue(commandArgs.slice(1), '--capability-ref');
255
+ if (/^\d+$/.test(args[0] ?? '')) {
256
+ const resolved = resolveVisibleActiveShortId(args[0]);
257
+ if (resolved !== taskId)
258
+ throw new Error('SANDBOX_TASK_REF_MISMATCH');
259
+ args[0] = resolved;
260
+ }
261
+ workflow = createTaskWorkflowRequest(command, args, taskId, generation);
262
+ }
263
+ catch (error) {
264
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SANDBOX_CONTROL_REQUEST_INVALID', message: error instanceof Error ? error.message : String(error) } })}\n`);
265
+ process.exitCode = 1;
266
+ return;
267
+ }
268
+ let response;
269
+ try {
270
+ const authority = lifecycleWorkflowAuthoritySelector(commandArgs, workflow);
271
+ response = requestSandboxTaskWorkflow({
272
+ workflow,
273
+ ...(authority ? { authority } : {})
274
+ });
275
+ }
276
+ catch (error) {
277
+ if (!(error instanceof SandboxControlClientError))
278
+ throw error;
279
+ writeClientError(error);
280
+ process.exitCode = error.detail.retryable ? 75 : 1;
281
+ return;
282
+ }
283
+ process.stdout.write(response.stdout);
284
+ process.stderr.write(response.stderr);
285
+ process.exitCode = response.phase === 'rejected' ? response.error?.retryable ? 75 : 1 : response.exitCode ?? 1;
286
+ return;
287
+ }
130
288
  let response;
131
289
  try {
132
290
  if (family === 'task-orchestration' && isCanonicalCodexPrepare(commandArgs)) {
@@ -134,7 +292,13 @@ async function sandboxControl(args) {
134
292
  const proof = contextPath
135
293
  ? controllerProofFromContext(verifyCodexSandboxControllerContextWithWarnings(contextPath).context)
136
294
  : null;
137
- response = requestSandboxTaskControl({ family, args: commandArgs, controllerProof: proof });
295
+ const authority = lifecycleAuthoritySelector(commandArgs);
296
+ response = requestSandboxTaskControl({
297
+ family,
298
+ args: commandArgs,
299
+ controllerProof: authority ? null : proof,
300
+ ...(authority ? { authority } : {})
301
+ });
138
302
  }
139
303
  else {
140
304
  response = requestSandboxControl({ family, args: commandArgs });
@@ -2,6 +2,7 @@ import { applyPrReviewActivityIntent, inspectPrReviewActivity } from '../task/ac
2
2
  import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.js';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.js';
4
4
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
5
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
5
6
  const USAGE = `Usage: agent-infra-internal task-activity <task-ref> pr-review-inspect
6
7
  agent-infra-internal task-activity <task-ref> pr-review-start --agent <agent> --artifact <canonical.md> --head <40hex> [--dry-run]
7
8
  agent-infra-internal task-activity <task-ref> pr-review-complete --agent <agent> --artifact <canonical.md> --head <40hex> --verdict <approved|changes-requested|commented> --blockers <N> --major <N> --minor <N> [--dry-run]
@@ -33,12 +34,20 @@ function usageFailure(message) {
33
34
  process.exitCode = 1;
34
35
  }
35
36
  async function taskActivity(args = []) {
37
+ if (!ensureInternalHandlerRoute('task-activity', args))
38
+ return;
36
39
  if (args[0] === '--help' || args[0] === '-h') {
37
40
  process.stdout.write(USAGE);
38
41
  return;
39
42
  }
40
43
  const [taskRef, kind] = args;
41
- if (!taskRef || taskRef.startsWith('--') || !kind || !OPERATIONS.has(kind)) {
44
+ if (!taskRef || taskRef.startsWith('--') || !kind || !OPERATIONS.has(kind)
45
+ || ![
46
+ internalHandlerRoute('task-activity', 'pr-review-inspect', kind),
47
+ internalHandlerRoute('task-activity', 'pr-review-start', kind),
48
+ internalHandlerRoute('task-activity', 'pr-review-complete', kind),
49
+ internalHandlerRoute('task-activity', 'pr-review-terminate', kind)
50
+ ].some(Boolean)) {
42
51
  usageFailure('task ref and a supported PR review intent are required');
43
52
  return;
44
53
  }
@@ -78,7 +87,7 @@ async function taskActivity(args = []) {
78
87
  usageFailure(`${kind} does not accept '${unexpected}'`);
79
88
  return;
80
89
  }
81
- if (kind === 'pr-review-inspect') {
90
+ if (internalHandlerRoute('task-activity', 'pr-review-inspect', kind)) {
82
91
  const result = inspectPrReviewActivity(values);
83
92
  process.stdout.write(`${JSON.stringify(result)}\n`);
84
93
  if (result.status === 'failed')
@@ -91,9 +100,9 @@ async function taskActivity(args = []) {
91
100
  return;
92
101
  }
93
102
  }
94
- const operationRequired = kind === 'pr-review-complete'
103
+ const operationRequired = internalHandlerRoute('task-activity', 'pr-review-complete', kind)
95
104
  ? ['verdict', 'blockers', 'major', 'minor']
96
- : kind === 'pr-review-terminate' ? ['outcome', 'reason'] : [];
105
+ : internalHandlerRoute('task-activity', 'pr-review-terminate', kind) ? ['outcome', 'reason'] : [];
97
106
  for (const key of operationRequired) {
98
107
  if (values[key] === undefined) {
99
108
  usageFailure(`${kind} requires '${key}'`);