@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
@@ -0,0 +1,306 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import { locateActivityLog, pairEntries } from '../task/activity-log.ts';
5
+ import { resolveTaskRef } from '../task/resolve-ref.ts';
6
+ import { applyTaskEvent } from '../task/events.ts';
7
+ import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
8
+ import { normalizeAgentToken } from '../agent-clients/tokens.ts';
9
+ import { createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.ts';
10
+ import { archiveManualValidationGeneration, createManualValidationTransaction, readManualValidationTransaction, retryManualValidationTransaction, summaryPreimageDigest, transitionManualValidationTransaction, validateManualValidationGenerationArchive, writeManualValidationTransactionAtomic } from '../task/manual-validation-transaction.ts';
11
+ import type { ManualValidationTransaction } from '../task/manual-validation-transaction.ts';
12
+ import type { ManualValidationReceipt } from '../task/manual-validation-receipt.ts';
13
+ import { sha256File } from '../task/artifact-receipts.ts';
14
+ import { summaryCommentState, syncPullRequestSummary } from '../platform/pr-summary.ts';
15
+ import type { PlatformClient } from '../platform/context.ts';
16
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
17
+
18
+ const USAGE = `Usage: agent-infra-internal manual-validation transaction <task-ref> --prepare --artifact <artifact> --summary-file <path> --agent <agent> [--cwd <path>]
19
+ agent-infra-internal manual-validation transaction <task-ref> --artifact <artifact> --summary-file <path> --change-report-file <path> --agent <agent> [--result pr_created|pr_reused|no_op] [--cwd <path>]`;
20
+
21
+ type OutputFormat = 'json' | 'text';
22
+ type ManualValidationCoordinatorOptions = {
23
+ client?: PlatformClient;
24
+ archiveGeneration?: typeof archiveManualValidationGeneration;
25
+ };
26
+ type ManualValidationResult = {
27
+ status: 'applied' | 'failed';
28
+ changed: false;
29
+ error: { code: string; message: string } | null;
30
+ transaction?: ManualValidationTransaction;
31
+ receipt?: ManualValidationReceipt;
32
+ prepared?: boolean;
33
+ idempotent?: boolean;
34
+ [key: string]: unknown;
35
+ };
36
+ function result(status: 'applied' | 'failed', error: { code: string; message: string } | null = null, extra: Record<string, unknown> = {}): ManualValidationResult {
37
+ return { status, changed: false, error, ...extra };
38
+ }
39
+
40
+ function printFailure(format: OutputFormat, error: { code: string; message: string }): void {
41
+ if (format === 'json') process.stdout.write(`${JSON.stringify(result('failed', error))}\n`);
42
+ else process.stderr.write(`${error.code}: ${error.message}\n`);
43
+ process.exitCode = 1;
44
+ }
45
+
46
+ function manualSummaryBody(body: string, phase: 'pending' | 'final', transactionId: string, receiptDigest = '', evidenceDigest = '', prHeadSha = ''): string {
47
+ const withoutPrevious = body
48
+ .replace(/^###\s+✅\s+(?:Manual Validation Passed|人工验证已通过)\s*$/gmu, '')
49
+ .replace(/^###\s+⏳\s+(?:Manual Validation Pending|人工验证待收尾)\s*$/gmu, '')
50
+ .replace(/Manual validation passed(?:\s+→)?/giu, 'Manual validation pending');
51
+ const section = phase === 'pending'
52
+ ? `### ⏳ Manual Validation Pending\n\nManual validation evidence is staged; transaction ${transactionId} is awaiting final promotion.`
53
+ : `### ✅ Manual Validation Passed\n\nManual validation passed; transaction=${transactionId}; receipt=${receiptDigest}; evidence=${evidenceDigest}; head=${prHeadSha}.`;
54
+ return `${withoutPrevious.replace(/\s+$/u, '')}\n\n${section}\n`;
55
+ }
56
+
57
+ function openManualValidationStarted(taskMdPath: string): { present: boolean; transactionId: string | null } {
58
+ let content: string;
59
+ try { content = fs.readFileSync(taskMdPath, 'utf8'); }
60
+ catch { return { present: false, transactionId: null }; }
61
+ const section = locateActivityLog(content);
62
+ if (!section) return { present: false, transactionId: null };
63
+ const row = pairEntries(section.entries)
64
+ .filter((item) => item.step === 'Complete Manual Validation' && item.started && !item.done)
65
+ .at(-1);
66
+ if (!row) return { present: false, transactionId: null };
67
+ return {
68
+ present: true,
69
+ transactionId: /(?:^|;\s*)transaction=([A-Za-z0-9][A-Za-z0-9._-]{0,127})(?:;|$)/u.exec(row.note)?.[1] ?? null
70
+ };
71
+ }
72
+
73
+ async function executeManualValidationTransaction(taskRef: string, values: Record<string, string>, cwd: string, options: ManualValidationCoordinatorOptions = {}) {
74
+ const prepareOnly = values.prepare === 'true';
75
+ const required = prepareOnly
76
+ ? ['artifact', 'summaryFile', 'agent'] as const
77
+ : ['artifact', 'summaryFile', 'changeReportFile', 'agent'] as const;
78
+ const missing = required.find((key) => !values[key]);
79
+ if (missing) return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_ARGS_INVALID', message: `transaction requires --${missing.replace(/[A-Z]/gu, (letter) => `-${letter.toLowerCase()}`)}` });
80
+ const agent = normalizeAgentToken(values.agent!);
81
+ if (!agent) return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_ARGS_INVALID', message: 'transaction agent is invalid' });
82
+ const primaryResult = values.result ?? 'no_op';
83
+ if (!['pr_created', 'pr_reused', 'no_op'].includes(primaryResult)) return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_ARGS_INVALID', message: '--result must be pr_created, pr_reused, or no_op' });
84
+ const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
85
+ if (!resolved.ok) return result('failed', { code: resolved.code, message: resolved.message });
86
+ try {
87
+ return await withTaskExecutionLock(
88
+ resolved.repoRoot,
89
+ resolved.taskId,
90
+ `manual-validation:${taskRef}`,
91
+ () => executeManualValidationTransactionLocked(taskRef, values, cwd, resolved, agent, primaryResult as 'pr_created' | 'pr_reused' | 'no_op', prepareOnly, options)
92
+ );
93
+ } catch (error) {
94
+ if (error instanceof TaskExecutionLockError) return result('failed', { code: error.code, message: error.message });
95
+ throw error;
96
+ }
97
+ }
98
+
99
+ async function executeManualValidationTransactionLocked(
100
+ taskRef: string,
101
+ values: Record<string, string>,
102
+ cwd: string,
103
+ resolved: Extract<ReturnType<typeof resolveTaskRef>, { ok: true }>,
104
+ agent: string,
105
+ primaryResult: 'pr_created' | 'pr_reused' | 'no_op',
106
+ prepareOnly: boolean,
107
+ options: ManualValidationCoordinatorOptions
108
+ ) {
109
+ const artifactPath = path.resolve(resolved.taskDir, values.artifact!);
110
+ if (!prepareOnly && !fs.existsSync(artifactPath)) return result('failed', { code: 'MANUAL_VALIDATION_ARTIFACT_MISSING', message: `manual-validation artifact is missing: ${values.artifact}` });
111
+ const currentState = await summaryCommentState(taskRef, { cwd, client: options.client });
112
+ if (!currentState.pullRequest) return result('failed', { code: 'MANUAL_VALIDATION_PR_REQUIRED', message: 'canonical pull-request head is unavailable' });
113
+ const pullRequest = currentState.pullRequest;
114
+ const preimageBody = currentState.comment?.body ?? '';
115
+ const preimage = { commentId: currentState.comment?.id ?? null, body: preimageBody, digest: summaryPreimageDigest(preimageBody) };
116
+ const evidenceDigest = sha256File(path.resolve(cwd, values.summaryFile!));
117
+ const archiveGeneration = options.archiveGeneration ?? archiveManualValidationGeneration;
118
+ let transactionResult = readManualValidationTransaction(resolved.taskDir, { taskId: resolved.taskId, prNumber: pullRequest.number, prHeadSha: pullRequest.head.sha, evidenceDigest, artifact: values.artifact! });
119
+ let previousTransaction: ManualValidationTransaction | null = null;
120
+ if (!transactionResult.ok && transactionResult.error.code === 'MANUAL_VALIDATION_TRANSACTION_IDENTITY_MISMATCH') {
121
+ const existing = readManualValidationTransaction(resolved.taskDir);
122
+ if (!existing.ok) return result('failed', existing.error);
123
+ if (!['aborted', 'recovery-required', 'committed'].includes(existing.value.phase)) return result('failed', transactionResult.error);
124
+ try { validateManualValidationGenerationArchive(resolved.taskDir, existing.value, existing.value.phase === 'committed'); }
125
+ catch (error) { return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: error instanceof Error ? error.message : String(error) }); }
126
+ previousTransaction = existing.value;
127
+ transactionResult = { ok: false, error: { code: 'MANUAL_VALIDATION_TRANSACTION_MISSING', message: 'previous failed transaction was archived for a new pull-request head' } };
128
+ }
129
+ if (!transactionResult.ok && transactionResult.error.code !== 'MANUAL_VALIDATION_TRANSACTION_MISSING') return result('failed', transactionResult.error);
130
+ if (transactionResult.ok && transactionResult.value.phase === 'committed') return result('applied', null, { transaction: transactionResult.value, receipt: transactionResult.value.committedReceipt, idempotent: true });
131
+ const openStarted = transactionResult.ok ? { present: false, transactionId: null } : openManualValidationStarted(resolved.taskMdPath);
132
+ if (openStarted.present && !openStarted.transactionId) {
133
+ return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'open manual-validation started event has no recoverable transactionId' });
134
+ }
135
+ if (previousTransaction && openStarted.transactionId === previousTransaction.transactionId) {
136
+ return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'previous manual-validation generation is still open; retry the existing transaction before starting a new generation' });
137
+ }
138
+ const transactionId = transactionResult.ok
139
+ ? transactionResult.value.transactionId
140
+ : (openStarted.transactionId ?? values.transactionId ?? `mv-${Date.now()}`);
141
+ const finalBodyWithoutReceipt = fs.readFileSync(path.resolve(cwd, values.summaryFile!), 'utf8');
142
+ const pendingBody = manualSummaryBody(finalBodyWithoutReceipt, 'pending', transactionId);
143
+ const createTransaction = (): ManualValidationTransaction => createManualValidationTransaction({
144
+ transactionId,
145
+ taskId: resolved.taskId,
146
+ prNumber: pullRequest.number,
147
+ prHeadSha: pullRequest.head.sha,
148
+ evidenceDigest,
149
+ summaryPreimage: preimage,
150
+ pendingSummaryDigest: summaryPreimageDigest(pendingBody),
151
+ finalSummaryDigest: manualValidationFinalSummaryDigest(manualSummaryBody(finalBodyWithoutReceipt, 'final', transactionId, '<receipt>', evidenceDigest, pullRequest.head.sha)),
152
+ artifact: values.artifact!,
153
+ attempt: 1,
154
+ createdAt: new Date().toISOString(),
155
+ updatedAt: new Date().toISOString()
156
+ });
157
+ let transaction: ManualValidationTransaction;
158
+ const idempotent = transactionResult.ok;
159
+ let startedEventApplied = false;
160
+ if (!transactionResult.ok) {
161
+ transaction = createTransaction();
162
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
163
+ if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
164
+ startedEventApplied = true;
165
+ if (previousTransaction) {
166
+ try { archiveGeneration(resolved.taskDir, previousTransaction, previousTransaction.phase === 'committed'); }
167
+ catch (error) { return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: error instanceof Error ? error.message : String(error) }); }
168
+ }
169
+ writeManualValidationTransactionAtomic(resolved.taskDir, transaction);
170
+ } else {
171
+ transaction = transactionResult.value;
172
+ if (['aborted', 'recovery-required'].includes(transaction.phase)) {
173
+ const retried = retryManualValidationTransaction(transaction);
174
+ if (!retried.ok) return result('failed', retried.error);
175
+ transaction = retried.value;
176
+ writeManualValidationTransactionAtomic(resolved.taskDir, transaction);
177
+ }
178
+ }
179
+ if (transaction.phase === 'prepared' && !startedEventApplied) {
180
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
181
+ if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
182
+ }
183
+ if (prepareOnly) return result('applied', null, { transaction, prepared: true, idempotent });
184
+ const transactionFailure = (failure: { code: string; message: string }): never => {
185
+ throw new Error(`${failure.code}: ${failure.message}`);
186
+ };
187
+ const transitionAndPersist = (
188
+ phase: Parameters<typeof transitionManualValidationTransaction>[1],
189
+ patch: Parameters<typeof transitionManualValidationTransaction>[2] = {}
190
+ ): void => {
191
+ const next = transitionManualValidationTransaction(transaction, phase, patch);
192
+ if (!next.ok) throw new Error(`${next.error.code}: ${next.error.message}`);
193
+ transaction = next.value;
194
+ writeManualValidationTransactionAtomic(resolved.taskDir, transaction);
195
+ };
196
+ try {
197
+ if (transaction.phase === 'prepared') {
198
+ const staged = await syncPullRequestSummary(taskRef, {
199
+ cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
200
+ manualValidation: { phase: 'pending' }, lockAlreadyHeld: true
201
+ });
202
+ if (!['applied', 'no-op'].includes(staged.status)) transactionFailure(staged.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'pending summary staging failed' });
203
+ transitionAndPersist('summary-staged');
204
+ }
205
+ let receiptResult = readManualValidationReceipt(resolved.taskDir, {
206
+ transactionId: transaction.transactionId,
207
+ taskId: resolved.taskId,
208
+ prNumber: pullRequest.number,
209
+ prHeadSha: pullRequest.head.sha,
210
+ evidenceDigest: transaction.evidenceDigest,
211
+ artifact: values.artifact!
212
+ });
213
+ if (!receiptResult.ok && receiptResult.error.code !== 'MANUAL_VALIDATION_RECEIPT_MISSING') transactionFailure(receiptResult.error);
214
+ let receipt: ManualValidationReceipt;
215
+ if (receiptResult.ok) {
216
+ receipt = receiptResult.value;
217
+ } else {
218
+ receipt = createManualValidationReceipt({
219
+ transactionId: transaction.transactionId,
220
+ taskId: resolved.taskId,
221
+ prNumber: pullRequest.number,
222
+ prHeadSha: pullRequest.head.sha,
223
+ evidenceDigest: transaction.evidenceDigest,
224
+ artifact: values.artifact!,
225
+ artifactSha256: sha256File(artifactPath),
226
+ pendingSummaryDigest: transaction.pendingSummaryDigest,
227
+ finalSummaryDigest: transaction.finalSummaryDigest,
228
+ committedAt: new Date().toISOString()
229
+ });
230
+ writeManualValidationReceiptAtomic(resolved.taskDir, receipt);
231
+ }
232
+ if (transaction.phase === 'summary-staged') {
233
+ transitionAndPersist('receipt-committed', { committedReceipt: receipt.receiptDigest });
234
+ }
235
+ if (transaction.phase === 'receipt-committed' && !transaction.eventAppended) {
236
+ const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { lockAlreadyHeld: true, repoRoot: cwd });
237
+ if (completed.status === 'failed') transactionFailure(completed.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation completion event failed' });
238
+ transitionAndPersist('receipt-committed', { eventAppended: true });
239
+ }
240
+ if (transaction.phase === 'receipt-committed') {
241
+ transitionAndPersist('final-promotion-in-progress');
242
+ }
243
+ const promoted = await syncPullRequestSummary(taskRef, {
244
+ cwd, client: options.client, agent, body: manualSummaryBody(finalBodyWithoutReceipt, 'final', transaction.transactionId, receipt.receiptDigest, receipt.evidenceDigest, receipt.prHeadSha), changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult, strict: true,
245
+ manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }, lockAlreadyHeld: true
246
+ });
247
+ if (!['applied', 'no-op'].includes(promoted.status)) transactionFailure(promoted.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'final summary promotion failed' });
248
+ const postWrite = await summaryCommentState(taskRef, { cwd, client: options.client });
249
+ if (!postWrite.comment?.body.includes('### ✅ Manual Validation Passed') || postWrite.pullRequest?.head.sha !== receipt.prHeadSha || !manualValidationFinalSummaryProjectionMatches(postWrite.comment.body, receipt)) transactionFailure({ code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'final summary post-write verification failed' });
250
+ transitionAndPersist('committed', { postWriteVerified: true });
251
+ return result('applied', null, { transaction, receipt, idempotent: false });
252
+ } catch (error) {
253
+ const message = error instanceof Error ? error.message : String(error);
254
+ if (transaction.phase === 'final-promotion-in-progress') {
255
+ try {
256
+ await syncPullRequestSummary(taskRef, {
257
+ cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
258
+ manualValidation: { phase: 'pending' }, lockAlreadyHeld: true
259
+ });
260
+ } catch {
261
+ // Preserve recovery-required when pending compensation cannot be confirmed.
262
+ }
263
+ }
264
+ const failedTransaction = transitionManualValidationTransaction(transaction, 'recovery-required', { error: message.slice(0, 400) });
265
+ if (failedTransaction.ok) writeManualValidationTransactionAtomic(resolved.taskDir, failedTransaction.value);
266
+ return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message });
267
+ }
268
+ }
269
+
270
+ function parse(args: string[], start: number): { values: Record<string, string>; error?: string } {
271
+ const values: Record<string, string> = {};
272
+ for (let index = start; index < args.length; index += 1) {
273
+ const flag = args[index]!;
274
+ if (flag === '--prepare') {
275
+ if (values.prepare) return { values, error: `duplicate option '${flag}'` };
276
+ values.prepare = 'true';
277
+ continue;
278
+ }
279
+ if (!['--format', '--cwd', '--artifact', '--summary-file', '--change-report-file', '--agent', '--result'].includes(flag)) return { values, error: `unknown option '${flag}'` };
280
+ const value = args[++index];
281
+ if (!value || value.startsWith('--')) return { values, error: `option '${flag}' requires a value` };
282
+ const key = flag.slice(2).replace(/-([a-z])/gu, (_, letter: string) => letter.toUpperCase());
283
+ if (values[key]) return { values, error: `duplicate option '${flag}'` };
284
+ values[key] = value;
285
+ }
286
+ return { values };
287
+ }
288
+
289
+ async function manualValidation(args: string[] = []): Promise<void> {
290
+ if (!ensureInternalHandlerRoute('manual-validation', args)) return;
291
+ if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(`${USAGE}\n`); return; }
292
+ const operation = args[0];
293
+ const isTransaction = operation === 'transaction' && internalHandlerRoute('manual-validation', 'transaction', operation);
294
+ if (!isTransaction) { printFailure('json', { code: 'MANUAL_VALIDATION_ARGS_INVALID', message: 'transaction operation is required' }); return; }
295
+ const taskRef = args[1];
296
+ if (!taskRef || taskRef.startsWith('--')) { printFailure('json', { code: 'MANUAL_VALIDATION_ARGS_INVALID', message: 'task ref is required' }); return; }
297
+ const parsed = parse(args, 2);
298
+ if (parsed.error) { printFailure('json', { code: 'MANUAL_VALIDATION_ARGS_INVALID', message: parsed.error }); return; }
299
+ const values = parsed.values;
300
+ const format = values.format === 'text' ? 'text' : 'json';
301
+ const output = await executeManualValidationTransaction(taskRef, values, path.resolve(values.cwd ?? process.cwd()));
302
+ process.stdout.write(format === 'json' ? `${JSON.stringify(output)}\n` : `${output.status === 'applied' ? 'Manual validation transaction committed.' : `${output.error?.code}: ${output.error?.message}`}\n`);
303
+ if (output.status === 'failed') process.exitCode = 1;
304
+ }
305
+
306
+ export { executeManualValidationTransaction, manualValidation };
@@ -7,6 +7,7 @@ import {
7
7
  watchPullRequestReadiness
8
8
  } from '../platform/pr-checks.ts';
9
9
  import type { ChecksResult } from '../platform/pr-checks.ts';
10
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
10
11
 
11
12
  const USAGE = `Usage: agent-infra-internal platform-checks inspect <task-ref> [--cwd <path>]
12
13
  agent-infra-internal platform-checks watch <task-ref> --interval-seconds <N> --deadline-seconds <N> [--cwd <path>]
@@ -53,9 +54,15 @@ function positive(value: string | undefined): number | null {
53
54
  }
54
55
 
55
56
  async function platformChecks(args: string[] = []): Promise<void> {
57
+ if (!ensureInternalHandlerRoute('platform-checks', args)) return;
56
58
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
57
59
  const operation = args[0];
58
- if (!operation || !['inspect', 'watch', 'resolve-run', 'logs'].includes(operation)) { fail('a valid operation is required'); return; }
60
+ if (!operation || ![
61
+ internalHandlerRoute('platform-checks', 'inspect', operation),
62
+ internalHandlerRoute('platform-checks', 'watch', operation),
63
+ internalHandlerRoute('platform-checks', 'resolve-run', operation),
64
+ internalHandlerRoute('platform-checks', 'logs', operation)
65
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
59
66
  const taskRef = args[1];
60
67
  if (!taskRef || taskRef.startsWith('--')) { fail(`${operation} requires a task ref`); return; }
61
68
  const parsed = parse(args, 2);
@@ -70,19 +77,20 @@ async function platformChecks(args: string[] = []): Promise<void> {
70
77
  };
71
78
  const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
72
79
  if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
73
- if (operation === 'inspect') { finish(await inspectPullRequestReadiness(taskRef, { cwd })); return; }
74
- if (operation === 'resolve-run') {
80
+ if (internalHandlerRoute('platform-checks', 'inspect', operation)) { finish(await inspectPullRequestReadiness(taskRef, { cwd })); return; }
81
+ if (internalHandlerRoute('platform-checks', 'resolve-run', operation)) {
75
82
  if (!values.checkName) { fail('resolve-run requires --check-name'); return; }
76
83
  finish(await resolvePlatformCheckRun(taskRef, { cwd, checkName: values.checkName, detailsUrl: values.detailsUrl }));
77
84
  return;
78
85
  }
79
- if (operation === 'logs') {
86
+ if (internalHandlerRoute('platform-checks', 'logs', operation)) {
80
87
  const run = positive(values.run);
81
88
  const job = values.job === undefined ? undefined : positive(values.job);
82
89
  if (!run || values.job !== undefined && !job) { fail('logs requires a positive --run and optional positive --job'); return; }
83
90
  finish(await fetchPlatformCheckLogs(taskRef, { cwd, run, job: job || undefined }));
84
91
  return;
85
92
  }
93
+ if (!internalHandlerRoute('platform-checks', 'watch', operation)) { fail('operation is not registered'); return; }
86
94
  const intervalSeconds = positive(values.intervalSeconds);
87
95
  const deadlineSeconds = positive(values.deadlineSeconds);
88
96
  if (!intervalSeconds || !deadlineSeconds) { fail('watch requires positive --interval-seconds and --deadline-seconds'); return; }
@@ -10,6 +10,7 @@ import {
10
10
  import type { CommentKind } from '../platform/issue-comments.ts';
11
11
  import type { PlatformResult } from '../platform/types.ts';
12
12
  import { backfillCompletionComments } from '../platform/completion-backfill.ts';
13
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
13
14
 
14
15
  const USAGE = `Usage: agent-infra-internal platform-comment list --issue <token> [--cwd <path>]
15
16
  agent-infra-internal platform-comment owner <task-ref> [--cwd <path>]
@@ -53,16 +54,22 @@ function readBodyFile(value: string, cwd: string): string {
53
54
  }
54
55
 
55
56
  async function platformComment(args: string[] = []): Promise<void> {
57
+ if (!ensureInternalHandlerRoute('platform-comment', args)) return;
56
58
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
57
59
  const operation = args[0];
58
- if (!operation || !['list', 'owner', 'backfill', 'sync'].includes(operation)) { fail('a valid operation is required'); return; }
60
+ if (!operation || ![
61
+ internalHandlerRoute('platform-comment', 'list', operation),
62
+ internalHandlerRoute('platform-comment', 'owner', operation),
63
+ internalHandlerRoute('platform-comment', 'backfill', operation),
64
+ internalHandlerRoute('platform-comment', 'sync', operation)
65
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
59
66
  const hasTaskRef = operation !== 'list';
60
67
  const taskRef = hasTaskRef ? args[1] : undefined;
61
68
  if (hasTaskRef && (!taskRef || taskRef.startsWith('--'))) { fail(`${operation} requires a task ref`); return; }
62
69
  const parsed = parseFlags(args, hasTaskRef ? 2 : 1);
63
70
  if (parsed.error) { fail(parsed.error); return; }
64
71
  const cwd = path.resolve(typeof parsed.values.cwd === 'string' ? parsed.values.cwd : process.cwd());
65
- if (operation === 'list') {
72
+ if (internalHandlerRoute('platform-comment', 'list', operation)) {
66
73
  const issue = parsed.values.issue;
67
74
  if (typeof issue !== 'string' || !issue) { fail('list requires --issue <token>'); return; }
68
75
  const unexpected = Object.keys(parsed.values).find((key) => !['issue', 'cwd'].includes(key));
@@ -70,13 +77,13 @@ async function platformComment(args: string[] = []): Promise<void> {
70
77
  finish(await listPlatformComments(issue, cwd));
71
78
  return;
72
79
  }
73
- if (operation === 'owner') {
80
+ if (internalHandlerRoute('platform-comment', 'owner', operation)) {
74
81
  const unexpected = Object.keys(parsed.values).find((key) => key !== 'cwd');
75
82
  if (unexpected) { fail(`owner does not accept '--${unexpected}'`); return; }
76
83
  finish(await checkPlatformCommentOwner(taskRef!, { cwd }));
77
84
  return;
78
85
  }
79
- if (operation === 'backfill') {
86
+ if (internalHandlerRoute('platform-comment', 'backfill', operation)) {
80
87
  const unexpected = Object.keys(parsed.values).find((key) => !['cwd', 'agent'].includes(key));
81
88
  if (unexpected) { fail(`backfill does not accept '--${unexpected}'`); return; }
82
89
  const agent = parsed.values.agent;
@@ -86,6 +93,7 @@ async function platformComment(args: string[] = []): Promise<void> {
86
93
  finish(await backfillCompletionComments(taskRef!, { cwd, agent: normalizedAgent }));
87
94
  return;
88
95
  }
96
+ if (!internalHandlerRoute('platform-comment', 'sync', operation)) { fail('operation is not registered'); return; }
89
97
  const kind = parsed.values.kind;
90
98
  const agent = parsed.values.agent;
91
99
  if (!['task', 'artifact', 'summary', 'cancel'].includes(String(kind))) { fail('sync requires a valid --kind'); return; }
@@ -1,6 +1,7 @@
1
1
  import path from 'node:path';
2
2
 
3
3
  import { resolvePlatformContext } from '../platform/context.ts';
4
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
4
5
 
5
6
  const USAGE = 'Usage: agent-infra-internal platform-context resolve [--cwd <path>]\n';
6
7
 
@@ -11,8 +12,9 @@ function fail(message: string): void {
11
12
  }
12
13
 
13
14
  async function platformContext(args: string[] = []): Promise<void> {
15
+ if (!ensureInternalHandlerRoute('platform-context', args)) return;
14
16
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
15
- if (args[0] !== 'resolve') { fail("operation must be 'resolve'"); return; }
17
+ if (!internalHandlerRoute('platform-context', 'resolve', args[0] ?? '')) { fail("operation must be 'resolve'"); return; }
16
18
  let cwd = process.cwd();
17
19
  const seen = new Set<string>();
18
20
  for (let index = 1; index < args.length; index += 1) {
@@ -8,6 +8,7 @@ import {
8
8
  syncPlatformIssue
9
9
  } from '../platform/issues.ts';
10
10
  import type { IssueResult } from '../platform/issues.ts';
11
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
11
12
 
12
13
  const USAGE = `Usage: agent-infra-internal platform-issue inspect <task-ref> [--cwd <path>]
13
14
  agent-infra-internal platform-issue create <task-ref> --agent <agent> [--dry-run] [--cwd <path>]
@@ -60,9 +61,15 @@ function oneOf(values: Record<string, string | boolean>, name: string, allowed:
60
61
  }
61
62
 
62
63
  async function platformIssue(args: string[] = []): Promise<void> {
64
+ if (!ensureInternalHandlerRoute('platform-issue', args)) return;
63
65
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
64
66
  const operation = args[0];
65
- if (!operation || !['inspect', 'create', 'bind', 'sync'].includes(operation)) { fail('a valid operation is required'); return; }
67
+ if (!operation || ![
68
+ internalHandlerRoute('platform-issue', 'inspect', operation),
69
+ internalHandlerRoute('platform-issue', 'create', operation),
70
+ internalHandlerRoute('platform-issue', 'bind', operation),
71
+ internalHandlerRoute('platform-issue', 'sync', operation)
72
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
66
73
  const taskRef = args[1];
67
74
  if (!taskRef || taskRef.startsWith('--')) { fail(`${operation} requires a task ref`); return; }
68
75
  const parsed = parse(args, 2);
@@ -75,15 +82,15 @@ async function platformIssue(args: string[] = []): Promise<void> {
75
82
  };
76
83
  const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
77
84
  if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
78
- if (operation === 'inspect') { finish(await inspectPlatformIssue(taskRef, { cwd })); return; }
85
+ if (internalHandlerRoute('platform-issue', 'inspect', operation)) { finish(await inspectPlatformIssue(taskRef, { cwd })); return; }
79
86
  if (typeof values.agent !== 'string' || !values.agent) { fail(`${operation} requires --agent`); return; }
80
87
  const agent = normalizeAgentToken(values.agent);
81
88
  if (!agent) { fail(`invalid --agent '${values.agent}': ${AGENT_USAGE_HINT}`); return; }
82
89
  values.agent = agent;
83
- if (operation === 'create') {
90
+ if (internalHandlerRoute('platform-issue', 'create', operation)) {
84
91
  finish(await createPlatformIssue(taskRef, { cwd, agent: values.agent, dryRun: values.dryRun === true })); return;
85
92
  }
86
- if (operation === 'bind') {
93
+ if (internalHandlerRoute('platform-issue', 'bind', operation)) {
87
94
  if (typeof values.issue !== 'string' || !values.issue) { fail('bind requires --issue <token>'); return; }
88
95
  finish(await bindPlatformIssue(taskRef, { cwd, agent: values.agent, issue: values.issue, dryRun: values.dryRun === true })); return;
89
96
  }
@@ -0,0 +1,70 @@
1
+ import path from 'node:path';
2
+
3
+ import { initializeLabels, initializeMilestones } from '../platform/repository-metadata.ts';
4
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
5
+
6
+ const USAGE = `Usage: agent-infra-internal platform-metadata init-labels [--cleanup-stale-in] [--cwd <path>]
7
+ agent-infra-internal platform-metadata init-milestones [--history] [--cwd <path>]
8
+ `;
9
+
10
+ function fail(message: string): void {
11
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'METADATA_INPUT_INVALID', message, retryable: false } })}\n`);
12
+ process.stderr.write(USAGE);
13
+ process.exitCode = 1;
14
+ }
15
+
16
+ function finish(result: { status: string; [key: string]: unknown }, preserveMilestoneFallback = false): void {
17
+ if (preserveMilestoneFallback && result.error && typeof result.error === 'object'
18
+ && (result.error as { code?: string }).code === 'PLATFORM_CAPABILITY_UNSUPPORTED') {
19
+ process.stderr.write('Milestone initialization skipped for unsupported platform.\n');
20
+ process.exitCode = 0;
21
+ return;
22
+ }
23
+ process.stdout.write(`${JSON.stringify(result)}\n`);
24
+ process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
25
+ }
26
+
27
+ function parseOptions(args: string[]): { cwd: string; cleanup: boolean; history: boolean } | null {
28
+ let cwd = process.cwd();
29
+ let cleanup = false;
30
+ let history = false;
31
+ const seen = new Set<string>();
32
+ for (let index = 0; index < args.length; index += 1) {
33
+ const flag = args[index]!;
34
+ if (seen.has(flag)) return null;
35
+ seen.add(flag);
36
+ if (flag === '--cleanup-stale-in') { cleanup = true; continue; }
37
+ if (flag === '--history') { history = true; continue; }
38
+ if (flag === '--cwd') {
39
+ const value = args[++index];
40
+ if (!value || value.startsWith('--')) return null;
41
+ cwd = path.resolve(value);
42
+ continue;
43
+ }
44
+ return null;
45
+ }
46
+ return { cwd: path.resolve(cwd), cleanup, history };
47
+ }
48
+
49
+ async function platformMetadata(args: string[] = []): Promise<void> {
50
+ if (!ensureInternalHandlerRoute('platform-metadata', args)) return;
51
+ if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
52
+ const action = args[0];
53
+ if (!internalHandlerRoute('platform-metadata', 'init-labels', action ?? '')
54
+ && !internalHandlerRoute('platform-metadata', 'init-milestones', action ?? '')) {
55
+ fail('a valid operation is required');
56
+ return;
57
+ }
58
+ if (action !== 'init-labels' && action !== 'init-milestones') { fail('a valid operation is required'); return; }
59
+ const parsed = parseOptions(args.slice(1));
60
+ if (!parsed) { fail('invalid metadata options'); return; }
61
+ if (action === 'init-labels' && parsed.history) { fail('init-labels does not accept --history'); return; }
62
+ if (action === 'init-milestones' && parsed.cleanup) { fail('init-milestones does not accept --cleanup-stale-in'); return; }
63
+ if (action === 'init-labels') {
64
+ finish(await initializeLabels({ cleanupStaleIn: parsed.cleanup }, { cwd: parsed.cwd }));
65
+ return;
66
+ }
67
+ finish(await initializeMilestones({ history: parsed.history }, { cwd: parsed.cwd }), true);
68
+ }
69
+
70
+ export { platformMetadata };
@@ -5,6 +5,7 @@ import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.ts
5
5
  import { listPrReviews, publishPrReview } from '../platform/pr-review.ts';
6
6
  import type { PrReviewEvent } from '../platform/pr-review.ts';
7
7
  import type { PlatformResult } from '../platform/types.ts';
8
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
8
9
 
9
10
  const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <token> [--cwd <path>]
10
11
  agent-infra-internal platform-pr-review list --pr <token> [--cwd <path>]
@@ -51,9 +52,14 @@ function readBodyFile(value: string, cwd: string): string {
51
52
  }
52
53
 
53
54
  async function platformPrReview(args: string[] = []): Promise<void> {
55
+ if (!ensureInternalHandlerRoute('platform-pr-review', args)) return;
54
56
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
55
57
  const operation = args[0];
56
- if (!operation || !['inspect', 'list', 'publish'].includes(operation)) { fail('a valid operation is required'); return; }
58
+ if (!operation || ![
59
+ internalHandlerRoute('platform-pr-review', 'inspect', operation),
60
+ internalHandlerRoute('platform-pr-review', 'list', operation),
61
+ operation === 'publish'
62
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
57
63
  const parsed = parse(args, 1);
58
64
  if (parsed.error) { fail(parsed.error); return; }
59
65
  const values = parsed.values;
@@ -67,19 +73,24 @@ async function platformPrReview(args: string[] = []): Promise<void> {
67
73
  if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
68
74
  const pr = values.pr;
69
75
  if (typeof pr !== 'string' || !pr) { fail(`${operation} requires --pr <token>`); return; }
70
- if (operation === 'inspect') {
76
+ if (internalHandlerRoute('platform-pr-review', 'inspect', operation)) {
71
77
  finish(await inspectPlatformPullRequestByNumber(pr, { cwd }));
72
78
  return;
73
79
  }
74
- if (operation === 'list') {
80
+ if (internalHandlerRoute('platform-pr-review', 'list', operation)) {
75
81
  finish(await listPrReviews(pr, { cwd }));
76
82
  return;
77
83
  }
78
84
  const scope = typeof values.scope === 'string' ? values.scope : '';
85
+ const publishSelector = /^TASK-\d{8}-\d{6}$/u.test(scope) ? 'publish-task' : /^pr\d+$/u.test(scope) ? 'publish-pr' : '';
79
86
  const round = Number(values.round);
80
87
  const commit = typeof values.commit === 'string' ? values.commit : '';
81
88
  const event = values.event as string;
82
89
  if (!scope || !/^(?:pr\d+|TASK-\d{8}-\d{6})$/.test(scope)) { fail('publish requires --scope <taskId|pr{N}>'); return; }
90
+ if (!internalHandlerRoute('platform-pr-review', 'publish-task', publishSelector)
91
+ && !internalHandlerRoute('platform-pr-review', 'publish-pr', publishSelector)) {
92
+ fail('publish scope is not registered'); return;
93
+ }
83
94
  if (!Number.isInteger(round) || round <= 0) { fail('publish requires a positive --round'); return; }
84
95
  if (!/^[0-9a-f]{7,40}$/i.test(commit)) { fail('publish requires --commit <sha>'); return; }
85
96
  if (!['COMMENT', 'APPROVE', 'REQUEST_CHANGES'].includes(event)) { fail('publish requires --event <COMMENT|APPROVE|REQUEST_CHANGES>'); return; }