@fitlab-ai/agent-infra 0.8.5 → 0.9.1

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 (467) hide show
  1. package/README.md +6 -1
  2. package/README.zh-CN.md +5 -1
  3. package/bin/cli.ts +2 -2
  4. package/dist/bin/cli.js +2 -2
  5. package/dist/bin/internal-cli.js +103 -0
  6. package/dist/lib/decide.js +81 -90
  7. package/dist/lib/defaults.json +1 -0
  8. package/dist/lib/git/review-snapshot.js +79 -0
  9. package/dist/lib/git/workflow.js +101 -0
  10. package/dist/lib/internal/git-workflow.js +42 -0
  11. package/dist/lib/internal/platform-checks.js +119 -0
  12. package/dist/lib/internal/platform-comment.js +129 -0
  13. package/dist/lib/internal/platform-context.js +46 -0
  14. package/dist/lib/internal/platform-issue.js +142 -0
  15. package/dist/lib/internal/platform-pr.js +146 -0
  16. package/dist/lib/internal/platform-release-notes.js +53 -0
  17. package/dist/lib/internal/release-workflow.js +320 -0
  18. package/dist/lib/internal/task-artifact.js +67 -0
  19. package/dist/lib/internal/task-context.js +43 -0
  20. package/dist/lib/internal/task-event.js +70 -0
  21. package/dist/lib/internal/task-ledger.js +114 -0
  22. package/dist/lib/internal/task-lifecycle.js +58 -0
  23. package/dist/lib/internal/task-short-id.js +83 -0
  24. package/dist/lib/internal/task-snapshot.js +47 -0
  25. package/dist/lib/internal/task-verify.js +50 -0
  26. package/dist/lib/internal/task-warning.js +74 -0
  27. package/dist/lib/platform/adapters.js +14 -0
  28. package/dist/lib/platform/context.js +146 -0
  29. package/dist/lib/platform/github-client.js +124 -0
  30. package/dist/lib/platform/github-release-notes.js +96 -0
  31. package/dist/lib/platform/issue-comments.js +409 -0
  32. package/dist/lib/platform/issue-metadata.js +183 -0
  33. package/dist/lib/platform/issues.js +619 -0
  34. package/dist/lib/platform/merged-pr-equivalence.js +54 -0
  35. package/dist/lib/platform/metadata-labels.js +28 -0
  36. package/dist/lib/platform/pr-checks.js +216 -0
  37. package/dist/lib/platform/pr-summary.js +88 -0
  38. package/dist/lib/platform/pull-request-metadata.js +38 -0
  39. package/dist/lib/platform/pull-requests.js +340 -0
  40. package/dist/lib/platform/release-notes.js +143 -0
  41. package/dist/lib/platform/releases.js +82 -0
  42. package/dist/lib/platform/types.js +22 -0
  43. package/dist/lib/platform/verification-required.js +102 -0
  44. package/dist/lib/platform/verification-sync.js +1014 -0
  45. package/dist/lib/platform/verification.js +6 -0
  46. package/dist/lib/release/channels.js +31 -0
  47. package/dist/lib/release/workflow.js +32 -0
  48. package/dist/lib/render.js +3 -2
  49. package/dist/lib/run/index.js +24 -7
  50. package/dist/lib/sandbox/build-proxy.js +63 -0
  51. package/dist/lib/sandbox/capture.js +25 -3
  52. package/dist/lib/sandbox/commands/create.js +93 -31
  53. package/dist/lib/sandbox/commands/enter.js +34 -11
  54. package/dist/lib/sandbox/commands/list-running.js +10 -8
  55. package/dist/lib/sandbox/commands/rebuild.js +24 -7
  56. package/dist/lib/sandbox/commands/show.js +2 -2
  57. package/dist/lib/sandbox/commands/start.js +53 -15
  58. package/dist/lib/sandbox/image-build.js +2 -1
  59. package/dist/lib/sandbox/index.js +6 -6
  60. package/dist/lib/sandbox/mounts.js +36 -0
  61. package/dist/lib/sandbox/recovery.js +562 -0
  62. package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
  63. package/dist/lib/sandbox/runtimes/base.dockerfile +8 -1
  64. package/dist/lib/sandbox/runtimes/java17.dockerfile +8 -1
  65. package/dist/lib/sandbox/runtimes/java21.dockerfile +8 -1
  66. package/dist/lib/sandbox/runtimes/node20.dockerfile +8 -1
  67. package/dist/lib/sandbox/runtimes/node22.dockerfile +8 -1
  68. package/dist/lib/sandbox/runtimes/python3.dockerfile +8 -1
  69. package/dist/lib/sandbox/shell.js +2 -1
  70. package/dist/lib/sandbox/task-resolver.js +5 -1
  71. package/dist/lib/sandbox/tools.js +19 -0
  72. package/dist/lib/server/protocol.js +5 -5
  73. package/dist/lib/task/activity-log.js +61 -0
  74. package/dist/lib/task/artifact-lifecycle.js +427 -0
  75. package/dist/lib/task/command-options.js +30 -0
  76. package/dist/lib/task/commands/cat.js +36 -6
  77. package/dist/lib/task/commands/decisions.js +80 -46
  78. package/dist/lib/task/commands/files.js +21 -7
  79. package/dist/lib/task/commands/grep.js +55 -7
  80. package/dist/lib/task/commands/issue-body.js +33 -19
  81. package/dist/lib/task/commands/log.js +27 -70
  82. package/dist/lib/task/commands/show.js +20 -7
  83. package/dist/lib/task/commands/status.js +18 -8
  84. package/dist/lib/task/decision-intents.js +154 -0
  85. package/dist/lib/task/decision-items.js +53 -0
  86. package/dist/lib/task/events.js +318 -0
  87. package/dist/lib/task/frontmatter.js +159 -1
  88. package/dist/lib/task/implementation-inputs.js +117 -0
  89. package/dist/lib/task/index.js +12 -9
  90. package/dist/lib/task/issue-form.js +21 -6
  91. package/dist/lib/task/ledger-intents.js +185 -0
  92. package/dist/lib/task/ledger.js +65 -35
  93. package/dist/lib/task/lifecycle.js +484 -0
  94. package/dist/lib/task/resolve-ref.js +152 -32
  95. package/dist/lib/task/review-artifacts.js +101 -0
  96. package/dist/lib/task/review-fingerprint.js +55 -0
  97. package/dist/lib/task/sections.js +358 -4
  98. package/dist/lib/task/short-id.js +292 -7
  99. package/dist/lib/task/snapshot.js +95 -0
  100. package/dist/lib/task/verification-checks.js +8 -0
  101. package/dist/lib/task/verification-config.js +14 -0
  102. package/dist/lib/task/verification-engine.js +923 -0
  103. package/dist/lib/task/verification-review.js +3 -0
  104. package/dist/lib/task/verification-types.js +2 -0
  105. package/dist/lib/task/verification.js +113 -0
  106. package/dist/lib/task/workflow-warning-intents.js +131 -0
  107. package/dist/lib/task/workflow-warnings.js +10 -78
  108. package/dist/lib/task/write.js +241 -0
  109. package/lib/decide.ts +57 -97
  110. package/lib/defaults.json +1 -0
  111. package/lib/git/review-snapshot.ts +73 -0
  112. package/lib/git/workflow.ts +101 -0
  113. package/lib/internal/git-workflow.ts +37 -0
  114. package/lib/internal/platform-checks.ts +101 -0
  115. package/lib/internal/platform-comment.ts +99 -0
  116. package/lib/internal/platform-context.ts +33 -0
  117. package/lib/internal/platform-issue.ts +116 -0
  118. package/lib/internal/platform-pr.ts +119 -0
  119. package/lib/internal/platform-release-notes.ts +55 -0
  120. package/lib/internal/release-workflow.ts +288 -0
  121. package/lib/internal/task-artifact.ts +47 -0
  122. package/lib/internal/task-context.ts +35 -0
  123. package/lib/internal/task-event.ts +51 -0
  124. package/lib/internal/task-ledger.ts +86 -0
  125. package/lib/internal/task-lifecycle.ts +41 -0
  126. package/lib/internal/task-short-id.ts +55 -0
  127. package/lib/internal/task-snapshot.ts +32 -0
  128. package/lib/internal/task-verify.ts +33 -0
  129. package/lib/internal/task-warning.ts +50 -0
  130. package/lib/platform/adapters.ts +30 -0
  131. package/lib/platform/context.ts +164 -0
  132. package/lib/platform/github-client.ts +146 -0
  133. package/lib/platform/github-release-notes.ts +132 -0
  134. package/lib/platform/issue-comments.ts +479 -0
  135. package/lib/platform/issue-metadata.ts +250 -0
  136. package/lib/platform/issues.ts +693 -0
  137. package/lib/platform/merged-pr-equivalence.ts +70 -0
  138. package/lib/platform/metadata-labels.ts +33 -0
  139. package/lib/platform/pr-checks.ts +247 -0
  140. package/lib/platform/pr-summary.ts +90 -0
  141. package/lib/platform/pull-request-metadata.ts +69 -0
  142. package/lib/platform/pull-requests.ts +386 -0
  143. package/lib/platform/release-notes.ts +167 -0
  144. package/lib/platform/releases.ts +71 -0
  145. package/lib/platform/types.ts +74 -0
  146. package/lib/platform/verification-required.ts +109 -0
  147. package/{runtime/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts} +198 -367
  148. package/lib/platform/verification.ts +11 -0
  149. package/lib/release/channels.ts +30 -0
  150. package/lib/release/workflow.ts +31 -0
  151. package/lib/render.ts +3 -2
  152. package/lib/run/index.ts +25 -7
  153. package/lib/sandbox/build-proxy.ts +94 -0
  154. package/lib/sandbox/capture.ts +29 -3
  155. package/lib/sandbox/commands/create.ts +120 -36
  156. package/lib/sandbox/commands/enter.ts +38 -11
  157. package/lib/sandbox/commands/list-running.ts +10 -8
  158. package/lib/sandbox/commands/rebuild.ts +29 -7
  159. package/lib/sandbox/commands/show.ts +2 -2
  160. package/lib/sandbox/commands/start.ts +50 -16
  161. package/lib/sandbox/image-build.ts +4 -1
  162. package/lib/sandbox/index.ts +6 -6
  163. package/lib/sandbox/mounts.ts +55 -0
  164. package/lib/sandbox/recovery.ts +828 -0
  165. package/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
  166. package/lib/sandbox/runtimes/base.dockerfile +8 -1
  167. package/lib/sandbox/runtimes/java17.dockerfile +8 -1
  168. package/lib/sandbox/runtimes/java21.dockerfile +8 -1
  169. package/lib/sandbox/runtimes/node20.dockerfile +8 -1
  170. package/lib/sandbox/runtimes/node22.dockerfile +8 -1
  171. package/lib/sandbox/runtimes/python3.dockerfile +8 -1
  172. package/lib/sandbox/shell.ts +3 -1
  173. package/lib/sandbox/task-resolver.ts +5 -1
  174. package/lib/sandbox/tools.ts +31 -0
  175. package/lib/server/protocol.ts +5 -5
  176. package/lib/task/activity-log.ts +62 -0
  177. package/lib/task/artifact-lifecycle.ts +484 -0
  178. package/lib/task/command-options.ts +32 -0
  179. package/lib/task/commands/cat.ts +22 -9
  180. package/lib/task/commands/decisions.ts +49 -47
  181. package/lib/task/commands/files.ts +14 -6
  182. package/lib/task/commands/grep.ts +34 -7
  183. package/lib/task/commands/issue-body.ts +26 -21
  184. package/lib/task/commands/log.ts +17 -70
  185. package/lib/task/commands/show.ts +14 -6
  186. package/lib/task/commands/status.ts +17 -7
  187. package/lib/task/decision-intents.ts +163 -0
  188. package/lib/task/decision-items.ts +64 -0
  189. package/lib/task/events.ts +320 -0
  190. package/lib/task/frontmatter.ts +202 -2
  191. package/lib/task/implementation-inputs.ts +137 -0
  192. package/lib/task/index.ts +12 -9
  193. package/lib/task/issue-form.ts +24 -6
  194. package/lib/task/ledger-intents.ts +201 -0
  195. package/lib/task/ledger.ts +77 -31
  196. package/lib/task/lifecycle.ts +458 -0
  197. package/lib/task/resolve-ref.ts +197 -36
  198. package/{templates/.agents/scripts/lib/review-artifacts.js → lib/task/review-artifacts.ts} +11 -12
  199. package/{templates/.agents/scripts/lib/post-review-commit.js → lib/task/review-fingerprint.ts} +26 -12
  200. package/lib/task/sections.ts +486 -4
  201. package/lib/task/short-id.ts +403 -9
  202. package/lib/task/snapshot.ts +143 -0
  203. package/lib/task/verification-checks.ts +9 -0
  204. package/lib/task/verification-config.ts +20 -0
  205. package/{templates/.agents/scripts/validate-artifact.js → lib/task/verification-engine.ts} +230 -421
  206. package/lib/task/verification-review.ts +10 -0
  207. package/lib/task/verification-types.ts +29 -0
  208. package/lib/task/verification.ts +156 -0
  209. package/lib/task/workflow-warning-intents.ts +142 -0
  210. package/lib/task/workflow-warnings.ts +10 -78
  211. package/lib/task/write.ts +468 -0
  212. package/package.json +4 -2
  213. package/templates/.agents/README.en.md +4 -3
  214. package/templates/.agents/README.zh-CN.md +4 -3
  215. package/templates/.agents/rules/README.en.md +6 -5
  216. package/templates/.agents/rules/README.zh-CN.md +6 -5
  217. package/templates/.agents/rules/create-issue.en.md +1 -1
  218. package/templates/.agents/rules/create-issue.github.en.md +5 -184
  219. package/templates/.agents/rules/create-issue.github.zh-CN.md +12 -178
  220. package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
  221. package/templates/.agents/rules/human-decision-context.en.md +36 -0
  222. package/templates/.agents/rules/human-decision-context.zh-CN.md +36 -0
  223. package/templates/.agents/rules/issue-fields.github.en.md +4 -148
  224. package/templates/.agents/rules/issue-fields.github.zh-CN.md +9 -144
  225. package/templates/.agents/rules/issue-pr-commands.en.md +43 -3
  226. package/templates/.agents/rules/issue-pr-commands.github.en.md +15 -220
  227. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +23 -213
  228. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +45 -3
  229. package/templates/.agents/rules/issue-sync.en.md +1 -1
  230. package/templates/.agents/rules/issue-sync.github.en.md +14 -301
  231. package/templates/.agents/rules/issue-sync.github.zh-CN.md +36 -287
  232. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  233. package/templates/.agents/rules/milestone-inference.en.md +1 -1
  234. package/templates/.agents/rules/milestone-inference.github.en.md +7 -119
  235. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +8 -108
  236. package/templates/.agents/rules/milestone-inference.zh-CN.md +1 -1
  237. package/templates/.agents/rules/next-step-output.en.md +12 -11
  238. package/templates/.agents/rules/next-step-output.zh-CN.md +12 -11
  239. package/templates/.agents/rules/no-mid-flow-questions.en.md +3 -3
  240. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +3 -3
  241. package/templates/.agents/rules/pr-checks-commands.en.md +16 -3
  242. package/templates/.agents/rules/pr-checks-commands.github.en.md +10 -54
  243. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +19 -47
  244. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +30 -3
  245. package/templates/.agents/rules/pr-sync.en.md +30 -3
  246. package/templates/.agents/rules/pr-sync.github.en.md +12 -115
  247. package/templates/.agents/rules/pr-sync.github.zh-CN.md +26 -104
  248. package/templates/.agents/rules/pr-sync.zh-CN.md +43 -3
  249. package/templates/.agents/rules/release-commands.en.md +2 -2
  250. package/templates/.agents/rules/release-commands.github.en.md +10 -40
  251. package/templates/.agents/rules/release-commands.github.zh-CN.md +9 -39
  252. package/templates/.agents/rules/release-commands.zh-CN.md +2 -2
  253. package/templates/.agents/rules/review-handshake.en.md +10 -6
  254. package/templates/.agents/rules/review-handshake.zh-CN.md +10 -6
  255. package/templates/.agents/rules/task-management.en.md +11 -2
  256. package/templates/.agents/rules/task-management.zh-CN.md +11 -3
  257. package/templates/.agents/rules/task-short-id.en.md +25 -29
  258. package/templates/.agents/rules/task-short-id.zh-CN.md +20 -23
  259. package/templates/.agents/rules/testing-discipline.en.md +20 -2
  260. package/templates/.agents/rules/testing-discipline.zh-CN.md +20 -2
  261. package/templates/.agents/scripts/lib/agent-infra-package.js +1 -9
  262. package/templates/.agents/scripts/task-short-id.js +71 -533
  263. package/templates/.agents/skills/analyze-task/SKILL.en.md +26 -56
  264. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +30 -60
  265. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -3
  266. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -3
  267. package/templates/.agents/skills/block-task/SKILL.en.md +21 -47
  268. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +23 -47
  269. package/templates/.agents/skills/block-task/config/verify.json +1 -2
  270. package/templates/.agents/skills/cancel-task/SKILL.en.md +16 -45
  271. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +16 -45
  272. package/templates/.agents/skills/cancel-task/config/verify.json +1 -2
  273. package/templates/.agents/skills/check-task/SKILL.en.md +6 -3
  274. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +6 -3
  275. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -24
  276. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -24
  277. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -24
  278. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -24
  279. package/templates/.agents/skills/code-task/SKILL.en.md +22 -35
  280. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +28 -44
  281. package/templates/.agents/skills/code-task/config/verify.en.json +3 -3
  282. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +3 -3
  283. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +13 -9
  284. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +13 -9
  285. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
  286. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
  287. package/templates/.agents/skills/code-task/reference/report-template.en.md +11 -1
  288. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +11 -1
  289. package/templates/.agents/skills/commit/SKILL.en.md +13 -11
  290. package/templates/.agents/skills/commit/SKILL.zh-CN.md +13 -11
  291. package/templates/.agents/skills/commit/config/verify.json +1 -2
  292. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -11
  293. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -11
  294. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +4 -8
  295. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +4 -8
  296. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +6 -18
  297. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +5 -17
  298. package/templates/.agents/skills/commit/reference/task-status-update.en.md +13 -0
  299. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +13 -0
  300. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +13 -36
  301. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +13 -36
  302. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -3
  303. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -3
  304. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +10 -54
  305. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +10 -79
  306. package/templates/.agents/skills/complete-task/SKILL.en.md +59 -63
  307. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +59 -63
  308. package/templates/.agents/skills/complete-task/config/verify.en.json +10 -7
  309. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +10 -7
  310. package/templates/.agents/skills/create-pr/SKILL.en.md +19 -44
  311. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +19 -43
  312. package/templates/.agents/skills/create-pr/config/verify.json +1 -2
  313. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +8 -12
  314. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +7 -11
  315. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -38
  316. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +16 -37
  317. package/templates/.agents/skills/create-task/SKILL.en.md +16 -13
  318. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +16 -13
  319. package/templates/.agents/skills/create-task/config/verify.json +1 -2
  320. package/templates/.agents/skills/create-task/reference/context-capture.en.md +29 -0
  321. package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +29 -0
  322. package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -2
  323. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +2 -2
  324. package/templates/.agents/skills/import-codescan/config/verify.json +1 -2
  325. package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
  326. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
  327. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -2
  328. package/templates/.agents/skills/import-issue/SKILL.en.md +9 -13
  329. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -14
  330. package/templates/.agents/skills/import-issue/config/verify.json +1 -2
  331. package/templates/.agents/skills/plan-task/SKILL.en.md +17 -42
  332. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -49
  333. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -3
  334. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -3
  335. package/templates/.agents/skills/post-release/SKILL.en.md +11 -81
  336. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +8 -78
  337. package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
  338. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
  339. package/templates/.agents/skills/release/SKILL.en.md +16 -163
  340. package/templates/.agents/skills/release/SKILL.zh-CN.md +15 -162
  341. package/templates/.agents/skills/restore-task/SKILL.en.md +11 -29
  342. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +11 -29
  343. package/templates/.agents/skills/restore-task/config/verify.json +1 -2
  344. package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -25
  345. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +13 -33
  346. package/templates/.agents/skills/review-analysis/config/verify.en.json +3 -4
  347. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +3 -4
  348. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +9 -12
  349. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +9 -12
  350. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +9 -2
  351. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +9 -2
  352. package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +7 -0
  353. package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +7 -0
  354. package/templates/.agents/skills/review-code/SKILL.en.md +22 -36
  355. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +23 -41
  356. package/templates/.agents/skills/review-code/config/verify.en.json +3 -4
  357. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +3 -4
  358. package/templates/.agents/skills/review-code/reference/output-templates.en.md +56 -18
  359. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +56 -18
  360. package/templates/.agents/skills/review-code/reference/report-template.en.md +11 -4
  361. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +11 -4
  362. package/templates/.agents/skills/review-code/reference/review-criteria.en.md +7 -0
  363. package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +7 -0
  364. package/templates/.agents/skills/review-plan/SKILL.en.md +13 -25
  365. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +13 -33
  366. package/templates/.agents/skills/review-plan/config/verify.en.json +3 -4
  367. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +3 -4
  368. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +9 -12
  369. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +9 -12
  370. package/templates/.agents/skills/review-plan/reference/report-template.en.md +9 -2
  371. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +9 -2
  372. package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +7 -0
  373. package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +7 -0
  374. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -2
  375. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -2
  376. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -15
  377. package/templates/.agents/skills/watch-pr/SKILL.en.md +24 -14
  378. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +25 -15
  379. package/templates/.agents/skills/watch-pr/config/verify.json +1 -2
  380. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
  381. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
  382. package/templates/.agents/templates/task.en.md +24 -1
  383. package/templates/.agents/templates/task.zh-CN.md +24 -1
  384. package/templates/.claude/commands/analyze-task.en.md +1 -1
  385. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  386. package/templates/.claude/commands/block-task.en.md +1 -1
  387. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  388. package/templates/.claude/commands/cancel-task.en.md +1 -1
  389. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  390. package/templates/.claude/commands/check-task.en.md +1 -1
  391. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  392. package/templates/.claude/commands/code-task.en.md +1 -1
  393. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  394. package/templates/.claude/commands/commit.en.md +1 -0
  395. package/templates/.claude/commands/commit.zh-CN.md +1 -0
  396. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  397. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  398. package/templates/.claude/commands/complete-task.en.md +1 -1
  399. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  400. package/templates/.claude/commands/create-pr.en.md +1 -1
  401. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  402. package/templates/.claude/commands/plan-task.en.md +1 -1
  403. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  404. package/templates/.claude/commands/review-analysis.en.md +1 -1
  405. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  406. package/templates/.claude/commands/review-code.en.md +1 -1
  407. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  408. package/templates/.claude/commands/review-plan.en.md +1 -1
  409. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  410. package/templates/.claude/commands/watch-pr.en.md +1 -1
  411. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  412. package/templates/.gemini/commands/_project_/analyze-task.en.toml +2 -0
  413. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +2 -0
  414. package/templates/.gemini/commands/_project_/block-task.en.toml +2 -0
  415. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +2 -0
  416. package/templates/.gemini/commands/_project_/cancel-task.en.toml +2 -0
  417. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +2 -0
  418. package/templates/.gemini/commands/_project_/check-task.en.toml +2 -0
  419. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +2 -0
  420. package/templates/.gemini/commands/_project_/code-task.en.toml +2 -0
  421. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +2 -0
  422. package/templates/.gemini/commands/_project_/commit.en.toml +4 -0
  423. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +4 -0
  424. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +2 -0
  425. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +2 -0
  426. package/templates/.gemini/commands/_project_/complete-task.en.toml +2 -0
  427. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +2 -0
  428. package/templates/.gemini/commands/_project_/create-pr.en.toml +2 -0
  429. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +2 -0
  430. package/templates/.gemini/commands/_project_/plan-task.en.toml +2 -0
  431. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +2 -0
  432. package/templates/.gemini/commands/_project_/review-analysis.en.toml +2 -0
  433. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +2 -0
  434. package/templates/.gemini/commands/_project_/review-code.en.toml +2 -0
  435. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +2 -0
  436. package/templates/.gemini/commands/_project_/review-plan.en.toml +2 -0
  437. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +2 -0
  438. package/templates/.gemini/commands/_project_/watch-pr.en.toml +2 -0
  439. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +2 -0
  440. package/templates/.git-hooks/check-large-files.cjs +92 -0
  441. package/templates/.git-hooks/check-version-format.sh +5 -1
  442. package/templates/.git-hooks/pre-commit +1 -0
  443. package/templates/.opencode/commands/analyze-task.en.md +1 -1
  444. package/templates/.opencode/commands/analyze-task.zh-CN.md +1 -1
  445. package/templates/.opencode/commands/check-task.en.md +1 -1
  446. package/templates/.opencode/commands/check-task.zh-CN.md +1 -1
  447. package/templates/.opencode/commands/code-task.en.md +1 -1
  448. package/templates/.opencode/commands/code-task.zh-CN.md +1 -1
  449. package/templates/.opencode/commands/commit.en.md +2 -0
  450. package/templates/.opencode/commands/commit.zh-CN.md +2 -0
  451. package/templates/.opencode/commands/complete-task.en.md +1 -1
  452. package/templates/.opencode/commands/complete-task.zh-CN.md +1 -1
  453. package/templates/.opencode/commands/plan-task.en.md +1 -1
  454. package/templates/.opencode/commands/plan-task.zh-CN.md +1 -1
  455. package/templates/.opencode/commands/review-analysis.en.md +1 -1
  456. package/templates/.opencode/commands/review-analysis.zh-CN.md +1 -1
  457. package/templates/.opencode/commands/review-code.en.md +1 -1
  458. package/templates/.opencode/commands/review-code.zh-CN.md +1 -1
  459. package/templates/.opencode/commands/review-plan.en.md +1 -1
  460. package/templates/.opencode/commands/review-plan.zh-CN.md +1 -1
  461. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +0 -40
  462. package/templates/.agents/scripts/platform-adapters/platform-sync.js +0 -13
  463. package/templates/.agents/scripts/review-diff-fingerprint.js +0 -170
  464. package/templates/.agents/scripts/workflow-warnings.js +0 -290
  465. package/templates/.agents/skills/code-task/scripts/detect-mode.js +0 -257
  466. package/templates/.agents/skills/release/scripts/manage-milestones.github.sh +0 -80
  467. package/templates/.agents/skills/release/scripts/manage-milestones.sh +0 -6
package/README.md CHANGED
@@ -35,9 +35,14 @@ agent-infra standardizes that shared infrastructure. It gives every supported AI
35
35
  ## See it in Action
36
36
 
37
37
  <p align="center">
38
- <img src="./assets/demo-init.gif" alt="CLI install and initialize demo" width="100%" style="max-width: 720px;">
38
+ <img src="./assets/demo-init.gif" alt="CLI install and initialize demo" width="720">
39
39
  </p>
40
40
 
41
+ > The demo is stored with Git LFS. Install Git LFS and run `git lfs install`
42
+ > before cloning, or run `git lfs pull` in an existing checkout. If the image
43
+ > is a small text pointer or is missing, verify `git lfs ls-files`, then retry
44
+ > `git lfs pull`.
45
+
41
46
  Once initialized, open the project in your AI TUI and install the latest skills:
42
47
 
43
48
  ```bash
package/README.zh-CN.md CHANGED
@@ -35,9 +35,13 @@ agent-infra 的目标就是把这层共享基础设施标准化。它为所有
35
35
  ## 实战演示
36
36
 
37
37
  <p align="center">
38
- <img src="./assets/demo-init.gif" alt="CLI 安装初始化演示" width="100%" style="max-width: 720px;">
38
+ <img src="./assets/demo-init.gif" alt="CLI 安装初始化演示" width="720">
39
39
  </p>
40
40
 
41
+ > 演示动画通过 Git LFS 存储。克隆前请安装 Git LFS 并运行 `git lfs install`;
42
+ > 已有检出可运行 `git lfs pull`。如果图片变成很小的文本指针或缺失,请先用
43
+ > `git lfs ls-files` 核对跟踪状态,再重试 `git lfs pull`。
44
+
41
45
  完成初始化后,在你的 AI TUI 中打开项目并安装最新 skills:
42
46
 
43
47
  ```bash
package/bin/cli.ts CHANGED
@@ -16,14 +16,14 @@ Usage: ai <command> [options]
16
16
 
17
17
  Commands:
18
18
  cp <ssh-alias> Copy local clipboard image to a remote macOS clipboard or Linux sandbox over SSH
19
- decide Record a human decision for a task HD item
19
+ decide Record a ruling; code-stage decisions require explicit implementation intent
20
20
  help Show this help message
21
21
  init Initialize a new project with update-agent-infra seed command
22
22
  merge Merge tasks from another workspace directory (active/blocked/completed/archive)
23
23
  run Schedule a lifecycle skill in the task sandbox tmux session
24
24
  sandbox, s Manage Docker-based AI sandboxes
25
25
  server Run the local AI collaboration daemon (start/stop/status/logs)
26
- task, t Read-only views over .agents/workspace tasks (cat / files / grep / log / ls / show / status)
26
+ task, t Read-only views of .agents/workspace tasks
27
27
  update Update seed files and sync file registry for an existing project
28
28
  version Show version
29
29
 
package/dist/bin/cli.js CHANGED
@@ -20,14 +20,14 @@ Usage: ai <command> [options]
20
20
 
21
21
  Commands:
22
22
  cp <ssh-alias> Copy local clipboard image to a remote macOS clipboard or Linux sandbox over SSH
23
- decide Record a human decision for a task HD item
23
+ decide Record a ruling; code-stage decisions require explicit implementation intent
24
24
  help Show this help message
25
25
  init Initialize a new project with update-agent-infra seed command
26
26
  merge Merge tasks from another workspace directory (active/blocked/completed/archive)
27
27
  run Schedule a lifecycle skill in the task sandbox tmux session
28
28
  sandbox, s Manage Docker-based AI sandboxes
29
29
  server Run the local AI collaboration daemon (start/stop/status/logs)
30
- task, t Read-only views over .agents/workspace tasks (cat / files / grep / log / ls / show / status)
30
+ task, t Read-only views of .agents/workspace tasks
31
31
  update Update seed files and sync file registry for an existing project
32
32
  version Show version
33
33
 
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ const [major = 0, minor = 0] = process.versions.node.split('.').map((part) => parseInt(part, 10));
3
+ if (major < 22 || (major === 22 && minor < 9)) {
4
+ process.stderr.write(`agent-infra-internal requires Node.js >= 22.9.0 (current: ${process.version})\n`);
5
+ process.exit(1);
6
+ }
7
+ const command = process.argv[2] || '';
8
+ switch (command) {
9
+ case 'git-workflow': {
10
+ const { gitWorkflow } = await import('../lib/internal/git-workflow.js');
11
+ gitWorkflow(process.argv.slice(3));
12
+ break;
13
+ }
14
+ case 'release-workflow': {
15
+ const { releaseWorkflow } = await import('../lib/internal/release-workflow.js');
16
+ await releaseWorkflow(process.argv.slice(3));
17
+ break;
18
+ }
19
+ case 'platform-release-notes': {
20
+ const { platformReleaseNotes } = await import('../lib/internal/platform-release-notes.js');
21
+ platformReleaseNotes(process.argv.slice(3));
22
+ break;
23
+ }
24
+ case 'platform-context': {
25
+ const { platformContext } = await import('../lib/internal/platform-context.js');
26
+ platformContext(process.argv.slice(3));
27
+ break;
28
+ }
29
+ case 'platform-comment': {
30
+ const { platformComment } = await import('../lib/internal/platform-comment.js');
31
+ platformComment(process.argv.slice(3));
32
+ break;
33
+ }
34
+ case 'platform-issue': {
35
+ const { platformIssue } = await import('../lib/internal/platform-issue.js');
36
+ platformIssue(process.argv.slice(3));
37
+ break;
38
+ }
39
+ case 'platform-pr': {
40
+ const { platformPr } = await import('../lib/internal/platform-pr.js');
41
+ platformPr(process.argv.slice(3));
42
+ break;
43
+ }
44
+ case 'platform-checks': {
45
+ const { platformChecks } = await import('../lib/internal/platform-checks.js');
46
+ await platformChecks(process.argv.slice(3));
47
+ break;
48
+ }
49
+ case 'task-context': {
50
+ const { taskContext } = await import('../lib/internal/task-context.js');
51
+ taskContext(process.argv.slice(3));
52
+ break;
53
+ }
54
+ case 'task-ledger': {
55
+ const { taskLedger } = await import('../lib/internal/task-ledger.js');
56
+ taskLedger(process.argv.slice(3));
57
+ break;
58
+ }
59
+ case 'task-warning': {
60
+ const { taskWarning } = await import('../lib/internal/task-warning.js');
61
+ taskWarning(process.argv.slice(3));
62
+ break;
63
+ }
64
+ case 'task-artifact': {
65
+ const { taskArtifact } = await import('../lib/internal/task-artifact.js');
66
+ taskArtifact(process.argv.slice(3));
67
+ break;
68
+ }
69
+ case 'task-event': {
70
+ const { taskEvent } = await import('../lib/internal/task-event.js');
71
+ taskEvent(process.argv.slice(3));
72
+ break;
73
+ }
74
+ case 'task-lifecycle': {
75
+ const { taskLifecycle } = await import('../lib/internal/task-lifecycle.js');
76
+ taskLifecycle(process.argv.slice(3));
77
+ break;
78
+ }
79
+ case 'task-short-id': {
80
+ const { taskShortId } = await import('../lib/internal/task-short-id.js');
81
+ taskShortId(process.argv.slice(3));
82
+ break;
83
+ }
84
+ case 'task-snapshot': {
85
+ const { taskSnapshot } = await import('../lib/internal/task-snapshot.js');
86
+ taskSnapshot(process.argv.slice(3));
87
+ break;
88
+ }
89
+ case 'task-verify': {
90
+ const { taskVerify } = await import('../lib/internal/task-verify.js');
91
+ taskVerify(process.argv.slice(3));
92
+ break;
93
+ }
94
+ default:
95
+ process.stdout.write(`${JSON.stringify({
96
+ status: 'failed',
97
+ changed: false,
98
+ error: { code: 'INTERNAL_COMMAND_INVALID', message: `unknown internal command '${command}'` }
99
+ })}\n`);
100
+ process.exitCode = 1;
101
+ }
102
+ export {};
103
+ //# sourceMappingURL=internal-cli.js.map
@@ -1,102 +1,93 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { execFileSync } from 'node:child_process';
4
1
  import { VERSION } from './version.js';
5
- import { resolveTaskRef } from './task/resolve-ref.js';
6
- const TASK_ID_RE = /^TASK-\d{8}-\d{6}$/;
7
- function detectRepoRoot() {
8
- return execFileSync('git', ['rev-parse', '--show-toplevel'], {
9
- encoding: 'utf8',
10
- stdio: ['pipe', 'pipe', 'pipe']
11
- }).trim();
12
- }
13
- function defaultNow() {
14
- return new Intl.DateTimeFormat('sv-SE', {
15
- timeZoneName: 'longOffset',
16
- year: 'numeric',
17
- month: '2-digit',
18
- day: '2-digit',
19
- hour: '2-digit',
20
- minute: '2-digit',
21
- second: '2-digit',
22
- hour12: false
23
- })
24
- .format(new Date())
25
- .replace(' GMT', '');
26
- }
27
- function taskPath(repoRoot, ref) {
28
- if (!TASK_ID_RE.test(ref)) {
29
- const resolved = resolveTaskRef(ref);
30
- if (!resolved.ok)
31
- throw new Error(resolved.message);
32
- if (!resolved.taskDir.includes(`${path.join('.agents', 'workspace', 'active')}${path.sep}`)) {
33
- throw new Error(`task ${resolved.taskId} is not active`);
2
+ import { parseTaskScope } from './task/command-options.js';
3
+ import { applyHumanDecision } from './task/decision-intents.js';
4
+ import { canonicalTimestamp } from './task/write.js';
5
+ function parseDecisionParts(parts) {
6
+ const decision = [];
7
+ let needsImplementation;
8
+ for (let index = 0; index < parts.length; index += 1) {
9
+ if (parts[index] !== '--needs-implementation') {
10
+ decision.push(parts[index]);
11
+ continue;
34
12
  }
35
- return resolved.taskMdPath;
13
+ if (needsImplementation !== undefined)
14
+ throw new Error("duplicate option '--needs-implementation'");
15
+ const value = parts[++index];
16
+ if (value !== 'true' && value !== 'false') {
17
+ throw new Error("--needs-implementation must be 'true' or 'false'");
18
+ }
19
+ needsImplementation = value === 'true';
36
20
  }
37
- const candidate = path.join(repoRoot, '.agents', 'workspace', 'active', ref, 'task.md');
38
- if (!fs.existsSync(candidate))
39
- throw new Error(`active task not found: ${ref}`);
40
- return candidate;
41
- }
42
- function replaceFrontmatterField(content, field, value) {
43
- const re = new RegExp(`^${field}:.*$`, 'm');
44
- if (re.test(content))
45
- return content.replace(re, `${field}: ${value}`);
46
- return content.replace(/^---\n/, `---\n${field}: ${value}\n`);
21
+ if (decision.length === 0)
22
+ throw new Error('decision content is required');
23
+ return { decision: decision.join(' '), needsImplementation };
47
24
  }
48
- function replaceLedgerRow(content, hdId) {
49
- const lines = content.split('\n');
50
- let found = false;
51
- let pending = false;
52
- for (let i = 0; i < lines.length; i += 1) {
53
- const line = lines[i];
54
- if (!line.trim().startsWith(`| ${hdId} |`))
55
- continue;
56
- found = true;
57
- const cells = line.split('|').slice(1, -1).map((cell) => cell.trim());
58
- if (cells[4] !== 'needs-human-decision')
59
- break;
60
- pending = true;
61
- cells[4] = 'human-decided';
62
- cells[5] = `task.md#${hdId}`;
63
- lines[i] = `| ${cells.join(' | ')} |`;
64
- break;
25
+ export async function decide(args, options = {}) {
26
+ let scope;
27
+ try {
28
+ scope = parseTaskScope(args);
65
29
  }
66
- return { content: lines.join('\n'), found, pending };
67
- }
68
- function appendUnderHeading(content, heading, block) {
69
- if (!content.includes(`${heading}\n`)) {
70
- return `${content.trimEnd()}\n\n${heading}\n\n${block}\n`;
30
+ catch (error) {
31
+ process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}\n`);
32
+ return 1;
71
33
  }
72
- const idx = content.indexOf(`${heading}\n`) + heading.length + 1;
73
- const before = content.slice(0, idx);
74
- const after = content.slice(idx);
75
- return `${before}\n${block}\n${after.replace(/^\n/, '')}`;
76
- }
77
- export async function decide(args, options = {}) {
78
- const [taskRef, hdId, ...decisionParts] = args;
79
- if (!taskRef || !hdId || decisionParts.length === 0) {
80
- process.stderr.write('Usage: ai decide <task-ref> <HD-id> <decision>\n');
34
+ let item;
35
+ const operands = [];
36
+ for (let index = 0; index < scope.positionals.length; index += 1) {
37
+ const arg = scope.positionals[index];
38
+ if (arg === '--item' || arg === '-i') {
39
+ if (item !== undefined) {
40
+ process.stderr.write("Error: duplicate option '--item'\n");
41
+ return 1;
42
+ }
43
+ item = scope.positionals[++index];
44
+ if (!item) {
45
+ process.stderr.write(`Error: ${arg} requires a value\n`);
46
+ return 1;
47
+ }
48
+ }
49
+ else if (arg.startsWith('--item=')) {
50
+ if (item !== undefined) {
51
+ process.stderr.write("Error: duplicate option '--item'\n");
52
+ return 1;
53
+ }
54
+ item = arg.slice('--item='.length);
55
+ if (item === '') {
56
+ process.stderr.write('Error: --item requires a value\n');
57
+ return 1;
58
+ }
59
+ }
60
+ else
61
+ operands.push(arg);
62
+ }
63
+ let taskRef = scope.taskRef;
64
+ let selector = item;
65
+ let decisionParts;
66
+ if (item !== undefined) {
67
+ decisionParts = operands;
68
+ }
69
+ else if (!scope.explicit) {
70
+ [taskRef, selector, ...decisionParts] = operands;
71
+ }
72
+ else {
73
+ decisionParts = [];
74
+ }
75
+ if (!selector || decisionParts.length === 0) {
76
+ process.stderr.write('Usage: ai decide [--task <ref>] --item <ordinal|ledger-id> [--needs-implementation true|false] <decision>\n ai decide <task-ref> <ordinal|ledger-id> [--needs-implementation true|false] <decision>\n');
81
77
  return 1;
82
78
  }
83
79
  try {
84
- const repoRoot = options.repoRoot ?? detectRepoRoot();
85
- const file = taskPath(repoRoot, taskRef);
86
- let content = fs.readFileSync(file, 'utf8');
87
- const replaced = replaceLedgerRow(content, hdId);
88
- if (!replaced.found)
89
- throw new Error(`${hdId} not found in review ledger`);
90
- if (!replaced.pending)
91
- throw new Error(`${hdId} is not needs-human-decision`);
92
- content = replaced.content;
93
- const now = (options.now ?? defaultNow)();
94
- content = replaceFrontmatterField(content, 'updated_at', now);
95
- content = replaceFrontmatterField(content, 'agent_infra_version', options.version ?? VERSION);
96
- const decision = decisionParts.join(' ');
97
- content = appendUnderHeading(content, '## 人工裁决', `### ${hdId}\n\n- **裁决时间**:${now}\n- **裁决结果**:${decision}`);
98
- content = appendUnderHeading(content, '## 活动日志', `- ${now} — **Human Decision** by human — ${hdId} decided`);
99
- fs.writeFileSync(file, content);
80
+ const parsedDecision = parseDecisionParts(decisionParts);
81
+ const now = (options.now ?? canonicalTimestamp)();
82
+ const result = applyHumanDecision({
83
+ taskRef, selector, decision: parsedDecision.decision,
84
+ needsImplementation: parsedDecision.needsImplementation
85
+ }, {
86
+ repoRoot: options.repoRoot,
87
+ metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
88
+ });
89
+ if (result.error)
90
+ throw new Error(result.error.message);
100
91
  return 0;
101
92
  }
102
93
  catch (error) {
@@ -42,6 +42,7 @@
42
42
  ".claude/commands/",
43
43
  ".codex/hooks.json",
44
44
  ".gemini/commands/",
45
+ ".git-hooks/check-large-files.cjs",
45
46
  ".git-hooks/check-version-format.sh",
46
47
  ".github/scripts/",
47
48
  ".github/workflows/metadata-sync.yml",
@@ -0,0 +1,79 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { execFileSync } from 'node:child_process';
6
+ function git(repoRoot, args, options = {}) {
7
+ return execFileSync('git', args, { cwd: repoRoot, encoding: options.encoding ?? 'utf8', env: options.env ?? process.env });
8
+ }
9
+ function splitNull(output) { return output.split('\0').filter(Boolean); }
10
+ function exists(filePath) { try {
11
+ fs.lstatSync(filePath);
12
+ return true;
13
+ }
14
+ catch {
15
+ return false;
16
+ } }
17
+ function withTemporaryIndex(repoRoot, baseline, callback) {
18
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-infra-review-index-'));
19
+ const env = { ...process.env, GIT_INDEX_FILE: path.join(tempDir, 'index') };
20
+ try {
21
+ execFileSync('git', ['read-tree', baseline], { cwd: repoRoot, env });
22
+ return callback(env);
23
+ }
24
+ finally {
25
+ fs.rmSync(tempDir, { recursive: true, force: true });
26
+ }
27
+ }
28
+ function projectWorktree(repoRoot, baseline, globs, env) {
29
+ const tracked = splitNull(String(git(repoRoot, ['diff', '--name-only', '-z', baseline, '--', ...globs])));
30
+ const untracked = splitNull(String(git(repoRoot, ['ls-files', '-o', '--exclude-standard', '-z', '--', ...globs])));
31
+ for (const filePath of new Set([...tracked, ...untracked])) {
32
+ const args = exists(path.join(repoRoot, filePath)) ? ['update-index', '--add', '--', filePath] : ['update-index', '--remove', '--', filePath];
33
+ execFileSync('git', args, { cwd: repoRoot, env });
34
+ }
35
+ }
36
+ function projectStaged(repoRoot, baseline, globs, env) {
37
+ for (const filePath of splitNull(String(git(repoRoot, ['diff', '--cached', '--name-only', '-z', baseline, '--', ...globs])))) {
38
+ const entry = execFileSync('git', ['--literal-pathspecs', 'ls-files', '--stage', '-z', '--', filePath], { cwd: repoRoot, encoding: 'buffer' });
39
+ execFileSync('git', ['update-index', '-z', '--index-info'], {
40
+ cwd: repoRoot, env, input: entry.length > 0 ? entry : Buffer.from(`0 ${'0'.repeat(40)}\t${filePath}\0`)
41
+ });
42
+ }
43
+ }
44
+ function snapshotReview(input) {
45
+ const repoRoot = String(git(input.cwd, ['rev-parse', '--show-toplevel'])).trim();
46
+ const resolvedBaseline = String(git(repoRoot, ['rev-parse', '--verify', `${input.baseline}^{commit}`])).trim();
47
+ return withTemporaryIndex(repoRoot, resolvedBaseline, (env) => {
48
+ if (input.mode === 'worktree')
49
+ projectWorktree(repoRoot, resolvedBaseline, input.globs, env);
50
+ else
51
+ projectStaged(repoRoot, resolvedBaseline, input.globs, env);
52
+ const diff = execFileSync('git', ['diff', '--cached', '--binary', resolvedBaseline, '--', ...input.globs], { cwd: repoRoot, encoding: 'buffer', env });
53
+ return {
54
+ baseline: resolvedBaseline,
55
+ fingerprint: `sha256:${crypto.createHash('sha256').update(diff).digest('hex')}`,
56
+ tree: String(git(repoRoot, ['write-tree'], { env })).trim()
57
+ };
58
+ });
59
+ }
60
+ function compareReviewTrees(input) {
61
+ const repoRoot = String(git(input.cwd, ['rev-parse', '--show-toplevel'])).trim();
62
+ git(repoRoot, ['rev-parse', '--verify', `${input.expected}^{tree}`]);
63
+ git(repoRoot, ['rev-parse', '--verify', `${input.actual}^{tree}`]);
64
+ const fields = splitNull(String(git(repoRoot, ['diff', '--name-status', '-z', '--no-renames', input.expected, input.actual])));
65
+ const result = { equal: fields.length === 0, added: [], missing: [], different: [] };
66
+ for (let index = 0; index < fields.length; index += 2) {
67
+ const status = fields[index];
68
+ const filePath = fields[index + 1];
69
+ if (status === 'A')
70
+ result.added.push(filePath);
71
+ else if (status === 'D')
72
+ result.missing.push(filePath);
73
+ else
74
+ result.different.push(filePath);
75
+ }
76
+ return result;
77
+ }
78
+ export { compareReviewTrees, snapshotReview };
79
+ //# sourceMappingURL=review-snapshot.js.map
@@ -0,0 +1,101 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ const defaultRunner = (args, cwd) => {
3
+ const result = spawnSync('git', [...args], { cwd, encoding: 'utf8' });
4
+ return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
5
+ };
6
+ function run(runner, cwd, args) {
7
+ return runner(args, cwd);
8
+ }
9
+ function value(runner, cwd, args, trim = true) {
10
+ const result = run(runner, cwd, args);
11
+ return result.status === 0 ? (trim ? result.stdout.trim() : result.stdout.replace(/\n$/, '')) : null;
12
+ }
13
+ function inspectGitWorkflow(cwd, runner = defaultRunner, remoteInput) {
14
+ const head = value(runner, cwd, ['rev-parse', 'HEAD']);
15
+ const branch = value(runner, cwd, ['branch', '--show-current']);
16
+ const upstream = value(runner, cwd, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}']);
17
+ const porcelain = value(runner, cwd, ['status', '--porcelain=v1'], false);
18
+ if (!head || branch === null || porcelain === null) {
19
+ return { status: 'failed', changed: false, snapshot: null, operations: [], error: { code: 'GIT_INSPECT_FAILED', message: 'Unable to inspect Git repository' } };
20
+ }
21
+ const lines = porcelain ? porcelain.split('\n') : [];
22
+ const remoteRefs = remoteInput ? Object.fromEntries(remoteInput.refs.map((ref) => {
23
+ const canonical = ref.startsWith('refs/') ? ref : `refs/heads/${ref}`;
24
+ const remote = run(runner, cwd, ['ls-remote', '--exit-code', remoteInput.remote, canonical]);
25
+ return [ref, remote.status === 0 ? remote.stdout.trim().split(/\s+/)[0] ?? null : null];
26
+ })) : {};
27
+ return {
28
+ status: 'no-op', changed: false,
29
+ snapshot: {
30
+ head, branch, upstream,
31
+ worktree: lines.filter((line) => line.startsWith('??') || line[1] !== ' ').map((line) => line.slice(3)),
32
+ staged: lines.filter((line) => !line.startsWith('??') && line[0] !== ' ').map((line) => line.slice(3)),
33
+ remoteRefs
34
+ },
35
+ operations: [], error: null
36
+ };
37
+ }
38
+ function validatePaths(paths) {
39
+ if (paths.length === 0)
40
+ return 'At least one explicit path is required';
41
+ for (const candidate of paths) {
42
+ if (!candidate || candidate.startsWith('/') || candidate.split(/[\\/]/).includes('..'))
43
+ return `Path escapes repository: ${candidate}`;
44
+ if (/(^|\/)(?:\.env|credentials\.json|id_rsa)(?:$|\/)/i.test(candidate))
45
+ return `Sensitive path is not allowed: ${candidate}`;
46
+ }
47
+ return null;
48
+ }
49
+ function commitExplicitPaths(input, runner = defaultRunner) {
50
+ const invalid = validatePaths(input.paths);
51
+ if (invalid || !input.message.trim())
52
+ return { status: 'failed', changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [], error: { code: 'GIT_COMMIT_INPUT_INVALID', message: invalid ?? 'Commit message is required' } };
53
+ const before = inspectGitWorkflow(input.cwd, runner);
54
+ if (!before.snapshot)
55
+ return before;
56
+ if (input.expectedHead && before.snapshot.head !== input.expectedHead)
57
+ return { status: 'failed', changed: false, snapshot: before.snapshot, operations: [], error: { code: 'GIT_HEAD_MISMATCH', message: `Expected HEAD ${input.expectedHead}, received ${before.snapshot.head}` } };
58
+ const selected = new Set(input.paths);
59
+ const unrelatedStaged = before.snapshot.staged.filter((candidate) => !selected.has(candidate));
60
+ if (unrelatedStaged.length > 0)
61
+ return { status: 'failed', changed: false, snapshot: before.snapshot, operations: [], error: { code: 'GIT_STAGED_SCOPE_MISMATCH', message: `Unrelated staged paths: ${unrelatedStaged.join(', ')}` } };
62
+ const add = run(runner, input.cwd, ['add', '--', ...input.paths]);
63
+ if (add.status !== 0)
64
+ return { status: 'failed', changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'stage', status: 'failed', message: add.stderr.trim() }], error: { code: 'GIT_STAGE_FAILED', message: add.stderr.trim() } };
65
+ const staged = run(runner, input.cwd, ['diff', '--cached', '--quiet', '--']);
66
+ if (staged.status === 0)
67
+ return { status: 'no-op', changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'stage', status: 'no-op' }], error: null };
68
+ if (input.expectedTree) {
69
+ const tree = value(runner, input.cwd, ['write-tree']);
70
+ if (tree !== input.expectedTree)
71
+ return { status: 'failed', changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'stage', status: 'applied' }], error: { code: 'GIT_TREE_MISMATCH', message: `Expected staged tree ${input.expectedTree}, received ${tree ?? 'unavailable'}` } };
72
+ }
73
+ const commit = run(runner, input.cwd, ['commit', '-m', input.message]);
74
+ const after = inspectGitWorkflow(input.cwd, runner);
75
+ if (commit.status !== 0)
76
+ return { status: 'failed', changed: false, snapshot: after.snapshot, operations: [{ name: 'commit', status: 'failed', message: commit.stderr.trim() }], error: { code: 'GIT_COMMIT_FAILED', message: commit.stderr.trim() } };
77
+ return { status: 'applied', changed: true, snapshot: after.snapshot, operations: [{ name: 'stage', status: 'applied' }, { name: 'commit', status: 'applied' }], error: null };
78
+ }
79
+ function pushGitRefs(input, runner = defaultRunner) {
80
+ if (!input.remote || input.refs.length === 0)
81
+ return { status: 'failed', changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [], error: { code: 'GIT_PUSH_INPUT_INVALID', message: 'Remote and refs are required' } };
82
+ const operations = [];
83
+ for (const ref of input.refs) {
84
+ if (!/^(?:refs\/(?:heads|tags)\/)?[A-Za-z0-9._/-]+$/.test(ref) || ref.startsWith('-')) {
85
+ operations.push({ name: 'push', ref, status: 'failed', message: 'Invalid ref' });
86
+ continue;
87
+ }
88
+ const pushed = run(runner, input.cwd, ['push', input.remote, ref]);
89
+ if (pushed.status !== 0) {
90
+ operations.push({ name: 'push', ref, status: 'failed', message: pushed.stderr.trim() });
91
+ continue;
92
+ }
93
+ const canonical = ref.startsWith('refs/') ? ref : `refs/heads/${ref}`;
94
+ const remoteFact = run(runner, input.cwd, ['ls-remote', '--exit-code', input.remote, canonical]);
95
+ operations.push({ name: 'push', ref, status: remoteFact.status === 0 ? 'applied' : 'failed', message: remoteFact.status === 0 ? undefined : 'Remote ref verification failed' });
96
+ }
97
+ const failures = operations.filter((item) => item.status === 'failed').length;
98
+ return { status: failures === 0 ? 'applied' : failures === operations.length ? 'failed' : 'degraded', changed: failures < operations.length, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations, error: failures ? { code: 'GIT_PUSH_PARTIAL', message: `${failures} ref push operation(s) failed` } : null };
99
+ }
100
+ export { commitExplicitPaths, inspectGitWorkflow, pushGitRefs };
101
+ //# sourceMappingURL=workflow.js.map
@@ -0,0 +1,42 @@
1
+ import fs from 'node:fs';
2
+ import { commitExplicitPaths, inspectGitWorkflow, pushGitRefs } from '../git/workflow.js';
3
+ import { compareReviewTrees, snapshotReview } from '../git/review-snapshot.js';
4
+ import { resolvePostReviewGlobs } from '../task/review-fingerprint.js';
5
+ function output(value) { process.stdout.write(`${JSON.stringify(value)}\n`); }
6
+ function gitWorkflow(args = []) {
7
+ const [action, ...rest] = args;
8
+ const cwdIndex = rest.indexOf('--cwd');
9
+ const cwd = cwdIndex >= 0 ? rest[cwdIndex + 1] : process.cwd();
10
+ let result;
11
+ if (action === 'inspect') {
12
+ const inputIndex = rest.indexOf('--input');
13
+ const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1], 'utf8')) : null;
14
+ result = inspectGitWorkflow(cwd ?? process.cwd(), undefined, input?.remote && input.refs ? { remote: input.remote, refs: input.refs } : undefined);
15
+ }
16
+ else if (action === 'commit') {
17
+ const inputIndex = rest.indexOf('--input');
18
+ const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1], 'utf8')) : null;
19
+ result = input ? commitExplicitPaths({ cwd: cwd ?? process.cwd(), ...input }) : { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
20
+ }
21
+ else if (action === 'push') {
22
+ const inputIndex = rest.indexOf('--input');
23
+ const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1], 'utf8')) : null;
24
+ result = input ? pushGitRefs({ cwd: cwd ?? process.cwd(), ...input }) : { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
25
+ }
26
+ else if (action === 'snapshot' || action === 'compare-trees') {
27
+ const inputIndex = rest.indexOf('--input');
28
+ const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1], 'utf8')) : null;
29
+ if (!input)
30
+ result = { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
31
+ else if (action === 'snapshot')
32
+ result = { status: 'no-op', changed: false, snapshot: snapshotReview({ cwd: cwd ?? process.cwd(), mode: input.mode, baseline: input.baseline, globs: input.globs ?? resolvePostReviewGlobs({}, {}) }), error: null };
33
+ else
34
+ result = { status: 'no-op', changed: false, comparison: compareReviewTrees({ cwd: cwd ?? process.cwd(), expected: input.expected, actual: input.actual }), error: null };
35
+ }
36
+ else
37
+ result = { status: 'failed', changed: false, error: { code: 'GIT_ACTION_INVALID', message: `Unknown git-workflow action '${action ?? ''}'` } };
38
+ output(result);
39
+ process.exitCode = result.status === 'failed' ? 1 : result.status === 'blocked' ? 2 : 0;
40
+ }
41
+ export { gitWorkflow };
42
+ //# sourceMappingURL=git-workflow.js.map