@fitlab-ai/agent-infra 0.9.14 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/internal-cli.sh +45 -0
  4. package/dist/bin/internal-cli.js +93 -30
  5. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  6. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +9 -4
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +43 -3
  8. package/dist/lib/defaults.json +103 -103
  9. package/dist/lib/fs/durable-write.js +39 -0
  10. package/dist/lib/fs/file-lock.js +111 -0
  11. package/dist/lib/host-control/audit.js +19 -0
  12. package/dist/lib/host-control/client.js +142 -0
  13. package/dist/lib/host-control/command.js +49 -0
  14. package/dist/lib/host-control/path.js +160 -0
  15. package/dist/lib/host-control/secure-fs.js +140 -0
  16. package/dist/lib/host-control/server.js +159 -0
  17. package/dist/lib/host-control/service.js +112 -0
  18. package/dist/lib/init.js +11 -2
  19. package/dist/lib/internal/cli-route-inventory.js +4 -2
  20. package/dist/lib/internal/codex-lifecycle.js +6 -6
  21. package/dist/lib/internal/demo-promotion.js +322 -0
  22. package/dist/lib/internal/demo-transcript.js +454 -0
  23. package/dist/lib/internal/host-control.js +28 -0
  24. package/dist/lib/internal/manual-validation.js +331 -0
  25. package/dist/lib/internal/platform-pr.js +18 -4
  26. package/dist/lib/internal/release-workflow.js +63 -84
  27. package/dist/lib/internal/sandbox-control.js +149 -2
  28. package/dist/lib/internal/task-artifact.js +16 -263
  29. package/dist/lib/internal/task-create.js +6 -5
  30. package/dist/lib/internal/task-event.js +37 -37
  31. package/dist/lib/internal/task-lifecycle.js +2 -2
  32. package/dist/lib/internal/task-operation-registry.js +101 -4
  33. package/dist/lib/internal/task-review.js +11 -56
  34. package/dist/lib/internal/task-validate.js +30 -10
  35. package/dist/lib/owned-path.js +33 -0
  36. package/dist/lib/platform/check-status.js +11 -0
  37. package/dist/lib/platform/comment-safety.js +4 -1
  38. package/dist/lib/platform/completion-backfill.js +1 -1
  39. package/dist/lib/platform/github-data.js +241 -0
  40. package/dist/lib/platform/github-provider.js +15 -20
  41. package/dist/lib/platform/issue-comments.js +18 -12
  42. package/dist/lib/platform/issues.js +2 -180
  43. package/dist/lib/platform/pr-change-report.js +5 -4
  44. package/dist/lib/platform/pr-checks.js +12 -65
  45. package/dist/lib/platform/pr-summary.js +117 -33
  46. package/dist/lib/platform/pull-requests.js +5 -108
  47. package/dist/lib/platform/snapshots.js +2 -0
  48. package/dist/lib/platform/task-identities.js +2 -9
  49. package/dist/lib/platform/verification-sync.js +132 -143
  50. package/dist/lib/pr-review/evidence-grading.js +4 -8
  51. package/dist/lib/release/workflow.js +1 -1
  52. package/dist/lib/sandbox/commands/create.js +7 -2
  53. package/dist/lib/sandbox/commands/rm.js +19 -1511
  54. package/dist/lib/sandbox/control/audit.js +203 -0
  55. package/dist/lib/sandbox/control/client.js +93 -54
  56. package/dist/lib/sandbox/control/executor.js +129 -65
  57. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  58. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  59. package/dist/lib/sandbox/control/lifecycle.js +36 -2
  60. package/dist/lib/sandbox/control/native-file-lock.js +6 -98
  61. package/dist/lib/sandbox/control/protocol.js +55 -4
  62. package/dist/lib/sandbox/control/server.js +518 -127
  63. package/dist/lib/sandbox/control/state.js +64 -0
  64. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  65. package/dist/lib/sandbox/control/workflow-executor.js +89 -0
  66. package/dist/lib/sandbox/index.js +1 -2
  67. package/dist/lib/sandbox/recovery.js +28 -4
  68. package/dist/lib/sandbox/removal.js +822 -0
  69. package/dist/lib/sandbox/task-cleanup.js +217 -0
  70. package/dist/lib/sandbox/workspace-identity.js +17 -1
  71. package/dist/lib/sandbox/workspace-view.js +13 -14
  72. package/dist/lib/task/activity-intent.js +2 -1
  73. package/dist/lib/task/activity-log.js +30 -24
  74. package/dist/lib/task/artifact-command.js +79 -0
  75. package/dist/lib/task/artifact-lifecycle.js +30 -28
  76. package/dist/lib/task/artifact-name.js +36 -0
  77. package/dist/lib/task/artifact-operations.js +29 -289
  78. package/dist/lib/task/artifact-receipts.js +3 -15
  79. package/dist/lib/task/artifact-recovery.js +430 -0
  80. package/dist/lib/task/artifact-repair-intent.js +134 -29
  81. package/dist/lib/task/artifact-schema.js +6 -14
  82. package/dist/lib/task/capabilities.js +12 -19
  83. package/dist/lib/task/codex-orchestration.js +71 -25
  84. package/dist/lib/task/commit-identity.js +28 -0
  85. package/dist/lib/task/commit-operation.js +33 -20
  86. package/dist/lib/task/control-authority.js +403 -6
  87. package/dist/lib/task/control-recovery.js +140 -0
  88. package/dist/lib/task/create-service.js +1 -8
  89. package/dist/lib/task/create.js +62 -9
  90. package/dist/lib/task/decision-details.js +2 -46
  91. package/dist/lib/task/delegation-receipts.js +64 -3
  92. package/dist/lib/task/events.js +275 -22
  93. package/dist/lib/task/finalization-state.js +9 -0
  94. package/dist/lib/task/human-override.js +8 -14
  95. package/dist/lib/task/implementation-inputs.js +3 -3
  96. package/dist/lib/task/intermediate-cleanup.js +441 -0
  97. package/dist/lib/task/invalidation.js +18 -65
  98. package/dist/lib/task/ledger-intents.js +7 -22
  99. package/dist/lib/task/ledger.js +1 -3
  100. package/dist/lib/task/lifecycle-recovery.js +549 -0
  101. package/dist/lib/task/lifecycle.js +31 -4
  102. package/dist/lib/task/local-artifact-finalization.js +197 -197
  103. package/dist/lib/task/manual-validation-completion.js +26 -0
  104. package/dist/lib/task/manual-validation-evidence.js +130 -0
  105. package/dist/lib/task/manual-validation-receipt.js +105 -0
  106. package/dist/lib/task/manual-validation-shared.js +40 -0
  107. package/dist/lib/task/manual-validation-transaction.js +243 -0
  108. package/dist/lib/task/markdown.js +47 -0
  109. package/dist/lib/task/orchestration.js +66 -19
  110. package/dist/lib/task/pr-delivery-fact.js +12 -56
  111. package/dist/lib/task/qualification-audit.js +20 -34
  112. package/dist/lib/task/recovery-warning.js +19 -0
  113. package/dist/lib/task/review-artifacts.js +2 -18
  114. package/dist/lib/task/review-command.js +26 -0
  115. package/dist/lib/task/review-finalization.js +175 -216
  116. package/dist/lib/task/review-fingerprint.js +2 -2
  117. package/dist/lib/task/sections.js +34 -56
  118. package/dist/lib/task/short-id.js +15 -7
  119. package/dist/lib/task/task-execution-lock.js +1 -1
  120. package/dist/lib/task/verification-engine.js +119 -337
  121. package/dist/lib/task/verification.js +1 -1
  122. package/dist/lib/task/workflow-command.js +16 -0
  123. package/dist/lib/task/workflow-warning-intents.js +0 -16
  124. package/dist/lib/task/workflow-warnings.js +28 -2
  125. package/dist/lib/update.js +2 -0
  126. package/dist/lib/version.js +1 -11
  127. package/dist/lifecycle-build-manifest.json +3 -3
  128. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  129. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +10 -4
  130. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +55 -3
  131. package/lib/fs/durable-write.ts +30 -0
  132. package/lib/fs/file-lock.ts +113 -0
  133. package/lib/host-control/audit.ts +22 -0
  134. package/lib/host-control/client.ts +172 -0
  135. package/lib/host-control/command.ts +60 -0
  136. package/lib/host-control/path.ts +167 -0
  137. package/lib/host-control/secure-fs.ts +135 -0
  138. package/lib/host-control/server.ts +180 -0
  139. package/lib/host-control/service.ts +133 -0
  140. package/lib/init.ts +15 -2
  141. package/lib/internal/cli-route-inventory.ts +4 -2
  142. package/lib/internal/codex-lifecycle.ts +6 -6
  143. package/lib/internal/demo-promotion.ts +354 -0
  144. package/lib/internal/demo-transcript.ts +419 -0
  145. package/lib/internal/host-control.ts +28 -0
  146. package/lib/internal/manual-validation.ts +315 -0
  147. package/lib/internal/platform-pr.ts +15 -4
  148. package/lib/internal/release-workflow.ts +74 -82
  149. package/lib/internal/sandbox-control.ts +162 -1
  150. package/lib/internal/task-artifact.ts +14 -217
  151. package/lib/internal/task-create.ts +5 -5
  152. package/lib/internal/task-event.ts +20 -11
  153. package/lib/internal/task-lifecycle.ts +4 -3
  154. package/lib/internal/task-operation-registry.ts +111 -4
  155. package/lib/internal/task-review.ts +9 -54
  156. package/lib/internal/task-validate.ts +26 -10
  157. package/lib/owned-path.ts +26 -0
  158. package/lib/platform/check-status.ts +9 -0
  159. package/lib/platform/comment-safety.ts +5 -0
  160. package/lib/platform/completion-backfill.ts +1 -1
  161. package/lib/platform/github-data.ts +322 -0
  162. package/lib/platform/github-provider.ts +15 -20
  163. package/lib/platform/issue-comments.ts +21 -14
  164. package/lib/platform/issues.ts +5 -246
  165. package/lib/platform/pr-change-report.ts +7 -5
  166. package/lib/platform/pr-checks.ts +13 -77
  167. package/lib/platform/pr-summary.ts +123 -35
  168. package/lib/platform/pull-requests.ts +6 -173
  169. package/lib/platform/snapshots.ts +53 -0
  170. package/lib/platform/task-identities.ts +3 -14
  171. package/lib/platform/verification-sync.ts +150 -156
  172. package/lib/pr-review/evidence-grading.ts +4 -9
  173. package/lib/release/workflow.ts +3 -3
  174. package/lib/sandbox/commands/create.ts +7 -6
  175. package/lib/sandbox/commands/rm.ts +21 -1895
  176. package/lib/sandbox/control/audit.ts +253 -0
  177. package/lib/sandbox/control/client.ts +109 -66
  178. package/lib/sandbox/control/executor.ts +134 -74
  179. package/lib/sandbox/control/finalization-response.ts +29 -0
  180. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  181. package/lib/sandbox/control/lifecycle.ts +45 -3
  182. package/lib/sandbox/control/native-file-lock.ts +6 -107
  183. package/lib/sandbox/control/protocol.ts +80 -6
  184. package/lib/sandbox/control/server.ts +567 -132
  185. package/lib/sandbox/control/state.ts +86 -0
  186. package/lib/sandbox/control/task-workflow.ts +95 -0
  187. package/lib/sandbox/control/workflow-executor.ts +92 -0
  188. package/lib/sandbox/index.ts +1 -2
  189. package/lib/sandbox/recovery.ts +28 -5
  190. package/lib/sandbox/removal.ts +1142 -0
  191. package/lib/sandbox/task-cleanup.ts +209 -0
  192. package/lib/sandbox/workspace-identity.ts +19 -3
  193. package/lib/sandbox/workspace-view.ts +17 -15
  194. package/lib/task/activity-intent.ts +2 -2
  195. package/lib/task/activity-log.ts +27 -19
  196. package/lib/task/artifact-command.ts +85 -0
  197. package/lib/task/artifact-lifecycle.ts +31 -26
  198. package/lib/task/artifact-name.ts +55 -0
  199. package/lib/task/artifact-operations.ts +34 -310
  200. package/lib/task/artifact-receipts.ts +3 -14
  201. package/lib/task/artifact-recovery.ts +519 -0
  202. package/lib/task/artifact-repair-intent.ts +162 -33
  203. package/lib/task/artifact-schema.ts +5 -34
  204. package/lib/task/capabilities.ts +13 -22
  205. package/lib/task/codex-orchestration.ts +85 -24
  206. package/lib/task/commit-identity.ts +31 -0
  207. package/lib/task/commit-operation.ts +37 -20
  208. package/lib/task/control-authority.ts +540 -10
  209. package/lib/task/control-recovery.ts +186 -0
  210. package/lib/task/create-service.ts +1 -10
  211. package/lib/task/create.ts +63 -8
  212. package/lib/task/decision-details.ts +3 -71
  213. package/lib/task/delegation-receipts.ts +73 -2
  214. package/lib/task/events.ts +309 -24
  215. package/lib/task/finalization-state.ts +11 -0
  216. package/lib/task/human-override.ts +8 -16
  217. package/lib/task/implementation-inputs.ts +3 -3
  218. package/lib/task/intermediate-cleanup.ts +493 -0
  219. package/lib/task/invalidation.ts +18 -62
  220. package/lib/task/ledger-intents.ts +7 -24
  221. package/lib/task/ledger.ts +1 -3
  222. package/lib/task/lifecycle-recovery.ts +691 -0
  223. package/lib/task/lifecycle.ts +30 -5
  224. package/lib/task/local-artifact-finalization.ts +244 -234
  225. package/lib/task/manual-validation-completion.ts +40 -0
  226. package/lib/task/manual-validation-evidence.ts +209 -0
  227. package/lib/task/manual-validation-receipt.ts +156 -0
  228. package/lib/task/manual-validation-shared.ts +50 -0
  229. package/lib/task/manual-validation-transaction.ts +304 -0
  230. package/lib/task/markdown.ts +70 -0
  231. package/lib/task/orchestration.ts +84 -19
  232. package/lib/task/pr-delivery-fact.ts +15 -62
  233. package/lib/task/qualification-audit.ts +22 -33
  234. package/lib/task/recovery-warning.ts +21 -0
  235. package/lib/task/review-artifacts.ts +1 -20
  236. package/lib/task/review-command.ts +24 -0
  237. package/lib/task/review-finalization.ts +183 -292
  238. package/lib/task/review-fingerprint.ts +2 -2
  239. package/lib/task/sections.ts +33 -54
  240. package/lib/task/short-id.ts +27 -5
  241. package/lib/task/task-execution-lock.ts +1 -1
  242. package/lib/task/verification-engine.ts +113 -383
  243. package/lib/task/verification-types.ts +15 -0
  244. package/lib/task/verification.ts +1 -1
  245. package/lib/task/workflow-command.ts +17 -0
  246. package/lib/task/workflow-warning-intents.ts +0 -13
  247. package/lib/task/workflow-warnings.ts +21 -2
  248. package/lib/update.ts +6 -0
  249. package/lib/version.ts +1 -15
  250. package/package.json +6 -6
  251. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  252. package/templates/.agents/rules/create-issue.en.md +1 -1
  253. package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
  254. package/templates/.agents/rules/issue-sync.en.md +4 -2
  255. package/templates/.agents/rules/issue-sync.zh-CN.md +4 -3
  256. package/templates/.agents/rules/local-artifact-repair.en.md +46 -39
  257. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +43 -36
  258. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  259. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  260. package/templates/.agents/scripts/package.json +3 -0
  261. package/templates/.agents/skills/analyze-task/SKILL.en.md +6 -6
  262. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
  263. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -1
  264. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -1
  265. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  266. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  267. package/templates/.agents/skills/block-task/config/verify.json +1 -1
  268. package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -3
  269. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -3
  270. package/templates/.agents/skills/cancel-task/config/verify.json +1 -1
  271. package/templates/.agents/skills/code-task/SKILL.en.md +7 -7
  272. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +7 -7
  273. package/templates/.agents/skills/code-task/config/verify.en.json +1 -1
  274. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -1
  275. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
  276. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
  277. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +33 -21
  278. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +33 -21
  279. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  280. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  281. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  282. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  283. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  284. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  285. package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
  286. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
  287. package/templates/.agents/skills/complete-task/config/verify.en.json +2 -2
  288. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +2 -2
  289. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +1 -1
  290. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +1 -1
  291. package/templates/.agents/skills/create-pr/SKILL.en.md +2 -2
  292. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +2 -2
  293. package/templates/.agents/skills/create-pr/config/verify.json +1 -1
  294. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +2 -2
  295. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +2 -2
  296. package/templates/.agents/skills/create-task/SKILL.en.md +5 -5
  297. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -5
  298. package/templates/.agents/skills/create-task/config/verify.json +1 -1
  299. package/templates/.agents/skills/import-issue/SKILL.en.md +8 -8
  300. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +8 -8
  301. package/templates/.agents/skills/import-issue/config/verify.json +2 -2
  302. package/templates/.agents/skills/plan-task/SKILL.en.md +4 -4
  303. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +4 -4
  304. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -1
  305. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -1
  306. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  307. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  308. package/templates/.agents/skills/restore-task/SKILL.en.md +2 -2
  309. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +2 -2
  310. package/templates/.agents/skills/restore-task/config/verify.json +1 -1
  311. package/templates/.agents/skills/review-analysis/SKILL.en.md +2 -2
  312. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +2 -2
  313. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -1
  314. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -1
  315. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +7 -7
  316. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +6 -6
  317. package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
  318. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
  319. package/templates/.agents/skills/review-code/config/verify.en.json +1 -1
  320. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -1
  321. package/templates/.agents/skills/review-code/reference/report-template.en.md +12 -12
  322. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +12 -12
  323. package/templates/.agents/skills/review-plan/SKILL.en.md +2 -2
  324. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +2 -2
  325. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -1
  326. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -1
  327. package/templates/.agents/skills/review-plan/reference/report-template.en.md +7 -7
  328. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +7 -7
  329. package/templates/.agents/skills/review-pr/config/verify.en.json +1 -1
  330. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +1 -1
  331. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +3 -3
  332. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +3 -3
  333. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +20 -3
  334. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +20 -3
  335. package/templates/.agents/skills/run-manual-validation/config/verify.en.json +1 -1
  336. package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +1 -1
  337. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  338. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  339. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -0
  340. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -0
  341. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  342. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  343. package/templates/.agents/skills/test/SKILL.en.md +17 -6
  344. package/templates/.agents/skills/test/SKILL.zh-CN.md +17 -6
  345. package/templates/.agents/templates/task.en.md +1 -1
  346. package/templates/.agents/templates/task.zh-CN.md +1 -1
  347. package/templates/.claude/commands/import-issue.en.md +1 -1
  348. package/templates/.claude/commands/import-issue.zh-CN.md +1 -1
  349. package/templates/.claude/commands/restore-task.en.md +1 -1
  350. package/templates/.claude/commands/restore-task.zh-CN.md +1 -1
  351. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  352. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  353. package/dist/lib/platform/adapters.js +0 -56
  354. package/lib/platform/adapters.ts +0 -197
@@ -1,5 +1,4 @@
1
1
  import type { ResourceIdentity } from '../platform/resource-identity.ts';
2
- import { isLegacyCompatibilityEnabled, legacyCompatibilityError, VERSION } from '../version.ts';
3
2
  import {
4
3
  isResourceIdentity,
5
4
  parseResourceIdentity,
@@ -17,14 +16,6 @@ type PrDeliveryIdentity = {
17
16
  base: { repository: string; ref: string; sha: string };
18
17
  };
19
18
 
20
- type LegacyPrDeliveryIdentity = {
21
- repository: string;
22
- number: number;
23
- nodeId: string;
24
- url: string;
25
- head: { repository: string; ref: string; sha: string };
26
- base: { repository: string; ref: string; sha: string };
27
- };
28
19
  type CurrentPrDeliveryIdentityInput = {
29
20
  resource: ResourceIdentity;
30
21
  repository: string;
@@ -93,10 +84,6 @@ function timestamp(value: unknown, label: string): string {
93
84
  if (Number.isNaN(Date.parse(result))) throw factError(`${label} must be a valid timestamp`);
94
85
  return new Date(result).toISOString();
95
86
  }
96
- function positiveNumber(value: unknown, label: string): number {
97
- if (!Number.isSafeInteger(value) || (value as number) <= 0) throw factError(`${label} must be a positive integer`);
98
- return value as number;
99
- }
100
87
  function parseRef(value: unknown, label: string): { repository: string; ref: string; sha: string } {
101
88
  if (!isRecord(value)) throw factError(`${label} must be an object`);
102
89
  exactKeys(value, ['repository', 'ref', 'sha'], label);
@@ -115,35 +102,19 @@ function canonicalIdentity(value: unknown): PrDeliveryIdentity {
115
102
  };
116
103
  }
117
104
 
118
- function decodeLegacyIdentity(value: unknown): PrDeliveryIdentity {
119
- if (!isRecord(value)) throw factError('legacy identity must be an object');
120
- // TODO(compat): Remove the v1 identity decoder before the first stable v1.0.0 release.
121
- exactKeys(value, ['repository', 'number', 'nodeId', 'url', 'head', 'base'], 'legacy identity');
122
- const legacy = {
123
- number: positiveNumber(value.number, 'legacy identity.number'),
124
- repository: text(value.repository, 'identity.repository'),
125
- nodeId: text(value.nodeId, 'legacy identity.nodeId'),
126
- url: text(value.url, 'identity.url'),
127
- head: parseRef(value.head, 'identity.head'),
128
- base: parseRef(value.base, 'identity.base')
129
- } satisfies LegacyPrDeliveryIdentity;
130
- return {
131
- resource: { kind: 'number', value: legacy.number },
132
- repository: legacy.repository,
133
- url: legacy.url,
134
- head: legacy.head,
135
- base: legacy.base
136
- };
137
- }
138
-
139
105
  function provenanceForSource(source: PrDeliveryBindingSource): PrDeliveryProvenance { return source === 'created' ? 'create-post' : source === 'reused' ? 'reuse' : source; }
140
106
 
141
- function parseFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
107
+ function legacyFactError(): PrDeliveryFactError {
108
+ return Object.assign(
109
+ new Error('PLATFORM_IDENTITY_LEGACY_UNSUPPORTED: v1 PR delivery fact is unsupported; use the previous tool version to view this task or migrate its fact to version 2 before using this version'),
110
+ { code: 'PLATFORM_IDENTITY_LEGACY_UNSUPPORTED' }
111
+ );
112
+ }
113
+
114
+ function parseFact(value: unknown): PrDeliveryFact {
142
115
  if (!isRecord(value)) throw factError('fact must be an object');
143
- if ((value.version !== 1 && value.version !== 2) || typeof value.state !== 'string') throw factError('version or state is invalid');
144
- if (value.version === 1 && !isLegacyCompatibilityEnabled(runtimeVersion)) {
145
- throw legacyCompatibilityError('v1 PR delivery fact', runtimeVersion);
146
- }
116
+ if (value.version === 1) throw legacyFactError();
117
+ if (value.version !== 2 || typeof value.state !== 'string') throw factError('version or state is invalid');
147
118
  if (value.state === 'unbound') {
148
119
  exactKeys(value, ['version', 'state', 'reason'], 'unbound fact');
149
120
  if (value.reason !== 'initial') throw factError('unbound reason is invalid');
@@ -155,24 +126,6 @@ function parseFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
155
126
  return { version: 2, state: 'skipped', reason: 'explicit', decidedAt: timestamp(value.decidedAt, 'skipped.decidedAt') };
156
127
  }
157
128
  if (value.state !== 'bound') throw factError('state is invalid');
158
- if (value.version === 1) {
159
- // TODO(compat): Remove this v1-to-v2 shape conversion before the first stable v1.0.0 release.
160
- exactKeys(value, ['version', 'state', 'identity', 'binding', 'provenance'], 'legacy bound fact');
161
- if (!isRecord(value.binding) || !isRecord(value.provenance)) throw factError('legacy binding or provenance is invalid');
162
- exactKeys(value.binding, ['status', 'source', 'verifiedAt', 'issueNumber', 'remoteState', 'mergedAt', 'mergeCommitSha'], 'legacy binding');
163
- const issueNumber = value.binding.issueNumber === null ? null : positiveNumber(value.binding.issueNumber, 'legacy binding.issueNumber');
164
- return parseFact({
165
- version: 2,
166
- state: 'bound',
167
- identity: decodeLegacyIdentity(value.identity),
168
- binding: {
169
- status: 'verified', source: value.binding.source, verifiedAt: timestamp(value.binding.verifiedAt, 'binding.verifiedAt'),
170
- issueIdentity: issueNumber === null ? null : { kind: 'number', value: issueNumber }, remoteState: value.binding.remoteState,
171
- mergedAt: value.binding.mergedAt === null ? null : timestamp(value.binding.mergedAt, 'binding.mergedAt'), mergeCommitSha: nullableText(value.binding.mergeCommitSha, 'binding.mergeCommitSha')
172
- },
173
- provenance: value.provenance
174
- }, runtimeVersion);
175
- }
176
129
  exactKeys(value, ['version', 'state', 'identity', 'binding', 'provenance'], 'bound fact');
177
130
  if (!isRecord(value.binding) || !isRecord(value.provenance)) throw factError('binding or provenance is invalid');
178
131
  exactKeys(value.binding, ['status', 'source', 'verifiedAt', 'issueIdentity', 'remoteState', 'mergedAt', 'mergeCommitSha'], 'binding');
@@ -195,19 +148,19 @@ function parseFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
195
148
  };
196
149
  }
197
150
 
198
- function decodePrDeliveryFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
151
+ function decodePrDeliveryFact(value: unknown, _runtimeVersion?: string): PrDeliveryFact {
199
152
  if (typeof value === 'string') {
200
153
  let decoded: unknown;
201
154
  try { decoded = JSON.parse(value); }
202
155
  catch { throw factError('value is not valid JSON'); }
203
- return parseFact(decoded, runtimeVersion);
156
+ return parseFact(decoded);
204
157
  }
205
- return parseFact(value, runtimeVersion);
158
+ return parseFact(value);
206
159
  }
207
160
  function encodePrDeliveryFact(fact: PrDeliveryFact): string { return JSON.stringify(parseFact(fact)); }
208
- function readPrDeliveryFact(metadata: Record<string, unknown>, runtimeVersion = VERSION): PrDeliveryFactReadResult {
161
+ function readPrDeliveryFact(metadata: Record<string, unknown>, _runtimeVersion?: string): PrDeliveryFactReadResult {
209
162
  if (!Object.hasOwn(metadata, PR_DELIVERY_FACT_KEY) || metadata[PR_DELIVERY_FACT_KEY] === '') return { status: 'missing', fact: null };
210
- try { return { status: 'valid', fact: decodePrDeliveryFact(metadata[PR_DELIVERY_FACT_KEY], runtimeVersion) }; }
163
+ try { return { status: 'valid', fact: decodePrDeliveryFact(metadata[PR_DELIVERY_FACT_KEY]) }; }
211
164
  catch (error) { return { status: 'invalid', fact: null, error: asFactError(error) }; }
212
165
  }
213
166
  function buildUnboundFact(): PrDeliveryFact { return { version: 2, state: 'unbound', reason: 'initial' }; }
@@ -1,7 +1,9 @@
1
1
  import { createHash } from 'node:crypto';
2
2
 
3
+ import { parseArtifactName } from './artifact-name.ts';
3
4
  import { parseTypedTaskFrontmatter } from './frontmatter.ts';
4
- import { parseTable } from './sections.ts';
5
+ import { findSectionRange, parseTable } from './sections.ts';
6
+ import { scanVisibleMarkdown } from './markdown.ts';
5
7
 
6
8
  const TASK_CONSTRAINT_HEADINGS = ['约束', 'Constraints'] as const;
7
9
  const TASK_CANDIDATE_HEADINGS = ['候选与否决方案', 'Candidate and Rejected Options', 'Candidates and Rejected Options', 'Candidates and Rejected Alternatives'] as const;
@@ -170,21 +172,9 @@ function taskInputDigest(qualification: Pick<TaskQualification, 'constraints' |
170
172
  return digest(canonicalTaskInput(qualification));
171
173
  }
172
174
 
173
- function sectionBody(content: string, aliases: readonly string[], level = 2): string | null {
174
- const heading = aliases.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
175
- const marker = '#'.repeat(level);
176
- const match = new RegExp(`^${marker}\\s+(${heading})\\s*$`, 'm').exec(content);
177
- if (!match) return null;
178
- const rest = content.slice((match.index ?? 0) + match[0].length);
179
- const end = rest.search(new RegExp(`^#{2,${level}}\\s+`, 'm'));
180
- return rest.slice(0, end < 0 ? rest.length : end);
181
- }
182
-
183
- function stripSection(content: string, aliases: readonly string[]): string {
184
- const body = sectionBody(content, aliases);
185
- if (body === null) return normalizeText(content);
186
- const heading = aliases.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
187
- return normalizeText(content.replace(new RegExp(`^##\\s+(?:${heading})\\s*$[\\s\\S]*?(?=^##\\s+|(?![\\s\\S]))`, 'm'), ''));
175
+ function sectionBody(content: string, aliases: readonly string[], level: 2 | 3 = 2): string | null {
176
+ const section = findSectionRange(content, aliases, level);
177
+ return section ? content.slice(section.bodyStart, section.end) : null;
188
178
  }
189
179
 
190
180
  function stripFrontmatter(content: string): string {
@@ -218,7 +208,7 @@ function nonConstraintInputDigest(content: string): string {
218
208
  ['返工意图', 'Rework Intents'],
219
209
  CONFIRMATION_HEADINGS,
220
210
  ['完成检查清单', 'Completion Checklist']
221
- ].reduce((value, aliases) => stripSection(value, aliases), projection);
211
+ ].reduce((value, aliases) => stripSectionAtLevel(value, aliases, 2), projection);
222
212
  return digest(projection);
223
213
  }
224
214
 
@@ -231,12 +221,9 @@ function stripTaskInputSection(content: string, aliases: readonly string[]): str
231
221
  return stripSectionAtLevel(result, aliases, 2);
232
222
  }
233
223
 
234
- function stripSectionAtLevel(content: string, aliases: readonly string[], level: number): string {
235
- const body = sectionBody(content, aliases, level);
236
- if (body === null) return normalizeText(content);
237
- const heading = aliases.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
238
- const marker = '#'.repeat(level);
239
- return normalizeText(content.replace(new RegExp(`^${marker}\\s+(?:${heading})\\s*$[\\s\\S]*?(?=^#{2,${level}}\\s+|(?![\\s\\S]))`, 'm'), ''));
224
+ function stripSectionAtLevel(content: string, aliases: readonly string[], level: 2 | 3): string {
225
+ const section = findSectionRange(content, aliases, level);
226
+ return normalizeText(section ? content.slice(0, section.start) + content.slice(section.end) : content);
240
227
  }
241
228
 
242
229
  function parseTaskQualification(content: string): { ok: true; qualification: TaskQualification } | { ok: false; code: string; message: string } {
@@ -246,12 +233,14 @@ function parseTaskQualification(content: string): { ok: true; qualification: Tas
246
233
  const hasCandidateHeading = candidateBody !== null;
247
234
  if ((!hasConstraintHeading && !hasCandidateHeading)
248
235
  || (hasConstraintHeading && hasCandidateHeading
249
- && !/^\s*\|/m.test(constraintBody!) && !/^\s*\|/m.test(candidateBody!))) {
236
+ && !scanVisibleMarkdown(constraintBody!).lines.some((line) => line.text.trim().startsWith('|'))
237
+ && !scanVisibleMarkdown(candidateBody!).lines.some((line) => line.text.trim().startsWith('|')))) {
250
238
  return { ok: true, qualification: { present: false, constraints: [], candidates: [], constraintDigest: digest([]), taskInputDigest: digest({ constraints: [], candidates: [] }), nonConstraintInputDigest: nonConstraintInputDigest(content) } };
251
239
  }
252
240
  if (!hasConstraintHeading || !hasCandidateHeading) {
253
- const hasCanonicalTable = new RegExp(`\\|\\s*${CONSTRAINT_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(content)
254
- || new RegExp(`\\|\\s*${CANDIDATE_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(content);
241
+ const visible = scanVisibleMarkdown(content).lines.map((line) => line.text).join('\n');
242
+ const hasCanonicalTable = new RegExp(`\\|\\s*${CONSTRAINT_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(visible)
243
+ || new RegExp(`\\|\\s*${CANDIDATE_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(visible);
255
244
  if (hasCanonicalTable) return { ok: false, code: 'QUALIFICATION_TASK_CONTRACT_INVALID', message: 'task qualification requires both constraints and candidates sections' };
256
245
  return { ok: true, qualification: { present: false, constraints: [], candidates: [], constraintDigest: digest([]), taskInputDigest: digest({ constraints: [], candidates: [] }), nonConstraintInputDigest: nonConstraintInputDigest(content) } };
257
246
  }
@@ -315,10 +304,10 @@ function parseAuditTable(content: string, heading: (typeof AUDIT_SUBSECTIONS)[nu
315
304
  return table?.rows.map((row) => ({ ...row.values })) ?? null;
316
305
  }
317
306
 
318
- function parseArtifactName(value: string): { family: ArtifactFamily; round: number } | null {
319
- const match = /^(analysis|review-analysis|plan|review-plan|code|review-code)(?:-r([2-9]|[1-9]\d+))?\.md$/.exec(value);
320
- if (!match) return null;
321
- return { family: match[1] as ArtifactFamily, round: match[2] ? Number(match[2]) : 1 };
307
+ function parseAuditArtifactName(value: string): { family: ArtifactFamily; round: number } | null {
308
+ const identity = parseArtifactName(value);
309
+ return identity && ARTIFACT_FAMILIES.includes(identity.family as ArtifactFamily)
310
+ ? { family: identity.family as ArtifactFamily, round: identity.round } : null;
322
311
  }
323
312
 
324
313
  function upstreamArtifactDigest(rows: readonly UpstreamRelation[]): string {
@@ -327,7 +316,7 @@ function upstreamArtifactDigest(rows: readonly UpstreamRelation[]): string {
327
316
  }
328
317
 
329
318
  function validateUpstreamRelation(row: UpstreamRelation): void {
330
- const identity = parseArtifactName(row.upstreamArtifact);
319
+ const identity = parseAuditArtifactName(row.upstreamArtifact);
331
320
  if (!ARTIFACT_FAMILIES.includes(row.upstreamFamily) || !identity || identity.family !== row.upstreamFamily
332
321
  || identity.round !== row.upstreamRound || !Number.isSafeInteger(row.upstreamRound)
333
322
  || !/^[a-f0-9]{64}$/i.test(row.upstreamSha256) || !RELATIONS.includes(row.relation)) {
@@ -368,7 +357,7 @@ function expectedQualificationRelations(
368
357
  const inputName = family === 'code' ? frontmatter.code_input_artifact : family.startsWith('review-') ? frontmatter.review_input_artifact : '';
369
358
  const inputSha256 = family === 'code' ? frontmatter.code_input_sha256 : family.startsWith('review-') ? frontmatter.review_input_sha256 : '';
370
359
  if (typeof inputName !== 'string' || !inputName || typeof inputSha256 !== 'string' || !inputSha256) return { ok: true, relations: undefined };
371
- const identity = parseArtifactName(inputName);
360
+ const identity = parseAuditArtifactName(inputName);
372
361
  if (!identity) return { ok: false, code: 'QUALIFICATION_STARTED_INPUT_INVALID', message: `started input '${inputName}' is not canonical` };
373
362
  const relation: UpstreamRelation = {
374
363
  upstreamFamily: identity.family, upstreamArtifact: inputName, upstreamRound: identity.round,
@@ -507,7 +496,7 @@ function validateQualificationAudit(
507
496
  || upstreamArtifactDigest(options.expectedUpstreamRelations) !== upstreamArtifactDigest(audit.audit.upstreamRelations)
508
497
  )) return { ok: false, code: 'QUALIFICATION_UPSTREAM_RELATION_MISMATCH', message: 'qualification audit upstream relations do not match the started artifact inputs' };
509
498
  if (options.family && options.artifact) {
510
- const identity = parseArtifactName(options.artifact);
499
+ const identity = parseAuditArtifactName(options.artifact);
511
500
  if (!identity || identity.family !== options.family) return { ok: false, code: 'QUALIFICATION_ARTIFACT_IDENTITY_INVALID', message: `artifact '${options.artifact}' is not canonical for '${options.family}'` };
512
501
  }
513
502
  return { ok: true, qualification: task.qualification, audit: audit.audit };
@@ -0,0 +1,21 @@
1
+ export type RecoveryWarning = Readonly<{ code: string; message: string; action: string }>;
2
+
3
+ function warningText(value: unknown): value is string {
4
+ return typeof value === 'string' && value.length > 0 && value.trim() === value && !/[\r\n]/u.test(value);
5
+ }
6
+
7
+ export function isRecoveryWarning(value: unknown): value is RecoveryWarning {
8
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
9
+ const warning = value as Record<string, unknown>;
10
+ return Object.keys(warning).sort().join(',') === 'action,code,message'
11
+ && warningText(warning.code)
12
+ && warningText(warning.message)
13
+ && warningText(warning.action);
14
+ }
15
+
16
+ export function sameRecoveryWarning(left: unknown, right: unknown): boolean {
17
+ return isRecoveryWarning(left) && isRecoveryWarning(right)
18
+ && left.code === right.code
19
+ && left.message === right.message
20
+ && left.action === right.action;
21
+ }
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
- import { scanVisibleMarkdown } from './decision-details.ts';
4
+ import { scanVisibleMarkdown } from './markdown.ts';
5
5
 
6
6
  type ReviewFindingCounts = {
7
7
  blocker: number;
@@ -53,23 +53,6 @@ function escapeRegExp(value: string): string {
53
53
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
54
54
  }
55
55
 
56
- function maxRound(entries: string[], stem: string): number {
57
- let max = 0;
58
- for (const entry of entries) {
59
- if (entry === `${stem}.md`) {
60
- max = Math.max(max, 1);
61
- continue;
62
- }
63
- const match = entry.match(new RegExp(`^${escapeRegExp(stem)}-r(\\d+)\\.md$`));
64
- if (match) max = Math.max(max, Number(match[1]));
65
- }
66
- return max;
67
- }
68
-
69
- function artifactName(stem: string, round: number): string {
70
- return round === 1 ? `${stem}.md` : `${stem}-r${round}.md`;
71
- }
72
-
73
56
  function normalizeVerdict(raw: unknown): ReviewVerdict | '' {
74
57
  const value = String(raw).trim().toLowerCase();
75
58
  if (value === '通过' || value === 'approved') return 'Approved';
@@ -260,12 +243,10 @@ function parseVerdict(reviewPath: string): PathVerdictResult {
260
243
  }
261
244
 
262
245
  export {
263
- artifactName,
264
246
  equalCounts,
265
247
  escapeRegExp,
266
248
  extractSection,
267
249
  finalizeReviewSummaryContent,
268
- maxRound,
269
250
  normalizeVerdict,
270
251
  parseReviewSummary,
271
252
  parseVerdict,
@@ -0,0 +1,24 @@
1
+ import type { ReviewFinalizationRequest } from './review-finalization.ts';
2
+
3
+ export function parseReviewCommand(args: readonly string[]): ReviewFinalizationRequest & {
4
+ overrideTicket?: string; overrideTarget?: string; overrideScope?: string;
5
+ } {
6
+ if (!args[0] || args[1] !== 'finalize-summary') throw new Error('task ref and finalize-summary are required');
7
+ const values: Record<string, string | boolean> = {};
8
+ const flags = {
9
+ '--stage': 'stage', '--artifact': 'artifact', '--orchestrated': 'orchestrated', '--dry-run': 'dryRun',
10
+ '--recovery-id': 'recoveryId',
11
+ '--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
12
+ } as const;
13
+ for (let index = 2; index < args.length; index += 1) {
14
+ const flag = args[index]!;
15
+ if (!Object.hasOwn(flags, flag)) throw new Error(`unknown option '${flag}'`);
16
+ const key = flags[flag as keyof typeof flags];
17
+ if (Object.hasOwn(values, key)) throw new Error(`duplicate option '${flag}'`);
18
+ const value = flag === '--orchestrated' || flag === '--dry-run' ? true : args[++index];
19
+ if (!value || typeof value === 'string' && value.startsWith('--')) throw new Error(`option '${flag}' requires a value`);
20
+ values[key] = value;
21
+ }
22
+ if (!values.stage || !values.artifact) throw new Error("options '--stage' and '--artifact' are required");
23
+ return { taskRef: args[0], ...values } as ReturnType<typeof parseReviewCommand>;
24
+ }