@fitlab-ai/agent-infra 0.9.12 → 0.9.14

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 (402) hide show
  1. package/README.md +11 -11
  2. package/README.zh-CN.md +11 -11
  3. package/bin/cli.ts +26 -9
  4. package/dist/bin/cli.js +173 -157
  5. package/dist/bin/internal-cli.js +66 -40
  6. package/dist/lib/agent-client.js +5 -0
  7. package/dist/lib/agent-clients/next-steps.js +6 -1
  8. package/dist/lib/decide.js +3 -3
  9. package/dist/lib/internal/agent-client.js +5 -2
  10. package/dist/lib/internal/cli-route-inventory.js +152 -0
  11. package/dist/lib/internal/codex-lifecycle.js +9 -6
  12. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  13. package/dist/lib/internal/git-workflow.js +10 -6
  14. package/dist/lib/internal/platform-checks.js +19 -7
  15. package/dist/lib/internal/platform-comment.js +25 -13
  16. package/dist/lib/internal/platform-context.js +6 -3
  17. package/dist/lib/internal/platform-issue.js +20 -13
  18. package/dist/lib/internal/platform-metadata.js +88 -0
  19. package/dist/lib/internal/platform-pr-review.js +26 -13
  20. package/dist/lib/internal/platform-pr.js +84 -31
  21. package/dist/lib/internal/platform-release-notes.js +9 -6
  22. package/dist/lib/internal/platform-security.js +93 -0
  23. package/dist/lib/internal/pr-review-grade.js +25 -12
  24. package/dist/lib/internal/release-workflow.js +23 -9
  25. package/dist/lib/internal/sandbox-control.js +50 -7
  26. package/dist/lib/internal/task-activity.js +16 -7
  27. package/dist/lib/internal/task-artifact.js +235 -24
  28. package/dist/lib/internal/task-context.js +4 -1
  29. package/dist/lib/internal/task-create.js +50 -17
  30. package/dist/lib/internal/task-delivery.js +4 -1
  31. package/dist/lib/internal/task-event.js +10 -4
  32. package/dist/lib/internal/task-finalization.js +6 -3
  33. package/dist/lib/internal/task-invalidation.js +63 -0
  34. package/dist/lib/internal/task-ledger.js +20 -6
  35. package/dist/lib/internal/task-lifecycle.js +6 -3
  36. package/dist/lib/internal/task-operation-registry.js +421 -0
  37. package/dist/lib/internal/task-orchestration.js +12 -0
  38. package/dist/lib/internal/task-override.js +14 -7
  39. package/dist/lib/internal/task-qualification.js +90 -0
  40. package/dist/lib/internal/task-review.js +7 -4
  41. package/dist/lib/internal/task-short-id.js +11 -1
  42. package/dist/lib/internal/task-snapshot.js +4 -1
  43. package/dist/lib/internal/task-validate.js +7 -2
  44. package/dist/lib/internal/task-verify.js +11 -7
  45. package/dist/lib/internal/task-warning.js +11 -4
  46. package/dist/lib/platform/adapters.js +1 -3
  47. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  48. package/dist/lib/platform/comment-safety.js +226 -0
  49. package/dist/lib/platform/completion-backfill.js +6 -5
  50. package/dist/lib/platform/context.js +70 -130
  51. package/dist/lib/platform/github-client.js +1 -1
  52. package/dist/lib/platform/github-provider.js +1130 -0
  53. package/dist/lib/platform/in-label-sync.js +143 -0
  54. package/dist/lib/platform/issue-comments.js +237 -72
  55. package/dist/lib/platform/issues.js +335 -189
  56. package/dist/lib/platform/metadata-labels.js +6 -2
  57. package/dist/lib/platform/none-provider.js +28 -0
  58. package/dist/lib/platform/pr-change-report.js +545 -0
  59. package/dist/lib/platform/pr-checks.js +119 -104
  60. package/dist/lib/platform/pr-review.js +88 -72
  61. package/dist/lib/platform/pr-summary.js +541 -50
  62. package/dist/lib/platform/provider-bridge.js +45 -0
  63. package/dist/lib/platform/provider-contract.d.ts +553 -0
  64. package/dist/lib/platform/provider-contract.js +99 -0
  65. package/dist/lib/platform/provider-loader.js +251 -0
  66. package/dist/lib/platform/provider-validation.js +577 -0
  67. package/dist/lib/platform/pull-request-metadata.js +8 -6
  68. package/dist/lib/platform/pull-requests.js +734 -543
  69. package/dist/lib/platform/release-notes.js +78 -55
  70. package/dist/lib/platform/releases.js +79 -50
  71. package/dist/lib/platform/repository-metadata.js +377 -0
  72. package/dist/lib/platform/resource-identity.d.ts +26 -0
  73. package/dist/lib/platform/resource-identity.js +92 -0
  74. package/dist/lib/platform/security-alerts.js +155 -0
  75. package/dist/lib/platform/task-identities.js +31 -0
  76. package/dist/lib/platform/verification-required.js +11 -12
  77. package/dist/lib/platform/verification-sync.js +129 -248
  78. package/dist/lib/pr-review/evidence-grading.js +19 -6
  79. package/dist/lib/process-data/index.js +7 -0
  80. package/dist/lib/run/index.js +68 -23
  81. package/dist/lib/sandbox/commands/control-status.js +22 -0
  82. package/dist/lib/sandbox/commands/create.js +32 -6
  83. package/dist/lib/sandbox/commands/ls.js +5 -0
  84. package/dist/lib/sandbox/commands/rm.js +827 -120
  85. package/dist/lib/sandbox/commands/show.js +16 -0
  86. package/dist/lib/sandbox/control/client.js +174 -19
  87. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  88. package/dist/lib/sandbox/control/container-identity.js +28 -31
  89. package/dist/lib/sandbox/control/executor.js +151 -16
  90. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  91. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  92. package/dist/lib/sandbox/control/protocol.js +77 -0
  93. package/dist/lib/sandbox/control/server.js +677 -34
  94. package/dist/lib/sandbox/control/state.js +209 -4
  95. package/dist/lib/sandbox/control/task-view.js +183 -0
  96. package/dist/lib/sandbox/engines/authority.js +289 -0
  97. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  98. package/dist/lib/sandbox/index.js +5 -0
  99. package/dist/lib/sandbox/recovery.js +21 -1
  100. package/dist/lib/sandbox/workspace-view.js +2 -1
  101. package/dist/lib/sandbox/worktree-safety.js +4 -1
  102. package/dist/lib/server/index.js +8 -0
  103. package/dist/lib/server/protocol.js +38 -1
  104. package/dist/lib/task/activity-log.js +8 -1
  105. package/dist/lib/task/artifact-lifecycle.js +75 -18
  106. package/dist/lib/task/artifact-operations.js +520 -0
  107. package/dist/lib/task/artifact-repair-intent.js +59 -0
  108. package/dist/lib/task/artifact-schema.js +135 -0
  109. package/dist/lib/task/capabilities.js +310 -0
  110. package/dist/lib/task/commands/status.js +32 -0
  111. package/dist/lib/task/commit-operation.js +12 -1
  112. package/dist/lib/task/control-authority.js +12 -5
  113. package/dist/lib/task/create-service.js +111 -12
  114. package/dist/lib/task/create.js +25 -0
  115. package/dist/lib/task/current-contract.js +5 -1
  116. package/dist/lib/task/decision-details.js +1 -1
  117. package/dist/lib/task/events.js +416 -17
  118. package/dist/lib/task/finalization.js +37 -13
  119. package/dist/lib/task/human-override.js +58 -36
  120. package/dist/lib/task/index.js +11 -3
  121. package/dist/lib/task/invalidation-command.js +86 -0
  122. package/dist/lib/task/invalidation.js +260 -0
  123. package/dist/lib/task/ledger-intents.js +37 -0
  124. package/dist/lib/task/local-artifact-finalization.js +299 -0
  125. package/dist/lib/task/orchestration.js +240 -144
  126. package/dist/lib/task/pr-delivery-fact.js +102 -101
  127. package/dist/lib/task/qualification-audit.js +490 -0
  128. package/dist/lib/task/qualification-confirmation.js +109 -0
  129. package/dist/lib/task/qualification-intents.js +148 -0
  130. package/dist/lib/task/review-artifacts.js +22 -23
  131. package/dist/lib/task/review-finalization.js +121 -4
  132. package/dist/lib/task/review-fingerprint.js +24 -2
  133. package/dist/lib/task/rework-intent.js +138 -0
  134. package/dist/lib/task/sections.js +6 -4
  135. package/dist/lib/task/skill-scope.js +23 -0
  136. package/dist/lib/task/task-execution-lock.js +27 -17
  137. package/dist/lib/task/verification-config.js +11 -0
  138. package/dist/lib/task/verification-engine.js +93 -16
  139. package/dist/lib/task/verification.js +3 -3
  140. package/dist/lib/task/workflow-warning-intents.js +1 -1
  141. package/dist/lib/task/write.js +11 -0
  142. package/dist/lib/version.js +11 -1
  143. package/dist/lifecycle-build-manifest.json +3 -3
  144. package/lib/agent-client.ts +9 -0
  145. package/lib/agent-clients/next-steps.ts +6 -1
  146. package/lib/decide.ts +3 -3
  147. package/lib/init.ts +1 -1
  148. package/lib/internal/agent-client.ts +4 -2
  149. package/lib/internal/cli-route-inventory.ts +140 -0
  150. package/lib/internal/codex-lifecycle.ts +8 -6
  151. package/lib/internal/codex-sandbox-controller.ts +7 -2
  152. package/lib/internal/git-workflow.ts +9 -6
  153. package/lib/internal/platform-checks.ts +14 -6
  154. package/lib/internal/platform-comment.ts +20 -12
  155. package/lib/internal/platform-context.ts +5 -3
  156. package/lib/internal/platform-issue.ts +17 -11
  157. package/lib/internal/platform-metadata.ts +70 -0
  158. package/lib/internal/platform-pr-review.ts +23 -12
  159. package/lib/internal/platform-pr.ts +65 -27
  160. package/lib/internal/platform-release-notes.ts +8 -6
  161. package/lib/internal/platform-security.ts +83 -0
  162. package/lib/internal/pr-review-grade.ts +20 -11
  163. package/lib/internal/release-workflow.ts +21 -9
  164. package/lib/internal/sandbox-control.ts +44 -6
  165. package/lib/internal/task-activity.ts +15 -7
  166. package/lib/internal/task-artifact.ts +204 -22
  167. package/lib/internal/task-context.ts +3 -1
  168. package/lib/internal/task-create.ts +78 -17
  169. package/lib/internal/task-delivery.ts +3 -1
  170. package/lib/internal/task-event.ts +9 -4
  171. package/lib/internal/task-finalization.ts +6 -4
  172. package/lib/internal/task-invalidation.ts +41 -0
  173. package/lib/internal/task-ledger.ts +21 -8
  174. package/lib/internal/task-lifecycle.ts +5 -3
  175. package/lib/internal/task-operation-registry.ts +482 -0
  176. package/lib/internal/task-orchestration.ts +12 -0
  177. package/lib/internal/task-override.ts +15 -9
  178. package/lib/internal/task-qualification.ts +61 -0
  179. package/lib/internal/task-review.ts +6 -4
  180. package/lib/internal/task-short-id.ts +10 -1
  181. package/lib/internal/task-snapshot.ts +3 -1
  182. package/lib/internal/task-validate.ts +6 -2
  183. package/lib/internal/task-verify.ts +10 -7
  184. package/lib/internal/task-warning.ts +10 -4
  185. package/lib/platform/adapters.ts +3 -2
  186. package/lib/platform/change-request-git-evidence.ts +36 -9
  187. package/lib/platform/comment-safety.ts +250 -0
  188. package/lib/platform/completion-backfill.ts +9 -8
  189. package/lib/platform/context.ts +97 -134
  190. package/lib/platform/github-client.ts +2 -2
  191. package/lib/platform/github-provider.ts +1132 -0
  192. package/lib/platform/in-label-sync.ts +208 -0
  193. package/lib/platform/issue-comments.ts +255 -80
  194. package/lib/platform/issues.ts +344 -174
  195. package/lib/platform/metadata-labels.ts +5 -2
  196. package/lib/platform/none-provider.ts +35 -0
  197. package/lib/platform/pr-change-report.ts +639 -0
  198. package/lib/platform/pr-checks.ts +126 -106
  199. package/lib/platform/pr-review.ts +88 -85
  200. package/lib/platform/pr-summary.ts +581 -53
  201. package/lib/platform/provider-bridge.ts +82 -0
  202. package/lib/platform/provider-contract.ts +611 -0
  203. package/lib/platform/provider-loader.ts +307 -0
  204. package/lib/platform/provider-validation.ts +611 -0
  205. package/lib/platform/pull-request-metadata.ts +10 -7
  206. package/lib/platform/pull-requests.ts +781 -550
  207. package/lib/platform/release-notes.ts +76 -59
  208. package/lib/platform/releases.ts +77 -43
  209. package/lib/platform/repository-metadata.ts +453 -0
  210. package/lib/platform/resource-identity.ts +121 -0
  211. package/lib/platform/security-alerts.ts +191 -0
  212. package/lib/platform/task-identities.ts +40 -0
  213. package/lib/platform/types.ts +4 -2
  214. package/lib/platform/verification-required.ts +11 -13
  215. package/lib/platform/verification-sync.ts +128 -304
  216. package/lib/pr-review/evidence-grading.ts +25 -8
  217. package/lib/process-data/index.ts +7 -0
  218. package/lib/run/index.ts +62 -22
  219. package/lib/sandbox/commands/control-status.ts +26 -0
  220. package/lib/sandbox/commands/create.ts +46 -6
  221. package/lib/sandbox/commands/ls.ts +7 -0
  222. package/lib/sandbox/commands/rm.ts +1000 -87
  223. package/lib/sandbox/commands/show.ts +16 -0
  224. package/lib/sandbox/control/client.ts +203 -19
  225. package/lib/sandbox/control/completed-reentry.ts +98 -0
  226. package/lib/sandbox/control/container-identity.ts +27 -43
  227. package/lib/sandbox/control/executor.ts +180 -15
  228. package/lib/sandbox/control/lifecycle.ts +629 -17
  229. package/lib/sandbox/control/native-file-lock.ts +209 -0
  230. package/lib/sandbox/control/protocol.ts +118 -2
  231. package/lib/sandbox/control/server.ts +724 -34
  232. package/lib/sandbox/control/state.ts +257 -4
  233. package/lib/sandbox/control/task-view.ts +240 -0
  234. package/lib/sandbox/engines/authority.ts +365 -0
  235. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  236. package/lib/sandbox/index.ts +7 -0
  237. package/lib/sandbox/recovery.ts +21 -1
  238. package/lib/sandbox/workspace-view.ts +9 -3
  239. package/lib/sandbox/worktree-safety.ts +4 -1
  240. package/lib/server/index.ts +10 -0
  241. package/lib/server/protocol.ts +36 -1
  242. package/lib/task/activity-log.ts +8 -0
  243. package/lib/task/artifact-lifecycle.ts +70 -22
  244. package/lib/task/artifact-operations.ts +626 -0
  245. package/lib/task/artifact-repair-intent.ts +71 -0
  246. package/lib/task/artifact-schema.ts +192 -0
  247. package/lib/task/capabilities.ts +331 -0
  248. package/lib/task/commands/status.ts +38 -0
  249. package/lib/task/commit-operation.ts +12 -1
  250. package/lib/task/control-authority.ts +22 -9
  251. package/lib/task/create-service.ts +139 -14
  252. package/lib/task/create.ts +27 -0
  253. package/lib/task/current-contract.ts +6 -1
  254. package/lib/task/decision-details.ts +6 -2
  255. package/lib/task/events.ts +392 -16
  256. package/lib/task/finalization.ts +50 -14
  257. package/lib/task/human-override.ts +70 -46
  258. package/lib/task/index.ts +16 -3
  259. package/lib/task/invalidation-command.ts +86 -0
  260. package/lib/task/invalidation.ts +332 -0
  261. package/lib/task/ledger-intents.ts +35 -1
  262. package/lib/task/local-artifact-finalization.ts +432 -0
  263. package/lib/task/orchestration.ts +223 -133
  264. package/lib/task/pr-delivery-fact.ts +131 -148
  265. package/lib/task/qualification-audit.ts +599 -0
  266. package/lib/task/qualification-confirmation.ts +117 -0
  267. package/lib/task/qualification-intents.ts +150 -0
  268. package/lib/task/review-artifacts.ts +21 -22
  269. package/lib/task/review-finalization.ts +133 -4
  270. package/lib/task/review-fingerprint.ts +23 -2
  271. package/lib/task/rework-intent.ts +165 -0
  272. package/lib/task/sections.ts +6 -4
  273. package/lib/task/skill-scope.ts +24 -0
  274. package/lib/task/task-execution-lock.ts +23 -14
  275. package/lib/task/verification-config.ts +12 -0
  276. package/lib/task/verification-engine.ts +103 -17
  277. package/lib/task/verification.ts +4 -4
  278. package/lib/task/workflow-warning-intents.ts +1 -1
  279. package/lib/task/write.ts +19 -0
  280. package/lib/update.ts +1 -1
  281. package/lib/version.ts +15 -1
  282. package/package.json +12 -1
  283. package/templates/.agents/rules/README.en.md +3 -1
  284. package/templates/.agents/rules/README.zh-CN.md +3 -1
  285. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  286. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  287. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  288. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  289. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  290. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  291. package/templates/.agents/rules/issue-sync.en.md +2 -0
  292. package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
  293. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  294. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  295. package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
  296. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
  297. package/templates/.agents/rules/pr-sync.en.md +10 -4
  298. package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
  299. package/templates/.agents/rules/security-alerts.en.md +8 -8
  300. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  301. package/templates/.agents/rules/task-short-id.en.md +1 -4
  302. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  303. package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
  304. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
  305. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  306. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  307. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  308. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  309. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  310. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  311. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  312. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  313. package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
  314. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
  315. package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
  316. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
  317. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  318. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  319. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  320. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  321. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  322. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  323. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  324. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  325. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  326. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  327. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
  328. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
  329. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
  330. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
  331. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  332. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  333. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
  334. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
  335. package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
  336. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
  337. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
  338. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
  339. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  340. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  341. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  342. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  343. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  344. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  345. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  346. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  347. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  348. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  349. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  350. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  351. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  352. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  353. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  354. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  355. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  356. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  357. package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
  358. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
  359. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  360. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  361. package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
  362. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
  363. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  364. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  365. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  366. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  367. package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
  368. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
  369. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  370. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  371. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  372. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  373. package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
  374. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
  375. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  376. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  377. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  378. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  379. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  380. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  381. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  382. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  383. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
  384. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
  385. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  386. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  387. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  388. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  389. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  390. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  391. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  392. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  393. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  394. package/templates/.agents/templates/task.en.md +24 -1
  395. package/templates/.agents/templates/task.zh-CN.md +24 -1
  396. package/templates/.github/workflows/pr-label.yml +7 -26
  397. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  398. package/templates/.agents/scripts/security-alerts.sh +0 -31
  399. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  400. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  401. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  402. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -5,10 +5,11 @@ 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
- const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <N> [--cwd <path>]
10
- agent-infra-internal platform-pr-review list --pr <N> [--cwd <path>]
11
- agent-infra-internal platform-pr-review publish --pr <N> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--dry-run] [--cwd <path>]
10
+ const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <token> [--cwd <path>]
11
+ agent-infra-internal platform-pr-review list --pr <token> [--cwd <path>]
12
+ agent-infra-internal platform-pr-review publish --pr <token> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--dry-run] [--cwd <path>]
12
13
  `;
13
14
 
14
15
  const BOOLEAN_FLAGS = new Set(['--dry-run']);
@@ -50,10 +51,15 @@ function readBodyFile(value: string, cwd: string): string {
50
51
  return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
51
52
  }
52
53
 
53
- function platformPrReview(args: string[] = []): void {
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;
@@ -65,21 +71,26 @@ function platformPrReview(args: string[] = []): void {
65
71
  };
66
72
  const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
67
73
  if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
68
- const pr = Number(values.pr);
69
- if (!Number.isInteger(pr) || pr <= 0) { fail(`${operation} requires a positive --pr`); return; }
70
- if (operation === 'inspect') {
71
- finish(inspectPlatformPullRequestByNumber(pr, { cwd }));
74
+ const pr = values.pr;
75
+ if (typeof pr !== 'string' || !pr) { fail(`${operation} requires --pr <token>`); return; }
76
+ if (internalHandlerRoute('platform-pr-review', 'inspect', operation)) {
77
+ finish(await inspectPlatformPullRequestByNumber(pr, { cwd }));
72
78
  return;
73
79
  }
74
- if (operation === 'list') {
75
- finish(listPrReviews(pr, { cwd }));
80
+ if (internalHandlerRoute('platform-pr-review', 'list', operation)) {
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; }
@@ -91,7 +102,7 @@ function platformPrReview(args: string[] = []): void {
91
102
  fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
92
103
  return;
93
104
  }
94
- finish(publishPrReview({
105
+ finish(await publishPrReview({
95
106
  cwd,
96
107
  prNumber: pr,
97
108
  identity: { scope, round, commitSha: commit },
@@ -8,24 +8,28 @@ import {
8
8
  inspectPlatformPullRequest,
9
9
  resolveExternalPullRequest,
10
10
  skipPlatformPullRequestFact,
11
- syncPlatformPullRequest
11
+ syncPlatformPullRequest,
12
+ syncPlatformPullRequestInLabels
12
13
  } from '../platform/pull-requests.ts';
13
14
  import type { PullRequestResult } from '../platform/pull-requests.ts';
14
- import { summaryContext, syncPullRequestSummary } from '../platform/pr-summary.ts';
15
+ import { reportWrite, summaryContext, syncPullRequestSummary } from '../platform/pr-summary.ts';
15
16
  import type { PlatformResult } from '../platform/types.ts';
17
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
16
18
 
17
19
  const USAGE = `Usage: agent-infra-internal platform-pr inspect <task-ref> [--cwd <path>]
18
- agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <N>] [--dry-run] [--cwd <path>]
20
+ agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <token>] [--dry-run] [--cwd <path>]
19
21
  agent-infra-internal platform-pr create <task-ref> --agent <agent> --base <branch> --head <branch> --title-file <path|-> --body-file <path|-> [--draft] [--dry-run] [--cwd <path>]
20
- agent-infra-internal platform-pr bind <task-ref> --pr <N> --agent <agent> [--dry-run] [--cwd <path>]
22
+ agent-infra-internal platform-pr bind <task-ref> --pr <token> --agent <agent> [--dry-run] [--cwd <path>]
21
23
  agent-infra-internal platform-pr skip <task-ref> --agent <agent> [--dry-run] [--cwd <path>]
22
24
  agent-infra-internal platform-pr sync <task-ref> --agent <agent> [--metadata] [--closing-issue] --result <pr_created|pr_reused|no_op> [--dry-run] [--cwd <path>]
25
+ agent-infra-internal platform-pr sync-in-labels --pr <N> [--dry-run] [--cwd <path>]
23
26
  agent-infra-internal platform-pr summary-context <task-ref> [--cwd <path>]
24
- agent-infra-internal platform-pr summary-sync <task-ref> --agent <agent> --body-file <path|-> --result <pr_created|pr_reused|no_op> [--dry-run] [--cwd <path>]
27
+ agent-infra-internal platform-pr change-report <task-ref> --agent <agent> --mechanical-file <path> --precheck-file <path> [--dry-run] [--cwd <path>]
28
+ agent-infra-internal platform-pr summary-sync <task-ref> --agent <agent> --body-file <path|-> --change-report-file <path> --result <pr_created|pr_reused|no_op> [--strict] [--dry-run] [--cwd <path>]
25
29
  `;
26
30
 
27
- const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue']);
28
- const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--pr', '--result']);
31
+ const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue', '--strict']);
32
+ const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--change-report-file', '--mechanical-file', '--precheck-file', '--pr', '--result']);
29
33
 
30
34
  function key(flag: string): string {
31
35
  return flag.slice(2).replace(/-([a-z])/g, (_, letter: string) => letter.toUpperCase());
@@ -63,10 +67,34 @@ function readFile(value: string, cwd: string): string {
63
67
  return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
64
68
  }
65
69
 
66
- function platformPr(args: string[] = []): void {
70
+ async function platformPr(args: string[] = []): Promise<void> {
71
+ if (!ensureInternalHandlerRoute('platform-pr', args)) return;
67
72
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
68
73
  const operation = args[0];
69
- if (!operation || !['inspect', 'resolve-external', 'create', 'bind', 'skip', 'sync', 'summary-context', 'summary-sync'].includes(operation)) { fail('a valid operation is required'); return; }
74
+ if (!operation || ![
75
+ internalHandlerRoute('platform-pr', 'inspect', operation),
76
+ internalHandlerRoute('platform-pr', 'resolve-external', operation),
77
+ internalHandlerRoute('platform-pr', 'create', operation),
78
+ internalHandlerRoute('platform-pr', 'bind', operation),
79
+ internalHandlerRoute('platform-pr', 'skip', operation),
80
+ internalHandlerRoute('platform-pr', 'sync', operation),
81
+ internalHandlerRoute('platform-pr', 'sync-in-labels', operation),
82
+ internalHandlerRoute('platform-pr', 'summary-context', operation),
83
+ internalHandlerRoute('platform-pr', 'change-report', operation),
84
+ internalHandlerRoute('platform-pr', 'summary-sync', operation)
85
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
86
+ if (internalHandlerRoute('platform-pr', 'sync-in-labels', operation)) {
87
+ const parsed = parse(args, 1);
88
+ if (parsed.error) { fail(parsed.error); return; }
89
+ const values = parsed.values;
90
+ const unexpected = Object.keys(values).find((name) => !['cwd', 'pr', 'dryRun'].includes(name));
91
+ if (unexpected) { fail(`sync-in-labels does not accept --${unexpected}`); return; }
92
+ const pr = Number(values.pr);
93
+ if (!Number.isInteger(pr) || pr <= 0) { fail('sync-in-labels requires a positive --pr'); return; }
94
+ const cwd = path.resolve(typeof values.cwd === 'string' ? values.cwd : process.cwd());
95
+ finish(await syncPlatformPullRequestInLabels(pr, { cwd, dryRun: values.dryRun === true }));
96
+ return;
97
+ }
70
98
  const taskRef = args[1];
71
99
  if (!taskRef || taskRef.startsWith('--')) { fail(`${operation} requires a task ref`); return; }
72
100
  const parsed = parse(args, 2);
@@ -80,19 +108,28 @@ function platformPr(args: string[] = []): void {
80
108
  bind: ['cwd', 'agent', 'pr', 'dryRun'],
81
109
  skip: ['cwd', 'agent', 'dryRun'],
82
110
  sync: ['cwd', 'agent', 'metadata', 'closingIssue', 'result', 'dryRun'],
111
+ 'sync-in-labels': ['cwd', 'pr', 'dryRun'],
83
112
  'summary-context': ['cwd'],
84
- 'summary-sync': ['cwd', 'agent', 'bodyFile', 'result', 'dryRun']
113
+ 'change-report': ['cwd', 'agent', 'mechanicalFile', 'precheckFile', 'dryRun'],
114
+ 'summary-sync': ['cwd', 'agent', 'bodyFile', 'changeReportFile', 'result', 'dryRun', 'strict']
85
115
  };
86
116
  const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
87
117
  if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
88
- if (operation === 'inspect') { finish(inspectPlatformPullRequest(taskRef, { cwd })); return; }
89
- if (operation === 'summary-context') { finish(summaryContext(taskRef, { cwd })); return; }
118
+ if (internalHandlerRoute('platform-pr', 'inspect', operation)) { finish(await inspectPlatformPullRequest(taskRef, { cwd })); return; }
119
+ if (internalHandlerRoute('platform-pr', 'summary-context', operation)) { finish(await summaryContext(taskRef, { cwd })); return; }
90
120
  if (typeof values.agent !== 'string' || !values.agent) { fail(`${operation} requires --agent`); return; }
91
121
  const agent = normalizeAgentToken(values.agent);
92
122
  if (!agent) { fail(`invalid --agent '${values.agent}': ${AGENT_USAGE_HINT}`); return; }
93
123
  values.agent = agent;
94
- if (operation === 'skip') {
95
- finish(skipPlatformPullRequestFact(taskRef, { cwd, agent, dryRun: values.dryRun === true }));
124
+ if (internalHandlerRoute('platform-pr', 'change-report', operation)) {
125
+ if (typeof values.mechanicalFile !== 'string' || typeof values.precheckFile !== 'string') { fail('change-report requires --mechanical-file and --precheck-file'); return; }
126
+ finish(await reportWrite(taskRef, {
127
+ cwd, agent: values.agent, mechanicalFile: values.mechanicalFile, precheckFile: values.precheckFile, dryRun: values.dryRun === true
128
+ }));
129
+ return;
130
+ }
131
+ if (internalHandlerRoute('platform-pr', 'skip', operation)) {
132
+ finish(await skipPlatformPullRequestFact(taskRef, { cwd, agent, dryRun: values.dryRun === true }));
96
133
  return;
97
134
  }
98
135
  const primaryResult = values.result === undefined ? undefined : values.result;
@@ -100,29 +137,30 @@ function platformPr(args: string[] = []): void {
100
137
  fail('--result must be pr_created, pr_reused, or no_op');
101
138
  return;
102
139
  }
103
- if (operation === 'resolve-external') {
104
- const pr = values.pr === undefined ? undefined : Number(values.pr);
105
- if (pr !== undefined && (!Number.isInteger(pr) || pr <= 0)) { fail('resolve-external requires a positive --pr'); return; }
106
- finish(resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
140
+ if (internalHandlerRoute('platform-pr', 'resolve-external', operation)) {
141
+ const pr = values.pr === undefined ? undefined : values.pr;
142
+ if (pr !== undefined && (typeof pr !== 'string' || !pr)) { fail('resolve-external requires --pr <token>'); return; }
143
+ finish(await resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
107
144
  return;
108
145
  }
109
- if (operation === 'bind') {
110
- const pr = Number(values.pr);
111
- if (!Number.isInteger(pr) || pr <= 0) { fail('bind requires a positive --pr'); return; }
112
- finish(bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
146
+ if (internalHandlerRoute('platform-pr', 'bind', operation)) {
147
+ const pr = values.pr;
148
+ if (typeof pr !== 'string' || !pr) { fail('bind requires --pr <token>'); return; }
149
+ finish(await bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
113
150
  return;
114
151
  }
115
- if (operation === 'sync') {
152
+ if (internalHandlerRoute('platform-pr', 'sync', operation)) {
116
153
  if (values.metadata !== true && values.closingIssue !== true) { fail('sync requires --metadata or --closing-issue'); return; }
117
154
  if (!primaryResult) { fail('sync requires --result pr_created, pr_reused, or no_op'); return; }
118
- finish(syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
155
+ finish(await syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
119
156
  return;
120
157
  }
121
- if (operation === 'summary-sync') {
158
+ if (internalHandlerRoute('platform-pr', 'summary-sync', operation)) {
122
159
  if (typeof values.bodyFile !== 'string') { fail('summary-sync requires --body-file'); return; }
160
+ if (typeof values.changeReportFile !== 'string') { fail('summary-sync requires --change-report-file'); return; }
123
161
  if (!primaryResult) { fail('summary-sync requires --result pr_created, pr_reused, or no_op'); return; }
124
162
  try {
125
- finish(syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
163
+ finish(await syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), changeReportFile: values.changeReportFile, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true, strict: values.strict === true }));
126
164
  } catch (error) {
127
165
  fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
128
166
  }
@@ -133,7 +171,7 @@ function platformPr(args: string[] = []): void {
133
171
  return;
134
172
  }
135
173
  try {
136
- finish(createPlatformPullRequest(taskRef, {
174
+ finish(await createPlatformPullRequest(taskRef, {
137
175
  cwd, agent: values.agent, base: values.base, head: values.head,
138
176
  title: readFile(values.titleFile, cwd), body: readFile(values.bodyFile, cwd),
139
177
  draft: values.draft === true, dryRun: values.dryRun === true
@@ -2,6 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
4
  import { publishReleaseNotes, releaseNoteContext, stageReleaseNotes } from '../platform/release-notes.ts';
5
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
5
6
 
6
7
  type ParsedOptions = Readonly<{ values: ReadonlyMap<string, string>; switches: ReadonlySet<string> }>;
7
8
 
@@ -36,14 +37,15 @@ function finish(result: { status: string; [key: string]: unknown }): void {
36
37
  process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
37
38
  }
38
39
 
39
- function platformReleaseNotes(args: string[] = []): void {
40
+ async function platformReleaseNotes(args: string[] = []): Promise<void> {
41
+ if (!ensureInternalHandlerRoute('platform-release-notes', args)) return;
40
42
  const [action, ...rest] = args;
41
- if (action === 'context') {
43
+ if (internalHandlerRoute('platform-release-notes', 'context', action ?? '')) {
42
44
  const parsed = parseOptions(rest, ['--cwd', '--history-limit', '--from-tag', '--to-tag', '--branch']);
43
45
  if (!parsed) return finish(invalidInput('invalid context options'));
44
46
  const cwd = path.resolve(parsed.values.get('--cwd') || process.cwd());
45
47
  const historyRaw = parsed.values.get('--history-limit') ?? null;
46
- finish(releaseNoteContext({
48
+ finish(await releaseNoteContext({
47
49
  fromTag: parsed.values.get('--from-tag') || '',
48
50
  toTag: parsed.values.get('--to-tag') || '',
49
51
  branch: parsed.values.get('--branch') || '',
@@ -51,7 +53,7 @@ function platformReleaseNotes(args: string[] = []): void {
51
53
  }, { cwd }));
52
54
  return;
53
55
  }
54
- if (action === 'stage') {
56
+ if (internalHandlerRoute('platform-release-notes', 'stage', action ?? '')) {
55
57
  const parsed = parseOptions(rest, ['--cwd', '--notes-file']);
56
58
  if (!parsed) return finish(invalidInput('invalid stage options'));
57
59
  const notesFile = parsed.values.get('--notes-file');
@@ -62,7 +64,7 @@ function platformReleaseNotes(args: string[] = []): void {
62
64
  ));
63
65
  return;
64
66
  }
65
- if (action === 'publish') {
67
+ if (internalHandlerRoute('platform-release-notes', 'publish', action ?? '')) {
66
68
  const parsed = parseOptions(
67
69
  rest,
68
70
  ['--cwd', '--notes-file', '--tag', '--title', '--expected-sha256'],
@@ -80,7 +82,7 @@ function platformReleaseNotes(args: string[] = []): void {
80
82
  fs.writeFileSync(resolvedNotesPath, fs.readFileSync(0));
81
83
  }
82
84
  try {
83
- finish(publishReleaseNotes({
85
+ finish(await publishReleaseNotes({
84
86
  tag: parsed.values.get('--tag') || '',
85
87
  title: parsed.values.get('--title') || parsed.values.get('--tag') || '',
86
88
  notesFile: resolvedNotesPath,
@@ -0,0 +1,83 @@
1
+ import path from 'node:path';
2
+
3
+ import { dismissSecurityAlert, readCommentFile, readSecurityAlert } from '../platform/security-alerts.ts';
4
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
5
+
6
+ const USAGE = `Usage: agent-infra-internal platform-security read --kind <dependabot|code-scanning> --number <number> [--cwd <path>]
7
+ agent-infra-internal platform-security dismiss --kind <dependabot|code-scanning> --number <number> --reason <reason> --comment-file <path> [--cwd <path>]
8
+ `;
9
+
10
+ function fail(message: string): void {
11
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SECURITY_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 }): void {
17
+ process.stdout.write(`${JSON.stringify(result)}\n`);
18
+ process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
19
+ }
20
+
21
+ function parseOptions(args: string[]): { values: Map<string, string>; switches: Set<string> } | null {
22
+ const values = new Map<string, string>();
23
+ const switches = new Set<string>();
24
+ const valueFlags = new Set(['--cwd', '--kind', '--number', '--reason', '--comment-file']);
25
+ for (let index = 0; index < args.length; index += 1) {
26
+ const flag = args[index]!;
27
+ if (flag === '--help' || flag === '-h') return null;
28
+ if (!valueFlags.has(flag) || values.has(flag) || switches.has(flag)) return null;
29
+ const value = args[++index];
30
+ if (!value || value.startsWith('--')) return null;
31
+ values.set(flag, value);
32
+ }
33
+ return { values, switches };
34
+ }
35
+
36
+ function required(values: Map<string, string>, flag: string): string | null {
37
+ const value = values.get(flag);
38
+ return value && !value.startsWith('--') ? value : null;
39
+ }
40
+
41
+ async function platformSecurity(args: string[] = []): Promise<void> {
42
+ if (!ensureInternalHandlerRoute('platform-security', args)) return;
43
+ if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
44
+ const action = args[0];
45
+ if (!internalHandlerRoute('platform-security', 'read', action ?? '')
46
+ && !internalHandlerRoute('platform-security', 'dismiss', action ?? '')) {
47
+ fail('a valid operation is required');
48
+ return;
49
+ }
50
+ if (action !== 'read' && action !== 'dismiss') { fail('a valid operation is required'); return; }
51
+ const parsed = parseOptions(args.slice(1));
52
+ if (!parsed) { fail('invalid security alert options'); return; }
53
+ const kind = required(parsed.values, '--kind');
54
+ const numberRaw = required(parsed.values, '--number');
55
+ const cwd = path.resolve(required(parsed.values, '--cwd') || process.cwd());
56
+ if (!kind || !numberRaw) { fail(`${action} requires --kind and --number`); return; }
57
+ const number = Number(numberRaw);
58
+ if (!Number.isSafeInteger(number) || number <= 0) { fail('--number must be a positive integer'); return; }
59
+
60
+ if (action === 'read') {
61
+ if ([...parsed.values.keys()].some((flag) => !['--kind', '--number', '--cwd'].includes(flag))) {
62
+ fail('read does not accept dismissal options');
63
+ return;
64
+ }
65
+ finish(await readSecurityAlert({ kind: kind as 'dependabot' | 'code-scanning', number }, { cwd }));
66
+ return;
67
+ }
68
+
69
+ const reason = required(parsed.values, '--reason');
70
+ const commentFile = required(parsed.values, '--comment-file');
71
+ if (!reason || !commentFile) { fail('dismiss requires --reason and --comment-file'); return; }
72
+ const comment = readCommentFile(commentFile, cwd);
73
+ if (!comment.ok) {
74
+ finish({ status: 'failed', changed: false, error: comment.error });
75
+ return;
76
+ }
77
+ finish(await dismissSecurityAlert(
78
+ { kind: kind as 'dependabot' | 'code-scanning', number, reason, comment: comment.value },
79
+ { cwd }
80
+ ));
81
+ }
82
+
83
+ export { platformSecurity };
@@ -11,9 +11,10 @@ import {
11
11
  import type { DecisionRecord, HostResolution } from '../pr-review/evidence-grading.ts';
12
12
  import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.ts';
13
13
  import { verifyInProcess } from '../task/verification-engine.ts';
14
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
14
15
 
15
16
  const USAGE = `Usage: agent-infra-internal pr-review-grade decide --input-file <path|-> [--cwd <path>]
16
- agent-infra-internal pr-review-grade resolve-host --pr <N> [--cwd <path>]
17
+ agent-infra-internal pr-review-grade resolve-host --pr <token> [--cwd <path>]
17
18
  agent-infra-internal pr-review-grade verify-artifact --artifact-file <path> [--cwd <path>]
18
19
  `;
19
20
 
@@ -49,10 +50,15 @@ function readInput(value: string, cwd: string): string {
49
50
  return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
50
51
  }
51
52
 
52
- function prReviewGrade(args: string[] = []): void {
53
+ async function prReviewGrade(args: string[] = []): Promise<void> {
54
+ if (!ensureInternalHandlerRoute('pr-review-grade', args)) return;
53
55
  if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
54
56
  const operation = args[0];
55
- if (!operation || !['decide', 'resolve-host', 'verify-artifact'].includes(operation)) { fail('a valid operation is required'); return; }
57
+ if (!operation || ![
58
+ internalHandlerRoute('pr-review-grade', 'decide', operation),
59
+ internalHandlerRoute('pr-review-grade', 'resolve-host', operation),
60
+ internalHandlerRoute('pr-review-grade', 'verify-artifact', operation)
61
+ ].some(Boolean)) { fail('a valid operation is required'); return; }
56
62
  const parsed = parseFlags(args, 1);
57
63
  if (parsed.error) { fail(parsed.error); return; }
58
64
  const values = parsed.values;
@@ -65,7 +71,7 @@ function prReviewGrade(args: string[] = []): void {
65
71
  const unexpected = Object.keys(values).find((key) => !allowed[operation]!.includes(key));
66
72
  if (unexpected) { fail(`${operation} does not accept '--${unexpected}'`); return; }
67
73
 
68
- if (operation === 'decide') {
74
+ if (internalHandlerRoute('pr-review-grade', 'decide', operation)) {
69
75
  if (typeof values.inputFile !== 'string') { fail('decide requires --input-file'); return; }
70
76
  let input: unknown;
71
77
  try {
@@ -84,10 +90,10 @@ function prReviewGrade(args: string[] = []): void {
84
90
  return;
85
91
  }
86
92
 
87
- if (operation === 'resolve-host') {
88
- const pr = Number(values.pr);
89
- if (!Number.isInteger(pr) || pr <= 0) { fail('resolve-host requires a positive --pr'); return; }
90
- const inspected = inspectPlatformPullRequestByNumber(pr, { cwd });
93
+ if (internalHandlerRoute('pr-review-grade', 'resolve-host', operation)) {
94
+ const pr = typeof values.pr === 'string' ? values.pr : '';
95
+ if (!pr) { fail('resolve-host requires --pr <token>'); return; }
96
+ const inspected = await inspectPlatformPullRequestByNumber(pr, { cwd });
91
97
  if (!inspected.pullRequest) {
92
98
  finish({
93
99
  status: 'failed', changed: false, host: null, candidates: [], closingIssues: [],
@@ -95,23 +101,26 @@ function prReviewGrade(args: string[] = []): void {
95
101
  }, inspected.status === 'blocked' ? 2 : 1);
96
102
  return;
97
103
  }
104
+ const prNumber = inspected.pullRequest.number;
105
+ const prIdentity = inspected.pullRequest.identity || { kind: 'number' as const, value: prNumber };
98
106
  const closingIssues = extractClosingIssueNumbers(inspected.pullRequest.body);
99
- const candidates = collectHostCandidates({ prNumber: pr, closingIssues, workspaceRoot: cwd });
107
+ const candidates = collectHostCandidates({ prNumber, prIdentity, closingIssues, workspaceRoot: cwd });
100
108
  const host: HostResolution = resolveHostFromCandidates(candidates);
101
109
  finish({
102
110
  status: 'ok', changed: false,
103
- pr: { number: pr, baseSha: inspected.pullRequest.base.sha, headSha: inspected.pullRequest.head.sha, state: inspected.pullRequest.state },
111
+ pr: { number: prNumber, identity: prIdentity, baseSha: inspected.pullRequest.base.sha, headSha: inspected.pullRequest.head.sha, state: inspected.pullRequest.state },
104
112
  closingIssues, candidates, host,
105
113
  taskIssueMatches: deriveTaskIssueMatches(host, closingIssues), error: null
106
114
  });
107
115
  return;
108
116
  }
109
117
 
118
+ if (!internalHandlerRoute('pr-review-grade', 'verify-artifact', operation)) { fail('operation is not registered'); return; }
110
119
  if (typeof values.artifactFile !== 'string') { fail('verify-artifact requires --artifact-file'); return; }
111
120
  const artifactPath = path.resolve(cwd, values.artifactFile);
112
121
  let result: Record<string, unknown>;
113
122
  try {
114
- result = verifyInProcess({
123
+ result = await verifyInProcess({
115
124
  mode: 'checks',
116
125
  skillName: 'review-pr',
117
126
  taskDir: path.dirname(artifactPath),
@@ -9,6 +9,7 @@ import { inspectPlatformRelease, reconcileReleaseMilestones } from '../platform/
9
9
  import { inspectHomebrewChannel, inspectNpmChannel } from '../release/channels.ts';
10
10
  import { releaseSnapshot } from '../release/workflow.ts';
11
11
  import type { PostReleaseFacts, ReleaseFacts } from '../release/workflow.ts';
12
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
12
13
 
13
14
  function command(cwd: string, executable: string, args: string[]) {
14
15
  return spawnSync(executable, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
@@ -251,7 +252,7 @@ async function inspectFacts(cwd: string, version: string): Promise<ReleaseFacts>
251
252
  const local = inspectLocalReleaseFacts(cwd, version);
252
253
  const remoteBranch = branch ? git(cwd, ['ls-remote', '--heads', 'origin', branch]) : null;
253
254
  const remoteTag = git(cwd, ['ls-remote', '--tags', 'origin', `refs/tags/${tag}`]);
254
- const platform = inspectPlatformRelease(tag, { cwd });
255
+ const platform = await inspectPlatformRelease(tag, { cwd });
255
256
  const npm = await inspectNpmChannel(pkg.name, version);
256
257
  const formulaUrl = `https://raw.githubusercontent.com/${config.org}/homebrew-tap/main/Formula/${config.project}.rb`;
257
258
  const homebrew = await inspectHomebrewChannel(formulaUrl, version);
@@ -262,7 +263,7 @@ async function inspectFacts(cwd: string, version: string): Promise<ReleaseFacts>
262
263
  localTagAncestor: local.localTagAncestor,
263
264
  localTagConflict: local.localTagConflict,
264
265
  remoteBranch: Boolean(remoteBranch && remoteBranch.split(/\s+/)[0] === head), remoteTag: Boolean(remoteTag),
265
- githubRelease: platform.platform.type !== 'github'
266
+ githubRelease: platform.error?.code === 'PLATFORM_CAPABILITY_UNSUPPORTED'
266
267
  ? true
267
268
  : platform.status === 'blocked' ? null : Boolean(platform.release?.published),
268
269
  npm: npm.published, homebrew: homebrew.published, smoke,
@@ -312,19 +313,26 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
312
313
  const version = String(rawVersion || '').replace(/^v/, '');
313
314
  const cwdIndex = rest.indexOf('--cwd');
314
315
  const cwd = path.resolve(cwdIndex >= 0 && rest[cwdIndex + 1] ? rest[cwdIndex + 1]! : process.cwd());
315
- if (!['inspect', 'prepare', 'publish', 'post-prepare', 'post-publish'].includes(action || '') || !semver.valid(version)) {
316
+ if (![
317
+ internalHandlerRoute('release-workflow', 'inspect', action || ''),
318
+ internalHandlerRoute('release-workflow', 'prepare', action || ''),
319
+ internalHandlerRoute('release-workflow', 'publish', action || ''),
320
+ internalHandlerRoute('release-workflow', 'post-prepare', action || ''),
321
+ internalHandlerRoute('release-workflow', 'post-publish', action || '')
322
+ ].some(Boolean) || !semver.valid(version)) {
316
323
  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`);
317
324
  process.exitCode = 1; return;
318
325
  }
326
+ if (!ensureInternalHandlerRoute('release-workflow', args)) return;
319
327
  const before = releaseSnapshot(version, await inspectFacts(cwd, version));
320
- if (action === 'inspect') { process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`); return; }
328
+ if (internalHandlerRoute('release-workflow', 'inspect', action || '')) { process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`); return; }
321
329
  if (before.facts.localTagConflict) {
322
330
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'GIT_TAG_CONFLICT', message: `Tag v${version} is not reachable from HEAD` } })}\n`);
323
331
  process.exitCode = 1; return;
324
332
  }
325
- if (action === 'prepare') {
333
+ if (internalHandlerRoute('release-workflow', 'prepare', action || '')) {
326
334
  if (before.phase !== 'unprepared') {
327
- const milestones = reconcileReleaseMilestones(version, { cwd });
335
+ const milestones = await reconcileReleaseMilestones(version, { cwd });
328
336
  process.stdout.write(`${JSON.stringify({ ...milestones, snapshot: before })}\n`);
329
337
  process.exitCode = milestones.status === 'failed' ? 1 : milestones.status === 'blocked' ? 2 : 0;
330
338
  return;
@@ -344,7 +352,7 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
344
352
  const committed = commitExplicitPaths({ cwd, paths: changedPaths(cwd), message: `chore: release v${version}` });
345
353
  if (committed.status === 'failed') { process.stdout.write(`${JSON.stringify(committed)}\n`); process.exitCode = 1; return; }
346
354
  const tagged = command(cwd, 'git', ['tag', '-a', `v${version}`, '-m', `Release v${version}`]);
347
- const milestones = tagged.status === 0 ? reconcileReleaseMilestones(version, { cwd }) : null;
355
+ const milestones = tagged.status === 0 ? await reconcileReleaseMilestones(version, { cwd }) : null;
348
356
  const snapshot = releaseSnapshot(version, await inspectFacts(cwd, version));
349
357
  const failed = tagged.status !== 0 || milestones?.status === 'failed';
350
358
  const blocked = milestones?.status === 'blocked';
@@ -352,14 +360,14 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
352
360
  process.stdout.write(`${JSON.stringify({ status, changed: true, snapshot, operations: milestones?.operations ?? [], error: tagged.status !== 0 ? { code: 'GIT_TAG_FAILED', message: String(tagged.stderr) } : milestones?.error ?? null })}\n`);
353
361
  process.exitCode = failed ? 1 : blocked ? 2 : 0; return;
354
362
  }
355
- if (action === 'publish') {
363
+ if (internalHandlerRoute('release-workflow', 'publish', action || '')) {
356
364
  if (!before.facts.localTag || !['prepared', 'partially-published'].includes(before.phase)) { process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_PHASE_INVALID', message: `Cannot publish from ${before.phase}` } })}\n`); process.exitCode = 1; return; }
357
365
  const branch = git(cwd, ['branch', '--show-current']) || '';
358
366
  const refs = [...(!before.facts.remoteBranch ? [branch] : []), ...(!before.facts.remoteTag ? [`refs/tags/v${version}`] : [])];
359
367
  const result = pushGitRefs({ cwd, remote: 'origin', refs });
360
368
  process.stdout.write(`${JSON.stringify({ ...result, snapshot: releaseSnapshot(version, await inspectFacts(cwd, version)) })}\n`); process.exitCode = result.status === 'failed' ? 1 : result.status === 'degraded' ? 2 : 0; return;
361
369
  }
362
- if (action === 'post-publish') {
370
+ if (internalHandlerRoute('release-workflow', 'post-publish', action || '')) {
363
371
  const expectedValues = optionValues(rest, '--expected-sha256');
364
372
  if (expectedValues.length !== 1 || !/^sha256:[0-9a-f]{64}$/.test(expectedValues[0]!)) {
365
373
  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`);
@@ -394,6 +402,10 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
394
402
  process.exitCode = blocked ? 2 : 1; return;
395
403
  }
396
404
 
405
+ if (!internalHandlerRoute('release-workflow', 'post-prepare', action || '')) {
406
+ process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_INPUT_INVALID', message: 'release-workflow action is not registered' } })}\n`);
407
+ process.exitCode = 1; return;
408
+ }
397
409
  if (before.phase === 'complete') {
398
410
  process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`);
399
411
  return;