@fitlab-ai/agent-infra 0.8.4 → 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 (443) 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 +9 -0
  6. package/dist/lib/git/review-snapshot.js +79 -0
  7. package/dist/lib/git/workflow.js +101 -0
  8. package/dist/lib/init.js +5 -0
  9. package/dist/lib/internal/git-workflow.js +42 -0
  10. package/dist/lib/internal/platform-checks.js +119 -0
  11. package/dist/lib/internal/platform-comment.js +129 -0
  12. package/dist/lib/internal/platform-context.js +46 -0
  13. package/dist/lib/internal/platform-issue.js +142 -0
  14. package/dist/lib/internal/platform-pr.js +146 -0
  15. package/dist/lib/internal/release-workflow.js +217 -0
  16. package/dist/lib/internal/task-artifact.js +67 -0
  17. package/dist/lib/internal/task-context.js +43 -0
  18. package/dist/lib/internal/task-event.js +70 -0
  19. package/dist/lib/internal/task-ledger.js +114 -0
  20. package/dist/lib/internal/task-lifecycle.js +58 -0
  21. package/dist/lib/internal/task-short-id.js +83 -0
  22. package/dist/lib/internal/task-snapshot.js +47 -0
  23. package/dist/lib/internal/task-verify.js +50 -0
  24. package/dist/lib/internal/task-warning.js +74 -0
  25. package/dist/lib/platform/adapters.js +14 -0
  26. package/dist/lib/platform/context.js +146 -0
  27. package/dist/lib/platform/github-client.js +124 -0
  28. package/dist/lib/platform/issue-comments.js +409 -0
  29. package/dist/lib/platform/issue-metadata.js +183 -0
  30. package/dist/lib/platform/issues.js +617 -0
  31. package/dist/lib/platform/metadata-labels.js +28 -0
  32. package/dist/lib/platform/pr-checks.js +216 -0
  33. package/dist/lib/platform/pr-summary.js +88 -0
  34. package/dist/lib/platform/pull-request-metadata.js +38 -0
  35. package/dist/lib/platform/pull-requests.js +338 -0
  36. package/dist/lib/platform/releases.js +82 -0
  37. package/dist/lib/platform/types.js +22 -0
  38. package/dist/lib/platform/verification-required.js +78 -0
  39. package/dist/lib/platform/verification-sync.js +1014 -0
  40. package/dist/lib/platform/verification.js +6 -0
  41. package/dist/lib/release/channels.js +31 -0
  42. package/dist/lib/release/workflow.js +32 -0
  43. package/dist/lib/render.js +3 -2
  44. package/dist/lib/run/index.js +24 -7
  45. package/dist/lib/sandbox/capture.js +25 -3
  46. package/dist/lib/sandbox/commands/create.js +66 -26
  47. package/dist/lib/sandbox/commands/enter.js +34 -11
  48. package/dist/lib/sandbox/commands/list-running.js +10 -8
  49. package/dist/lib/sandbox/commands/show.js +2 -2
  50. package/dist/lib/sandbox/commands/start.js +53 -15
  51. package/dist/lib/sandbox/engine.js +33 -3
  52. package/dist/lib/sandbox/engines/colima.js +2 -2
  53. package/dist/lib/sandbox/index.js +6 -6
  54. package/dist/lib/sandbox/mounts.js +36 -0
  55. package/dist/lib/sandbox/recovery.js +562 -0
  56. package/dist/lib/sandbox/runtimes/base.dockerfile +4 -0
  57. package/dist/lib/sandbox/task-resolver.js +5 -1
  58. package/dist/lib/sandbox/tools.js +19 -0
  59. package/dist/lib/server/daemon.js +9 -0
  60. package/dist/lib/server/process-control.js +66 -73
  61. package/dist/lib/server/process-state.js +168 -0
  62. package/dist/lib/server/protocol.js +5 -5
  63. package/dist/lib/task/activity-log.js +61 -0
  64. package/dist/lib/task/artifact-lifecycle.js +427 -0
  65. package/dist/lib/task/command-options.js +30 -0
  66. package/dist/lib/task/commands/cat.js +36 -6
  67. package/dist/lib/task/commands/decisions.js +80 -46
  68. package/dist/lib/task/commands/files.js +21 -7
  69. package/dist/lib/task/commands/grep.js +55 -7
  70. package/dist/lib/task/commands/issue-body.js +23 -14
  71. package/dist/lib/task/commands/log.js +27 -70
  72. package/dist/lib/task/commands/show.js +20 -7
  73. package/dist/lib/task/commands/status.js +18 -8
  74. package/dist/lib/task/decision-intents.js +154 -0
  75. package/dist/lib/task/decision-items.js +53 -0
  76. package/dist/lib/task/events.js +318 -0
  77. package/dist/lib/task/frontmatter.js +159 -1
  78. package/dist/lib/task/implementation-inputs.js +117 -0
  79. package/dist/lib/task/index.js +12 -9
  80. package/dist/lib/task/issue-form.js +19 -6
  81. package/dist/lib/task/ledger-intents.js +185 -0
  82. package/dist/lib/task/ledger.js +65 -35
  83. package/dist/lib/task/lifecycle.js +484 -0
  84. package/dist/lib/task/resolve-ref.js +152 -32
  85. package/dist/lib/task/review-artifacts.js +101 -0
  86. package/dist/lib/task/review-fingerprint.js +46 -0
  87. package/dist/lib/task/sections.js +358 -4
  88. package/dist/lib/task/short-id.js +292 -7
  89. package/dist/lib/task/snapshot.js +95 -0
  90. package/dist/lib/task/verification-checks.js +8 -0
  91. package/dist/lib/task/verification-config.js +14 -0
  92. package/dist/lib/task/verification-engine.js +906 -0
  93. package/dist/lib/task/verification-review.js +3 -0
  94. package/dist/lib/task/verification-types.js +2 -0
  95. package/dist/lib/task/verification.js +113 -0
  96. package/dist/lib/task/workflow-warning-intents.js +131 -0
  97. package/dist/lib/task/workflow-warnings.js +10 -78
  98. package/dist/lib/task/write.js +241 -0
  99. package/dist/lib/update.js +2 -0
  100. package/lib/decide.ts +57 -97
  101. package/lib/defaults.json +9 -0
  102. package/lib/git/review-snapshot.ts +73 -0
  103. package/lib/git/workflow.ts +101 -0
  104. package/lib/init.ts +9 -0
  105. package/lib/internal/git-workflow.ts +37 -0
  106. package/lib/internal/platform-checks.ts +101 -0
  107. package/lib/internal/platform-comment.ts +99 -0
  108. package/lib/internal/platform-context.ts +33 -0
  109. package/lib/internal/platform-issue.ts +116 -0
  110. package/lib/internal/platform-pr.ts +119 -0
  111. package/lib/internal/release-workflow.ts +186 -0
  112. package/lib/internal/task-artifact.ts +47 -0
  113. package/lib/internal/task-context.ts +35 -0
  114. package/lib/internal/task-event.ts +51 -0
  115. package/lib/internal/task-ledger.ts +86 -0
  116. package/lib/internal/task-lifecycle.ts +41 -0
  117. package/lib/internal/task-short-id.ts +55 -0
  118. package/lib/internal/task-snapshot.ts +32 -0
  119. package/lib/internal/task-verify.ts +33 -0
  120. package/lib/internal/task-warning.ts +50 -0
  121. package/lib/platform/adapters.ts +30 -0
  122. package/lib/platform/context.ts +164 -0
  123. package/lib/platform/github-client.ts +146 -0
  124. package/lib/platform/issue-comments.ts +479 -0
  125. package/lib/platform/issue-metadata.ts +250 -0
  126. package/lib/platform/issues.ts +691 -0
  127. package/lib/platform/metadata-labels.ts +33 -0
  128. package/lib/platform/pr-checks.ts +246 -0
  129. package/lib/platform/pr-summary.ts +90 -0
  130. package/lib/platform/pull-request-metadata.ts +69 -0
  131. package/lib/platform/pull-requests.ts +380 -0
  132. package/lib/platform/releases.ts +71 -0
  133. package/lib/platform/types.ts +74 -0
  134. package/lib/platform/verification-required.ts +83 -0
  135. package/{templates/.agents/scripts/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts} +221 -363
  136. package/lib/platform/verification.ts +11 -0
  137. package/lib/release/channels.ts +30 -0
  138. package/lib/release/workflow.ts +31 -0
  139. package/lib/render.ts +3 -2
  140. package/lib/run/index.ts +25 -7
  141. package/lib/sandbox/capture.ts +29 -3
  142. package/lib/sandbox/commands/create.ts +75 -28
  143. package/lib/sandbox/commands/enter.ts +38 -11
  144. package/lib/sandbox/commands/list-running.ts +10 -8
  145. package/lib/sandbox/commands/show.ts +2 -2
  146. package/lib/sandbox/commands/start.ts +50 -16
  147. package/lib/sandbox/engine.ts +37 -3
  148. package/lib/sandbox/engines/colima.ts +2 -2
  149. package/lib/sandbox/index.ts +6 -6
  150. package/lib/sandbox/mounts.ts +55 -0
  151. package/lib/sandbox/recovery.ts +828 -0
  152. package/lib/sandbox/runtimes/base.dockerfile +4 -0
  153. package/lib/sandbox/task-resolver.ts +5 -1
  154. package/lib/sandbox/tools.ts +31 -0
  155. package/lib/server/daemon.ts +9 -0
  156. package/lib/server/process-control.ts +70 -71
  157. package/lib/server/process-state.ts +183 -0
  158. package/lib/server/protocol.ts +5 -5
  159. package/lib/task/activity-log.ts +62 -0
  160. package/lib/task/artifact-lifecycle.ts +484 -0
  161. package/lib/task/command-options.ts +32 -0
  162. package/lib/task/commands/cat.ts +22 -9
  163. package/lib/task/commands/decisions.ts +49 -47
  164. package/lib/task/commands/files.ts +14 -6
  165. package/lib/task/commands/grep.ts +34 -7
  166. package/lib/task/commands/issue-body.ts +16 -16
  167. package/lib/task/commands/log.ts +17 -70
  168. package/lib/task/commands/show.ts +14 -6
  169. package/lib/task/commands/status.ts +17 -7
  170. package/lib/task/decision-intents.ts +163 -0
  171. package/lib/task/decision-items.ts +64 -0
  172. package/lib/task/events.ts +320 -0
  173. package/lib/task/frontmatter.ts +202 -2
  174. package/lib/task/implementation-inputs.ts +137 -0
  175. package/lib/task/index.ts +12 -9
  176. package/lib/task/issue-form.ts +20 -6
  177. package/lib/task/ledger-intents.ts +201 -0
  178. package/lib/task/ledger.ts +77 -31
  179. package/lib/task/lifecycle.ts +458 -0
  180. package/lib/task/resolve-ref.ts +197 -36
  181. package/{templates/.agents/scripts/lib/review-artifacts.js → lib/task/review-artifacts.ts} +11 -12
  182. package/{templates/.agents/scripts/lib/post-review-commit.js → lib/task/review-fingerprint.ts} +20 -10
  183. package/lib/task/sections.ts +486 -4
  184. package/lib/task/short-id.ts +403 -9
  185. package/lib/task/snapshot.ts +143 -0
  186. package/lib/task/verification-checks.ts +9 -0
  187. package/lib/task/verification-config.ts +20 -0
  188. package/{templates/.agents/scripts/validate-artifact.js → lib/task/verification-engine.ts} +257 -451
  189. package/lib/task/verification-review.ts +9 -0
  190. package/lib/task/verification-types.ts +29 -0
  191. package/lib/task/verification.ts +156 -0
  192. package/lib/task/workflow-warning-intents.ts +142 -0
  193. package/lib/task/workflow-warnings.ts +10 -78
  194. package/lib/task/write.ts +468 -0
  195. package/lib/update.ts +6 -0
  196. package/package.json +5 -2
  197. package/templates/.agents/README.en.md +6 -3
  198. package/templates/.agents/README.zh-CN.md +6 -3
  199. package/templates/.agents/rules/README.en.md +6 -5
  200. package/templates/.agents/rules/README.zh-CN.md +6 -5
  201. package/templates/.agents/rules/create-issue.en.md +1 -1
  202. package/templates/.agents/rules/create-issue.github.en.md +5 -184
  203. package/templates/.agents/rules/create-issue.github.zh-CN.md +12 -178
  204. package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
  205. package/templates/.agents/rules/human-decision-context.en.md +36 -0
  206. package/templates/.agents/rules/human-decision-context.zh-CN.md +36 -0
  207. package/templates/.agents/rules/issue-fields.github.en.md +4 -148
  208. package/templates/.agents/rules/issue-fields.github.zh-CN.md +9 -144
  209. package/templates/.agents/rules/issue-pr-commands.en.md +43 -3
  210. package/templates/.agents/rules/issue-pr-commands.github.en.md +15 -220
  211. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +23 -213
  212. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +45 -3
  213. package/templates/.agents/rules/issue-sync.en.md +1 -1
  214. package/templates/.agents/rules/issue-sync.github.en.md +14 -301
  215. package/templates/.agents/rules/issue-sync.github.zh-CN.md +36 -287
  216. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  217. package/templates/.agents/rules/milestone-inference.en.md +1 -1
  218. package/templates/.agents/rules/milestone-inference.github.en.md +7 -119
  219. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +8 -108
  220. package/templates/.agents/rules/milestone-inference.zh-CN.md +1 -1
  221. package/templates/.agents/rules/next-step-output.en.md +12 -11
  222. package/templates/.agents/rules/next-step-output.zh-CN.md +12 -11
  223. package/templates/.agents/rules/no-mid-flow-questions.en.md +3 -3
  224. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +3 -3
  225. package/templates/.agents/rules/pr-checks-commands.en.md +16 -3
  226. package/templates/.agents/rules/pr-checks-commands.github.en.md +10 -54
  227. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +19 -47
  228. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +30 -3
  229. package/templates/.agents/rules/pr-sync.en.md +30 -3
  230. package/templates/.agents/rules/pr-sync.github.en.md +12 -115
  231. package/templates/.agents/rules/pr-sync.github.zh-CN.md +26 -104
  232. package/templates/.agents/rules/pr-sync.zh-CN.md +43 -3
  233. package/templates/.agents/rules/review-handshake.en.md +13 -9
  234. package/templates/.agents/rules/review-handshake.zh-CN.md +13 -9
  235. package/templates/.agents/rules/task-management.en.md +11 -2
  236. package/templates/.agents/rules/task-management.zh-CN.md +11 -3
  237. package/templates/.agents/rules/task-short-id.en.md +25 -29
  238. package/templates/.agents/rules/task-short-id.zh-CN.md +20 -23
  239. package/templates/.agents/scripts/lib/agent-infra-package.js +141 -0
  240. package/templates/.agents/scripts/task-short-id.js +71 -533
  241. package/templates/.agents/skills/analyze-task/SKILL.en.md +22 -55
  242. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +26 -59
  243. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -3
  244. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -3
  245. package/templates/.agents/skills/block-task/SKILL.en.md +21 -47
  246. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +23 -47
  247. package/templates/.agents/skills/block-task/config/verify.json +1 -2
  248. package/templates/.agents/skills/cancel-task/SKILL.en.md +16 -45
  249. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +16 -45
  250. package/templates/.agents/skills/cancel-task/config/verify.json +1 -2
  251. package/templates/.agents/skills/check-task/SKILL.en.md +6 -3
  252. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +6 -3
  253. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -24
  254. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -24
  255. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -24
  256. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -24
  257. package/templates/.agents/skills/code-task/SKILL.en.md +22 -35
  258. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +28 -44
  259. package/templates/.agents/skills/code-task/config/verify.en.json +3 -3
  260. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +3 -3
  261. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +13 -9
  262. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +13 -9
  263. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
  264. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
  265. package/templates/.agents/skills/code-task/reference/report-template.en.md +11 -1
  266. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +11 -1
  267. package/templates/.agents/skills/commit/SKILL.en.md +18 -14
  268. package/templates/.agents/skills/commit/SKILL.zh-CN.md +18 -14
  269. package/templates/.agents/skills/commit/config/verify.json +1 -2
  270. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -11
  271. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -11
  272. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +4 -8
  273. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +4 -8
  274. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +6 -18
  275. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +5 -17
  276. package/templates/.agents/skills/commit/reference/task-status-update.en.md +42 -2
  277. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +42 -2
  278. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +13 -36
  279. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +13 -36
  280. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -3
  281. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -3
  282. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +10 -54
  283. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +10 -79
  284. package/templates/.agents/skills/complete-task/SKILL.en.md +59 -63
  285. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +59 -63
  286. package/templates/.agents/skills/complete-task/config/verify.en.json +11 -6
  287. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +11 -6
  288. package/templates/.agents/skills/create-pr/SKILL.en.md +19 -44
  289. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +19 -43
  290. package/templates/.agents/skills/create-pr/config/verify.json +1 -2
  291. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +8 -12
  292. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +7 -11
  293. package/templates/.agents/skills/create-task/SKILL.en.md +12 -13
  294. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +12 -13
  295. package/templates/.agents/skills/create-task/config/verify.json +1 -2
  296. package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -2
  297. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +2 -2
  298. package/templates/.agents/skills/import-codescan/config/verify.json +1 -2
  299. package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
  300. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
  301. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -2
  302. package/templates/.agents/skills/import-issue/SKILL.en.md +9 -13
  303. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -14
  304. package/templates/.agents/skills/import-issue/config/verify.json +1 -2
  305. package/templates/.agents/skills/init-milestones/SKILL.en.md +2 -2
  306. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +2 -2
  307. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +5 -4
  308. package/templates/.agents/skills/plan-task/SKILL.en.md +17 -42
  309. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -49
  310. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -3
  311. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -3
  312. package/templates/.agents/skills/post-release/SKILL.en.md +11 -81
  313. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +8 -78
  314. package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
  315. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
  316. package/templates/.agents/skills/release/SKILL.en.md +16 -163
  317. package/templates/.agents/skills/release/SKILL.zh-CN.md +15 -162
  318. package/templates/.agents/skills/restore-task/SKILL.en.md +11 -29
  319. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +11 -29
  320. package/templates/.agents/skills/restore-task/config/verify.json +1 -2
  321. package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -25
  322. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +13 -33
  323. package/templates/.agents/skills/review-analysis/config/verify.en.json +3 -4
  324. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +3 -4
  325. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +9 -12
  326. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +9 -12
  327. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +9 -2
  328. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +9 -2
  329. package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +7 -0
  330. package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +7 -0
  331. package/templates/.agents/skills/review-code/SKILL.en.md +22 -36
  332. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +23 -41
  333. package/templates/.agents/skills/review-code/config/verify.en.json +5 -5
  334. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +5 -5
  335. package/templates/.agents/skills/review-code/reference/output-templates.en.md +56 -18
  336. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +56 -18
  337. package/templates/.agents/skills/review-code/reference/report-template.en.md +12 -4
  338. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +12 -4
  339. package/templates/.agents/skills/review-code/reference/review-criteria.en.md +7 -0
  340. package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +7 -0
  341. package/templates/.agents/skills/review-plan/SKILL.en.md +13 -25
  342. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +13 -33
  343. package/templates/.agents/skills/review-plan/config/verify.en.json +3 -4
  344. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +3 -4
  345. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +9 -12
  346. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +9 -12
  347. package/templates/.agents/skills/review-plan/reference/report-template.en.md +9 -2
  348. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +9 -2
  349. package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +7 -0
  350. package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +7 -0
  351. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +6 -3
  352. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +6 -3
  353. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +177 -151
  354. package/templates/.agents/skills/watch-pr/SKILL.en.md +24 -14
  355. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +25 -15
  356. package/templates/.agents/skills/watch-pr/config/verify.json +1 -2
  357. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
  358. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
  359. package/templates/.agents/templates/task.en.md +6 -1
  360. package/templates/.agents/templates/task.zh-CN.md +6 -1
  361. package/templates/.claude/commands/analyze-task.en.md +1 -1
  362. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  363. package/templates/.claude/commands/block-task.en.md +1 -1
  364. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  365. package/templates/.claude/commands/cancel-task.en.md +1 -1
  366. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  367. package/templates/.claude/commands/check-task.en.md +1 -1
  368. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  369. package/templates/.claude/commands/code-task.en.md +1 -1
  370. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  371. package/templates/.claude/commands/commit.en.md +1 -0
  372. package/templates/.claude/commands/commit.zh-CN.md +1 -0
  373. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  374. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  375. package/templates/.claude/commands/complete-task.en.md +1 -1
  376. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  377. package/templates/.claude/commands/create-pr.en.md +1 -1
  378. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  379. package/templates/.claude/commands/plan-task.en.md +1 -1
  380. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  381. package/templates/.claude/commands/review-analysis.en.md +1 -1
  382. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  383. package/templates/.claude/commands/review-code.en.md +1 -1
  384. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  385. package/templates/.claude/commands/review-plan.en.md +1 -1
  386. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  387. package/templates/.claude/commands/watch-pr.en.md +1 -1
  388. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  389. package/templates/.gemini/commands/_project_/analyze-task.en.toml +2 -0
  390. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +2 -0
  391. package/templates/.gemini/commands/_project_/block-task.en.toml +2 -0
  392. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +2 -0
  393. package/templates/.gemini/commands/_project_/cancel-task.en.toml +2 -0
  394. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +2 -0
  395. package/templates/.gemini/commands/_project_/check-task.en.toml +2 -0
  396. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +2 -0
  397. package/templates/.gemini/commands/_project_/code-task.en.toml +2 -0
  398. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +2 -0
  399. package/templates/.gemini/commands/_project_/commit.en.toml +4 -0
  400. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +4 -0
  401. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +2 -0
  402. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +2 -0
  403. package/templates/.gemini/commands/_project_/complete-task.en.toml +2 -0
  404. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +2 -0
  405. package/templates/.gemini/commands/_project_/create-pr.en.toml +2 -0
  406. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +2 -0
  407. package/templates/.gemini/commands/_project_/plan-task.en.toml +2 -0
  408. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +2 -0
  409. package/templates/.gemini/commands/_project_/review-analysis.en.toml +2 -0
  410. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +2 -0
  411. package/templates/.gemini/commands/_project_/review-code.en.toml +2 -0
  412. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +2 -0
  413. package/templates/.gemini/commands/_project_/review-plan.en.toml +2 -0
  414. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +2 -0
  415. package/templates/.gemini/commands/_project_/watch-pr.en.toml +2 -0
  416. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +2 -0
  417. package/templates/.git-hooks/check-large-files.cjs +92 -0
  418. package/templates/.git-hooks/check-version-format.sh +5 -1
  419. package/templates/.git-hooks/pre-commit +1 -0
  420. package/templates/.opencode/commands/analyze-task.en.md +1 -1
  421. package/templates/.opencode/commands/analyze-task.zh-CN.md +1 -1
  422. package/templates/.opencode/commands/check-task.en.md +1 -1
  423. package/templates/.opencode/commands/check-task.zh-CN.md +1 -1
  424. package/templates/.opencode/commands/code-task.en.md +1 -1
  425. package/templates/.opencode/commands/code-task.zh-CN.md +1 -1
  426. package/templates/.opencode/commands/commit.en.md +2 -0
  427. package/templates/.opencode/commands/commit.zh-CN.md +2 -0
  428. package/templates/.opencode/commands/complete-task.en.md +1 -1
  429. package/templates/.opencode/commands/complete-task.zh-CN.md +1 -1
  430. package/templates/.opencode/commands/plan-task.en.md +1 -1
  431. package/templates/.opencode/commands/plan-task.zh-CN.md +1 -1
  432. package/templates/.opencode/commands/review-analysis.en.md +1 -1
  433. package/templates/.opencode/commands/review-analysis.zh-CN.md +1 -1
  434. package/templates/.opencode/commands/review-code.en.md +1 -1
  435. package/templates/.opencode/commands/review-code.zh-CN.md +1 -1
  436. package/templates/.opencode/commands/review-plan.en.md +1 -1
  437. package/templates/.opencode/commands/review-plan.zh-CN.md +1 -1
  438. package/templates/.agents/scripts/platform-adapters/platform-sync.js +0 -13
  439. package/templates/.agents/scripts/review-diff-fingerprint.js +0 -99
  440. package/templates/.agents/scripts/workflow-warnings.js +0 -290
  441. package/templates/.agents/skills/code-task/scripts/detect-mode.js +0 -257
  442. package/templates/.agents/skills/release/scripts/manage-milestones.github.sh +0 -80
  443. package/templates/.agents/skills/release/scripts/manage-milestones.sh +0 -6
@@ -1,556 +1,94 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { fileURLToPath, pathToFileURL } from "node:url";
4
-
5
- const TASK_ID_RE = /^TASK-\d{8}-\d{6}$/;
6
- const SHORT_ID_RE = /^#\d+$/;
7
- const REGISTRY_NAME = ".short-ids.json";
8
- const LOCK_NAME = ".short-ids.json.lock";
9
- const DEFAULT_LOCK_TIMEOUT_MS = 5000;
10
- // Kept in sync with lib/defaults.json's task.shortIdLength. Used when there is
11
- // no `--short-id-length` flag and no readable `task.shortIdLength` in
12
- // .agents/.airc.json (e.g. the project upgraded but hasn't re-run
13
- // ai update-agent-infra to backfill the field).
14
- const DEFAULT_SHORT_ID_LENGTH = 2;
15
-
16
- // process.stdout.write / process.stderr.write are non-blocking when the
17
- // destination is a pipe (e.g. when spawned via child_process.spawnSync). On
18
- // some platforms (notably macOS) the Node process can exit before the buffer
19
- // flushes, leaving the parent with empty stdout. Use fs.writeSync to guarantee
20
- // synchronous, fully-flushed writes — this is critical because the parent
21
- // CLI/test code relies on stdout to carry the resolved task id / short id.
22
- function writeStdout(text) {
23
- fs.writeSync(1, text);
24
- }
25
-
26
- function writeStderr(text) {
27
- fs.writeSync(2, text);
28
- }
29
-
30
- function usage() {
31
- return [
32
- "Usage: task-short-id.js <subcommand> [args]",
33
- "",
34
- "Subcommands:",
35
- " alloc <task-id> Allocate short id for a task in the registry",
36
- " release <task-id> Release short id (idempotent; exit 0 if not present)",
37
- " resolve <#N> Resolve short id to full task id",
38
- " list Print registry JSON",
39
- " list --verify Read-only check; exit 1 if active dir / registry disagree",
40
- "",
41
- "Options:",
42
- " --active-dir <path> Override active dir (default: <repo>/.agents/workspace/active)",
43
- " --short-id-length N Override configured width (default: from .airc.json or 2)"
44
- ].join("\n");
45
- }
46
-
47
- function parseArgs(argv) {
48
- const args = { positional: [], activeDir: null, shortIdLength: null, verify: false, help: false };
49
- for (let i = 0; i < argv.length; i += 1) {
50
- const a = argv[i];
51
- if (a === "--active-dir") {
52
- args.activeDir = argv[++i];
53
- } else if (a === "--short-id-length") {
54
- args.shortIdLength = Number(argv[++i]);
55
- } else if (a === "--verify") {
56
- args.verify = true;
57
- } else if (a === "-h" || a === "--help") {
58
- args.help = true;
59
- } else if (a.startsWith("--")) {
60
- throw new Error(`Unknown option: ${a}`);
61
- } else {
62
- args.positional.push(a);
63
- }
64
- }
65
- return args;
66
- }
3
+ import { spawnSync } from "node:child_process";
4
+ import { fileURLToPath } from "node:url";
67
5
 
68
6
  function findRepoRoot(start) {
69
- let dir = path.resolve(start || process.cwd());
7
+ let current = path.resolve(start);
70
8
  for (;;) {
71
- if (fs.existsSync(path.join(dir, ".agents", ".airc.json"))) return dir;
72
- const parent = path.dirname(dir);
73
- if (parent === dir) return null;
74
- dir = parent;
75
- }
76
- }
77
-
78
- function readShortIdLength(repoRoot, override) {
79
- if (typeof override === "number" && Number.isFinite(override) && override >= 1) {
80
- return override;
81
- }
82
- if (!repoRoot) return DEFAULT_SHORT_ID_LENGTH;
83
- try {
84
- const cfgPath = path.join(repoRoot, ".agents", ".airc.json");
85
- const cfg = JSON.parse(fs.readFileSync(cfgPath, "utf8"));
86
- const v = cfg && cfg.task && cfg.task.shortIdLength;
87
- if (typeof v === "number" && Number.isFinite(v) && v >= 1) return v;
88
- } catch {
89
- // ignore
90
- }
91
- return DEFAULT_SHORT_ID_LENGTH;
92
- }
93
-
94
- function readRegistry(registryPath) {
95
- if (!fs.existsSync(registryPath)) {
96
- return { version: 1, ids: {} };
97
- }
98
- let raw;
99
- try {
100
- raw = fs.readFileSync(registryPath, "utf8");
101
- } catch (e) {
102
- writeStderr(`Error: cannot read registry ${registryPath}: ${e.message}\n`);
103
- process.exit(2);
104
- }
105
- try {
106
- const data = JSON.parse(raw);
107
- if (!data || typeof data !== "object" || !data.ids || typeof data.ids !== "object") {
108
- writeStderr(`Error: registry ${registryPath} has invalid schema\n`);
109
- process.exit(2);
110
- }
111
- if (data.version !== 1) data.version = 1;
112
- return data;
113
- } catch (e) {
114
- writeStderr(`Error: registry ${registryPath} is not valid JSON: ${e.message}\n`);
115
- process.exit(2);
9
+ if (fs.existsSync(path.join(current, ".agents", ".airc.json"))) return current;
10
+ const parent = path.dirname(current);
11
+ if (parent === current) return null;
12
+ current = parent;
116
13
  }
117
14
  }
118
15
 
119
- function writeRegistryAtomic(data, registryPath) {
120
- const tmpPath = `${registryPath}.tmp.${process.pid}`;
121
- fs.writeFileSync(tmpPath, `${JSON.stringify(data, null, 2)}\n`);
122
- fs.renameSync(tmpPath, registryPath);
123
- }
124
-
125
- function withRegistryLock(activeDir, fn, timeoutMs = DEFAULT_LOCK_TIMEOUT_MS) {
126
- fs.mkdirSync(activeDir, { recursive: true });
127
- const lockDir = path.join(activeDir, LOCK_NAME);
128
- const start = Date.now();
16
+ function findSourceCli() {
17
+ let current = path.dirname(fileURLToPath(import.meta.url));
129
18
  for (;;) {
130
- try {
131
- fs.mkdirSync(lockDir, { recursive: false });
132
- break;
133
- } catch (e) {
134
- if (e.code !== "EEXIST") throw e;
135
- if (Date.now() - start > timeoutMs) {
136
- writeStderr(`Error: registry lock timeout after ${timeoutMs}ms\n`);
137
- process.exit(3);
138
- }
139
- const elapsed = Date.now() - start;
140
- const wait = Math.min(500, 50 * Math.pow(2, Math.floor(elapsed / 200)));
141
- const deadline = Date.now() + wait;
142
- while (Date.now() < deadline) {
143
- /* busy wait, ms-scale */
144
- }
145
- }
146
- }
147
- // Register cleanup that runs even on process.exit (which skips try/finally).
148
- const cleanup = () => {
149
- try {
150
- fs.rmdirSync(lockDir);
151
- } catch {
152
- /* lock-dir already removed */
153
- }
154
- };
155
- process.once("exit", cleanup);
156
- try {
157
- return fn();
158
- } finally {
159
- process.removeListener("exit", cleanup);
160
- cleanup();
161
- }
162
- }
163
-
164
- function padShortId(n, shortIdLength) {
165
- return String(n).padStart(shortIdLength, "0");
166
- }
167
-
168
- function allocateMinFreeInt(registry, shortIdLength) {
169
- const maxN = Math.pow(10, shortIdLength) - 1;
170
- for (let n = 1; n <= maxN; n += 1) {
171
- if (!registry.ids[padShortId(n, shortIdLength)]) return n;
172
- }
173
- return null;
174
- }
175
-
176
- function parseShortIdArg(arg, shortIdLength) {
177
- const L = shortIdLength;
178
- const max = Math.pow(10, L) - 1;
179
- // Accept bare numeric or '#'-prefixed; canonicalize to zero-padded key.
180
- // Bare numeric is the recommended form (no shell quoting needed).
181
- const m = /^#?(\d+)$/.exec(arg);
182
- if (!m) {
183
- writeStderr(
184
- `Error: invalid short id format '${arg}', ` +
185
- `expected bare digits (recommended) or '#'-prefixed digits; ` +
186
- `e.g. '11' or '#11' (shortIdLength=${L}, max=${max})\n`
187
- );
188
- process.exit(1);
189
- }
190
- const n = Number(m[1]);
191
- if (n === 0) {
192
- writeStderr(
193
- `Error: short id '${arg}' is invalid (#${"0".repeat(L)} is reserved)\n`
194
- );
195
- process.exit(1);
196
- }
197
- if (n > max) {
198
- writeStderr(
199
- `Error: short id ${n} exceeds shortIdLength=${L} capacity (max=${max}); ` +
200
- `archive tasks or raise task.shortIdLength in .agents/.airc.json\n`
201
- );
202
- process.exit(1);
19
+ const candidate = path.join(current, "bin", "internal-cli.ts");
20
+ if (fs.existsSync(candidate)) return candidate;
21
+ const parent = path.dirname(current);
22
+ if (parent === current) return null;
23
+ current = parent;
203
24
  }
204
- return String(n).padStart(L, "0");
205
25
  }
206
26
 
207
- function planTransaction(registry, activeDir, shortIdLength) {
208
- const maxN = Math.pow(10, shortIdLength) - 1;
209
-
210
- // A1: active task id set
211
- const activeTaskIds = new Set(
212
- fs
213
- .readdirSync(activeDir)
214
- .filter((d) => TASK_ID_RE.test(d))
215
- .filter((d) => fs.existsSync(path.join(activeDir, d, "task.md")))
216
- );
217
-
218
- // A2: stale entries (registry points at a task no longer active)
219
- const pendingRegistryDeletes = [];
220
- for (const [key, taskId] of Object.entries(registry.ids)) {
221
- if (!activeTaskIds.has(taskId)) pendingRegistryDeletes.push(key);
222
- }
223
-
224
- const projectedIds = { ...registry.ids };
225
- for (const key of pendingRegistryDeletes) delete projectedIds[key];
226
-
227
- // A3: duplicate key detection (after stale cleanup)
228
- const taskIdToKey = new Map();
229
- for (const [key, taskId] of Object.entries(projectedIds)) {
230
- if (taskIdToKey.has(taskId)) {
231
- const existingKey = taskIdToKey.get(taskId);
232
- writeStderr(
233
- `Error: duplicate registry entries for taskId ${taskId} at keys [#${existingKey}, #${key}]; manual resolution required\n`
234
- );
235
- process.exit(2);
236
- }
237
- taskIdToKey.set(taskId, key);
238
- }
239
-
240
- // The registry is the sole source of truth: short ids are allocated only by
241
- // explicit `alloc` (planAlloc), never inferred from task.md or auto-allocated
242
- // for active tasks. Read paths (resolve/list) only run stale cleanup (A2).
243
- const plannedRegistryWrites = [];
244
-
245
- const tx = {
246
- _registry: registry,
247
- _activeDir: activeDir,
248
- _registrySnapshot: { ...registry.ids },
249
- _pendingRegistryDeletes: pendingRegistryDeletes,
250
- _plannedRegistryWrites: plannedRegistryWrites,
251
- _projectedIds: projectedIds,
252
- _taskIdToKey: taskIdToKey,
253
- _shortIdLength: shortIdLength,
254
- _maxN: maxN,
255
-
256
- planAlloc(taskId) {
257
- const taskMdPath = path.join(activeDir, taskId, "task.md");
258
- if (!fs.existsSync(taskMdPath)) {
259
- throw new Error(`planAlloc: task.md not found for ${taskId}`);
260
- }
261
- if (this._taskIdToKey.has(taskId)) {
262
- return this._taskIdToKey.get(taskId);
263
- }
264
- const inUse = Object.keys(this._projectedIds).length;
265
- if (inUse >= this._maxN) {
266
- throw new Error(
267
- `Error: short id width exhausted (current shortIdLength=${this._shortIdLength}, ` +
268
- `${inUse}/${this._maxN} slots in use). Archive some active tasks or raise task.shortIdLength.`
269
- );
270
- }
271
- const n = allocateMinFreeInt({ ids: this._projectedIds }, this._shortIdLength);
272
- const key = padShortId(n, this._shortIdLength);
273
- this._projectedIds[key] = taskId;
274
- this._taskIdToKey.set(taskId, key);
275
- this._plannedRegistryWrites.push({ key, taskId });
276
- return key; // zero-padded; matches registry key
277
- },
278
-
279
- planRelease(taskId) {
280
- const key = this._taskIdToKey.get(taskId);
281
- if (!key) return; // idempotent
282
- this._plannedRegistryWrites = this._plannedRegistryWrites.filter(
283
- (w) => w.taskId !== taskId
284
- );
285
- this._pendingRegistryDeletes.push(key);
286
- delete this._projectedIds[key];
287
- this._taskIdToKey.delete(taskId);
288
- },
289
-
290
- commit(registryPath) {
291
- // Apply registry mutation in memory, then persist atomically.
292
- for (const key of this._pendingRegistryDeletes) delete this._registry.ids[key];
293
- for (const { key, taskId } of this._plannedRegistryWrites) {
294
- this._registry.ids[key] = taskId;
295
- }
296
- try {
297
- writeRegistryAtomic(this._registry, registryPath);
298
- } catch (e) {
299
- this._registry.ids = this._registrySnapshot;
300
- throw new Error(`Failed to persist registry to ${registryPath}: ${e.message}`);
301
- }
302
- }
303
- };
304
-
305
- return tx;
306
- }
307
-
308
- function verifyRegistry(registry, activeDir) {
309
- const activeTaskIds = new Set(
310
- fs
311
- .readdirSync(activeDir)
312
- .filter((d) => TASK_ID_RE.test(d))
313
- .filter((d) => fs.existsSync(path.join(activeDir, d, "task.md")))
314
- );
315
- const registryTaskIds = new Set(Object.values(registry.ids));
316
- const missing_in_registry = [];
317
- for (const taskId of activeTaskIds) {
318
- if (!registryTaskIds.has(taskId)) {
319
- missing_in_registry.push({ taskId });
320
- }
321
- }
322
- const orphans_in_registry = [];
323
- for (const [key, taskId] of Object.entries(registry.ids)) {
324
- if (!activeTaskIds.has(taskId)) {
325
- orphans_in_registry.push({ key: `#${key}`, taskId });
326
- }
327
- }
328
- const taskIdToKeys = new Map();
329
- for (const [key, taskId] of Object.entries(registry.ids)) {
330
- if (!taskIdToKeys.has(taskId)) taskIdToKeys.set(taskId, []);
331
- taskIdToKeys.get(taskId).push(key);
332
- }
333
- const duplicate_registry_keys = [];
334
- for (const [taskId, keys] of taskIdToKeys) {
335
- if (keys.length > 1) {
336
- duplicate_registry_keys.push({ taskId, keys: keys.map((k) => `#${k}`) });
337
- }
27
+ function configuredWidth(repoRoot) {
28
+ if (!repoRoot) return 2;
29
+ try {
30
+ const config = JSON.parse(fs.readFileSync(path.join(repoRoot, ".agents", ".airc.json"), "utf8"));
31
+ const value = config?.task?.shortIdLength;
32
+ return Number.isInteger(value) && value >= 1 ? value : 2;
33
+ } catch {
34
+ return 2;
338
35
  }
339
- return {
340
- missing_in_registry,
341
- orphans_in_registry,
342
- duplicate_registry_keys
343
- };
344
36
  }
345
37
 
346
- function cmdAlloc(taskId, activeDir, registryPath, shortIdLength) {
347
- if (!TASK_ID_RE.test(taskId)) {
348
- writeStderr(`Error: invalid task id format '${taskId}'\n`);
349
- process.exit(1);
350
- }
351
- return withRegistryLock(activeDir, () => {
352
- const taskMdPath = path.join(activeDir, taskId, "task.md");
353
- if (!fs.existsSync(taskMdPath)) {
354
- writeStderr(`Error: task ${taskId} not found in ${activeDir} (no task.md)\n`);
355
- process.exit(1);
38
+ function resolveCommand(command) {
39
+ if (process.platform !== "win32" || path.extname(command)) return command;
40
+ const pathValue = process.env.Path || process.env.PATH || "";
41
+ const extensions = (process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
42
+ for (const dir of pathValue.split(path.delimiter).filter(Boolean)) {
43
+ for (const extension of extensions) {
44
+ const candidate = path.join(dir, `${command}${extension.toLowerCase()}`);
45
+ if (fs.existsSync(candidate)) return candidate;
46
+ const upperCandidate = path.join(dir, `${command}${extension.toUpperCase()}`);
47
+ if (fs.existsSync(upperCandidate)) return upperCandidate;
356
48
  }
357
- const registry = readRegistry(registryPath);
358
- const tx = planTransaction(registry, activeDir, shortIdLength);
359
- let shortId;
360
- try {
361
- shortId = tx.planAlloc(taskId);
362
- } catch (e) {
363
- writeStderr(`${e.message}\n`);
364
- process.exit(2);
365
- }
366
- try {
367
- tx.commit(registryPath);
368
- } catch (e) {
369
- writeStderr(`${e.message}\n`);
370
- process.exit(1);
371
- }
372
- // shortId is already zero-padded (returned by tx.planAlloc; matches registry key)
373
- writeStdout(`#${shortId}\n`);
374
- });
375
- }
376
-
377
- function cmdRelease(taskId, activeDir, registryPath, shortIdLength) {
378
- if (!TASK_ID_RE.test(taskId)) {
379
- writeStderr(`Error: invalid task id format '${taskId}'\n`);
380
- process.exit(1);
381
49
  }
382
- return withRegistryLock(activeDir, () => {
383
- const registry = readRegistry(registryPath);
384
- const tx = planTransaction(registry, activeDir, shortIdLength);
385
- tx.planRelease(taskId);
386
- try {
387
- tx.commit(registryPath);
388
- } catch (e) {
389
- writeStderr(`${e.message}\n`);
390
- process.exit(1);
391
- }
392
- // idempotent exit 0
393
- });
394
- }
395
-
396
- function cmdResolve(shortIdArg, activeDir, registryPath, shortIdLength) {
397
- // Accepts bare digits ('11') or '#'-prefixed form ('#11', '#11', '#005'); normalized by
398
- // numeric value with capacity check (n > 10^L-1) and reserved-zero rejection.
399
- const key = parseShortIdArg(shortIdArg, shortIdLength);
400
- return withRegistryLock(activeDir, () => {
401
- const registry = readRegistry(registryPath);
402
- const tx = planTransaction(registry, activeDir, shortIdLength);
403
- const taskId = tx._projectedIds[key];
404
- if (!taskId) {
405
- const hasPendingMutations =
406
- tx._plannedRegistryWrites.length > 0 ||
407
- tx._pendingRegistryDeletes.length > 0;
408
- if (hasPendingMutations) {
409
- try {
410
- tx.commit(registryPath);
411
- } catch (e) {
412
- writeStderr(`${e.message}\n`);
413
- process.exit(1);
414
- }
415
- }
416
- if (Object.keys(tx._projectedIds).length === 0) {
417
- writeStderr(
418
- `Error: short id '#${key}' not found; active task registry is empty.\n`
419
- );
420
- } else {
421
- writeStderr(
422
- `Error: short id '#${key}' not found in active task registry ` +
423
- `(it may have been cleaned up after archival; check 'task-short-id.js list').\n`
424
- );
425
- }
426
- process.exit(1);
427
- }
428
- try {
429
- tx.commit(registryPath);
430
- } catch (e) {
431
- writeStderr(`${e.message}\n`);
432
- process.exit(1);
433
- }
434
- writeStdout(`${taskId}\n`);
435
- });
50
+ return command;
436
51
  }
437
52
 
438
- function cmdList(activeDir, registryPath, verify) {
439
- if (!verify) {
440
- const registry = readRegistry(registryPath);
441
- writeStdout(`${JSON.stringify(registry, null, 2)}\n`);
442
- return;
443
- }
444
- const registry = readRegistry(registryPath);
445
- if (!fs.existsSync(activeDir)) {
446
- writeStdout("");
447
- return;
448
- }
449
- const diff = verifyRegistry(registry, activeDir);
450
- const hasIssues =
451
- diff.missing_in_registry.length > 0 ||
452
- diff.orphans_in_registry.length > 0 ||
453
- diff.duplicate_registry_keys.length > 0;
454
- if (hasIssues) {
455
- writeStdout(`${JSON.stringify(diff, null, 2)}\n`);
456
- process.exit(1);
457
- }
458
- // consistent: empty stdout, exit 0
53
+ const args = process.argv.slice(2);
54
+ if (args.includes("--help") || args.includes("-h")) {
55
+ fs.writeSync(1, "Usage: task-short-id.js <alloc|release|resolve|list> [argument] [--active-dir <path>] [--short-id-length <N>] [--verify]\n");
56
+ process.exit(0);
459
57
  }
460
-
461
- function main(argv) {
462
- let args;
463
- try {
464
- args = parseArgs(argv);
465
- } catch (e) {
466
- writeStderr(`${e.message}\n${usage()}\n`);
58
+ const repoRoot = findRepoRoot(process.cwd());
59
+ const forwarded = [...args];
60
+ if (!forwarded.includes("--active-dir")) {
61
+ if (!repoRoot) {
62
+ fs.writeSync(2, "Error: cannot determine active task directory\n");
467
63
  process.exit(1);
468
64
  }
469
- if (args.help || args.positional.length === 0) {
470
- writeStdout(`${usage()}\n`);
471
- return;
472
- }
473
- const subcommand = args.positional[0];
474
- const repoRoot = findRepoRoot(process.cwd());
475
- const activeDir = args.activeDir
476
- ? path.resolve(args.activeDir)
477
- : repoRoot
478
- ? path.join(repoRoot, ".agents", "workspace", "active")
479
- : null;
480
- if (!activeDir) {
481
- writeStderr(
482
- `Error: cannot locate active dir (no .agents/.airc.json found above ${process.cwd()})\n`
483
- );
484
- process.exit(2);
485
- }
486
- const shortIdLength = readShortIdLength(repoRoot, args.shortIdLength);
487
- const registryPath = path.join(activeDir, REGISTRY_NAME);
488
-
489
- switch (subcommand) {
490
- case "alloc":
491
- if (!args.positional[1]) {
492
- writeStderr(`Usage: alloc <task-id>\n`);
493
- process.exit(1);
494
- }
495
- return cmdAlloc(args.positional[1], activeDir, registryPath, shortIdLength);
496
- case "release":
497
- if (!args.positional[1]) {
498
- writeStderr(`Usage: release <task-id>\n`);
499
- process.exit(1);
500
- }
501
- return cmdRelease(args.positional[1], activeDir, registryPath, shortIdLength);
502
- case "resolve":
503
- if (!args.positional[1]) {
504
- writeStderr(`Usage: resolve <#N>\n`);
505
- process.exit(1);
506
- }
507
- return cmdResolve(args.positional[1], activeDir, registryPath, shortIdLength);
508
- case "list":
509
- return cmdList(activeDir, registryPath, args.verify);
510
- default:
511
- writeStderr(`Unknown subcommand: ${subcommand}\n${usage()}\n`);
512
- process.exit(1);
513
- }
514
- }
515
-
516
- // Compare canonicalized (symlink-resolved) paths so this script still runs as a
517
- // CLI when invoked through a temp-dir symlink (notably /var/folders on macOS,
518
- // which is a symlink to /private/var/folders; process.argv[1] keeps the
519
- // symlinked path while import.meta.url is auto-resolved to the realpath).
520
- const isCli = (() => {
521
- const entry = process.argv[1];
522
- if (!entry) return false;
523
- try {
524
- const realEntry = fs.realpathSync(entry);
525
- const realModule = fs.realpathSync(fileURLToPath(import.meta.url));
526
- return realEntry === realModule;
527
- } catch {
528
- return false;
529
- }
530
- })();
531
-
532
- if (isCli) {
533
- main(process.argv.slice(2));
65
+ forwarded.push("--active-dir", path.join(repoRoot, ".agents", "workspace", "active"));
66
+ }
67
+ if (!forwarded.includes("--short-id-length")) {
68
+ forwarded.push("--short-id-length", String(configuredWidth(repoRoot)));
69
+ }
70
+ const sourceCli = findSourceCli();
71
+ const installedCli = resolveCommand("agent-infra-internal");
72
+ const child = sourceCli
73
+ ? spawnSync(process.execPath, ["--experimental-strip-types", sourceCli, "task-short-id", ...forwarded], { encoding: "utf8" })
74
+ : spawnSync(installedCli, ["task-short-id", ...forwarded], {
75
+ encoding: "utf8",
76
+ shell: process.platform === "win32" && /\.(?:bat|cmd)$/i.test(installedCli)
77
+ });
78
+ if (child.error) {
79
+ fs.writeSync(2, `Error: ${child.error.message}\n`);
80
+ process.exit(1);
81
+ }
82
+ let result;
83
+ try {
84
+ result = JSON.parse(child.stdout);
85
+ } catch {
86
+ fs.writeSync(2, child.stderr || "Error: invalid task-short-id response\n");
87
+ process.exit(child.status || 1);
88
+ }
89
+ if (result.output) fs.writeSync(1, `${result.output}${result.output.endsWith("\n") ? "" : "\n"}`);
90
+ if (result.status === "failed") {
91
+ if (!result.output) fs.writeSync(2, `Error: ${result.error?.message || "short-id operation failed"}\n`);
92
+ const code = result.error?.code || "";
93
+ process.exit(code.includes("LOCK") ? 3 : /SCHEMA|JSON|DUPLICATE/.test(code) || (code.includes("CAPACITY") && args[0] === "alloc") ? 2 : 1);
534
94
  }
535
-
536
- export {
537
- TASK_ID_RE,
538
- SHORT_ID_RE,
539
- REGISTRY_NAME,
540
- parseArgs,
541
- findRepoRoot,
542
- readShortIdLength,
543
- readRegistry,
544
- writeRegistryAtomic,
545
- withRegistryLock,
546
- padShortId,
547
- parseShortIdArg,
548
- allocateMinFreeInt,
549
- planTransaction,
550
- verifyRegistry,
551
- cmdAlloc,
552
- cmdRelease,
553
- cmdResolve,
554
- cmdList,
555
- main
556
- };