@fitlab-ai/agent-infra 0.8.5 → 0.9.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 (425) hide show
  1. package/bin/cli.ts +2 -2
  2. package/dist/bin/cli.js +2 -2
  3. package/dist/bin/internal-cli.js +98 -0
  4. package/dist/lib/decide.js +81 -90
  5. package/dist/lib/defaults.json +1 -0
  6. package/dist/lib/git/review-snapshot.js +79 -0
  7. package/dist/lib/git/workflow.js +101 -0
  8. package/dist/lib/internal/git-workflow.js +42 -0
  9. package/dist/lib/internal/platform-checks.js +119 -0
  10. package/dist/lib/internal/platform-comment.js +129 -0
  11. package/dist/lib/internal/platform-context.js +46 -0
  12. package/dist/lib/internal/platform-issue.js +142 -0
  13. package/dist/lib/internal/platform-pr.js +146 -0
  14. package/dist/lib/internal/release-workflow.js +217 -0
  15. package/dist/lib/internal/task-artifact.js +67 -0
  16. package/dist/lib/internal/task-context.js +43 -0
  17. package/dist/lib/internal/task-event.js +70 -0
  18. package/dist/lib/internal/task-ledger.js +114 -0
  19. package/dist/lib/internal/task-lifecycle.js +58 -0
  20. package/dist/lib/internal/task-short-id.js +83 -0
  21. package/dist/lib/internal/task-snapshot.js +47 -0
  22. package/dist/lib/internal/task-verify.js +50 -0
  23. package/dist/lib/internal/task-warning.js +74 -0
  24. package/dist/lib/platform/adapters.js +14 -0
  25. package/dist/lib/platform/context.js +146 -0
  26. package/dist/lib/platform/github-client.js +124 -0
  27. package/dist/lib/platform/issue-comments.js +409 -0
  28. package/dist/lib/platform/issue-metadata.js +183 -0
  29. package/dist/lib/platform/issues.js +617 -0
  30. package/dist/lib/platform/metadata-labels.js +28 -0
  31. package/dist/lib/platform/pr-checks.js +216 -0
  32. package/dist/lib/platform/pr-summary.js +88 -0
  33. package/dist/lib/platform/pull-request-metadata.js +38 -0
  34. package/dist/lib/platform/pull-requests.js +338 -0
  35. package/dist/lib/platform/releases.js +82 -0
  36. package/dist/lib/platform/types.js +22 -0
  37. package/dist/lib/platform/verification-required.js +78 -0
  38. package/dist/lib/platform/verification-sync.js +1014 -0
  39. package/dist/lib/platform/verification.js +6 -0
  40. package/dist/lib/release/channels.js +31 -0
  41. package/dist/lib/release/workflow.js +32 -0
  42. package/dist/lib/render.js +3 -2
  43. package/dist/lib/run/index.js +24 -7
  44. package/dist/lib/sandbox/capture.js +25 -3
  45. package/dist/lib/sandbox/commands/create.js +36 -22
  46. package/dist/lib/sandbox/commands/enter.js +34 -11
  47. package/dist/lib/sandbox/commands/list-running.js +10 -8
  48. package/dist/lib/sandbox/commands/show.js +2 -2
  49. package/dist/lib/sandbox/commands/start.js +53 -15
  50. package/dist/lib/sandbox/index.js +6 -6
  51. package/dist/lib/sandbox/mounts.js +36 -0
  52. package/dist/lib/sandbox/recovery.js +562 -0
  53. package/dist/lib/sandbox/task-resolver.js +5 -1
  54. package/dist/lib/sandbox/tools.js +19 -0
  55. package/dist/lib/server/protocol.js +5 -5
  56. package/dist/lib/task/activity-log.js +61 -0
  57. package/dist/lib/task/artifact-lifecycle.js +427 -0
  58. package/dist/lib/task/command-options.js +30 -0
  59. package/dist/lib/task/commands/cat.js +36 -6
  60. package/dist/lib/task/commands/decisions.js +80 -46
  61. package/dist/lib/task/commands/files.js +21 -7
  62. package/dist/lib/task/commands/grep.js +55 -7
  63. package/dist/lib/task/commands/issue-body.js +23 -14
  64. package/dist/lib/task/commands/log.js +27 -70
  65. package/dist/lib/task/commands/show.js +20 -7
  66. package/dist/lib/task/commands/status.js +18 -8
  67. package/dist/lib/task/decision-intents.js +154 -0
  68. package/dist/lib/task/decision-items.js +53 -0
  69. package/dist/lib/task/events.js +318 -0
  70. package/dist/lib/task/frontmatter.js +159 -1
  71. package/dist/lib/task/implementation-inputs.js +117 -0
  72. package/dist/lib/task/index.js +12 -9
  73. package/dist/lib/task/issue-form.js +19 -6
  74. package/dist/lib/task/ledger-intents.js +185 -0
  75. package/dist/lib/task/ledger.js +65 -35
  76. package/dist/lib/task/lifecycle.js +484 -0
  77. package/dist/lib/task/resolve-ref.js +152 -32
  78. package/dist/lib/task/review-artifacts.js +101 -0
  79. package/dist/lib/task/review-fingerprint.js +46 -0
  80. package/dist/lib/task/sections.js +358 -4
  81. package/dist/lib/task/short-id.js +292 -7
  82. package/dist/lib/task/snapshot.js +95 -0
  83. package/dist/lib/task/verification-checks.js +8 -0
  84. package/dist/lib/task/verification-config.js +14 -0
  85. package/dist/lib/task/verification-engine.js +906 -0
  86. package/dist/lib/task/verification-review.js +3 -0
  87. package/dist/lib/task/verification-types.js +2 -0
  88. package/dist/lib/task/verification.js +113 -0
  89. package/dist/lib/task/workflow-warning-intents.js +131 -0
  90. package/dist/lib/task/workflow-warnings.js +10 -78
  91. package/dist/lib/task/write.js +241 -0
  92. package/lib/decide.ts +57 -97
  93. package/lib/defaults.json +1 -0
  94. package/lib/git/review-snapshot.ts +73 -0
  95. package/lib/git/workflow.ts +101 -0
  96. package/lib/internal/git-workflow.ts +37 -0
  97. package/lib/internal/platform-checks.ts +101 -0
  98. package/lib/internal/platform-comment.ts +99 -0
  99. package/lib/internal/platform-context.ts +33 -0
  100. package/lib/internal/platform-issue.ts +116 -0
  101. package/lib/internal/platform-pr.ts +119 -0
  102. package/lib/internal/release-workflow.ts +186 -0
  103. package/lib/internal/task-artifact.ts +47 -0
  104. package/lib/internal/task-context.ts +35 -0
  105. package/lib/internal/task-event.ts +51 -0
  106. package/lib/internal/task-ledger.ts +86 -0
  107. package/lib/internal/task-lifecycle.ts +41 -0
  108. package/lib/internal/task-short-id.ts +55 -0
  109. package/lib/internal/task-snapshot.ts +32 -0
  110. package/lib/internal/task-verify.ts +33 -0
  111. package/lib/internal/task-warning.ts +50 -0
  112. package/lib/platform/adapters.ts +30 -0
  113. package/lib/platform/context.ts +164 -0
  114. package/lib/platform/github-client.ts +146 -0
  115. package/lib/platform/issue-comments.ts +479 -0
  116. package/lib/platform/issue-metadata.ts +250 -0
  117. package/lib/platform/issues.ts +691 -0
  118. package/lib/platform/metadata-labels.ts +33 -0
  119. package/lib/platform/pr-checks.ts +246 -0
  120. package/lib/platform/pr-summary.ts +90 -0
  121. package/lib/platform/pull-request-metadata.ts +69 -0
  122. package/lib/platform/pull-requests.ts +380 -0
  123. package/lib/platform/releases.ts +71 -0
  124. package/lib/platform/types.ts +74 -0
  125. package/lib/platform/verification-required.ts +83 -0
  126. package/{runtime/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts} +198 -367
  127. package/lib/platform/verification.ts +11 -0
  128. package/lib/release/channels.ts +30 -0
  129. package/lib/release/workflow.ts +31 -0
  130. package/lib/render.ts +3 -2
  131. package/lib/run/index.ts +25 -7
  132. package/lib/sandbox/capture.ts +29 -3
  133. package/lib/sandbox/commands/create.ts +43 -25
  134. package/lib/sandbox/commands/enter.ts +38 -11
  135. package/lib/sandbox/commands/list-running.ts +10 -8
  136. package/lib/sandbox/commands/show.ts +2 -2
  137. package/lib/sandbox/commands/start.ts +50 -16
  138. package/lib/sandbox/index.ts +6 -6
  139. package/lib/sandbox/mounts.ts +55 -0
  140. package/lib/sandbox/recovery.ts +828 -0
  141. package/lib/sandbox/task-resolver.ts +5 -1
  142. package/lib/sandbox/tools.ts +31 -0
  143. package/lib/server/protocol.ts +5 -5
  144. package/lib/task/activity-log.ts +62 -0
  145. package/lib/task/artifact-lifecycle.ts +484 -0
  146. package/lib/task/command-options.ts +32 -0
  147. package/lib/task/commands/cat.ts +22 -9
  148. package/lib/task/commands/decisions.ts +49 -47
  149. package/lib/task/commands/files.ts +14 -6
  150. package/lib/task/commands/grep.ts +34 -7
  151. package/lib/task/commands/issue-body.ts +16 -16
  152. package/lib/task/commands/log.ts +17 -70
  153. package/lib/task/commands/show.ts +14 -6
  154. package/lib/task/commands/status.ts +17 -7
  155. package/lib/task/decision-intents.ts +163 -0
  156. package/lib/task/decision-items.ts +64 -0
  157. package/lib/task/events.ts +320 -0
  158. package/lib/task/frontmatter.ts +202 -2
  159. package/lib/task/implementation-inputs.ts +137 -0
  160. package/lib/task/index.ts +12 -9
  161. package/lib/task/issue-form.ts +20 -6
  162. package/lib/task/ledger-intents.ts +201 -0
  163. package/lib/task/ledger.ts +77 -31
  164. package/lib/task/lifecycle.ts +458 -0
  165. package/lib/task/resolve-ref.ts +197 -36
  166. package/{templates/.agents/scripts/lib/review-artifacts.js → lib/task/review-artifacts.ts} +11 -12
  167. package/{templates/.agents/scripts/lib/post-review-commit.js → lib/task/review-fingerprint.ts} +17 -12
  168. package/lib/task/sections.ts +486 -4
  169. package/lib/task/short-id.ts +403 -9
  170. package/lib/task/snapshot.ts +143 -0
  171. package/lib/task/verification-checks.ts +9 -0
  172. package/lib/task/verification-config.ts +20 -0
  173. package/{templates/.agents/scripts/validate-artifact.js → lib/task/verification-engine.ts} +199 -406
  174. package/lib/task/verification-review.ts +9 -0
  175. package/lib/task/verification-types.ts +29 -0
  176. package/lib/task/verification.ts +156 -0
  177. package/lib/task/workflow-warning-intents.ts +142 -0
  178. package/lib/task/workflow-warnings.ts +10 -78
  179. package/lib/task/write.ts +468 -0
  180. package/package.json +4 -2
  181. package/templates/.agents/README.en.md +4 -3
  182. package/templates/.agents/README.zh-CN.md +4 -3
  183. package/templates/.agents/rules/README.en.md +6 -5
  184. package/templates/.agents/rules/README.zh-CN.md +6 -5
  185. package/templates/.agents/rules/create-issue.en.md +1 -1
  186. package/templates/.agents/rules/create-issue.github.en.md +5 -184
  187. package/templates/.agents/rules/create-issue.github.zh-CN.md +12 -178
  188. package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
  189. package/templates/.agents/rules/human-decision-context.en.md +36 -0
  190. package/templates/.agents/rules/human-decision-context.zh-CN.md +36 -0
  191. package/templates/.agents/rules/issue-fields.github.en.md +4 -148
  192. package/templates/.agents/rules/issue-fields.github.zh-CN.md +9 -144
  193. package/templates/.agents/rules/issue-pr-commands.en.md +43 -3
  194. package/templates/.agents/rules/issue-pr-commands.github.en.md +15 -220
  195. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +23 -213
  196. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +45 -3
  197. package/templates/.agents/rules/issue-sync.en.md +1 -1
  198. package/templates/.agents/rules/issue-sync.github.en.md +14 -301
  199. package/templates/.agents/rules/issue-sync.github.zh-CN.md +36 -287
  200. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  201. package/templates/.agents/rules/milestone-inference.en.md +1 -1
  202. package/templates/.agents/rules/milestone-inference.github.en.md +7 -119
  203. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +8 -108
  204. package/templates/.agents/rules/milestone-inference.zh-CN.md +1 -1
  205. package/templates/.agents/rules/next-step-output.en.md +12 -11
  206. package/templates/.agents/rules/next-step-output.zh-CN.md +12 -11
  207. package/templates/.agents/rules/no-mid-flow-questions.en.md +3 -3
  208. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +3 -3
  209. package/templates/.agents/rules/pr-checks-commands.en.md +16 -3
  210. package/templates/.agents/rules/pr-checks-commands.github.en.md +10 -54
  211. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +19 -47
  212. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +30 -3
  213. package/templates/.agents/rules/pr-sync.en.md +30 -3
  214. package/templates/.agents/rules/pr-sync.github.en.md +12 -115
  215. package/templates/.agents/rules/pr-sync.github.zh-CN.md +26 -104
  216. package/templates/.agents/rules/pr-sync.zh-CN.md +43 -3
  217. package/templates/.agents/rules/review-handshake.en.md +8 -5
  218. package/templates/.agents/rules/review-handshake.zh-CN.md +8 -5
  219. package/templates/.agents/rules/task-management.en.md +11 -2
  220. package/templates/.agents/rules/task-management.zh-CN.md +11 -3
  221. package/templates/.agents/rules/task-short-id.en.md +25 -29
  222. package/templates/.agents/rules/task-short-id.zh-CN.md +20 -23
  223. package/templates/.agents/scripts/lib/agent-infra-package.js +1 -9
  224. package/templates/.agents/scripts/task-short-id.js +71 -533
  225. package/templates/.agents/skills/analyze-task/SKILL.en.md +22 -55
  226. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +26 -59
  227. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -3
  228. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -3
  229. package/templates/.agents/skills/block-task/SKILL.en.md +21 -47
  230. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +23 -47
  231. package/templates/.agents/skills/block-task/config/verify.json +1 -2
  232. package/templates/.agents/skills/cancel-task/SKILL.en.md +16 -45
  233. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +16 -45
  234. package/templates/.agents/skills/cancel-task/config/verify.json +1 -2
  235. package/templates/.agents/skills/check-task/SKILL.en.md +6 -3
  236. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +6 -3
  237. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -24
  238. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -24
  239. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -24
  240. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -24
  241. package/templates/.agents/skills/code-task/SKILL.en.md +22 -35
  242. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +28 -44
  243. package/templates/.agents/skills/code-task/config/verify.en.json +3 -3
  244. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +3 -3
  245. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +13 -9
  246. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +13 -9
  247. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
  248. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
  249. package/templates/.agents/skills/code-task/reference/report-template.en.md +11 -1
  250. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +11 -1
  251. package/templates/.agents/skills/commit/SKILL.en.md +13 -11
  252. package/templates/.agents/skills/commit/SKILL.zh-CN.md +13 -11
  253. package/templates/.agents/skills/commit/config/verify.json +1 -2
  254. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -11
  255. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -11
  256. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +4 -8
  257. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +4 -8
  258. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +6 -18
  259. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +5 -17
  260. package/templates/.agents/skills/commit/reference/task-status-update.en.md +13 -0
  261. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +13 -0
  262. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +13 -36
  263. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +13 -36
  264. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -3
  265. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -3
  266. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +10 -54
  267. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +10 -79
  268. package/templates/.agents/skills/complete-task/SKILL.en.md +59 -63
  269. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +59 -63
  270. package/templates/.agents/skills/complete-task/config/verify.en.json +11 -7
  271. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +11 -7
  272. package/templates/.agents/skills/create-pr/SKILL.en.md +19 -44
  273. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +19 -43
  274. package/templates/.agents/skills/create-pr/config/verify.json +1 -2
  275. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +8 -12
  276. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +7 -11
  277. package/templates/.agents/skills/create-task/SKILL.en.md +12 -13
  278. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +12 -13
  279. package/templates/.agents/skills/create-task/config/verify.json +1 -2
  280. package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -2
  281. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +2 -2
  282. package/templates/.agents/skills/import-codescan/config/verify.json +1 -2
  283. package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
  284. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
  285. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -2
  286. package/templates/.agents/skills/import-issue/SKILL.en.md +9 -13
  287. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -14
  288. package/templates/.agents/skills/import-issue/config/verify.json +1 -2
  289. package/templates/.agents/skills/plan-task/SKILL.en.md +17 -42
  290. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -49
  291. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -3
  292. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -3
  293. package/templates/.agents/skills/post-release/SKILL.en.md +11 -81
  294. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +8 -78
  295. package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
  296. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
  297. package/templates/.agents/skills/release/SKILL.en.md +16 -163
  298. package/templates/.agents/skills/release/SKILL.zh-CN.md +15 -162
  299. package/templates/.agents/skills/restore-task/SKILL.en.md +11 -29
  300. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +11 -29
  301. package/templates/.agents/skills/restore-task/config/verify.json +1 -2
  302. package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -25
  303. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +13 -33
  304. package/templates/.agents/skills/review-analysis/config/verify.en.json +3 -4
  305. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +3 -4
  306. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +9 -12
  307. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +9 -12
  308. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +9 -2
  309. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +9 -2
  310. package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +7 -0
  311. package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +7 -0
  312. package/templates/.agents/skills/review-code/SKILL.en.md +22 -36
  313. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +23 -41
  314. package/templates/.agents/skills/review-code/config/verify.en.json +3 -4
  315. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +3 -4
  316. package/templates/.agents/skills/review-code/reference/output-templates.en.md +56 -18
  317. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +56 -18
  318. package/templates/.agents/skills/review-code/reference/report-template.en.md +11 -4
  319. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +11 -4
  320. package/templates/.agents/skills/review-code/reference/review-criteria.en.md +7 -0
  321. package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +7 -0
  322. package/templates/.agents/skills/review-plan/SKILL.en.md +13 -25
  323. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +13 -33
  324. package/templates/.agents/skills/review-plan/config/verify.en.json +3 -4
  325. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +3 -4
  326. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +9 -12
  327. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +9 -12
  328. package/templates/.agents/skills/review-plan/reference/report-template.en.md +9 -2
  329. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +9 -2
  330. package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +7 -0
  331. package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +7 -0
  332. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -2
  333. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -2
  334. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -15
  335. package/templates/.agents/skills/watch-pr/SKILL.en.md +24 -14
  336. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +25 -15
  337. package/templates/.agents/skills/watch-pr/config/verify.json +1 -2
  338. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
  339. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
  340. package/templates/.agents/templates/task.en.md +6 -1
  341. package/templates/.agents/templates/task.zh-CN.md +6 -1
  342. package/templates/.claude/commands/analyze-task.en.md +1 -1
  343. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  344. package/templates/.claude/commands/block-task.en.md +1 -1
  345. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  346. package/templates/.claude/commands/cancel-task.en.md +1 -1
  347. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  348. package/templates/.claude/commands/check-task.en.md +1 -1
  349. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  350. package/templates/.claude/commands/code-task.en.md +1 -1
  351. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  352. package/templates/.claude/commands/commit.en.md +1 -0
  353. package/templates/.claude/commands/commit.zh-CN.md +1 -0
  354. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  355. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  356. package/templates/.claude/commands/complete-task.en.md +1 -1
  357. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  358. package/templates/.claude/commands/create-pr.en.md +1 -1
  359. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  360. package/templates/.claude/commands/plan-task.en.md +1 -1
  361. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  362. package/templates/.claude/commands/review-analysis.en.md +1 -1
  363. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  364. package/templates/.claude/commands/review-code.en.md +1 -1
  365. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  366. package/templates/.claude/commands/review-plan.en.md +1 -1
  367. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  368. package/templates/.claude/commands/watch-pr.en.md +1 -1
  369. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  370. package/templates/.gemini/commands/_project_/analyze-task.en.toml +2 -0
  371. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +2 -0
  372. package/templates/.gemini/commands/_project_/block-task.en.toml +2 -0
  373. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +2 -0
  374. package/templates/.gemini/commands/_project_/cancel-task.en.toml +2 -0
  375. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +2 -0
  376. package/templates/.gemini/commands/_project_/check-task.en.toml +2 -0
  377. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +2 -0
  378. package/templates/.gemini/commands/_project_/code-task.en.toml +2 -0
  379. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +2 -0
  380. package/templates/.gemini/commands/_project_/commit.en.toml +4 -0
  381. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +4 -0
  382. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +2 -0
  383. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +2 -0
  384. package/templates/.gemini/commands/_project_/complete-task.en.toml +2 -0
  385. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +2 -0
  386. package/templates/.gemini/commands/_project_/create-pr.en.toml +2 -0
  387. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +2 -0
  388. package/templates/.gemini/commands/_project_/plan-task.en.toml +2 -0
  389. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +2 -0
  390. package/templates/.gemini/commands/_project_/review-analysis.en.toml +2 -0
  391. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +2 -0
  392. package/templates/.gemini/commands/_project_/review-code.en.toml +2 -0
  393. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +2 -0
  394. package/templates/.gemini/commands/_project_/review-plan.en.toml +2 -0
  395. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +2 -0
  396. package/templates/.gemini/commands/_project_/watch-pr.en.toml +2 -0
  397. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +2 -0
  398. package/templates/.git-hooks/check-large-files.cjs +92 -0
  399. package/templates/.git-hooks/check-version-format.sh +5 -1
  400. package/templates/.git-hooks/pre-commit +1 -0
  401. package/templates/.opencode/commands/analyze-task.en.md +1 -1
  402. package/templates/.opencode/commands/analyze-task.zh-CN.md +1 -1
  403. package/templates/.opencode/commands/check-task.en.md +1 -1
  404. package/templates/.opencode/commands/check-task.zh-CN.md +1 -1
  405. package/templates/.opencode/commands/code-task.en.md +1 -1
  406. package/templates/.opencode/commands/code-task.zh-CN.md +1 -1
  407. package/templates/.opencode/commands/commit.en.md +2 -0
  408. package/templates/.opencode/commands/commit.zh-CN.md +2 -0
  409. package/templates/.opencode/commands/complete-task.en.md +1 -1
  410. package/templates/.opencode/commands/complete-task.zh-CN.md +1 -1
  411. package/templates/.opencode/commands/plan-task.en.md +1 -1
  412. package/templates/.opencode/commands/plan-task.zh-CN.md +1 -1
  413. package/templates/.opencode/commands/review-analysis.en.md +1 -1
  414. package/templates/.opencode/commands/review-analysis.zh-CN.md +1 -1
  415. package/templates/.opencode/commands/review-code.en.md +1 -1
  416. package/templates/.opencode/commands/review-code.zh-CN.md +1 -1
  417. package/templates/.opencode/commands/review-plan.en.md +1 -1
  418. package/templates/.opencode/commands/review-plan.zh-CN.md +1 -1
  419. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +0 -40
  420. package/templates/.agents/scripts/platform-adapters/platform-sync.js +0 -13
  421. package/templates/.agents/scripts/review-diff-fingerprint.js +0 -170
  422. package/templates/.agents/scripts/workflow-warnings.js +0 -290
  423. package/templates/.agents/skills/code-task/scripts/detect-mode.js +0 -257
  424. package/templates/.agents/skills/release/scripts/manage-milestones.github.sh +0 -80
  425. package/templates/.agents/skills/release/scripts/manage-milestones.sh +0 -6
@@ -0,0 +1,61 @@
1
+ const HEADING_RE = /^##\s+(活动日志|Activity Log)\s*$/;
2
+ const NEXT_H2_RE = /^##\s/;
3
+ const ENTRY_RE = /^- (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}) — \*\*(.+?)\*\* by (.+?) — (.*)$/;
4
+ const STARTED_SUFFIX_RE = /\s*\[started\]\s*$/;
5
+ function parseActivityLog(content) {
6
+ const section = locateActivityLog(content);
7
+ return section ? { sectionFound: true, entries: section.entries } : { sectionFound: false, entries: [] };
8
+ }
9
+ function locateActivityLog(content) {
10
+ const lines = content.split('\n');
11
+ const headings = lines.map((line, index) => HEADING_RE.test(line) ? index : -1).filter((index) => index >= 0);
12
+ if (headings.length !== 1)
13
+ return null;
14
+ const i = headings[0];
15
+ let end = lines.length;
16
+ for (let j = i + 1; j < lines.length; j += 1) {
17
+ if (NEXT_H2_RE.test(lines[j])) {
18
+ end = j;
19
+ break;
20
+ }
21
+ }
22
+ const bodyLines = lines.slice(i + 1, end);
23
+ const parsed = [];
24
+ for (const line of bodyLines) {
25
+ const m = ENTRY_RE.exec(line);
26
+ if (!m)
27
+ continue;
28
+ parsed.push({ entry: { time: m[1], step: m[2], agent: m[3], note: m[4] }, epoch: Date.parse(m[1].replace(' ', 'T')), order: parsed.length });
29
+ }
30
+ parsed.sort((a, b) => a.epoch - b.epoch || a.order - b.order);
31
+ return { heading: HEADING_RE.exec(lines[i])[1], body: bodyLines.join('\n').replace(/^\n+|\n+$/g, ''), entries: parsed.map((item) => item.entry) };
32
+ }
33
+ function appendActivityEntry(section, entry) {
34
+ const line = `- ${entry.time} — **${entry.step}** by ${entry.agent} — ${entry.note}`;
35
+ return section.body ? `${section.body}\n${line}` : line;
36
+ }
37
+ function pairEntries(entries) {
38
+ const rows = [];
39
+ const open = new Map();
40
+ for (const entry of entries) {
41
+ const started = STARTED_SUFFIX_RE.test(entry.step);
42
+ const base = entry.step.replace(STARTED_SUFFIX_RE, '');
43
+ if (started) {
44
+ const row = { step: base, agent: entry.agent, started: entry.time, done: '', note: entry.note };
45
+ rows.push(row);
46
+ const queue = open.get(base) ?? [];
47
+ queue.push(row);
48
+ open.set(base, queue);
49
+ }
50
+ else {
51
+ const pending = open.get(base)?.shift();
52
+ if (pending)
53
+ Object.assign(pending, { done: entry.time, agent: entry.agent, note: entry.note });
54
+ else
55
+ rows.push({ step: base, agent: entry.agent, started: '', done: entry.time, note: entry.note });
56
+ }
57
+ }
58
+ return rows;
59
+ }
60
+ export { parseActivityLog, locateActivityLog, appendActivityEntry, pairEntries };
61
+ //# sourceMappingURL=activity-log.js.map
@@ -0,0 +1,427 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { resolveTaskRef } from './resolve-ref.js';
4
+ import { locateActivityLog } from './activity-log.js';
5
+ import { parseImplementationInputs, selectPendingImplementationInput } from './implementation-inputs.js';
6
+ import { extractSection, findSectionHeading } from './sections.js';
7
+ const artifactFamilyCatalog = [
8
+ { family: 'analysis', sectionAliases: ['分析', 'Analysis'], heading: '分析', labels: ['需求分析报告', 'Requirements Analysis'] },
9
+ { family: 'review-analysis', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['需求分析审查', 'Analysis Review'] },
10
+ { family: 'plan', sectionAliases: ['设计', 'Design'], heading: '设计', labels: ['技术方案', 'Technical Plan'] },
11
+ { family: 'review-plan', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['技术方案审查', 'Plan Review'] },
12
+ { family: 'code', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['实现报告', 'Implementation Report'] },
13
+ { family: 'review-code', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['代码审查', 'Code Review'] },
14
+ { family: 'manual-validation', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['人工验证', 'Manual Validation'] }
15
+ ];
16
+ const FAMILY_SET = new Set(artifactFamilyCatalog.map((item) => item.family));
17
+ const BLOCKING_DIAGNOSTICS = new Set([
18
+ 'NONCANONICAL_NAME', 'ROUND_OUT_OF_RANGE', 'MISSING_BASE', 'ROUND_GAP',
19
+ 'DUPLICATE_LOGICAL_ROUND', 'NON_REGULAR_FILE', 'SYMBOLIC_LINK',
20
+ 'FILESYSTEM_RACE', 'CATALOG_CONFLICT'
21
+ ]);
22
+ function familySpec(family) {
23
+ return artifactFamilyCatalog.find((item) => item.family === family) ?? null;
24
+ }
25
+ function artifactName(family, round) {
26
+ if (!FAMILY_SET.has(family))
27
+ throw new Error(`unknown artifact family '${family}'`);
28
+ if (!Number.isSafeInteger(round) || round < 1)
29
+ throw new Error('artifact round must be a safe positive integer');
30
+ return round === 1 ? `${family}.md` : `${family}-r${round}.md`;
31
+ }
32
+ function parseArtifactName(name) {
33
+ if (path.basename(name) !== name)
34
+ return null;
35
+ const matches = [];
36
+ for (const spec of artifactFamilyCatalog) {
37
+ if (name === `${spec.family}.md`)
38
+ matches.push({ family: spec.family, round: 1, name });
39
+ const match = new RegExp(`^${escapeRegExp(spec.family)}-r([1-9]\\d*)\\.md$`).exec(name);
40
+ if (!match)
41
+ continue;
42
+ const round = Number(match[1]);
43
+ if (Number.isSafeInteger(round) && round >= 2 && String(round) === match[1]) {
44
+ matches.push({ family: spec.family, round, name });
45
+ }
46
+ }
47
+ return matches.length === 1 ? matches[0] : null;
48
+ }
49
+ function escapeRegExp(value) {
50
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
51
+ }
52
+ function failure(requestRef, family, error, extra = {}) {
53
+ return {
54
+ status: 'failed', changed: false, requestRef, taskId: null, taskDir: null,
55
+ taskState: null, family, artifacts: [], latest: null, next: null,
56
+ reviewedInput: null, diagnostics: [], error, ...extra
57
+ };
58
+ }
59
+ function diagnostic(code, family, name, message) {
60
+ return { code, family, name, message };
61
+ }
62
+ function inspectTaskArtifacts(taskRef, family, options = {}) {
63
+ const spec = familySpec(family);
64
+ if (!spec)
65
+ return failure(taskRef, family, { code: 'ARTIFACT_FAMILY_UNKNOWN', message: `unknown artifact family '${family}'` });
66
+ const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
67
+ if (!resolved.ok)
68
+ return failure(taskRef, family, { code: resolved.code, message: resolved.message }, { taskId: resolved.taskId });
69
+ return inspectArtifactDirectory(resolved.taskDir, spec.family, {
70
+ requestRef: taskRef, taskId: resolved.taskId, taskState: resolved.state
71
+ });
72
+ }
73
+ function inspectArtifactDirectory(taskDir, family, identity = {}) {
74
+ const requestRef = identity.requestRef ?? taskDir;
75
+ let entries;
76
+ try {
77
+ entries = fs.readdirSync(taskDir, { withFileTypes: true });
78
+ }
79
+ catch (error) {
80
+ return failure(requestRef, family, { code: 'ARTIFACT_DIRECTORY_READ_FAILED', message: String(error) }, {
81
+ taskId: identity.taskId ?? null, taskDir, taskState: identity.taskState ?? null
82
+ });
83
+ }
84
+ const artifacts = [];
85
+ const diagnostics = [];
86
+ for (const entry of entries) {
87
+ const parsed = parseArtifactName(entry.name);
88
+ const reserved = entry.name.toLowerCase().startsWith(`${family.toLowerCase()}-r`) || entry.name.toLowerCase() === `${family.toLowerCase()}.md`;
89
+ if (!parsed || parsed.family !== family) {
90
+ if (reserved) {
91
+ const roundText = new RegExp(`^${escapeRegExp(family)}-r(.+)\\.md$`, 'i').exec(entry.name)?.[1];
92
+ const code = roundText && /^\d+$/.test(roundText) && !Number.isSafeInteger(Number(roundText))
93
+ ? 'ROUND_OUT_OF_RANGE' : 'NONCANONICAL_NAME';
94
+ diagnostics.push(diagnostic(code, family, entry.name, `noncanonical ${family} artifact candidate '${entry.name}' (verify whether this is an unrelated file with a reserved prefix)`));
95
+ }
96
+ continue;
97
+ }
98
+ const abs = path.join(taskDir, entry.name);
99
+ try {
100
+ const stat = fs.lstatSync(abs);
101
+ if (stat.isSymbolicLink()) {
102
+ diagnostics.push(diagnostic('SYMBOLIC_LINK', family, entry.name, `symbolic links are not workflow artifacts: ${entry.name}`));
103
+ continue;
104
+ }
105
+ if (!stat.isFile()) {
106
+ diagnostics.push(diagnostic('NON_REGULAR_FILE', family, entry.name, `artifact is not a regular file: ${entry.name}`));
107
+ continue;
108
+ }
109
+ try {
110
+ fs.accessSync(abs, fs.constants.R_OK);
111
+ }
112
+ catch {
113
+ diagnostics.push(diagnostic('FILESYSTEM_RACE', family, entry.name, `artifact is not readable: ${entry.name}`));
114
+ continue;
115
+ }
116
+ artifacts.push({ ...parsed, path: abs, size: stat.size, mtimeMs: stat.mtimeMs });
117
+ }
118
+ catch (error) {
119
+ diagnostics.push(diagnostic('FILESYSTEM_RACE', family, entry.name, String(error)));
120
+ }
121
+ }
122
+ artifacts.sort((left, right) => left.round - right.round);
123
+ const rounds = new Set(artifacts.map((item) => item.round));
124
+ if (artifacts.length > 0 && !rounds.has(1))
125
+ diagnostics.push(diagnostic('MISSING_BASE', family, null, `${family}.md is missing`));
126
+ const max = artifacts.at(-1)?.round ?? 0;
127
+ for (let round = 1; round <= max; round += 1) {
128
+ if (!rounds.has(round))
129
+ diagnostics.push(diagnostic('ROUND_GAP', family, null, `${artifactName(family, round)} is missing`));
130
+ }
131
+ const latest = artifacts.at(-1) ?? null;
132
+ const reviewedInput = family.startsWith('review-') && latest
133
+ ? resolveReviewedInput(taskDir, latest, family === 'review-analysis' ? 'analysis' : family === 'review-plan' ? 'plan' : 'code', diagnostics)
134
+ : null;
135
+ return {
136
+ status: 'ready', changed: false, requestRef, taskId: identity.taskId ?? null,
137
+ taskDir, taskState: identity.taskState ?? null, family, artifacts, latest,
138
+ next: { round: max + 1, name: artifactName(family, max + 1) },
139
+ reviewedInput, diagnostics, error: null
140
+ };
141
+ }
142
+ function resolveReviewedInput(taskDir, review, expectedFamily, diagnostics) {
143
+ let content;
144
+ try {
145
+ content = fs.readFileSync(review.path, 'utf8');
146
+ }
147
+ catch (error) {
148
+ diagnostics.push(diagnostic('BROKEN_REFERENCE', review.family, review.name, String(error)));
149
+ return null;
150
+ }
151
+ const lines = content.split(/\r?\n/);
152
+ const header = lines.findIndex((line) => /\*\*(?:审查输入|Review Input)\*\*[::]/.test(line));
153
+ const referenceBlock = header >= 0 ? lines.slice(header, header + 12).join('\n') : '';
154
+ const candidates = [...referenceBlock.matchAll(/`([^`]+\.md)`/g)].map((match) => match[1]);
155
+ const parsed = candidates.map((name) => parseArtifactName(name)).find((item) => item?.family === expectedFamily);
156
+ if (!parsed) {
157
+ diagnostics.push(diagnostic('BROKEN_REFERENCE', review.family, review.name, `${review.name} does not reference a canonical ${expectedFamily} artifact`));
158
+ return null;
159
+ }
160
+ const abs = path.join(taskDir, parsed.name);
161
+ try {
162
+ const stat = fs.lstatSync(abs);
163
+ if (!stat.isFile() || stat.isSymbolicLink())
164
+ throw new Error('referenced input is not a regular file');
165
+ if (stat.mtimeMs > review.mtimeMs) {
166
+ diagnostics.push(diagnostic('BROKEN_REFERENCE', review.family, review.name, `${parsed.name} is newer than ${review.name}`));
167
+ return null;
168
+ }
169
+ return { ...parsed, path: abs, size: stat.size, mtimeMs: stat.mtimeMs };
170
+ }
171
+ catch (error) {
172
+ diagnostics.push(diagnostic('BROKEN_REFERENCE', review.family, review.name, `${parsed.name}: ${String(error)}`));
173
+ return null;
174
+ }
175
+ }
176
+ function extractMarkdownSection(content, names) {
177
+ const lines = content.split(/\r?\n/);
178
+ const allowed = new Set(names);
179
+ const start = lines.findIndex((line) => {
180
+ const match = /^##\s+(.+?)\s*$/.exec(line.trim());
181
+ return Boolean(match?.[1] && allowed.has(match[1]));
182
+ });
183
+ if (start === -1)
184
+ return '';
185
+ let end = lines.length;
186
+ for (let index = start + 1; index < lines.length; index += 1) {
187
+ if (/^##\s+/.test(lines[index])) {
188
+ end = index;
189
+ break;
190
+ }
191
+ }
192
+ return lines.slice(start + 1, end).join('\n');
193
+ }
194
+ function assertWritableInventory(inventory) {
195
+ if (inventory.status === 'failed')
196
+ return inventory.error;
197
+ const blockers = inventory.diagnostics.filter((item) => BLOCKING_DIAGNOSTICS.has(item.code));
198
+ return blockers.length === 0 ? null : {
199
+ code: 'ARTIFACT_TOPOLOGY_CONFLICT',
200
+ message: blockers.map((item) => `${item.code}: ${item.message}`).join('; ')
201
+ };
202
+ }
203
+ const REQUIRED_INPUT = {
204
+ 'review-analysis': 'analysis', plan: 'analysis', 'review-plan': 'plan', 'review-code': 'code'
205
+ };
206
+ const OPTIONAL_CONTEXT = {
207
+ analysis: { family: 'review-analysis', requireReference: true },
208
+ plan: { family: 'review-plan', requireReference: true },
209
+ 'review-code': { family: 'review-plan' },
210
+ 'manual-validation': { family: 'review-code' }
211
+ };
212
+ function resolveArtifactContext(taskRef, family, options = {}) {
213
+ const inventory = inspectTaskArtifacts(taskRef, family, options);
214
+ if (inventory.status === 'failed')
215
+ return { ...inventory, inputs: [], codeMode: null };
216
+ const writableError = assertWritableInventory(inventory);
217
+ if (writableError)
218
+ return { ...inventory, status: 'failed', inputs: [], codeMode: null, error: writableError };
219
+ if (inventory.family === 'code')
220
+ return resolveCodeContext(inventory, options);
221
+ const required = REQUIRED_INPUT[inventory.family];
222
+ const inputs = [];
223
+ if (required) {
224
+ const input = inspectTaskArtifacts(taskRef, required, options);
225
+ if (input.status === 'failed' || !input.latest) {
226
+ return { ...inventory, status: 'failed', inputs, codeMode: null, error: { code: 'ARTIFACT_INPUT_MISSING', message: `latest ${required} artifact is required` } };
227
+ }
228
+ inputs.push(input.latest);
229
+ }
230
+ const optional = OPTIONAL_CONTEXT[inventory.family];
231
+ if (optional) {
232
+ const context = inspectTaskArtifacts(taskRef, optional.family, options);
233
+ if (context.status === 'ready' && context.latest) {
234
+ if (optional.requireReference && !context.reviewedInput) {
235
+ return { ...inventory, status: 'failed', inputs, codeMode: null, error: { code: 'ARTIFACT_REFERENCE_INVALID', message: `${context.latest.name} has no valid reviewed input` } };
236
+ }
237
+ inputs.push(context.latest);
238
+ }
239
+ }
240
+ return { ...inventory, inputs, codeMode: null };
241
+ }
242
+ function resolveCodeContext(inventory, options) {
243
+ const taskRef = inventory.requestRef;
244
+ const plan = inspectTaskArtifacts(taskRef, 'plan', options);
245
+ if (plan.status === 'failed' || !plan.latest)
246
+ return contextFailure(inventory, 'ARTIFACT_INPUT_MISSING', 'latest plan artifact is required');
247
+ const reviewPlan = inspectTaskArtifacts(taskRef, 'review-plan', options);
248
+ const reviewCode = inspectTaskArtifacts(taskRef, 'review-code', options);
249
+ const latestCode = inventory.latest;
250
+ const codeMax = latestCode?.round ?? 0;
251
+ const reviewMax = reviewCode.latest?.round ?? 0;
252
+ const inputs = [plan.latest];
253
+ if (!latestCode) {
254
+ if (!reviewPlan.latest || reviewPlan.reviewedInput?.name !== plan.latest.name) {
255
+ return contextFailure(inventory, 'ARTIFACT_INPUT_MISSING', `latest plan '${plan.latest.name}' requires a matching approved review-plan`);
256
+ }
257
+ const verdict = parseVerdict(reviewPlan.latest.path);
258
+ if (!verdict.ok)
259
+ return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', verdict.message, reviewPlan.latest.name);
260
+ if (verdict.verdict !== 'Approved') {
261
+ return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', `latest ${reviewPlan.latest.name} is not approved`, reviewPlan.latest.name);
262
+ }
263
+ return withCodeMode(inventory, inputs, 'ready', 'init', codeMax, reviewMax, null, null, 'No prior code artifact. Starting initial implementation (round 1 -> code.md).');
264
+ }
265
+ if (reviewPlan.latest && reviewPlan.reviewedInput?.name === plan.latest.name) {
266
+ const verdict = parseVerdict(reviewPlan.latest.path);
267
+ if (verdict.ok && verdict.verdict === 'Approved' && reviewPlan.latest.mtimeMs > latestCode.mtimeMs) {
268
+ return withCodeMode(inventory, inputs, 'ready', 'init', codeMax, reviewMax, verdict.verdict, reviewPlan.latest.name, `Latest ${reviewPlan.latest.name} is approved and newer than the latest code artifact. Entering replan-driven init.`);
269
+ }
270
+ }
271
+ if (reviewMax < codeMax) {
272
+ const expected = artifactName('review-code', codeMax);
273
+ return contextFailure(inventory, 'ARTIFACT_INPUT_MISSING', `${expected} is required before another code round`, expected);
274
+ }
275
+ const review = reviewCode.latest;
276
+ if (!review)
277
+ return contextFailure(inventory, 'ARTIFACT_INPUT_MISSING', 'latest review-code artifact is required');
278
+ const verdict = parseVerdict(review.path);
279
+ if (!verdict.ok)
280
+ return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', verdict.message);
281
+ if (verdict.verdict === 'Approved') {
282
+ const decision = resolveDecisionImplementationInput(inventory, review);
283
+ if ('error' in decision)
284
+ return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', decision.error, review.name);
285
+ if (decision.input) {
286
+ return withCodeMode(inventory, [...inputs, review], 'ready', 'decision', codeMax, reviewMax, verdict.verdict, review.name, `Implementation input ${decision.input.id} requires a new code round.`, decision.input.id, decision.input.ledgerId, decision.input.decisionEvidence);
287
+ }
288
+ }
289
+ if (verdict.verdict === 'Approved' || verdict.verdict === 'Rejected') {
290
+ return withCodeMode(inventory, [...inputs, review], 'refused', 'refused', codeMax, reviewMax, verdict.verdict, review.name, verdict.verdict === 'Approved'
291
+ ? `Latest ${review.name} verdict is Approved with no findings. Nothing to fix. Run /commit to proceed.`
292
+ : `Latest ${review.name} verdict is Rejected. Re-plan before re-running code-task.`);
293
+ }
294
+ return withCodeMode(inventory, [...inputs, review], 'ready', 'fix', codeMax, reviewMax, verdict.verdict, review.name, `Latest ${review.name} requires or permits fixes. Entering fix mode.`);
295
+ }
296
+ function contextFailure(inventory, code, message, reviewArtifact = null) {
297
+ return { ...inventory, status: 'failed', inputs: [], codeMode: { mode: 'error', codeMax: inventory.latest?.round ?? 0, reviewMax: 0, verdict: null, reviewArtifact, implementationInput: null, decisionId: null, decisionEvidence: null, message }, error: { code, message } };
298
+ }
299
+ function withCodeMode(inventory, inputs, status, mode, codeMax, reviewMax, verdict, reviewArtifact, message, implementationInput = null, decisionId = null, decisionEvidence = null) {
300
+ return { ...inventory, status, inputs, codeMode: { mode, codeMax, reviewMax, verdict, reviewArtifact, implementationInput, decisionId, decisionEvidence, message }, error: status === 'refused' ? { code: 'ARTIFACT_MODE_REFUSED', message } : null };
301
+ }
302
+ function resolveDecisionImplementationInput(inventory, review) {
303
+ if (!inventory.taskDir)
304
+ return { error: 'task directory is unavailable' };
305
+ let content;
306
+ try {
307
+ content = fs.readFileSync(path.join(inventory.taskDir, 'task.md'), 'utf8');
308
+ }
309
+ catch (error) {
310
+ return { error: String(error) };
311
+ }
312
+ let rows;
313
+ try {
314
+ rows = parseImplementationInputs(content).rows;
315
+ }
316
+ catch (error) {
317
+ return { error: error instanceof Error ? error.message : String(error) };
318
+ }
319
+ const pending = rows.filter((row) => row.needsImplementation && row.status === 'pending');
320
+ if (pending.length === 0)
321
+ return { input: null };
322
+ const activity = locateActivityLog(content);
323
+ if (!activity)
324
+ return { error: 'task has no unique Activity Log section' };
325
+ const reviewEntries = activity.entries.filter((entry) => /^Review Code \(Round \d+\)$/.test(entry.step) && entry.note.includes(`→ ${review.name}`));
326
+ const completed = reviewEntries.at(-1);
327
+ if (!completed)
328
+ return { error: `cannot find completed Activity Log identity for ${review.name}` };
329
+ try {
330
+ return { input: selectPendingImplementationInput(rows, completed.time) };
331
+ }
332
+ catch (error) {
333
+ return { error: error instanceof Error ? error.message : String(error) };
334
+ }
335
+ }
336
+ function normalizeVerdict(value) {
337
+ const normalized = value.trim().toLowerCase();
338
+ if (normalized === '通过' || normalized === 'approved')
339
+ return 'Approved';
340
+ if (normalized === '需要修改' || normalized === 'changes requested')
341
+ return 'Changes Requested';
342
+ if (normalized === '拒绝' || normalized === 'rejected')
343
+ return 'Rejected';
344
+ return null;
345
+ }
346
+ function parseVerdict(file) {
347
+ let content;
348
+ try {
349
+ content = fs.readFileSync(file, 'utf8');
350
+ }
351
+ catch (error) {
352
+ return { ok: false, message: String(error) };
353
+ }
354
+ const summary = extractMarkdownSection(content, ['审查摘要', 'Review Summary']);
355
+ const verdictMatch = /^[-*]?\s*\*\*(?:总体结论|Overall Verdict)\*\*[::]\s*(.+?)\s*$/im.exec(summary);
356
+ const verdict = verdictMatch?.[1] ? normalizeVerdict(verdictMatch[1]) : null;
357
+ if (!verdict)
358
+ return { ok: false, message: `cannot parse verdict in ${path.basename(file)}` };
359
+ if (verdict !== 'Approved')
360
+ return { ok: true, verdict };
361
+ const findings = /^[-*]?\s*\*\*(?:发现(AI 可处理)|Findings \(AI-actionable\))\*\*[::]\s*(.+?)\s*$/im.exec(summary)?.[1];
362
+ const counts = findings?.match(/(\d+)\s*(?:阻塞项|blockers?).*?(\d+)\s*(?:主要|majors?).*?(\d+)\s*(?:次要|minors?)/i);
363
+ if (!counts)
364
+ return { ok: false, message: `cannot parse findings count in ${path.basename(file)}` };
365
+ return { ok: true, verdict: counts.slice(1).some((value) => Number(value) > 0) ? 'Approved-with-issues' : 'Approved' };
366
+ }
367
+ function validateCompletedArtifact(taskDir, family, name, round) {
368
+ if (path.basename(name) !== name)
369
+ return { ok: false, error: { code: 'ARTIFACT_PATH_INVALID', message: 'artifact must be a top-level basename' } };
370
+ const parsed = parseArtifactName(name);
371
+ if (!parsed || parsed.family !== family || (round !== undefined && parsed.round !== round)) {
372
+ return { ok: false, error: { code: 'ARTIFACT_IDENTITY_INVALID', message: `artifact '${name}' does not match ${family}${round ? ` round ${round}` : ''}` } };
373
+ }
374
+ const abs = path.join(taskDir, name);
375
+ let stat;
376
+ try {
377
+ stat = fs.lstatSync(abs);
378
+ }
379
+ catch {
380
+ return { ok: false, error: { code: 'ARTIFACT_NOT_FOUND', message: `artifact '${name}' is not landed` } };
381
+ }
382
+ if (stat.isSymbolicLink() || !stat.isFile())
383
+ return { ok: false, error: { code: 'ARTIFACT_NOT_REGULAR', message: `artifact '${name}' is not a regular file` } };
384
+ try {
385
+ fs.accessSync(abs, fs.constants.R_OK);
386
+ }
387
+ catch {
388
+ return { ok: false, error: { code: 'ARTIFACT_NOT_READABLE', message: `artifact '${name}' is not readable` } };
389
+ }
390
+ const inventory = inspectArtifactDirectory(taskDir, family);
391
+ const topology = assertWritableInventory(inventory);
392
+ if (topology)
393
+ return { ok: false, error: topology };
394
+ const artifact = inventory.artifacts.find((item) => item.name === name);
395
+ return artifact ? { ok: true, artifact } : { ok: false, error: { code: 'ARTIFACT_NOT_FOUND', message: `artifact '${name}' is not in inventory` } };
396
+ }
397
+ function buildArtifactLinkSection(content, artifact) {
398
+ const spec = familySpec(artifact.family);
399
+ const aliases = [...spec.sectionAliases];
400
+ const heading = findSectionHeading(content, aliases);
401
+ const english = heading === spec.sectionAliases[1];
402
+ const label = english
403
+ ? `${spec.labels[1]} (Round ${artifact.round})`
404
+ : `${spec.labels[0]}(Round ${artifact.round})`;
405
+ const link = `[${label}](${artifact.name})`;
406
+ let body = extractSection(content, aliases);
407
+ if (body.includes(`](${artifact.name})`))
408
+ return { aliases, heading, body };
409
+ const placeholders = new Set([
410
+ '[分析阶段的发现。哪些文件受影响?范围是什么?]',
411
+ '[Findings from the analysis phase. Which files are affected? What is the scope?]',
412
+ '[技术方案。接口、数据流、架构决策。]',
413
+ '[Technical approach. Interfaces, data flow, architecture decisions.]',
414
+ '[实现阶段的备注。做出的决策、权衡、与设计的偏差。]',
415
+ '[Notes from the code phase. Decisions made, trade-offs, deviations from design.]'
416
+ ]);
417
+ const lines = body.split(/\r?\n/);
418
+ const placeholder = lines.findIndex((line) => placeholders.has(line.trim()));
419
+ if (placeholder >= 0)
420
+ lines[placeholder] = link;
421
+ else
422
+ lines.push(...(body ? ['', link] : [link]));
423
+ body = lines.join('\n').replace(/^\n+|\n+$/g, '');
424
+ return { aliases, heading, body };
425
+ }
426
+ export { artifactFamilyCatalog, artifactName, parseArtifactName, familySpec, inspectTaskArtifacts, inspectArtifactDirectory, resolveArtifactContext, assertWritableInventory, validateCompletedArtifact, buildArtifactLinkSection };
427
+ //# sourceMappingURL=artifact-lifecycle.js.map
@@ -0,0 +1,30 @@
1
+ function parseTaskScope(args) {
2
+ const positionals = [];
3
+ let taskRef;
4
+ let explicit = false;
5
+ for (let index = 0; index < args.length; index += 1) {
6
+ const arg = args[index];
7
+ let value;
8
+ if (arg === '--task' || arg === '-t') {
9
+ value = args[++index];
10
+ if (value === undefined || value === '' || value.startsWith('-'))
11
+ throw new Error(`${arg} requires a value`);
12
+ }
13
+ else if (arg.startsWith('--task=')) {
14
+ value = arg.slice('--task='.length);
15
+ if (value === '')
16
+ throw new Error('--task requires a value');
17
+ }
18
+ else {
19
+ positionals.push(arg);
20
+ continue;
21
+ }
22
+ if (explicit)
23
+ throw new Error("duplicate option '--task'");
24
+ taskRef = value;
25
+ explicit = true;
26
+ }
27
+ return { taskRef, positionals, explicit };
28
+ }
29
+ export { parseTaskScope };
30
+ //# sourceMappingURL=command-options.js.map
@@ -1,10 +1,14 @@
1
1
  import fs from 'node:fs';
2
- import { resolveTaskRef } from '../resolve-ref.js';
2
+ import { parseTaskScope } from '../command-options.js';
3
+ import { resolveTaskContext } from '../resolve-ref.js';
3
4
  import { resolveArtifact } from '../artifacts.js';
4
- const USAGE = `Usage: ai task cat <N | #N | TASK-id> <artifact | N>
5
+ const USAGE = `Usage: ai task cat <artifact | N>
6
+ ai task cat (--task <ref> | -t <ref>) <artifact | N>
7
+ ai task cat <ref> <artifact | N>
5
8
 
6
9
  Prints a task artifact's raw content to stdout.
7
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
10
+ One positional Uses current task context and treats the operand as the artifact.
11
+ <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
8
12
  <artifact | N> Artifact filename (with or without '.md'), or the number from 'ai task files'.
9
13
  `;
10
14
  function cat(args = []) {
@@ -12,12 +16,38 @@ function cat(args = []) {
12
16
  process.stdout.write(USAGE);
13
17
  return;
14
18
  }
15
- if (args.length < 2) {
19
+ let scope;
20
+ try {
21
+ scope = parseTaskScope(args);
22
+ }
23
+ catch (error) {
24
+ process.stderr.write(`ai task cat: ${error instanceof Error ? error.message : String(error)}\n`);
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ let taskRef;
29
+ let artifact;
30
+ if (scope.explicit) {
31
+ if (scope.positionals.length !== 1) {
32
+ process.stdout.write(USAGE);
33
+ process.exitCode = 1;
34
+ return;
35
+ }
36
+ taskRef = scope.taskRef;
37
+ artifact = scope.positionals[0];
38
+ }
39
+ else if (scope.positionals.length === 1) {
40
+ artifact = scope.positionals[0];
41
+ }
42
+ else if (scope.positionals.length === 2) {
43
+ [taskRef, artifact] = scope.positionals;
44
+ }
45
+ else {
16
46
  process.stdout.write(USAGE);
17
47
  process.exitCode = 1;
18
48
  return;
19
49
  }
20
- const resolved = resolveTaskRef(args[0]);
50
+ const resolved = resolveTaskContext(taskRef);
21
51
  if (!resolved.ok) {
22
52
  process.stderr.write(`ai task cat: ${resolved.message}\n`);
23
53
  process.exitCode = 1;
@@ -25,7 +55,7 @@ function cat(args = []) {
25
55
  }
26
56
  let artifactPath;
27
57
  try {
28
- artifactPath = resolveArtifact(resolved.taskDir, args[1]);
58
+ artifactPath = resolveArtifact(resolved.taskDir, artifact);
29
59
  }
30
60
  catch (e) {
31
61
  process.stderr.write(`ai task cat: ${e.message}\n`);