@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
@@ -1,11 +1,15 @@
1
1
  import fs from 'node:fs';
2
- import { resolveTaskRef } from '../resolve-ref.ts';
2
+ import { parseTaskScope } from '../command-options.ts';
3
+ import { resolveTaskContext } from '../resolve-ref.ts';
3
4
  import { resolveArtifact } from '../artifacts.ts';
4
5
 
5
- const USAGE = `Usage: ai task cat <N | #N | TASK-id> <artifact | N>
6
+ const USAGE = `Usage: ai task cat <artifact | N>
7
+ ai task cat (--task <ref> | -t <ref>) <artifact | N>
8
+ ai task cat <ref> <artifact | N>
6
9
 
7
10
  Prints a task artifact's raw content to stdout.
8
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
11
+ One positional Uses current task context and treats the operand as the artifact.
12
+ <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
9
13
  <artifact | N> Artifact filename (with or without '.md'), or the number from 'ai task files'.
10
14
  `;
11
15
 
@@ -14,12 +18,21 @@ function cat(args: string[] = []): void {
14
18
  process.stdout.write(USAGE);
15
19
  return;
16
20
  }
17
- if (args.length < 2) {
18
- process.stdout.write(USAGE);
19
- process.exitCode = 1;
20
- return;
21
+ let scope;
22
+ try { scope = parseTaskScope(args); } catch (error) {
23
+ process.stderr.write(`ai task cat: ${error instanceof Error ? error.message : String(error)}\n`); process.exitCode = 1; return;
21
24
  }
22
- const resolved = resolveTaskRef(args[0]!);
25
+ let taskRef: string | undefined;
26
+ let artifact: string | undefined;
27
+ if (scope.explicit) {
28
+ if (scope.positionals.length !== 1) { process.stdout.write(USAGE); process.exitCode = 1; return; }
29
+ taskRef = scope.taskRef; artifact = scope.positionals[0];
30
+ } else if (scope.positionals.length === 1) {
31
+ artifact = scope.positionals[0];
32
+ } else if (scope.positionals.length === 2) {
33
+ [taskRef, artifact] = scope.positionals;
34
+ } else { process.stdout.write(USAGE); process.exitCode = 1; return; }
35
+ const resolved = resolveTaskContext(taskRef);
23
36
  if (!resolved.ok) {
24
37
  process.stderr.write(`ai task cat: ${resolved.message}\n`);
25
38
  process.exitCode = 1;
@@ -27,7 +40,7 @@ function cat(args: string[] = []): void {
27
40
  }
28
41
  let artifactPath: string;
29
42
  try {
30
- artifactPath = resolveArtifact(resolved.taskDir, args[1]!);
43
+ artifactPath = resolveArtifact(resolved.taskDir, artifact!);
31
44
  } catch (e) {
32
45
  process.stderr.write(`ai task cat: ${(e as Error).message}\n`);
33
46
  process.exitCode = 1;
@@ -1,19 +1,24 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { formatTable } from '../../table.ts';
4
- import { resolveTaskRef } from '../resolve-ref.ts';
5
- import { parseLedger, HUMAN_DECISION_STATUSES, type LedgerRow } from '../ledger.ts';
4
+ import { parseTaskScope } from '../command-options.ts';
5
+ import { resolveTaskContext } from '../resolve-ref.ts';
6
+ import { isReviewStage, parseLedger, type LedgerRow, type ReviewStage } from '../ledger.ts';
7
+ import { listDecisionItems, selectDecisionItem } from '../decision-items.ts';
6
8
  import { extractSubSection } from '../sections.ts';
7
9
 
8
- const USAGE = `Usage: ai task decisions <N | #N | TASK-id> [selector] [options]
10
+ const USAGE = `Usage: ai task decisions [--task <ref> | -t <ref>] [--item <selector> | -i <selector>] [options]
11
+ ai task decisions <ref> [selector] [options]
9
12
 
10
- Lists the human-decision (HD-) items recorded in a task's review disagreement
13
+ Lists decision items recorded in a task's review disagreement
11
14
  ledger, or prints the full detail block for a single item. Read-only.
12
15
 
13
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
14
- [selector] Ordinal (1-based) or HD id (e.g. 'HD-3') to show one item's detail.
16
+ Omit <ref> Resolve the unique active task for the current branch.
17
+ <ref> Legacy positional task ref.
18
+ [selector] Ordinal (1-based) or ledger id (e.g. 'PL-3') to show one item's detail.
15
19
 
16
20
  Options:
21
+ -i, --item <s> Select an item when task scope is implicit or flag-based.
17
22
  --all Include already-decided (human-decided) items, not just pending.
18
23
  --stage <s> Filter to one stage: analysis | plan | code.
19
24
  --format <fmt> Output format: text (default) | markdown.
@@ -22,9 +27,7 @@ Options:
22
27
  Aliased as 'ai task d'.
23
28
  `;
24
29
 
25
- const STAGES = new Set(['analysis', 'plan', 'code']);
26
30
  const FORMATS = new Set(['text', 'markdown']);
27
- const HD_ID_RE = /^HD-\d+$/;
28
31
 
29
32
  function fail(message: string): void {
30
33
  process.stderr.write(`ai task decisions: ${message}\n`);
@@ -33,6 +36,7 @@ function fail(message: string): void {
33
36
 
34
37
  type ParsedArgs = {
35
38
  positionals: string[];
39
+ item?: string;
36
40
  all: boolean;
37
41
  stage?: string;
38
42
  format: string;
@@ -45,6 +49,15 @@ function parseArgs(args: string[]): ParsedArgs | null {
45
49
  const a = args[i]!;
46
50
  if (a === '--all') {
47
51
  out.all = true;
52
+ } else if (a === '--item' || a === '-i') {
53
+ const v = args[i + 1];
54
+ if (v === undefined) { fail(`${a} requires a value`); return null; }
55
+ if (out.item !== undefined) { fail("duplicate option '--item'"); return null; }
56
+ out.item = v; i += 1;
57
+ } else if (a.startsWith('--item=')) {
58
+ if (out.item !== undefined) { fail("duplicate option '--item'"); return null; }
59
+ out.item = a.slice('--item='.length);
60
+ if (out.item === '') { fail('--item requires a value'); return null; }
48
61
  } else if (a === '--stage') {
49
62
  const v = args[i + 1];
50
63
  if (v === undefined) {
@@ -86,7 +99,7 @@ function roundOf(file: string): number {
86
99
  return m ? Number.parseInt(m[1]!, 10) : 1;
87
100
  }
88
101
 
89
- // Locate the `### HD-N` detail block for a row. Prefer the artifact named by the
102
+ // Locate the `### {ledger-id}` detail block for a row. Prefer the artifact named by the
90
103
  // row's evidence anchor; otherwise scan analysis/plan/code artifacts and return
91
104
  // the block from the highest-round file that contains it. Returns '' when none
92
105
  // is found (caller degrades gracefully — plan B3).
@@ -118,12 +131,12 @@ function findDetailBlock(row: LedgerRow, taskDir: string): string {
118
131
  return best;
119
132
  }
120
133
 
121
- // Pull the `## 人工裁决` record lines that mention this HD id, so a decided item
134
+ // Pull the `## 人工裁决` record lines that mention this ledger id, so a decided item
122
135
  // shows the human's recorded ruling alongside its detail block.
123
136
  function findDecisionRecord(id: string, content: string): string[] {
124
137
  const lines = content.split('\n');
125
138
  let i = 0;
126
- while (i < lines.length && !/^##\s+(人工裁决|Human Decisions?)\s*$/.test(lines[i]!)) i += 1;
139
+ while (i < lines.length && !/^##\s+(人工裁决|Human Rulings|Human Decisions?)\s*$/.test(lines[i]!)) i += 1;
127
140
  if (i >= lines.length) return [];
128
141
  const idRe = new RegExp(`(^|[^\\w-])${id}(?![\\w-])`);
129
142
  const out: string[] = [];
@@ -181,29 +194,12 @@ function renderDetail(
181
194
  taskDir: string,
182
195
  content: string
183
196
  ): void {
184
- let row: LedgerRow | undefined;
185
- if (/^\d+$/.test(selector)) {
186
- const idx = Number.parseInt(selector, 10) - 1;
187
- if (idx < 0 || idx >= rows.length) {
188
- fail(`ordinal '${selector}' out of range (1..${rows.length})`);
189
- return;
190
- }
191
- row = rows[idx];
192
- } else {
193
- const want = selector.toUpperCase();
194
- const matches = rows.filter((r) => r.id.toUpperCase() === want);
195
- if (matches.length === 0) {
196
- fail(`no decision item matches '${selector}'`);
197
- return;
198
- }
199
- if (matches.length > 1) {
200
- fail(`duplicate id '${selector}' in ledger; select by ordinal instead`);
201
- return;
202
- }
203
- row = matches[0];
197
+ const selected = selectDecisionItem(rows, selector);
198
+ if (!selected.ok) {
199
+ fail(selected.message);
200
+ return;
204
201
  }
205
-
206
- const r = row!;
202
+ const r = selected.row;
207
203
  const block = findDetailBlock(r, taskDir);
208
204
  const lines: string[] = [];
209
205
  if (format === 'markdown') {
@@ -232,14 +228,11 @@ function decisions(args: string[] = []): void {
232
228
  process.stdout.write(USAGE);
233
229
  return;
234
230
  }
235
- const parsed = parseArgs(args);
231
+ let scope;
232
+ try { scope = parseTaskScope(args); } catch (error) { fail(error instanceof Error ? error.message : String(error)); return; }
233
+ const parsed = parseArgs(scope.positionals);
236
234
  if (!parsed) return;
237
- if (parsed.positionals.length === 0) {
238
- process.stdout.write(USAGE);
239
- process.exitCode = 1;
240
- return;
241
- }
242
- if (parsed.stage !== undefined && !STAGES.has(parsed.stage)) {
235
+ if (parsed.stage !== undefined && !isReviewStage(parsed.stage)) {
243
236
  fail(`invalid --stage '${parsed.stage}' (expected analysis|plan|code)`);
244
237
  return;
245
238
  }
@@ -248,20 +241,29 @@ function decisions(args: string[] = []): void {
248
241
  return;
249
242
  }
250
243
 
251
- const resolved = resolveTaskRef(parsed.positionals[0]!);
244
+ let taskRef = scope.taskRef;
245
+ let selector = parsed.item;
246
+ if (parsed.item !== undefined) {
247
+ if (parsed.positionals.length > 0) { fail('positional task ref/selector cannot be combined with --item'); return; }
248
+ } else if (scope.explicit) {
249
+ if (parsed.positionals.length > 0) { fail('positional task ref/selector cannot be combined with --task'); return; }
250
+ } else {
251
+ if (parsed.positionals.length > 2) { fail('too many positional arguments'); return; }
252
+ taskRef = parsed.positionals[0];
253
+ selector = parsed.positionals[1];
254
+ }
255
+ const resolved = resolveTaskContext(taskRef);
252
256
  if (!resolved.ok) {
253
257
  fail(resolved.message);
254
258
  return;
255
259
  }
256
260
 
257
261
  const content = fs.readFileSync(resolved.taskMdPath, 'utf8');
258
- let rows = parseLedger(content).filter((r) => HD_ID_RE.test(r.id));
259
- rows = rows.filter((r) =>
260
- parsed.all ? HUMAN_DECISION_STATUSES.has(r.status) : r.status === 'needs-human-decision'
261
- );
262
- if (parsed.stage !== undefined) rows = rows.filter((r) => r.stage === parsed.stage);
262
+ const rows = listDecisionItems(parseLedger(content), {
263
+ includeDecided: parsed.all,
264
+ stage: parsed.stage as ReviewStage | undefined
265
+ });
263
266
 
264
- const selector = parsed.positionals[1];
265
267
  if (selector === undefined) {
266
268
  renderList(rows, parsed.format, resolved.taskDir);
267
269
  } else {
@@ -1,11 +1,13 @@
1
1
  import { formatTable } from '../../table.ts';
2
- import { resolveTaskRef } from '../resolve-ref.ts';
2
+ import { parseTaskScope } from '../command-options.ts';
3
+ import { resolveTaskContext } from '../resolve-ref.ts';
3
4
  import { enumerateArtifacts } from '../artifacts.ts';
4
5
 
5
- const USAGE = `Usage: ai task files <N | #N | TASK-id>
6
+ const USAGE = `Usage: ai task files [<N | TASK-id> | --task <ref> | -t <ref>]
6
7
 
7
8
  Lists the artifacts in a task directory with stable numbers.
8
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
9
+ Omit <ref> Resolve the unique active task for the current branch.
10
+ <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
9
11
 
10
12
  Columns: # (artifact number, usable with 'ai task cat') / NAME / SIZE (bytes) / MTIME
11
13
  `;
@@ -25,12 +27,18 @@ function formatMtime(mtimeMs: number): string {
25
27
  }
26
28
 
27
29
  function files(args: string[] = []): void {
28
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
30
+ if (args[0] === '--help' || args[0] === '-h') {
29
31
  process.stdout.write(USAGE);
30
- if (args.length === 0) process.exitCode = 1;
31
32
  return;
32
33
  }
33
- const resolved = resolveTaskRef(args[0]!);
34
+ let scope;
35
+ try { scope = parseTaskScope(args); } catch (error) {
36
+ process.stderr.write(`ai task files: ${error instanceof Error ? error.message : String(error)}\n`); process.exitCode = 1; return;
37
+ }
38
+ if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
39
+ process.stderr.write('ai task files: task ref must be provided once\n'); process.exitCode = 1; return;
40
+ }
41
+ const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
34
42
  if (!resolved.ok) {
35
43
  process.stderr.write(`ai task files: ${resolved.message}\n`);
36
44
  process.exitCode = 1;
@@ -1,14 +1,15 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { resolveTaskRef, detectRepoRoot, enumerateTaskDirs } from '../resolve-ref.ts';
3
+ import { resolveTaskContext, resolveTaskRef, detectRepoRoot, enumerateTaskDirs } from '../resolve-ref.ts';
4
4
  import { enumerateArtifacts, resolveArtifact } from '../artifacts.ts';
5
5
  import { loadShortIdByTaskId } from '../short-id.ts';
6
6
 
7
7
  const USAGE = `Usage: ai task grep <pattern> [ref] [artifact | N]
8
+ ai task grep <pattern> (--current | --task <ref> | -t <ref>) [artifact | N]
8
9
 
9
10
  Literal (non-regex) line search across task artifacts.
10
11
  <pattern> Literal substring to match (NOT a regex). Case-sensitive by default.
11
- [ref] Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
+ [ref] Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
13
  Omit to scan every task under active / blocked / completed
13
14
  (archive is skipped). With a ref, narrows to that single task
14
15
  (a TASK-id ref can also resolve an archived task).
@@ -17,6 +18,8 @@ Literal (non-regex) line search across task artifacts.
17
18
 
18
19
  Options:
19
20
  -i, --ignore-case Case-insensitive matching.
21
+ --current Limit search to the current task context.
22
+ -t, --task <ref> Limit search to an explicit task.
20
23
  -- Treat the rest as positional (use for patterns starting with '-').
21
24
 
22
25
  Output: '{taskId} [#short] {fileStem}:{line}: {matched-line}' (short id only for active tasks).
@@ -62,14 +65,31 @@ function scanArtifact(
62
65
  function grep(args: string[] = []): void {
63
66
  const positional: string[] = [];
64
67
  let ignoreCase = false;
68
+ let current = false;
69
+ let taskRef: string | undefined;
65
70
  let optsEnded = false;
66
- for (const a of args) {
71
+ for (let index = 0; index < args.length; index += 1) {
72
+ const a = args[index]!;
67
73
  if (!optsEnded && a === '--') { optsEnded = true; continue; }
68
74
  if (!optsEnded && (a === '-h' || a === '--help')) {
69
75
  process.stdout.write(USAGE);
70
76
  return;
71
77
  }
72
78
  if (!optsEnded && (a === '-i' || a === '--ignore-case')) { ignoreCase = true; continue; }
79
+ if (!optsEnded && a === '--current') { current = true; continue; }
80
+ if (!optsEnded && (a === '--task' || a === '-t')) {
81
+ if (taskRef !== undefined) { process.stderr.write("ai task grep: duplicate option '--task'\n"); process.exitCode = 1; return; }
82
+ const value = args[++index];
83
+ if (!value || value.startsWith('-')) { process.stderr.write(`ai task grep: ${a} requires a value\n`); process.exitCode = 1; return; }
84
+ taskRef = value;
85
+ continue;
86
+ }
87
+ if (!optsEnded && a.startsWith('--task=')) {
88
+ if (taskRef !== undefined) { process.stderr.write("ai task grep: duplicate option '--task'\n"); process.exitCode = 1; return; }
89
+ taskRef = a.slice('--task='.length);
90
+ if (taskRef === '') { process.stderr.write('ai task grep: --task requires a value\n'); process.exitCode = 1; return; }
91
+ continue;
92
+ }
73
93
  if (!optsEnded && a.startsWith('-') && a !== '-') {
74
94
  process.stderr.write(`ai task grep: unknown flag: ${a}\n`);
75
95
  process.exitCode = 1;
@@ -83,19 +103,26 @@ function grep(args: string[] = []): void {
83
103
  process.exitCode = 1;
84
104
  return;
85
105
  }
86
- if (positional.length > 3) {
106
+ if (current && taskRef !== undefined) {
107
+ process.stderr.write('ai task grep: --current and --task are mutually exclusive\n'); process.exitCode = 1; return;
108
+ }
109
+ if (positional.length > 3 || ((current || taskRef !== undefined) && positional.length > 2)) {
87
110
  process.stderr.write('ai task grep: too many arguments\n');
88
111
  process.exitCode = 1;
89
112
  return;
90
113
  }
91
114
 
92
- const [pattern, ref, artifactOrN] = positional;
115
+ let [pattern, ref, artifactOrN] = positional;
116
+ if (current || taskRef !== undefined) {
117
+ artifactOrN = ref;
118
+ ref = taskRef;
119
+ }
93
120
  const matcher = makeMatcher(pattern!, ignoreCase);
94
121
  const chunks: string[] = [];
95
122
  const emit = (line: string) => chunks.push(line);
96
123
  let total = 0;
97
124
 
98
- if (ref === undefined) {
125
+ if (ref === undefined && !current) {
99
126
  // No ref: full scan across active / blocked / completed (no archive).
100
127
  let repoRoot: string;
101
128
  try {
@@ -113,7 +140,7 @@ function grep(args: string[] = []): void {
113
140
  }
114
141
  }
115
142
  } else {
116
- const resolved = resolveTaskRef(ref);
143
+ const resolved = current ? resolveTaskContext() : resolveTaskRef(ref!);
117
144
  if (!resolved.ok) {
118
145
  process.stderr.write(`ai task grep: ${resolved.message}\n`);
119
146
  process.exitCode = 1;
@@ -1,14 +1,16 @@
1
1
  import fs from 'node:fs';
2
- import { resolveTaskRef } from '../resolve-ref.ts';
2
+ import { parseTaskScope } from '../command-options.ts';
3
+ import { resolveTaskContext } from '../resolve-ref.ts';
3
4
  import { extractTitle } from '../frontmatter.ts';
4
5
  import { extractSection, findSectionHeading } from '../sections.ts';
5
6
  import { renderTemplateBody, PLACEHOLDER } from '../issue-form.ts';
6
7
  import type { TaskFields } from '../issue-form.ts';
7
8
 
8
- const USAGE = `Usage: ai task issue-body <N | #N | TASK-id> [--template <path>]
9
+ const USAGE = `Usage: ai task issue-body [<ref> | --task <ref> | -t <ref>] [--template <path>]
9
10
 
10
11
  Print a deterministic Issue body extracted from a task's task.md.
11
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
+ Omit <ref> Resolve the unique active task for the current branch.
13
+ <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
14
  --template <path> Render the final body for the given GitHub Issue Form (scenario A);
13
15
  without it, print the default '描述 + 需求' body (scenario B).
14
16
 
@@ -40,28 +42,19 @@ function readTaskFields(content: string): TaskFields {
40
42
  }
41
43
 
42
44
  function issueBody(args: string[] = []): void {
43
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
45
+ if (args[0] === '--help' || args[0] === '-h') {
44
46
  process.stdout.write(USAGE);
45
- if (args.length === 0) process.exitCode = 1;
46
47
  return;
47
48
  }
48
49
 
49
- let ref: string | undefined;
50
50
  let templatePath: string | undefined;
51
+ const scopeArgs: string[] = [];
51
52
  for (let i = 0; i < args.length; i += 1) {
52
53
  const arg = args[i]!;
53
54
  if (arg === '--template') {
54
55
  templatePath = args[i + 1];
55
56
  i += 1;
56
- } else if (ref === undefined) {
57
- ref = arg;
58
- }
59
- }
60
-
61
- if (!ref) {
62
- process.stderr.write('ai task issue-body: missing task ref\n');
63
- process.exitCode = 1;
64
- return;
57
+ } else { scopeArgs.push(arg); }
65
58
  }
66
59
  if (templatePath === undefined && args.includes('--template')) {
67
60
  process.stderr.write('ai task issue-body: --template requires a path\n');
@@ -69,7 +62,14 @@ function issueBody(args: string[] = []): void {
69
62
  return;
70
63
  }
71
64
 
72
- const resolved = resolveTaskRef(ref);
65
+ let scope;
66
+ try { scope = parseTaskScope(scopeArgs); } catch (error) {
67
+ process.stderr.write(`ai task issue-body: ${error instanceof Error ? error.message : String(error)}\n`); process.exitCode = 1; return;
68
+ }
69
+ if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
70
+ process.stderr.write('ai task issue-body: task ref must be provided once\n'); process.exitCode = 1; return;
71
+ }
72
+ const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
73
73
  if (!resolved.ok) {
74
74
  process.stderr.write(`ai task issue-body: ${resolved.message}\n`);
75
75
  process.exitCode = 1;
@@ -1,14 +1,17 @@
1
1
  import fs from 'node:fs';
2
2
  import { formatTable } from '../../table.ts';
3
- import { resolveTaskRef } from '../resolve-ref.ts';
4
- import { parseLedger, type LedgerRow } from '../ledger.ts';
3
+ import { parseTaskScope } from '../command-options.ts';
4
+ import { resolveTaskContext } from '../resolve-ref.ts';
5
+ import { isReviewStage, parseLedger, type LedgerRow, type ReviewStage } from '../ledger.ts';
6
+ import { parseActivityLog, pairEntries } from '../activity-log.ts';
5
7
 
6
- const USAGE = `Usage: ai task log <N | #N | TASK-id>
8
+ const USAGE = `Usage: ai task log [<N | TASK-id> | --task <ref> | -t <ref>]
7
9
 
8
10
  Renders a task's activity log as a per-step status table. A step's start and
9
11
  completion are paired onto one row: STARTED holds the start time, DONE the
10
12
  completion time (or '(in progress)' while still running).
11
- <ref> Bare numeric / '#N' short id, or a full TASK-YYYYMMDD-HHMMSS id.
13
+ Omit <ref> Resolve the unique active task for the current branch.
14
+ <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
15
 
13
16
  Columns: # (row) / STEP / AGENT / STARTED / DONE / NOTE
14
17
  A human-executed step shows AGENT as 'human' and, when it has no start marker,
@@ -20,27 +23,17 @@ Columns: # (row) / STEP / AGENT / STARTED / DONE / NOTE
20
23
  const TABLE_HEADERS = ['#', 'STEP', 'AGENT', 'STARTED', 'DONE', 'NOTE'] as const;
21
24
 
22
25
  // The activity-log H2 heading is language-dependent (zh template / en template).
23
- const HEADING_RE = /^##\s+(活动日志|Activity Log)\s*$/;
24
- const NEXT_H2_RE = /^##\s/;
25
26
  // `- {time} — **{step}** by {agent} — {note}` ; the separator is an em-dash
26
27
  // (U+2014). STEP/AGENT are non-greedy so a note that itself contains ' — ' or
27
28
  // '→' is not mis-split; NOTE greedily takes the rest of the line.
28
- const ENTRY_RE =
29
- /^- (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}) — \*\*(.+?)\*\* by (.+?) — (.*)$/;
30
-
31
- type LogEntry = { time: string; step: string; agent: string; note: string };
32
- type ReviewStage = 'analysis' | 'plan' | 'code';
33
-
34
29
  // One rendered row = one step instance. `started`/`done` are timestamps; an empty
35
30
  // `done` with a non-empty `started` means the step is still in flight, while an
36
31
  // empty `started` is a historical done-only entry (no start marker was written).
37
- type StepRow = { step: string; agent: string; started: string; done: string; note: string };
38
32
 
39
33
  // A start marker reuses the normal entry grammar and only suffixes its action
40
34
  // with ` [started]`; the matching done entry carries the identical base action
41
35
  // without the suffix. Pairing therefore keys on the base action (including any
42
36
  // `(Round N)`), so every round and every repeated execution pairs on its own.
43
- const STARTED_SUFFIX_RE = /\s*\[started\]\s*$/;
44
37
  // Short agent tokens that actually appear in activity logs for AI executors
45
38
  // (workflow recommended_agents claude/codex/gemini/cursor + enabled TUI opencode;
46
39
  // note these differ from the `.airc.json` long names claude-code/gemini-cli).
@@ -52,59 +45,11 @@ const REVIEW_STAGE_PREFIXES: { prefix: string; stage: ReviewStage }[] = [
52
45
  { prefix: 'Review Code', stage: 'code' }
53
46
  ];
54
47
 
55
- function parseActivityLog(content: string): { sectionFound: boolean; entries: LogEntry[] } {
56
- const lines = content.split('\n');
57
- let i = 0;
58
- while (i < lines.length && !HEADING_RE.test(lines[i]!)) i += 1;
59
- if (i >= lines.length) return { sectionFound: false, entries: [] };
60
- const parsed: { entry: LogEntry; epoch: number; order: number }[] = [];
61
- for (let j = i + 1; j < lines.length; j += 1) {
62
- if (NEXT_H2_RE.test(lines[j]!)) break;
63
- const m = ENTRY_RE.exec(lines[j]!);
64
- if (!m) continue; // skip blank / non-entry / malformed lines
65
- parsed.push({
66
- entry: { time: m[1]!, step: m[2]!, agent: m[3]!, note: m[4]! },
67
- epoch: Date.parse(m[1]!.replace(' ', 'T')),
68
- order: parsed.length
69
- });
70
- }
71
- // Ascending by time; stable tie-break on original order for equal timestamps.
72
- parsed.sort((a, b) => a.epoch - b.epoch || a.order - b.order);
73
- return { sectionFound: true, entries: parsed.map((p) => p.entry) };
74
- }
75
-
76
48
  // Collapse a chronological entry list into per-step rows: a `[started]` marker
77
49
  // opens a row, the next matching done entry fills it in place (FIFO per base
78
50
  // action). Started-only rows stay in flight; done-only entries (legacy logs with
79
51
  // no start marker) render as standalone rows. Result order = first-seen order,
80
52
  // which is already ascending because `entries` is sorted ascending.
81
- function pairEntries(entries: LogEntry[]): StepRow[] {
82
- const rows: StepRow[] = [];
83
- const open = new Map<string, StepRow[]>();
84
- for (const e of entries) {
85
- const isStarted = STARTED_SUFFIX_RE.test(e.step);
86
- const base = e.step.replace(STARTED_SUFFIX_RE, '');
87
- if (isStarted) {
88
- const row: StepRow = { step: base, agent: e.agent, started: e.time, done: '', note: e.note };
89
- rows.push(row);
90
- const queue = open.get(base);
91
- if (queue) queue.push(row);
92
- else open.set(base, [row]);
93
- } else {
94
- const pending = open.get(base)?.shift();
95
- if (pending) {
96
- // Done fills the open row; the done entry carries the meaningful note.
97
- pending.done = e.time;
98
- pending.agent = e.agent;
99
- pending.note = e.note;
100
- } else {
101
- rows.push({ step: base, agent: e.agent, started: '', done: e.time, note: e.note });
102
- }
103
- }
104
- }
105
- return rows;
106
- }
107
-
108
53
  function countHumanDecisionsByStage(rows: LedgerRow[]): Map<ReviewStage, number> {
109
54
  const counts = new Map<ReviewStage, number>();
110
55
  for (const row of rows) {
@@ -114,10 +59,6 @@ function countHumanDecisionsByStage(rows: LedgerRow[]): Map<ReviewStage, number>
114
59
  return counts;
115
60
  }
116
61
 
117
- function isReviewStage(stage: string): stage is ReviewStage {
118
- return stage === 'analysis' || stage === 'plan' || stage === 'code';
119
- }
120
-
121
62
  function reviewStageForStep(step: string): ReviewStage | undefined {
122
63
  return REVIEW_STAGE_PREFIXES.find(({ prefix }) => step.startsWith(prefix))?.stage;
123
64
  }
@@ -173,12 +114,18 @@ function foldHumanCounts(note: string, decisions: number, manualValidation: numb
173
114
  }
174
115
 
175
116
  function log(args: string[] = []): void {
176
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
117
+ if (args[0] === '--help' || args[0] === '-h') {
177
118
  process.stdout.write(USAGE);
178
- if (args.length === 0) process.exitCode = 1;
179
119
  return;
180
120
  }
181
- const resolved = resolveTaskRef(args[0]!);
121
+ let scope;
122
+ try { scope = parseTaskScope(args); } catch (error) {
123
+ process.stderr.write(`ai task log: ${error instanceof Error ? error.message : String(error)}\n`); process.exitCode = 1; return;
124
+ }
125
+ if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
126
+ process.stderr.write('ai task log: task ref must be provided once\n'); process.exitCode = 1; return;
127
+ }
128
+ const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
182
129
  if (!resolved.ok) {
183
130
  process.stderr.write(`ai task log: ${resolved.message}\n`);
184
131
  process.exitCode = 1;
@@ -216,4 +163,4 @@ function log(args: string[] = []): void {
216
163
  process.stdout.write(`Total: ${steps.length} steps\n`);
217
164
  }
218
165
 
219
- export { log, parseActivityLog, pairEntries, isHumanAgent };
166
+ export { log, isHumanAgent };
@@ -1,21 +1,29 @@
1
1
  import fs from 'node:fs';
2
- import { resolveTaskRef } from '../resolve-ref.ts';
2
+ import { parseTaskScope } from '../command-options.ts';
3
+ import { resolveTaskContext } from '../resolve-ref.ts';
3
4
 
4
- const USAGE = `Usage: ai task show <N | #N | TASK-id>
5
+ const USAGE = `Usage: ai task show [<N | TASK-id> | --task <ref> | -t <ref>]
5
6
 
6
7
  Prints the task.md content for the matching task.
8
+ Omit the ref Resolve the unique active task for the current branch.
7
9
  N (bare numeric) Recommended; resolves the active short id via the registry.
8
- '#N' Compatibility form for old commands.
9
10
  TASK-YYYYMMDD-HHMMSS Locates a task in active / blocked / completed / archive.
10
11
  `;
11
12
 
12
13
  function show(args: string[] = []): void {
13
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
14
+ if (args[0] === '--help' || args[0] === '-h') {
14
15
  process.stdout.write(USAGE);
15
- if (args.length === 0) process.exitCode = 1;
16
16
  return;
17
17
  }
18
- const resolved = resolveTaskRef(args[0]!);
18
+ let scope;
19
+ try { scope = parseTaskScope(args); } catch (error) {
20
+ process.stderr.write(`ai task show: ${error instanceof Error ? error.message : String(error)}\n`);
21
+ process.exitCode = 1; return;
22
+ }
23
+ if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
24
+ process.stderr.write('ai task show: task ref must be provided once\n'); process.exitCode = 1; return;
25
+ }
26
+ const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
19
27
  if (!resolved.ok) {
20
28
  process.stderr.write(`ai task show: ${resolved.message}\n`);
21
29
  process.exitCode = 1;