@fitlab-ai/agent-infra 0.9.10 → 0.9.12

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 (375) hide show
  1. package/README.md +19 -9
  2. package/README.zh-CN.md +19 -9
  3. package/bin/cli.ts +17 -4
  4. package/dist/bin/cli.js +19 -4
  5. package/dist/bin/internal-cli.js +55 -4
  6. package/dist/lib/agent-client.js +0 -1
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
  8. package/dist/lib/agent-clients/adapters/opencode-sandbox.js +0 -4
  9. package/dist/lib/agent-clients/adapters/traecli.js +7 -8
  10. package/dist/lib/agent-clients/config.js +14 -99
  11. package/dist/lib/agent-clients/reconcile.js +1 -11
  12. package/dist/lib/agent-clients/schema.js +5 -4
  13. package/dist/lib/agent-clients/tokens.js +5 -15
  14. package/dist/lib/decide.js +14 -30
  15. package/dist/lib/defaults.json +8 -0
  16. package/dist/lib/git/workflow.js +43 -1
  17. package/dist/lib/init.js +3 -2
  18. package/dist/lib/internal/git-workflow.js +8 -1
  19. package/dist/lib/internal/platform-pr.js +8 -2
  20. package/dist/lib/internal/release-workflow.js +0 -1
  21. package/dist/lib/internal/task-delivery.js +59 -0
  22. package/dist/lib/internal/task-finalization.js +19 -9
  23. package/dist/lib/internal/task-ledger.js +8 -2
  24. package/dist/lib/internal/task-lifecycle.js +17 -93
  25. package/dist/lib/internal/task-orchestration.js +30 -216
  26. package/dist/lib/internal/task-validate.js +2 -1
  27. package/dist/lib/merge.js +205 -103
  28. package/dist/lib/platform/github-client.js +7 -1
  29. package/dist/lib/platform/pr-checks.js +8 -5
  30. package/dist/lib/platform/pr-summary.js +12 -8
  31. package/dist/lib/platform/pull-requests.js +393 -91
  32. package/dist/lib/platform/verification-required.js +13 -2
  33. package/dist/lib/platform/verification-sync.js +9 -4
  34. package/dist/lib/pr-review/evidence-grading.js +12 -4
  35. package/dist/lib/process-data/normalize.js +2 -9
  36. package/dist/lib/run/host.js +46 -16
  37. package/dist/lib/sandbox/agent-client-reconciler.js +4 -12
  38. package/dist/lib/sandbox/commands/create.js +3 -3
  39. package/dist/lib/sandbox/commands/enter.js +18 -4
  40. package/dist/lib/sandbox/config.js +8 -12
  41. package/dist/lib/sandbox/control/executor.js +131 -39
  42. package/dist/lib/sandbox/control/lifecycle.js +55 -24
  43. package/dist/lib/sandbox/control/server.js +18 -16
  44. package/dist/lib/sandbox/mounts.js +3 -2
  45. package/dist/lib/sandbox/recovery.js +123 -22
  46. package/dist/lib/sandbox/workspace-identity.js +14 -0
  47. package/dist/lib/sandbox/workspace-view.js +8 -9
  48. package/dist/lib/self-update.js +278 -0
  49. package/dist/lib/server/process-state.js +2 -2
  50. package/dist/lib/server/protocol.js +5 -5
  51. package/dist/lib/task/activity-log.js +4 -1
  52. package/dist/lib/task/artifact-lifecycle.js +6 -4
  53. package/dist/lib/task/codex-orchestration.js +1 -1
  54. package/dist/lib/task/command-options.js +1 -3
  55. package/dist/lib/task/commands/cat.js +0 -5
  56. package/dist/lib/task/commands/decisions.js +76 -92
  57. package/dist/lib/task/commands/files.js +6 -6
  58. package/dist/lib/task/commands/grep.js +25 -61
  59. package/dist/lib/task/commands/issue-body.js +6 -6
  60. package/dist/lib/task/commands/log.js +25 -10
  61. package/dist/lib/task/commands/show.js +5 -6
  62. package/dist/lib/task/commands/status.js +8 -8
  63. package/dist/lib/task/commit-intent.js +100 -0
  64. package/dist/lib/task/commit-operation.js +181 -91
  65. package/dist/lib/task/commit-policy.js +1 -1
  66. package/dist/lib/task/control-authority.js +431 -0
  67. package/dist/lib/task/create.js +39 -8
  68. package/dist/lib/task/current-contract.js +35 -0
  69. package/dist/lib/task/decision-details.js +218 -0
  70. package/dist/lib/task/decision-intents.js +5 -2
  71. package/dist/lib/task/delivery-target.js +97 -0
  72. package/dist/lib/task/delivery.js +153 -0
  73. package/dist/lib/task/events.js +11 -5
  74. package/dist/lib/task/human-override.js +5 -2
  75. package/dist/lib/task/index.js +19 -20
  76. package/dist/lib/task/ledger-intents.js +8 -9
  77. package/dist/lib/task/ledger.js +13 -6
  78. package/dist/lib/task/lifecycle.js +122 -9
  79. package/dist/lib/task/orchestration.js +105 -75
  80. package/dist/lib/task/pr-delivery-fact.js +182 -0
  81. package/dist/lib/task/review-artifacts.js +31 -12
  82. package/dist/lib/task/review-finalization.js +13 -4
  83. package/dist/lib/task/review-fingerprint.js +8 -0
  84. package/dist/lib/task/verification-engine.js +86 -39
  85. package/dist/lib/task/verification-review.js +2 -2
  86. package/dist/lib/task/workspace-snapshot.js +5 -11
  87. package/dist/lib/task/write.js +11 -1
  88. package/dist/lib/update.js +13 -35
  89. package/dist/lib/version.js +5 -1
  90. package/dist/lifecycle-build-manifest.json +3 -3
  91. package/lib/agent-client.ts +0 -1
  92. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
  93. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
  94. package/lib/agent-clients/adapters/opencode-sandbox.ts +0 -5
  95. package/lib/agent-clients/adapters/traecli.ts +7 -8
  96. package/lib/agent-clients/config.ts +14 -144
  97. package/lib/agent-clients/reconcile.ts +1 -12
  98. package/lib/agent-clients/schema.ts +5 -4
  99. package/lib/agent-clients/tokens.ts +5 -18
  100. package/lib/decide.ts +12 -22
  101. package/lib/defaults.json +8 -0
  102. package/lib/git/workflow.ts +38 -1
  103. package/lib/init.ts +5 -2
  104. package/lib/internal/git-workflow.ts +7 -1
  105. package/lib/internal/platform-pr.ts +8 -1
  106. package/lib/internal/release-workflow.ts +0 -1
  107. package/lib/internal/task-delivery.ts +53 -0
  108. package/lib/internal/task-finalization.ts +27 -13
  109. package/lib/internal/task-ledger.ts +8 -2
  110. package/lib/internal/task-lifecycle.ts +33 -76
  111. package/lib/internal/task-orchestration.ts +33 -190
  112. package/lib/internal/task-validate.ts +3 -2
  113. package/lib/merge.ts +236 -120
  114. package/lib/platform/github-client.ts +8 -1
  115. package/lib/platform/pr-checks.ts +7 -5
  116. package/lib/platform/pr-summary.ts +10 -7
  117. package/lib/platform/pull-requests.ts +425 -87
  118. package/lib/platform/verification-required.ts +12 -2
  119. package/lib/platform/verification-sync.ts +9 -4
  120. package/lib/pr-review/evidence-grading.ts +7 -4
  121. package/lib/process-data/normalize.ts +2 -8
  122. package/lib/run/host.ts +63 -14
  123. package/lib/sandbox/agent-client-reconciler.ts +5 -15
  124. package/lib/sandbox/commands/create.ts +4 -4
  125. package/lib/sandbox/commands/enter.ts +24 -4
  126. package/lib/sandbox/config.ts +9 -14
  127. package/lib/sandbox/control/container-identity.ts +2 -2
  128. package/lib/sandbox/control/executor.ts +148 -51
  129. package/lib/sandbox/control/lifecycle.ts +59 -31
  130. package/lib/sandbox/control/protocol.ts +1 -3
  131. package/lib/sandbox/control/server.ts +15 -12
  132. package/lib/sandbox/control/state.ts +7 -7
  133. package/lib/sandbox/mounts.ts +4 -3
  134. package/lib/sandbox/recovery.ts +162 -34
  135. package/lib/sandbox/tools.ts +1 -1
  136. package/lib/sandbox/workspace-identity.ts +28 -0
  137. package/lib/sandbox/workspace-view.ts +14 -10
  138. package/lib/self-update.ts +341 -0
  139. package/lib/server/process-state.ts +2 -2
  140. package/lib/server/protocol.ts +5 -5
  141. package/lib/task/activity-log.ts +6 -1
  142. package/lib/task/artifact-lifecycle.ts +7 -5
  143. package/lib/task/codex-orchestration.ts +2 -1
  144. package/lib/task/command-options.ts +1 -2
  145. package/lib/task/commands/cat.ts +0 -4
  146. package/lib/task/commands/decisions.ts +80 -75
  147. package/lib/task/commands/files.ts +6 -6
  148. package/lib/task/commands/grep.ts +23 -51
  149. package/lib/task/commands/issue-body.ts +6 -6
  150. package/lib/task/commands/log.ts +22 -10
  151. package/lib/task/commands/show.ts +5 -6
  152. package/lib/task/commands/status.ts +8 -8
  153. package/lib/task/commit-intent.ts +137 -0
  154. package/lib/task/commit-operation.ts +161 -79
  155. package/lib/task/commit-policy.ts +1 -2
  156. package/lib/task/control-authority.ts +563 -0
  157. package/lib/task/create.ts +40 -10
  158. package/lib/task/current-contract.ts +49 -0
  159. package/lib/task/decision-details.ts +280 -0
  160. package/lib/task/decision-intents.ts +7 -2
  161. package/lib/task/delivery-target.ts +130 -0
  162. package/lib/task/delivery.ts +160 -0
  163. package/lib/task/events.ts +10 -5
  164. package/lib/task/human-override.ts +5 -2
  165. package/lib/task/index.ts +19 -20
  166. package/lib/task/ledger-intents.ts +6 -8
  167. package/lib/task/ledger.ts +17 -7
  168. package/lib/task/lifecycle.ts +113 -4
  169. package/lib/task/orchestration.ts +102 -80
  170. package/lib/task/pr-delivery-fact.ts +254 -0
  171. package/lib/task/review-artifacts.ts +53 -15
  172. package/lib/task/review-finalization.ts +21 -5
  173. package/lib/task/review-fingerprint.ts +10 -0
  174. package/lib/task/verification-engine.ts +78 -46
  175. package/lib/task/verification-review.ts +3 -1
  176. package/lib/task/workspace-snapshot.ts +4 -13
  177. package/lib/task/write.ts +20 -1
  178. package/lib/update.ts +14 -38
  179. package/lib/version.ts +6 -1
  180. package/package.json +1 -1
  181. package/templates/.agents/README.en.md +5 -3
  182. package/templates/.agents/README.zh-CN.md +5 -3
  183. package/templates/.agents/rules/README.en.md +4 -2
  184. package/templates/.agents/rules/README.zh-CN.md +4 -2
  185. package/templates/.agents/rules/compatibility-policy.en.md +5 -4
  186. package/templates/.agents/rules/compatibility-policy.zh-CN.md +5 -4
  187. package/templates/.agents/rules/create-issue.en.md +11 -2
  188. package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
  189. package/templates/.agents/rules/human-decision-context.en.md +9 -7
  190. package/templates/.agents/rules/human-decision-context.zh-CN.md +9 -7
  191. package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +1 -1
  192. package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +1 -1
  193. package/templates/.agents/rules/issue-pr-commands.en.md +5 -18
  194. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  195. package/templates/.agents/rules/issue-sync.en.md +26 -5
  196. package/templates/.agents/rules/issue-sync.zh-CN.md +62 -5
  197. package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
  198. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
  199. package/templates/.agents/rules/local-artifact-repair.en.md +46 -0
  200. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +46 -0
  201. package/templates/.agents/rules/milestone-inference.en.md +12 -2
  202. package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
  203. package/templates/.agents/rules/next-step-output.en.md +3 -3
  204. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -3
  205. package/templates/.agents/rules/no-mid-flow-questions.en.md +1 -1
  206. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +1 -1
  207. package/templates/.agents/rules/pr-sync.en.md +23 -14
  208. package/templates/.agents/rules/pr-sync.zh-CN.md +23 -2
  209. package/templates/.agents/rules/release-commands.en.md +42 -3
  210. package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
  211. package/templates/.agents/rules/review-handshake.en.md +1 -1
  212. package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
  213. package/templates/.agents/rules/security-alerts.en.md +17 -2
  214. package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
  215. package/templates/.agents/rules/sync-content-generation.en.md +8 -0
  216. package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
  217. package/templates/.agents/rules/task-management.en.md +2 -3
  218. package/templates/.agents/rules/task-management.zh-CN.md +2 -3
  219. package/templates/.agents/scripts/security-alerts.github.sh +151 -0
  220. package/templates/.agents/scripts/security-alerts.sh +31 -0
  221. package/templates/.agents/skills/analyze-task/SKILL.en.md +4 -3
  222. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +4 -3
  223. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  224. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  225. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  226. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  227. package/templates/.agents/skills/check-task/SKILL.en.md +2 -2
  228. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +2 -2
  229. package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -3
  230. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -3
  231. package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -3
  232. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -3
  233. package/templates/.agents/skills/code-task/SKILL.en.md +8 -5
  234. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +9 -6
  235. package/templates/.agents/skills/commit/SKILL.en.md +30 -10
  236. package/templates/.agents/skills/commit/SKILL.zh-CN.md +6 -7
  237. package/templates/.agents/skills/commit/config/verify.json +1 -1
  238. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
  239. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
  240. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  241. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  242. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -2
  243. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
  244. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -6
  245. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -6
  246. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  247. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  248. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
  249. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
  250. package/templates/.agents/skills/complete-task/SKILL.en.md +13 -13
  251. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +13 -13
  252. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
  253. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
  254. package/templates/.agents/skills/create-pr/SKILL.en.md +9 -11
  255. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +9 -11
  256. package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -4
  257. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -4
  258. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +203 -0
  259. package/templates/.agents/skills/create-release-note/SKILL.en.md +5 -6
  260. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +5 -6
  261. package/templates/.agents/skills/create-task/SKILL.en.md +2 -1
  262. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +2 -1
  263. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  264. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  265. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  266. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  267. package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
  268. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
  269. package/templates/.agents/skills/init-labels/SKILL.en.md +9 -10
  270. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
  271. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
  272. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
  273. package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
  274. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
  275. package/templates/.agents/skills/plan-task/SKILL.en.md +4 -3
  276. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +4 -3
  277. package/templates/.agents/skills/restore-task/SKILL.en.md +1 -1
  278. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +1 -1
  279. package/templates/.agents/skills/review-analysis/SKILL.en.md +8 -5
  280. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +8 -5
  281. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -0
  282. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -0
  283. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
  284. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
  285. package/templates/.agents/skills/review-code/SKILL.en.md +11 -8
  286. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +11 -8
  287. package/templates/.agents/skills/review-code/config/verify.en.json +1 -0
  288. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -0
  289. package/templates/.agents/skills/review-code/reference/migration-risks.en.md +2 -1
  290. package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +2 -1
  291. package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
  292. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
  293. package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
  294. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
  295. package/templates/.agents/skills/review-plan/SKILL.en.md +8 -5
  296. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +8 -5
  297. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -0
  298. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -0
  299. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
  300. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
  301. package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
  302. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
  303. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
  304. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
  305. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -0
  306. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -0
  307. package/templates/.agents/skills/run-task/SKILL.en.md +5 -1
  308. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +5 -1
  309. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -2
  310. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -2
  311. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +144 -109
  312. package/templates/.agents/skills/watch-pr/SKILL.en.md +5 -5
  313. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +5 -5
  314. package/templates/.agents/templates/task.en.md +6 -2
  315. package/templates/.agents/templates/task.zh-CN.md +6 -2
  316. package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
  317. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
  318. package/templates/.agents/workflows/feature-development.en.yaml +9 -8
  319. package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
  320. package/templates/.agents/workflows/refactoring.en.yaml +9 -8
  321. package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
  322. package/templates/.claude/commands/analyze-task.en.md +1 -1
  323. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  324. package/templates/.claude/commands/block-task.en.md +1 -1
  325. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  326. package/templates/.claude/commands/cancel-task.en.md +1 -1
  327. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  328. package/templates/.claude/commands/check-task.en.md +1 -1
  329. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  330. package/templates/.claude/commands/code-task.en.md +1 -1
  331. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  332. package/templates/.claude/commands/commit.en.md +1 -1
  333. package/templates/.claude/commands/commit.zh-CN.md +1 -1
  334. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  335. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  336. package/templates/.claude/commands/complete-task.en.md +1 -1
  337. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  338. package/templates/.claude/commands/create-pr.en.md +1 -1
  339. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  340. package/templates/.claude/commands/plan-task.en.md +1 -1
  341. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  342. package/templates/.claude/commands/review-analysis.en.md +1 -1
  343. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  344. package/templates/.claude/commands/review-code.en.md +1 -1
  345. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  346. package/templates/.claude/commands/review-plan.en.md +1 -1
  347. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  348. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  349. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  350. package/templates/.claude/commands/run-task.en.md +1 -1
  351. package/templates/.claude/commands/run-task.zh-CN.md +1 -1
  352. package/templates/.claude/commands/watch-pr.en.md +1 -1
  353. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  354. package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.en.md +0 -1
  355. package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.zh-CN.md +0 -1
  356. package/dist/lib/builtin-tuis.js +0 -40
  357. package/lib/builtin-tuis.ts +0 -56
  358. package/templates/.agents/rules/create-issue.github.en.md +0 -14
  359. package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
  360. package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
  361. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
  362. package/templates/.agents/rules/issue-sync.github.en.md +0 -40
  363. package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
  364. package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
  365. package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
  366. package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
  367. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
  368. package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
  369. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
  370. package/templates/.agents/rules/pr-sync.github.en.md +0 -43
  371. package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
  372. package/templates/.agents/rules/release-commands.github.en.md +0 -38
  373. package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -38
  374. package/templates/.agents/rules/security-alerts.github.en.md +0 -43
  375. package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
@@ -0,0 +1,137 @@
1
+ import { createHash } from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ export type CheckpointIntentState = 'prepared' | 'committed' | 'synced';
6
+
7
+ export type CheckpointIntent = Readonly<{
8
+ version: 1;
9
+ taskId: string;
10
+ branch: string;
11
+ mode: 'local';
12
+ expectedHead: string;
13
+ expectedTree: string;
14
+ paths: readonly string[];
15
+ message: string;
16
+ round: number;
17
+ digest: string;
18
+ state: CheckpointIntentState;
19
+ committedHead: string | null;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ }>;
23
+
24
+ type IntentIdentity = Readonly<{
25
+ taskId: string;
26
+ branch: string;
27
+ mode: 'local';
28
+ expectedHead: string;
29
+ expectedTree: string;
30
+ paths: readonly string[];
31
+ message: string;
32
+ round: number;
33
+ }>;
34
+
35
+ function intentRoot(repoRoot: string): string {
36
+ return path.join(repoRoot, '.agents', 'workspace', '.task-commit-intents');
37
+ }
38
+
39
+ function intentPath(repoRoot: string, taskId: string): string {
40
+ return path.join(intentRoot(repoRoot), `${taskId}.json`);
41
+ }
42
+
43
+ function checkpointIntentDigest(identity: IntentIdentity): string {
44
+ return createHash('sha256').update(JSON.stringify({
45
+ taskId: identity.taskId,
46
+ branch: identity.branch,
47
+ mode: identity.mode,
48
+ expectedHead: identity.expectedHead,
49
+ expectedTree: identity.expectedTree,
50
+ paths: [...identity.paths],
51
+ message: identity.message,
52
+ round: identity.round
53
+ })).digest('hex');
54
+ }
55
+
56
+ function isIntent(value: unknown): value is CheckpointIntent {
57
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
58
+ const intent = value as Record<string, unknown>;
59
+ return intent.version === 1
60
+ && typeof intent.taskId === 'string' && intent.taskId.length > 0
61
+ && typeof intent.branch === 'string' && intent.branch.length > 0
62
+ && intent.mode === 'local'
63
+ && typeof intent.expectedHead === 'string' && /^[a-f0-9]{40,64}$/.test(intent.expectedHead)
64
+ && typeof intent.expectedTree === 'string' && /^[a-f0-9]{40,64}$/.test(intent.expectedTree)
65
+ && Array.isArray(intent.paths) && intent.paths.every((item) => typeof item === 'string' && item.length > 0)
66
+ && typeof intent.message === 'string' && intent.message.length > 0
67
+ && Number.isSafeInteger(intent.round) && Number(intent.round) > 0
68
+ && typeof intent.digest === 'string' && /^[a-f0-9]{64}$/.test(intent.digest)
69
+ && ['prepared', 'committed', 'synced'].includes(String(intent.state))
70
+ && (intent.committedHead === null || (typeof intent.committedHead === 'string' && /^[a-f0-9]{40,64}$/.test(intent.committedHead)))
71
+ && typeof intent.createdAt === 'string' && intent.createdAt.length > 0
72
+ && typeof intent.updatedAt === 'string' && intent.updatedAt.length > 0
73
+ && intent.digest === checkpointIntentDigest(intent as unknown as IntentIdentity);
74
+ }
75
+
76
+ function readCheckpointIntent(repoRoot: string, taskId: string): CheckpointIntent | null {
77
+ const target = intentPath(repoRoot, taskId);
78
+ if (!fs.existsSync(target)) return null;
79
+ const value = JSON.parse(fs.readFileSync(target, 'utf8')) as unknown;
80
+ if (!isIntent(value)) throw new Error('COMMIT_INTENT_INVALID: checkpoint intent schema is invalid');
81
+ return value;
82
+ }
83
+
84
+ function writeCheckpointIntent(repoRoot: string, value: CheckpointIntent): void {
85
+ if (!isIntent(value)) throw new Error('COMMIT_INTENT_INVALID: checkpoint intent schema is invalid');
86
+ const directory = intentRoot(repoRoot);
87
+ fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
88
+ const target = intentPath(repoRoot, value.taskId);
89
+ const temporary = `${target}.${process.pid}.${Date.now()}.tmp`;
90
+ fs.writeFileSync(temporary, `${JSON.stringify(value)}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
91
+ try { fs.renameSync(temporary, target); }
92
+ catch (error) {
93
+ try { fs.unlinkSync(temporary); } catch { /* preserve primary error */ }
94
+ throw error;
95
+ }
96
+ }
97
+
98
+ function updateCheckpointIntent(
99
+ value: CheckpointIntent,
100
+ patch: Partial<Pick<CheckpointIntent, 'state' | 'committedHead' | 'updatedAt'>>
101
+ ): CheckpointIntent {
102
+ const next = { ...value, ...patch };
103
+ if (next.state === 'prepared' && next.committedHead !== null) throw new Error('COMMIT_INTENT_INVALID: prepared intent cannot have a committed head');
104
+ if (next.state !== 'prepared' && !next.committedHead) throw new Error('COMMIT_INTENT_INVALID: committed intent requires a committed head');
105
+ return next;
106
+ }
107
+
108
+ function removeCheckpointIntent(repoRoot: string, taskId: string): void {
109
+ const target = intentPath(repoRoot, taskId);
110
+ try { fs.unlinkSync(target); } catch (error) {
111
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
112
+ }
113
+ }
114
+
115
+ function sameCheckpointIntent(left: CheckpointIntent, right: IntentIdentity): boolean {
116
+ return left.digest === checkpointIntentDigest(right)
117
+ && left.taskId === right.taskId
118
+ && left.branch === right.branch
119
+ && left.mode === right.mode
120
+ && left.expectedHead === right.expectedHead
121
+ && left.expectedTree === right.expectedTree
122
+ && left.message === right.message
123
+ && left.round === right.round
124
+ && JSON.stringify(left.paths) === JSON.stringify(right.paths);
125
+ }
126
+
127
+ export {
128
+ checkpointIntentDigest,
129
+ intentPath,
130
+ intentRoot,
131
+ isIntent,
132
+ readCheckpointIntent,
133
+ removeCheckpointIntent,
134
+ sameCheckpointIntent,
135
+ updateCheckpointIntent,
136
+ writeCheckpointIntent
137
+ };
@@ -11,10 +11,13 @@ import { appendActivityEntry, locateActivityLog } from './activity-log.ts';
11
11
  import { captureTaskWriteMetadata, writeTask } from './write.ts';
12
12
  import type { TaskMutation } from './write.ts';
13
13
  import {
14
- commitOrchestrationStageCompletion,
15
- planOrchestrationStageCompletion
16
- } from './orchestration.ts';
17
- import type { OrchestrationStageCompletion } from './orchestration.ts';
14
+ checkpointIntentDigest,
15
+ readCheckpointIntent,
16
+ removeCheckpointIntent,
17
+ sameCheckpointIntent,
18
+ updateCheckpointIntent,
19
+ writeCheckpointIntent
20
+ } from './commit-intent.ts';
18
21
 
19
22
  type CommitExecutionMode = 'direct' | 'orchestrated';
20
23
 
@@ -27,10 +30,15 @@ type CommitOperationInput = Readonly<{
27
30
  taskRef?: string;
28
31
  agent?: string;
29
32
  mode?: CommitExecutionMode;
33
+ round?: number;
34
+ delivery?: Readonly<{
35
+ mode: 'local' | 'push';
36
+ remote: string;
37
+ refs: readonly string[];
38
+ }> | Readonly<{ mode: 'local' }>;
30
39
  push?: Readonly<{
31
40
  remote: string;
32
41
  refs: readonly string[];
33
- automatic: boolean;
34
42
  }>;
35
43
  }>;
36
44
 
@@ -56,6 +64,7 @@ type BoundTask = Readonly<{
56
64
  }>;
57
65
 
58
66
  const HEAD_REF = /^refs\/heads\/(.+)$/;
67
+ type CommitDelivery = Readonly<{ mode: 'local' } | { mode: 'push'; remote: string; refs: readonly string[] }>;
59
68
 
60
69
  function isCommitExecutionMode(value: unknown): value is CommitExecutionMode {
61
70
  return value === 'direct' || value === 'orchestrated';
@@ -69,6 +78,12 @@ function gitText(repoRoot: string, args: readonly string[]): string {
69
78
  }).trim();
70
79
  }
71
80
 
81
+ function effectiveDelivery(input: CommitOperationInput): CommitDelivery | null {
82
+ if (input.delivery) return input.delivery;
83
+ if (input.push) return { mode: 'push', remote: input.push.remote, refs: input.push.refs };
84
+ return null;
85
+ }
86
+
72
87
  function canonicalRepositoryRoot(cwd: string): string {
73
88
  return gitText(cwd, ['rev-parse', '--show-toplevel']);
74
89
  }
@@ -155,9 +170,10 @@ function boundTask(
155
170
 
156
171
  function validateCommon(input: CommitOperationInput, branch: string | null): Readonly<{ code: string; message: string }> | null {
157
172
  if (!input.message.trim()) return { code: 'GIT_COMMIT_INPUT_INVALID', message: 'Commit message is required' };
158
- if (input.paths.length === 0 && !input.push) return { code: 'GIT_COMMIT_INPUT_INVALID', message: 'At least one explicit path is required unless this is a push-only retry' };
159
173
  if (!/^[a-f0-9]{40,64}$/.test(input.expectedHead)) return { code: 'GIT_HEAD_EXPECTATION_REQUIRED', message: 'A valid expected HEAD is required' };
160
174
  if (!/^[a-f0-9]{40,64}$/.test(input.expectedTree)) return { code: 'GIT_TREE_EXPECTATION_REQUIRED', message: 'A valid expected tree is required' };
175
+ const delivery = effectiveDelivery(input);
176
+ if (!delivery) return { code: 'GIT_PUSH_INPUT_INVALID', message: 'Commit delivery requires a delivery policy' };
161
177
  if (input.paths.some((candidate) => !candidate || candidate.startsWith('/') || candidate.split(/[\\/]/).includes('..'))) {
162
178
  return { code: 'GIT_COMMIT_INPUT_INVALID', message: 'Commit paths must stay inside the repository' };
163
179
  }
@@ -165,9 +181,9 @@ function validateCommon(input: CommitOperationInput, branch: string | null): Rea
165
181
  return { code: 'GIT_COMMIT_INPUT_INVALID', message: 'Sensitive paths cannot be committed' };
166
182
  }
167
183
  if (branch !== null && branch === '') return { code: 'GIT_BRANCH_INVALID', message: 'A named branch is required' };
168
- if (input.push) {
169
- if (!input.push.remote || input.push.refs.length !== 1) return { code: 'GIT_PUSH_INPUT_INVALID', message: 'Push requires one remote and one ref' };
170
- const ref = input.push.refs[0] ?? '';
184
+ if (delivery.mode === 'push') {
185
+ if (!delivery.remote || delivery.refs.length !== 1) return { code: 'GIT_PUSH_INPUT_INVALID', message: 'Push requires one remote and one ref' };
186
+ const ref = delivery.refs[0] ?? '';
171
187
  if (!HEAD_REF.test(ref) || HEAD_REF.exec(ref)?.[1] !== branch) {
172
188
  return { code: 'GIT_PUSH_INPUT_INVALID', message: 'Push ref must be the current full heads ref' };
173
189
  }
@@ -175,34 +191,6 @@ function validateCommon(input: CommitOperationInput, branch: string | null): Rea
175
191
  return null;
176
192
  }
177
193
 
178
- function validateOrchestrated(
179
- input: CommitOperationInput,
180
- task: BoundTask
181
- ): { plan: OrchestrationStageCompletion } | { error: Readonly<{ code: string; message: string }> } {
182
- if (!input.agent) return { error: { code: 'ORCHESTRATION_PROVENANCE_MISMATCH', message: 'orchestrated commit requires an agent' } };
183
- const planned = planOrchestrationStageCompletion(task.taskId, {
184
- stage: 'commit',
185
- round: 1,
186
- artifact: 'commit',
187
- role: 'executor',
188
- agent: input.agent
189
- }, { repoRoot: task.repoRoot });
190
- const run = planned.result.run;
191
- if (
192
- !planned.plan
193
- || !run
194
- || run.status !== 'running'
195
- || !run.commitAuthorization.issuedAt
196
- || run.commitAuthorization.consumedAt
197
- ) return {
198
- error: {
199
- code: planned.result.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH',
200
- message: planned.result.error?.message ?? 'orchestrated commit requires one matching activated commit delegation'
201
- }
202
- };
203
- return { plan: planned.plan };
204
- }
205
-
206
194
  function syncTaskCommit(
207
195
  input: CommitOperationInput,
208
196
  task: BoundTask,
@@ -230,7 +218,10 @@ function syncTaskCommit(
230
218
  heading: activity.heading,
231
219
  body: appendActivityEntry(activity, { time: metadata.timestamp, step: 'Commit', agent: input.agent!, note: commitNote })
232
220
  });
233
- const frontmatter: Record<string, string> = { assigned_to: input.agent! };
221
+ const frontmatter: Record<string, string> = {
222
+ assigned_to: input.agent!,
223
+ checkpoint_commit: committedHead
224
+ };
234
225
  mutations.push({ kind: 'frontmatter', set: frontmatter });
235
226
  if (mutations.length === 0) return null;
236
227
  const written = writeTask({
@@ -259,29 +250,133 @@ function syncTaskCommit(
259
250
  }
260
251
  }
261
252
 
253
+ function checkpointChildMatches(task: BoundTask, intent: NonNullable<ReturnType<typeof readCheckpointIntent>>, head: string): boolean {
254
+ try {
255
+ const parent = gitText(task.repoRoot, ['rev-parse', `${head}^`]);
256
+ const tree = gitText(task.repoRoot, ['rev-parse', `${head}^{tree}`]);
257
+ const message = gitText(task.repoRoot, ['show', '-s', '--format=%s', head]);
258
+ const changed = gitText(task.repoRoot, ['diff-tree', '--no-commit-id', '--name-only', '-r', head]).split('\n').filter(Boolean).sort();
259
+ return parent === intent.expectedHead
260
+ && tree === intent.expectedTree
261
+ && message === intent.message
262
+ && JSON.stringify(changed) === JSON.stringify([...intent.paths].sort());
263
+ } catch {
264
+ return false;
265
+ }
266
+ }
267
+
268
+ function checkpointIdentity(input: CommitOperationInput, task: BoundTask, delivery: CommitDelivery): Parameters<typeof checkpointIntentDigest>[0] {
269
+ if (delivery.mode !== 'local') throw new Error('checkpoint identity requires local delivery');
270
+ return {
271
+ taskId: task.taskId,
272
+ branch: task.branch,
273
+ mode: 'local',
274
+ expectedHead: input.expectedHead,
275
+ expectedTree: input.expectedTree,
276
+ paths: [...input.paths],
277
+ message: input.message,
278
+ round: input.round ?? 1
279
+ };
280
+ }
281
+
282
+ function checkpointTimestamp(): string {
283
+ return new Date().toISOString();
284
+ }
285
+
262
286
  function executeUnlocked(input: CommitOperationInput, task: BoundTask | null, mode: CommitExecutionMode): CommitOperationResult {
263
287
  const inspected = inspectGitWorkflow(input.cwd);
264
288
  if (!inspected.snapshot) return failure(input, mode, task?.taskId ?? null, 'GIT_INSPECT_FAILED', 'Unable to inspect Git repository');
289
+ if (mode === 'orchestrated') return failure(
290
+ input,
291
+ mode,
292
+ task?.taskId ?? null,
293
+ 'ORCHESTRATED_COMMIT_REMOVED',
294
+ 'Orchestrated commit is no longer a lifecycle stage; use local checkpoint delivery from code-task',
295
+ 'blocked',
296
+ inspected.snapshot
297
+ );
265
298
  const branch = inspected.snapshot.branch;
266
299
  const commonError = validateCommon(input, branch);
267
300
  if (commonError) return failure(input, mode, task?.taskId ?? null, commonError.code, commonError.message, 'blocked', inspected.snapshot);
268
301
  if (task && task.state !== 'active') return failure(input, mode, task.taskId, 'TASK_STATE_INVALID', 'task-bound commit requires an active task', 'blocked', inspected.snapshot);
269
302
  if (task && task.branch !== branch) return failure(input, mode, task.taskId, 'GIT_BRANCH_MISMATCH', `Task branch '${task.branch}' does not match current branch '${branch}'`, 'blocked', inspected.snapshot);
270
303
  if (task && !input.agent) return failure(input, mode, task.taskId, 'COMMIT_AGENT_REQUIRED', 'task-bound commit requires an agent', 'blocked', inspected.snapshot);
271
- const orchestrationValidation = mode === 'orchestrated'
272
- ? (task
273
- ? validateOrchestrated(input, task)
274
- : { error: { code: 'ORCHESTRATION_TASK_REQUIRED', message: 'orchestrated commit requires a task context' } })
275
- : null;
276
- if (orchestrationValidation && 'error' in orchestrationValidation) {
277
- const error = orchestrationValidation.error;
278
- return failure(input, mode, task?.taskId ?? null, error.code, error.message, 'blocked', inspected.snapshot);
279
- }
280
- const orchestrationCompletion = orchestrationValidation && 'plan' in orchestrationValidation
281
- ? orchestrationValidation.plan
282
- : null;
283
-
284
- const committed = input.paths.length === 0
304
+ const delivery = effectiveDelivery(input)!;
305
+ if (delivery.mode === 'local' && !task) return failure(input, mode, null, 'CHECKPOINT_TASK_REQUIRED', 'local checkpoint delivery requires a task context', 'blocked', inspected.snapshot);
306
+ let pendingIntent: NonNullable<ReturnType<typeof readCheckpointIntent>> | null = null;
307
+ let checkpointCommittedHead: string | null = null;
308
+ const committed = delivery.mode === 'local'
309
+ ? (() => {
310
+ const identity = checkpointIdentity(input, task!, delivery);
311
+ try {
312
+ pendingIntent = readCheckpointIntent(task!.repoRoot, task!.taskId);
313
+ } catch (error) {
314
+ return {
315
+ status: 'failed' as const, changed: false, snapshot: inspected.snapshot, operations: [],
316
+ error: { code: 'COMMIT_INTENT_INVALID', message: error instanceof Error ? error.message : String(error) }
317
+ };
318
+ }
319
+ if (pendingIntent && !sameCheckpointIntent(pendingIntent, identity)) return {
320
+ status: 'failed' as const, changed: false, snapshot: inspected.snapshot, operations: [],
321
+ error: { code: 'COMMIT_INTENT_CONFLICT', message: 'A different checkpoint intent is still pending for this task' }
322
+ };
323
+ if (!pendingIntent) {
324
+ const timestamp = checkpointTimestamp();
325
+ pendingIntent = {
326
+ version: 1, ...identity, digest: checkpointIntentDigest(identity), state: 'prepared',
327
+ committedHead: null, createdAt: timestamp, updatedAt: timestamp
328
+ };
329
+ try { writeCheckpointIntent(task!.repoRoot, pendingIntent); }
330
+ catch (error) {
331
+ return {
332
+ status: 'failed' as const, changed: false, snapshot: inspected.snapshot, operations: [],
333
+ error: { code: 'COMMIT_INTENT_WRITE_FAILED', message: error instanceof Error ? error.message : String(error) }
334
+ };
335
+ }
336
+ }
337
+ if (pendingIntent.state !== 'prepared') {
338
+ checkpointCommittedHead = pendingIntent.committedHead;
339
+ return {
340
+ status: 'no-op' as const, changed: false, snapshot: inspected.snapshot,
341
+ operations: [{ name: 'commit', status: 'no-op' as const }], error: null
342
+ };
343
+ }
344
+ if (inspected.snapshot.head !== identity.expectedHead && !checkpointChildMatches(task!, pendingIntent, inspected.snapshot.head)) return {
345
+ status: 'failed' as const, changed: false, snapshot: inspected.snapshot, operations: [],
346
+ error: { code: 'COMMIT_INTENT_HEAD_CONFLICT', message: 'Current HEAD does not match the pending checkpoint intent' }
347
+ };
348
+ if (inspected.snapshot.head !== identity.expectedHead) {
349
+ checkpointCommittedHead = inspected.snapshot.head;
350
+ pendingIntent = updateCheckpointIntent(pendingIntent, {
351
+ state: 'committed', committedHead: checkpointCommittedHead, updatedAt: checkpointTimestamp()
352
+ });
353
+ writeCheckpointIntent(task!.repoRoot, pendingIntent);
354
+ return {
355
+ status: 'no-op' as const, changed: false, snapshot: inspected.snapshot,
356
+ operations: [{ name: 'commit', status: 'no-op' as const }], error: null
357
+ };
358
+ }
359
+ if (input.paths.length === 0) return {
360
+ status: 'failed' as const, changed: false, snapshot: inspected.snapshot, operations: [],
361
+ error: { code: 'GIT_COMMIT_INPUT_INVALID', message: 'Local checkpoint requires explicit paths' }
362
+ };
363
+ const created = commitExplicitPaths({
364
+ cwd: input.cwd, paths: input.paths, message: input.message,
365
+ expectedHead: identity.expectedHead, expectedTree: identity.expectedTree
366
+ });
367
+ if (created.status === 'applied' && created.snapshot?.head) {
368
+ checkpointCommittedHead = created.snapshot.head;
369
+ pendingIntent = updateCheckpointIntent(pendingIntent, {
370
+ state: 'committed', committedHead: checkpointCommittedHead, updatedAt: checkpointTimestamp()
371
+ });
372
+ writeCheckpointIntent(task!.repoRoot, pendingIntent);
373
+ } else if (created.status === 'no-op') {
374
+ removeCheckpointIntent(task!.repoRoot, task!.taskId);
375
+ pendingIntent = null;
376
+ }
377
+ return created;
378
+ })()
379
+ : input.paths.length === 0
285
380
  ? (() => {
286
381
  if (inspected.snapshot.worktree.length > 0 || inspected.snapshot.staged.length > 0) return {
287
382
  status: 'failed' as const,
@@ -330,41 +425,20 @@ function executeUnlocked(input: CommitOperationInput, task: BoundTask | null, mo
330
425
  };
331
426
 
332
427
  const warnings: OperationWarning[] = [];
333
- if (orchestrationCompletion) {
334
- try {
335
- commitOrchestrationStageCompletion(orchestrationCompletion);
336
- } catch (error) {
337
- warnings.push(warning(
338
- 'ORCHESTRATION_COMPLETION_FAILED',
339
- error instanceof Error ? error.message : String(error),
340
- true,
341
- 'orchestration',
342
- task?.taskId ?? 'orchestration',
343
- 'ACTION_REQUIRED'
344
- ));
345
- }
346
- }
347
428
  let status: CommitOperationResult['status'] = committed.status;
348
429
  let result: CommitOperationResult['result'] = committed.status === 'applied' ? 'committed' : 'no_op';
349
- if (input.push) {
350
- const target = `${input.push.remote}:${input.push.refs[0]}`;
351
- const decision = commitPushDecision({ branch, automatic: input.push.automatic }, target);
430
+ if (delivery.mode === 'push') {
431
+ const target = `${delivery.remote}:${delivery.refs[0]}`;
432
+ const decision = commitPushDecision({ branch }, target);
352
433
  if (!decision.shouldPush) {
353
434
  warnings.push(decision.warning!);
354
435
  } else {
355
436
  const pushed = pushGitRefs({
356
- cwd: input.cwd,
357
- remote: input.push.remote,
358
- refs: input.push.refs,
437
+ cwd: input.cwd, remote: delivery.remote, refs: delivery.refs,
359
438
  expectedSha: committed.snapshot?.head ?? gitText(input.cwd, ['rev-parse', 'HEAD'])
360
439
  });
361
440
  if (pushed.status !== 'applied') warnings.push(warning(
362
- 'COMMIT_PUSH_FAILED',
363
- pushed.error?.message ?? 'Git push failed',
364
- true,
365
- 'push',
366
- target,
367
- 'ACTION_REQUIRED'
441
+ 'COMMIT_PUSH_FAILED', pushed.error?.message ?? 'Git push failed', true, 'push', target, 'ACTION_REQUIRED'
368
442
  ));
369
443
  }
370
444
  }
@@ -373,12 +447,20 @@ function executeUnlocked(input: CommitOperationInput, task: BoundTask | null, mo
373
447
  result = 'committed_with_warnings';
374
448
  }
375
449
  if (task && (committed.status === 'applied' || committed.status === 'no-op')) {
376
- const taskWarning = syncTaskCommit(input, task, committed.snapshot?.head ?? gitText(task.repoRoot, ['rev-parse', 'HEAD']));
450
+ const committedHead = checkpointCommittedHead ?? committed.snapshot?.head ?? gitText(task.repoRoot, ['rev-parse', 'HEAD']);
451
+ const taskWarning = syncTaskCommit(input, task, committedHead);
377
452
  if (taskWarning) {
378
453
  warnings.push(taskWarning);
379
454
  status = 'applied';
380
455
  result = 'committed_with_warnings';
381
456
  }
457
+ if (delivery.mode === 'local' && !taskWarning && pendingIntent && checkpointCommittedHead) {
458
+ const synced = updateCheckpointIntent(pendingIntent, {
459
+ state: 'synced', committedHead: checkpointCommittedHead, updatedAt: checkpointTimestamp()
460
+ });
461
+ writeCheckpointIntent(task.repoRoot, synced);
462
+ removeCheckpointIntent(task.repoRoot, task.taskId);
463
+ }
382
464
  }
383
465
  return {
384
466
  status,
@@ -2,7 +2,6 @@ import type { OperationWarning } from './operation-outcome.ts';
2
2
 
3
3
  type CommitPushPolicy = Readonly<{
4
4
  branch: string;
5
- automatic: boolean;
6
5
  }>;
7
6
 
8
7
  type CommitPushDecision = Readonly<{
@@ -12,7 +11,7 @@ type CommitPushDecision = Readonly<{
12
11
 
13
12
  function commitPushDecision(policy: CommitPushPolicy, target: string): CommitPushDecision {
14
13
  const branch = policy.branch.trim();
15
- if (policy.automatic && (branch === 'main' || branch === 'master')) return {
14
+ if (branch === 'main' || branch === 'master') return {
16
15
  shouldPush: false,
17
16
  warning: {
18
17
  code: 'COMMIT_AUTOPUSH_PROTECTED_BRANCH',