@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
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,98 @@
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-context': {
20
+ const { platformContext } = await import('../lib/internal/platform-context.js');
21
+ platformContext(process.argv.slice(3));
22
+ break;
23
+ }
24
+ case 'platform-comment': {
25
+ const { platformComment } = await import('../lib/internal/platform-comment.js');
26
+ platformComment(process.argv.slice(3));
27
+ break;
28
+ }
29
+ case 'platform-issue': {
30
+ const { platformIssue } = await import('../lib/internal/platform-issue.js');
31
+ platformIssue(process.argv.slice(3));
32
+ break;
33
+ }
34
+ case 'platform-pr': {
35
+ const { platformPr } = await import('../lib/internal/platform-pr.js');
36
+ platformPr(process.argv.slice(3));
37
+ break;
38
+ }
39
+ case 'platform-checks': {
40
+ const { platformChecks } = await import('../lib/internal/platform-checks.js');
41
+ await platformChecks(process.argv.slice(3));
42
+ break;
43
+ }
44
+ case 'task-context': {
45
+ const { taskContext } = await import('../lib/internal/task-context.js');
46
+ taskContext(process.argv.slice(3));
47
+ break;
48
+ }
49
+ case 'task-ledger': {
50
+ const { taskLedger } = await import('../lib/internal/task-ledger.js');
51
+ taskLedger(process.argv.slice(3));
52
+ break;
53
+ }
54
+ case 'task-warning': {
55
+ const { taskWarning } = await import('../lib/internal/task-warning.js');
56
+ taskWarning(process.argv.slice(3));
57
+ break;
58
+ }
59
+ case 'task-artifact': {
60
+ const { taskArtifact } = await import('../lib/internal/task-artifact.js');
61
+ taskArtifact(process.argv.slice(3));
62
+ break;
63
+ }
64
+ case 'task-event': {
65
+ const { taskEvent } = await import('../lib/internal/task-event.js');
66
+ taskEvent(process.argv.slice(3));
67
+ break;
68
+ }
69
+ case 'task-lifecycle': {
70
+ const { taskLifecycle } = await import('../lib/internal/task-lifecycle.js');
71
+ taskLifecycle(process.argv.slice(3));
72
+ break;
73
+ }
74
+ case 'task-short-id': {
75
+ const { taskShortId } = await import('../lib/internal/task-short-id.js');
76
+ taskShortId(process.argv.slice(3));
77
+ break;
78
+ }
79
+ case 'task-snapshot': {
80
+ const { taskSnapshot } = await import('../lib/internal/task-snapshot.js');
81
+ taskSnapshot(process.argv.slice(3));
82
+ break;
83
+ }
84
+ case 'task-verify': {
85
+ const { taskVerify } = await import('../lib/internal/task-verify.js');
86
+ taskVerify(process.argv.slice(3));
87
+ break;
88
+ }
89
+ default:
90
+ process.stdout.write(`${JSON.stringify({
91
+ status: 'failed',
92
+ changed: false,
93
+ error: { code: 'INTERNAL_COMMAND_INVALID', message: `unknown internal command '${command}'` }
94
+ })}\n`);
95
+ process.exitCode = 1;
96
+ }
97
+ export {};
98
+ //# 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,10 +42,19 @@
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/",
48
+ ".github/workflows/metadata-sync.yml",
49
+ ".github/workflows/pr-label.yml",
50
+ ".github/workflows/status-label.yml",
47
51
  ".opencode/commands/"
48
52
  ],
53
+ "guardedManaged": [
54
+ ".github/workflows/metadata-sync.yml",
55
+ ".github/workflows/pr-label.yml",
56
+ ".github/workflows/status-label.yml"
57
+ ],
49
58
  "merged": [
50
59
  "**/post-release.*",
51
60
  "**/release.*",
@@ -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
package/dist/lib/init.js CHANGED
@@ -197,6 +197,8 @@ async function cmdInit() {
197
197
  // install skill
198
198
  copySkillDir(path.join(templateDir, '.agents', 'skills', 'update-agent-infra'), path.join('.agents', 'skills', 'update-agent-infra'), replacements, language, platformType);
199
199
  ok('Installed .agents/skills/update-agent-infra/');
200
+ renderFile(path.join(templateDir, '.agents', 'scripts', 'lib', 'agent-infra-package.js'), path.join('.agents', 'scripts', 'lib', 'agent-infra-package.js'), replacements);
201
+ ok('Installed .agents/scripts/lib/agent-infra-package.js');
200
202
  // install Claude command (only if enabled)
201
203
  if (enabledTUISet.has('claude-code')) {
202
204
  renderFile(path.join(templateDir, '.claude', 'commands', claudeSrc), path.join('.claude', 'commands', 'update-agent-infra.md'), replacements);
@@ -245,6 +247,9 @@ async function cmdInit() {
245
247
  console.log('');
246
248
  ok('Project initialized successfully!');
247
249
  console.log('');
250
+ console.log(' If this init used npx, install agent-infra persistently before update or validation:');
251
+ console.log(' npm install -g @fitlab-ai/agent-infra');
252
+ console.log('');
248
253
  if (enabledTUISet.size === 0) {
249
254
  console.log(' No built-in TUI selected.');
250
255
  console.log(` Configure "customTUIs" in ${configPath} before running update-agent-infra.`);
@@ -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