@fitlab-ai/agent-infra 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/bin/cli.ts +2 -2
  2. package/dist/bin/cli.js +2 -2
  3. package/dist/bin/internal-cli.js +98 -0
  4. package/dist/lib/decide.js +81 -90
  5. package/dist/lib/defaults.json +1 -0
  6. package/dist/lib/git/review-snapshot.js +79 -0
  7. package/dist/lib/git/workflow.js +101 -0
  8. package/dist/lib/internal/git-workflow.js +42 -0
  9. package/dist/lib/internal/platform-checks.js +119 -0
  10. package/dist/lib/internal/platform-comment.js +129 -0
  11. package/dist/lib/internal/platform-context.js +46 -0
  12. package/dist/lib/internal/platform-issue.js +142 -0
  13. package/dist/lib/internal/platform-pr.js +146 -0
  14. package/dist/lib/internal/release-workflow.js +217 -0
  15. package/dist/lib/internal/task-artifact.js +67 -0
  16. package/dist/lib/internal/task-context.js +43 -0
  17. package/dist/lib/internal/task-event.js +70 -0
  18. package/dist/lib/internal/task-ledger.js +114 -0
  19. package/dist/lib/internal/task-lifecycle.js +58 -0
  20. package/dist/lib/internal/task-short-id.js +83 -0
  21. package/dist/lib/internal/task-snapshot.js +47 -0
  22. package/dist/lib/internal/task-verify.js +50 -0
  23. package/dist/lib/internal/task-warning.js +74 -0
  24. package/dist/lib/platform/adapters.js +14 -0
  25. package/dist/lib/platform/context.js +146 -0
  26. package/dist/lib/platform/github-client.js +124 -0
  27. package/dist/lib/platform/issue-comments.js +409 -0
  28. package/dist/lib/platform/issue-metadata.js +183 -0
  29. package/dist/lib/platform/issues.js +617 -0
  30. package/dist/lib/platform/metadata-labels.js +28 -0
  31. package/dist/lib/platform/pr-checks.js +216 -0
  32. package/dist/lib/platform/pr-summary.js +88 -0
  33. package/dist/lib/platform/pull-request-metadata.js +38 -0
  34. package/dist/lib/platform/pull-requests.js +338 -0
  35. package/dist/lib/platform/releases.js +82 -0
  36. package/dist/lib/platform/types.js +22 -0
  37. package/dist/lib/platform/verification-required.js +78 -0
  38. package/dist/lib/platform/verification-sync.js +1014 -0
  39. package/dist/lib/platform/verification.js +6 -0
  40. package/dist/lib/release/channels.js +31 -0
  41. package/dist/lib/release/workflow.js +32 -0
  42. package/dist/lib/render.js +3 -2
  43. package/dist/lib/run/index.js +24 -7
  44. package/dist/lib/sandbox/capture.js +25 -3
  45. package/dist/lib/sandbox/commands/create.js +36 -22
  46. package/dist/lib/sandbox/commands/enter.js +34 -11
  47. package/dist/lib/sandbox/commands/list-running.js +10 -8
  48. package/dist/lib/sandbox/commands/show.js +2 -2
  49. package/dist/lib/sandbox/commands/start.js +53 -15
  50. package/dist/lib/sandbox/index.js +6 -6
  51. package/dist/lib/sandbox/mounts.js +36 -0
  52. package/dist/lib/sandbox/recovery.js +562 -0
  53. package/dist/lib/sandbox/task-resolver.js +5 -1
  54. package/dist/lib/sandbox/tools.js +19 -0
  55. package/dist/lib/server/protocol.js +5 -5
  56. package/dist/lib/task/activity-log.js +61 -0
  57. package/dist/lib/task/artifact-lifecycle.js +427 -0
  58. package/dist/lib/task/command-options.js +30 -0
  59. package/dist/lib/task/commands/cat.js +36 -6
  60. package/dist/lib/task/commands/decisions.js +80 -46
  61. package/dist/lib/task/commands/files.js +21 -7
  62. package/dist/lib/task/commands/grep.js +55 -7
  63. package/dist/lib/task/commands/issue-body.js +23 -14
  64. package/dist/lib/task/commands/log.js +27 -70
  65. package/dist/lib/task/commands/show.js +20 -7
  66. package/dist/lib/task/commands/status.js +18 -8
  67. package/dist/lib/task/decision-intents.js +154 -0
  68. package/dist/lib/task/decision-items.js +53 -0
  69. package/dist/lib/task/events.js +318 -0
  70. package/dist/lib/task/frontmatter.js +159 -1
  71. package/dist/lib/task/implementation-inputs.js +117 -0
  72. package/dist/lib/task/index.js +12 -9
  73. package/dist/lib/task/issue-form.js +19 -6
  74. package/dist/lib/task/ledger-intents.js +185 -0
  75. package/dist/lib/task/ledger.js +65 -35
  76. package/dist/lib/task/lifecycle.js +484 -0
  77. package/dist/lib/task/resolve-ref.js +152 -32
  78. package/dist/lib/task/review-artifacts.js +101 -0
  79. package/dist/lib/task/review-fingerprint.js +46 -0
  80. package/dist/lib/task/sections.js +358 -4
  81. package/dist/lib/task/short-id.js +292 -7
  82. package/dist/lib/task/snapshot.js +95 -0
  83. package/dist/lib/task/verification-checks.js +8 -0
  84. package/dist/lib/task/verification-config.js +14 -0
  85. package/dist/lib/task/verification-engine.js +906 -0
  86. package/dist/lib/task/verification-review.js +3 -0
  87. package/dist/lib/task/verification-types.js +2 -0
  88. package/dist/lib/task/verification.js +113 -0
  89. package/dist/lib/task/workflow-warning-intents.js +131 -0
  90. package/dist/lib/task/workflow-warnings.js +10 -78
  91. package/dist/lib/task/write.js +241 -0
  92. package/lib/decide.ts +57 -97
  93. package/lib/defaults.json +1 -0
  94. package/lib/git/review-snapshot.ts +73 -0
  95. package/lib/git/workflow.ts +101 -0
  96. package/lib/internal/git-workflow.ts +37 -0
  97. package/lib/internal/platform-checks.ts +101 -0
  98. package/lib/internal/platform-comment.ts +99 -0
  99. package/lib/internal/platform-context.ts +33 -0
  100. package/lib/internal/platform-issue.ts +116 -0
  101. package/lib/internal/platform-pr.ts +119 -0
  102. package/lib/internal/release-workflow.ts +186 -0
  103. package/lib/internal/task-artifact.ts +47 -0
  104. package/lib/internal/task-context.ts +35 -0
  105. package/lib/internal/task-event.ts +51 -0
  106. package/lib/internal/task-ledger.ts +86 -0
  107. package/lib/internal/task-lifecycle.ts +41 -0
  108. package/lib/internal/task-short-id.ts +55 -0
  109. package/lib/internal/task-snapshot.ts +32 -0
  110. package/lib/internal/task-verify.ts +33 -0
  111. package/lib/internal/task-warning.ts +50 -0
  112. package/lib/platform/adapters.ts +30 -0
  113. package/lib/platform/context.ts +164 -0
  114. package/lib/platform/github-client.ts +146 -0
  115. package/lib/platform/issue-comments.ts +479 -0
  116. package/lib/platform/issue-metadata.ts +250 -0
  117. package/lib/platform/issues.ts +691 -0
  118. package/lib/platform/metadata-labels.ts +33 -0
  119. package/lib/platform/pr-checks.ts +246 -0
  120. package/lib/platform/pr-summary.ts +90 -0
  121. package/lib/platform/pull-request-metadata.ts +69 -0
  122. package/lib/platform/pull-requests.ts +380 -0
  123. package/lib/platform/releases.ts +71 -0
  124. package/lib/platform/types.ts +74 -0
  125. package/lib/platform/verification-required.ts +83 -0
  126. package/{runtime/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts} +198 -367
  127. package/lib/platform/verification.ts +11 -0
  128. package/lib/release/channels.ts +30 -0
  129. package/lib/release/workflow.ts +31 -0
  130. package/lib/render.ts +3 -2
  131. package/lib/run/index.ts +25 -7
  132. package/lib/sandbox/capture.ts +29 -3
  133. package/lib/sandbox/commands/create.ts +43 -25
  134. package/lib/sandbox/commands/enter.ts +38 -11
  135. package/lib/sandbox/commands/list-running.ts +10 -8
  136. package/lib/sandbox/commands/show.ts +2 -2
  137. package/lib/sandbox/commands/start.ts +50 -16
  138. package/lib/sandbox/index.ts +6 -6
  139. package/lib/sandbox/mounts.ts +55 -0
  140. package/lib/sandbox/recovery.ts +828 -0
  141. package/lib/sandbox/task-resolver.ts +5 -1
  142. package/lib/sandbox/tools.ts +31 -0
  143. package/lib/server/protocol.ts +5 -5
  144. package/lib/task/activity-log.ts +62 -0
  145. package/lib/task/artifact-lifecycle.ts +484 -0
  146. package/lib/task/command-options.ts +32 -0
  147. package/lib/task/commands/cat.ts +22 -9
  148. package/lib/task/commands/decisions.ts +49 -47
  149. package/lib/task/commands/files.ts +14 -6
  150. package/lib/task/commands/grep.ts +34 -7
  151. package/lib/task/commands/issue-body.ts +16 -16
  152. package/lib/task/commands/log.ts +17 -70
  153. package/lib/task/commands/show.ts +14 -6
  154. package/lib/task/commands/status.ts +17 -7
  155. package/lib/task/decision-intents.ts +163 -0
  156. package/lib/task/decision-items.ts +64 -0
  157. package/lib/task/events.ts +320 -0
  158. package/lib/task/frontmatter.ts +202 -2
  159. package/lib/task/implementation-inputs.ts +137 -0
  160. package/lib/task/index.ts +12 -9
  161. package/lib/task/issue-form.ts +20 -6
  162. package/lib/task/ledger-intents.ts +201 -0
  163. package/lib/task/ledger.ts +77 -31
  164. package/lib/task/lifecycle.ts +458 -0
  165. package/lib/task/resolve-ref.ts +197 -36
  166. package/{templates/.agents/scripts/lib/review-artifacts.js → lib/task/review-artifacts.ts} +11 -12
  167. package/{templates/.agents/scripts/lib/post-review-commit.js → lib/task/review-fingerprint.ts} +17 -12
  168. package/lib/task/sections.ts +486 -4
  169. package/lib/task/short-id.ts +403 -9
  170. package/lib/task/snapshot.ts +143 -0
  171. package/lib/task/verification-checks.ts +9 -0
  172. package/lib/task/verification-config.ts +20 -0
  173. package/{templates/.agents/scripts/validate-artifact.js → lib/task/verification-engine.ts} +199 -406
  174. package/lib/task/verification-review.ts +9 -0
  175. package/lib/task/verification-types.ts +29 -0
  176. package/lib/task/verification.ts +156 -0
  177. package/lib/task/workflow-warning-intents.ts +142 -0
  178. package/lib/task/workflow-warnings.ts +10 -78
  179. package/lib/task/write.ts +468 -0
  180. package/package.json +4 -2
  181. package/templates/.agents/README.en.md +4 -3
  182. package/templates/.agents/README.zh-CN.md +4 -3
  183. package/templates/.agents/rules/README.en.md +6 -5
  184. package/templates/.agents/rules/README.zh-CN.md +6 -5
  185. package/templates/.agents/rules/create-issue.en.md +1 -1
  186. package/templates/.agents/rules/create-issue.github.en.md +5 -184
  187. package/templates/.agents/rules/create-issue.github.zh-CN.md +12 -178
  188. package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
  189. package/templates/.agents/rules/human-decision-context.en.md +36 -0
  190. package/templates/.agents/rules/human-decision-context.zh-CN.md +36 -0
  191. package/templates/.agents/rules/issue-fields.github.en.md +4 -148
  192. package/templates/.agents/rules/issue-fields.github.zh-CN.md +9 -144
  193. package/templates/.agents/rules/issue-pr-commands.en.md +43 -3
  194. package/templates/.agents/rules/issue-pr-commands.github.en.md +15 -220
  195. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +23 -213
  196. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +45 -3
  197. package/templates/.agents/rules/issue-sync.en.md +1 -1
  198. package/templates/.agents/rules/issue-sync.github.en.md +14 -301
  199. package/templates/.agents/rules/issue-sync.github.zh-CN.md +36 -287
  200. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  201. package/templates/.agents/rules/milestone-inference.en.md +1 -1
  202. package/templates/.agents/rules/milestone-inference.github.en.md +7 -119
  203. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +8 -108
  204. package/templates/.agents/rules/milestone-inference.zh-CN.md +1 -1
  205. package/templates/.agents/rules/next-step-output.en.md +12 -11
  206. package/templates/.agents/rules/next-step-output.zh-CN.md +12 -11
  207. package/templates/.agents/rules/no-mid-flow-questions.en.md +3 -3
  208. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +3 -3
  209. package/templates/.agents/rules/pr-checks-commands.en.md +16 -3
  210. package/templates/.agents/rules/pr-checks-commands.github.en.md +10 -54
  211. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +19 -47
  212. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +30 -3
  213. package/templates/.agents/rules/pr-sync.en.md +30 -3
  214. package/templates/.agents/rules/pr-sync.github.en.md +12 -115
  215. package/templates/.agents/rules/pr-sync.github.zh-CN.md +26 -104
  216. package/templates/.agents/rules/pr-sync.zh-CN.md +43 -3
  217. package/templates/.agents/rules/review-handshake.en.md +8 -5
  218. package/templates/.agents/rules/review-handshake.zh-CN.md +8 -5
  219. package/templates/.agents/rules/task-management.en.md +11 -2
  220. package/templates/.agents/rules/task-management.zh-CN.md +11 -3
  221. package/templates/.agents/rules/task-short-id.en.md +25 -29
  222. package/templates/.agents/rules/task-short-id.zh-CN.md +20 -23
  223. package/templates/.agents/scripts/lib/agent-infra-package.js +1 -9
  224. package/templates/.agents/scripts/task-short-id.js +71 -533
  225. package/templates/.agents/skills/analyze-task/SKILL.en.md +22 -55
  226. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +26 -59
  227. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -3
  228. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -3
  229. package/templates/.agents/skills/block-task/SKILL.en.md +21 -47
  230. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +23 -47
  231. package/templates/.agents/skills/block-task/config/verify.json +1 -2
  232. package/templates/.agents/skills/cancel-task/SKILL.en.md +16 -45
  233. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +16 -45
  234. package/templates/.agents/skills/cancel-task/config/verify.json +1 -2
  235. package/templates/.agents/skills/check-task/SKILL.en.md +6 -3
  236. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +6 -3
  237. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -24
  238. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -24
  239. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -24
  240. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -24
  241. package/templates/.agents/skills/code-task/SKILL.en.md +22 -35
  242. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +28 -44
  243. package/templates/.agents/skills/code-task/config/verify.en.json +3 -3
  244. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +3 -3
  245. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +13 -9
  246. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +13 -9
  247. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
  248. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
  249. package/templates/.agents/skills/code-task/reference/report-template.en.md +11 -1
  250. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +11 -1
  251. package/templates/.agents/skills/commit/SKILL.en.md +13 -11
  252. package/templates/.agents/skills/commit/SKILL.zh-CN.md +13 -11
  253. package/templates/.agents/skills/commit/config/verify.json +1 -2
  254. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -11
  255. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -11
  256. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +4 -8
  257. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +4 -8
  258. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +6 -18
  259. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +5 -17
  260. package/templates/.agents/skills/commit/reference/task-status-update.en.md +13 -0
  261. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +13 -0
  262. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +13 -36
  263. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +13 -36
  264. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -3
  265. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -3
  266. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +10 -54
  267. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +10 -79
  268. package/templates/.agents/skills/complete-task/SKILL.en.md +59 -63
  269. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +59 -63
  270. package/templates/.agents/skills/complete-task/config/verify.en.json +11 -7
  271. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +11 -7
  272. package/templates/.agents/skills/create-pr/SKILL.en.md +19 -44
  273. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +19 -43
  274. package/templates/.agents/skills/create-pr/config/verify.json +1 -2
  275. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +8 -12
  276. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +7 -11
  277. package/templates/.agents/skills/create-task/SKILL.en.md +12 -13
  278. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +12 -13
  279. package/templates/.agents/skills/create-task/config/verify.json +1 -2
  280. package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -2
  281. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +2 -2
  282. package/templates/.agents/skills/import-codescan/config/verify.json +1 -2
  283. package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
  284. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
  285. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -2
  286. package/templates/.agents/skills/import-issue/SKILL.en.md +9 -13
  287. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -14
  288. package/templates/.agents/skills/import-issue/config/verify.json +1 -2
  289. package/templates/.agents/skills/plan-task/SKILL.en.md +17 -42
  290. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -49
  291. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -3
  292. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -3
  293. package/templates/.agents/skills/post-release/SKILL.en.md +11 -81
  294. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +8 -78
  295. package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
  296. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
  297. package/templates/.agents/skills/release/SKILL.en.md +16 -163
  298. package/templates/.agents/skills/release/SKILL.zh-CN.md +15 -162
  299. package/templates/.agents/skills/restore-task/SKILL.en.md +11 -29
  300. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +11 -29
  301. package/templates/.agents/skills/restore-task/config/verify.json +1 -2
  302. package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -25
  303. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +13 -33
  304. package/templates/.agents/skills/review-analysis/config/verify.en.json +3 -4
  305. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +3 -4
  306. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +9 -12
  307. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +9 -12
  308. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +9 -2
  309. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +9 -2
  310. package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +7 -0
  311. package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +7 -0
  312. package/templates/.agents/skills/review-code/SKILL.en.md +22 -36
  313. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +23 -41
  314. package/templates/.agents/skills/review-code/config/verify.en.json +3 -4
  315. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +3 -4
  316. package/templates/.agents/skills/review-code/reference/output-templates.en.md +56 -18
  317. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +56 -18
  318. package/templates/.agents/skills/review-code/reference/report-template.en.md +11 -4
  319. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +11 -4
  320. package/templates/.agents/skills/review-code/reference/review-criteria.en.md +7 -0
  321. package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +7 -0
  322. package/templates/.agents/skills/review-plan/SKILL.en.md +13 -25
  323. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +13 -33
  324. package/templates/.agents/skills/review-plan/config/verify.en.json +3 -4
  325. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +3 -4
  326. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +9 -12
  327. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +9 -12
  328. package/templates/.agents/skills/review-plan/reference/report-template.en.md +9 -2
  329. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +9 -2
  330. package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +7 -0
  331. package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +7 -0
  332. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -2
  333. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -2
  334. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -15
  335. package/templates/.agents/skills/watch-pr/SKILL.en.md +24 -14
  336. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +25 -15
  337. package/templates/.agents/skills/watch-pr/config/verify.json +1 -2
  338. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
  339. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
  340. package/templates/.agents/templates/task.en.md +6 -1
  341. package/templates/.agents/templates/task.zh-CN.md +6 -1
  342. package/templates/.claude/commands/analyze-task.en.md +1 -1
  343. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  344. package/templates/.claude/commands/block-task.en.md +1 -1
  345. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  346. package/templates/.claude/commands/cancel-task.en.md +1 -1
  347. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  348. package/templates/.claude/commands/check-task.en.md +1 -1
  349. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  350. package/templates/.claude/commands/code-task.en.md +1 -1
  351. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  352. package/templates/.claude/commands/commit.en.md +1 -0
  353. package/templates/.claude/commands/commit.zh-CN.md +1 -0
  354. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  355. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  356. package/templates/.claude/commands/complete-task.en.md +1 -1
  357. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  358. package/templates/.claude/commands/create-pr.en.md +1 -1
  359. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  360. package/templates/.claude/commands/plan-task.en.md +1 -1
  361. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  362. package/templates/.claude/commands/review-analysis.en.md +1 -1
  363. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  364. package/templates/.claude/commands/review-code.en.md +1 -1
  365. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  366. package/templates/.claude/commands/review-plan.en.md +1 -1
  367. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  368. package/templates/.claude/commands/watch-pr.en.md +1 -1
  369. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  370. package/templates/.gemini/commands/_project_/analyze-task.en.toml +2 -0
  371. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +2 -0
  372. package/templates/.gemini/commands/_project_/block-task.en.toml +2 -0
  373. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +2 -0
  374. package/templates/.gemini/commands/_project_/cancel-task.en.toml +2 -0
  375. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +2 -0
  376. package/templates/.gemini/commands/_project_/check-task.en.toml +2 -0
  377. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +2 -0
  378. package/templates/.gemini/commands/_project_/code-task.en.toml +2 -0
  379. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +2 -0
  380. package/templates/.gemini/commands/_project_/commit.en.toml +4 -0
  381. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +4 -0
  382. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +2 -0
  383. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +2 -0
  384. package/templates/.gemini/commands/_project_/complete-task.en.toml +2 -0
  385. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +2 -0
  386. package/templates/.gemini/commands/_project_/create-pr.en.toml +2 -0
  387. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +2 -0
  388. package/templates/.gemini/commands/_project_/plan-task.en.toml +2 -0
  389. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +2 -0
  390. package/templates/.gemini/commands/_project_/review-analysis.en.toml +2 -0
  391. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +2 -0
  392. package/templates/.gemini/commands/_project_/review-code.en.toml +2 -0
  393. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +2 -0
  394. package/templates/.gemini/commands/_project_/review-plan.en.toml +2 -0
  395. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +2 -0
  396. package/templates/.gemini/commands/_project_/watch-pr.en.toml +2 -0
  397. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +2 -0
  398. package/templates/.git-hooks/check-large-files.cjs +92 -0
  399. package/templates/.git-hooks/check-version-format.sh +5 -1
  400. package/templates/.git-hooks/pre-commit +1 -0
  401. package/templates/.opencode/commands/analyze-task.en.md +1 -1
  402. package/templates/.opencode/commands/analyze-task.zh-CN.md +1 -1
  403. package/templates/.opencode/commands/check-task.en.md +1 -1
  404. package/templates/.opencode/commands/check-task.zh-CN.md +1 -1
  405. package/templates/.opencode/commands/code-task.en.md +1 -1
  406. package/templates/.opencode/commands/code-task.zh-CN.md +1 -1
  407. package/templates/.opencode/commands/commit.en.md +2 -0
  408. package/templates/.opencode/commands/commit.zh-CN.md +2 -0
  409. package/templates/.opencode/commands/complete-task.en.md +1 -1
  410. package/templates/.opencode/commands/complete-task.zh-CN.md +1 -1
  411. package/templates/.opencode/commands/plan-task.en.md +1 -1
  412. package/templates/.opencode/commands/plan-task.zh-CN.md +1 -1
  413. package/templates/.opencode/commands/review-analysis.en.md +1 -1
  414. package/templates/.opencode/commands/review-analysis.zh-CN.md +1 -1
  415. package/templates/.opencode/commands/review-code.en.md +1 -1
  416. package/templates/.opencode/commands/review-code.zh-CN.md +1 -1
  417. package/templates/.opencode/commands/review-plan.en.md +1 -1
  418. package/templates/.opencode/commands/review-plan.zh-CN.md +1 -1
  419. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +0 -40
  420. package/templates/.agents/scripts/platform-adapters/platform-sync.js +0 -13
  421. package/templates/.agents/scripts/review-diff-fingerprint.js +0 -170
  422. package/templates/.agents/scripts/workflow-warnings.js +0 -290
  423. package/templates/.agents/skills/code-task/scripts/detect-mode.js +0 -257
  424. package/templates/.agents/skills/release/scripts/manage-milestones.github.sh +0 -80
  425. package/templates/.agents/skills/release/scripts/manage-milestones.sh +0 -6
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,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