agentplane 0.3.9 → 0.3.11

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 (404) hide show
  1. package/assets/AGENTS.md +4 -2
  2. package/assets/agents/CODER.json +1 -1
  3. package/assets/policy/dod.core.md +1 -1
  4. package/assets/policy/governance.md +5 -3
  5. package/assets/policy/incidents.md +19 -77
  6. package/assets/policy/workflow.branch_pr.md +2 -0
  7. package/assets/policy/workflow.direct.md +3 -1
  8. package/bin/agentplane.js +56 -1
  9. package/bin/runtime-watch.js +1 -0
  10. package/bin/stale-dist-policy.d.ts +1 -1
  11. package/bin/stale-dist-policy.js +13 -0
  12. package/dist/.build-manifest.json +462 -202
  13. package/dist/cli/bootstrap-guide.d.ts +1 -0
  14. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  15. package/dist/cli/bootstrap-guide.js +20 -1
  16. package/dist/cli/command-guide.d.ts.map +1 -1
  17. package/dist/cli/command-guide.js +2 -1
  18. package/dist/cli/command-invocations.d.ts.map +1 -1
  19. package/dist/cli/command-invocations.js +6 -1
  20. package/dist/cli/command-snippets.d.ts +2 -0
  21. package/dist/cli/command-snippets.d.ts.map +1 -1
  22. package/dist/cli/command-snippets.js +2 -0
  23. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  24. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  25. package/dist/cli/run-cli/command-catalog/core.js +10 -0
  26. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  27. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  28. package/dist/cli/run-cli/command-catalog/project.js +3 -1
  29. package/dist/cli/run-cli/command-catalog/task.d.ts +1 -1
  30. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -1
  31. package/dist/cli/run-cli/command-catalog/task.js +10 -0
  32. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  33. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  34. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  35. package/dist/cli/run-cli/commands/config.js +13 -0
  36. package/dist/cli/run-cli/commands/core/preflight.d.ts.map +1 -1
  37. package/dist/cli/run-cli/commands/core/preflight.js +44 -1
  38. package/dist/cli/run-cli.js +2 -2
  39. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  40. package/dist/cli/run-cli.test-helpers.js +12 -0
  41. package/dist/commands/backend.d.ts.map +1 -1
  42. package/dist/commands/backend.js +4 -0
  43. package/dist/commands/branch/cleanup-merged.d.ts +2 -0
  44. package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
  45. package/dist/commands/branch/cleanup-merged.js +132 -28
  46. package/dist/commands/branch/work-start.d.ts.map +1 -1
  47. package/dist/commands/branch/work-start.js +60 -1
  48. package/dist/commands/cleanup/merged.command.d.ts +2 -0
  49. package/dist/commands/cleanup/merged.command.d.ts.map +1 -1
  50. package/dist/commands/cleanup/merged.command.js +24 -0
  51. package/dist/commands/doctor/branch-pr.d.ts +4 -0
  52. package/dist/commands/doctor/branch-pr.d.ts.map +1 -0
  53. package/dist/commands/doctor/branch-pr.js +96 -0
  54. package/dist/commands/doctor/fixes.d.ts +5 -0
  55. package/dist/commands/doctor/fixes.d.ts.map +1 -1
  56. package/dist/commands/doctor/fixes.js +70 -0
  57. package/dist/commands/doctor.run.d.ts.map +1 -1
  58. package/dist/commands/doctor.run.js +6 -1
  59. package/dist/commands/finish.run.d.ts.map +1 -1
  60. package/dist/commands/finish.run.js +11 -0
  61. package/dist/commands/finish.spec.d.ts +11 -0
  62. package/dist/commands/finish.spec.d.ts.map +1 -1
  63. package/dist/commands/finish.spec.js +51 -0
  64. package/dist/commands/guard/impl/close-message.d.ts.map +1 -1
  65. package/dist/commands/guard/impl/close-message.js +23 -6
  66. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  67. package/dist/commands/guard/impl/commands.js +24 -2
  68. package/dist/commands/guard/impl/env.d.ts +1 -0
  69. package/dist/commands/guard/impl/env.d.ts.map +1 -1
  70. package/dist/commands/guard/impl/env.js +1 -0
  71. package/dist/commands/hooks/index.d.ts.map +1 -1
  72. package/dist/commands/hooks/index.js +98 -1
  73. package/dist/commands/incidents/advise.command.d.ts +15 -0
  74. package/dist/commands/incidents/advise.command.d.ts.map +1 -0
  75. package/dist/commands/incidents/advise.command.js +139 -0
  76. package/dist/commands/incidents/collect.command.d.ts +11 -0
  77. package/dist/commands/incidents/collect.command.d.ts.map +1 -0
  78. package/dist/commands/incidents/collect.command.js +72 -0
  79. package/dist/commands/incidents/incidents.command.d.ts +5 -0
  80. package/dist/commands/incidents/incidents.command.d.ts.map +1 -0
  81. package/dist/commands/incidents/incidents.command.js +21 -0
  82. package/dist/commands/incidents/shared.d.ts +76 -0
  83. package/dist/commands/incidents/shared.d.ts.map +1 -0
  84. package/dist/commands/incidents/shared.js +261 -0
  85. package/dist/commands/pr/check.d.ts.map +1 -1
  86. package/dist/commands/pr/check.js +249 -75
  87. package/dist/commands/pr/close-superseded.d.ts +9 -0
  88. package/dist/commands/pr/close-superseded.d.ts.map +1 -0
  89. package/dist/commands/pr/close-superseded.js +129 -0
  90. package/dist/commands/pr/close.d.ts +11 -0
  91. package/dist/commands/pr/close.d.ts.map +1 -0
  92. package/dist/commands/pr/close.js +116 -0
  93. package/dist/commands/pr/index.d.ts +2 -0
  94. package/dist/commands/pr/index.d.ts.map +1 -1
  95. package/dist/commands/pr/index.js +2 -0
  96. package/dist/commands/pr/integrate/artifacts.d.ts +7 -0
  97. package/dist/commands/pr/integrate/artifacts.d.ts.map +1 -1
  98. package/dist/commands/pr/integrate/artifacts.js +66 -1
  99. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  100. package/dist/commands/pr/integrate/cmd.js +20 -0
  101. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts +8 -0
  102. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts.map +1 -0
  103. package/dist/commands/pr/integrate/internal/bootstrap-guidance.js +59 -0
  104. package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
  105. package/dist/commands/pr/integrate/internal/finalize.js +40 -12
  106. package/dist/commands/pr/integrate/internal/merge.d.ts +4 -0
  107. package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
  108. package/dist/commands/pr/integrate/internal/merge.js +59 -15
  109. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts +13 -0
  110. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts.map +1 -0
  111. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.js +25 -0
  112. package/dist/commands/pr/integrate/internal/prepare.d.ts +3 -2
  113. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  114. package/dist/commands/pr/integrate/internal/prepare.js +107 -19
  115. package/dist/commands/pr/internal/freshness.d.ts +20 -0
  116. package/dist/commands/pr/internal/freshness.d.ts.map +1 -0
  117. package/dist/commands/pr/internal/freshness.js +50 -0
  118. package/dist/commands/pr/internal/gh-api.d.ts +6 -0
  119. package/dist/commands/pr/internal/gh-api.d.ts.map +1 -0
  120. package/dist/commands/pr/internal/gh-api.js +80 -0
  121. package/dist/commands/pr/internal/note-store.d.ts +18 -0
  122. package/dist/commands/pr/internal/note-store.d.ts.map +1 -0
  123. package/dist/commands/pr/internal/note-store.js +66 -0
  124. package/dist/commands/pr/internal/pr-paths.d.ts +13 -0
  125. package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
  126. package/dist/commands/pr/internal/pr-paths.js +13 -0
  127. package/dist/commands/pr/internal/review-template.d.ts +24 -4
  128. package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
  129. package/dist/commands/pr/internal/review-template.js +221 -33
  130. package/dist/commands/pr/internal/sync.d.ts +41 -0
  131. package/dist/commands/pr/internal/sync.d.ts.map +1 -0
  132. package/dist/commands/pr/internal/sync.js +598 -0
  133. package/dist/commands/pr/note.d.ts.map +1 -1
  134. package/dist/commands/pr/note.js +37 -4
  135. package/dist/commands/pr/open.d.ts +1 -0
  136. package/dist/commands/pr/open.d.ts.map +1 -1
  137. package/dist/commands/pr/open.js +18 -54
  138. package/dist/commands/pr/pr.command.d.ts +15 -0
  139. package/dist/commands/pr/pr.command.d.ts.map +1 -1
  140. package/dist/commands/pr/pr.command.js +124 -5
  141. package/dist/commands/pr/update.d.ts.map +1 -1
  142. package/dist/commands/pr/update.js +58 -74
  143. package/dist/commands/recipes/impl/commands/cache-prune.d.ts.map +1 -1
  144. package/dist/commands/recipes/impl/commands/cache-prune.js +14 -0
  145. package/dist/commands/recipes/impl/commands/install.js +1 -1
  146. package/dist/commands/recipes/impl/commands/list-remote.d.ts.map +1 -1
  147. package/dist/commands/recipes/impl/commands/list-remote.js +1 -0
  148. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  149. package/dist/commands/recipes/impl/commands/remove.js +9 -1
  150. package/dist/commands/release/apply.command.d.ts.map +1 -1
  151. package/dist/commands/release/apply.command.js +12 -17
  152. package/dist/commands/release/apply.preflight.d.ts.map +1 -1
  153. package/dist/commands/release/apply.preflight.js +1 -1
  154. package/dist/commands/shared/approval-requirements.d.ts +5 -7
  155. package/dist/commands/shared/approval-requirements.d.ts.map +1 -1
  156. package/dist/commands/shared/approval-requirements.js +3 -73
  157. package/dist/commands/shared/gh-transport.d.ts +16 -0
  158. package/dist/commands/shared/gh-transport.d.ts.map +1 -0
  159. package/dist/commands/shared/gh-transport.js +71 -0
  160. package/dist/commands/shared/git-diff.d.ts +3 -1
  161. package/dist/commands/shared/git-diff.d.ts.map +1 -1
  162. package/dist/commands/shared/git-diff.js +10 -2
  163. package/dist/commands/shared/git-ops.d.ts +1 -0
  164. package/dist/commands/shared/git-ops.d.ts.map +1 -1
  165. package/dist/commands/shared/git-ops.js +15 -0
  166. package/dist/commands/shared/git-worktree.d.ts +2 -0
  167. package/dist/commands/shared/git-worktree.d.ts.map +1 -1
  168. package/dist/commands/shared/git-worktree.js +22 -2
  169. package/dist/commands/shared/network-approval.d.ts +2 -0
  170. package/dist/commands/shared/network-approval.d.ts.map +1 -1
  171. package/dist/commands/shared/network-approval.js +1 -1
  172. package/dist/commands/shared/post-commit-pr-artifacts.d.ts +9 -0
  173. package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -0
  174. package/dist/commands/shared/post-commit-pr-artifacts.js +22 -0
  175. package/dist/commands/shared/pr-meta.d.ts +29 -0
  176. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  177. package/dist/commands/shared/pr-meta.js +152 -3
  178. package/dist/commands/shared/task-backend.d.ts +9 -0
  179. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  180. package/dist/commands/shared/task-backend.js +34 -22
  181. package/dist/commands/shared/task-local-freshness.d.ts +13 -0
  182. package/dist/commands/shared/task-local-freshness.d.ts.map +1 -0
  183. package/dist/commands/shared/task-local-freshness.js +20 -0
  184. package/dist/commands/shared/task-mutation.d.ts +2 -0
  185. package/dist/commands/shared/task-mutation.d.ts.map +1 -1
  186. package/dist/commands/shared/task-mutation.js +7 -0
  187. package/dist/commands/task/block.d.ts.map +1 -1
  188. package/dist/commands/task/block.js +1 -0
  189. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  190. package/dist/commands/task/close-duplicate.js +34 -1
  191. package/dist/commands/task/close-shared.d.ts.map +1 -1
  192. package/dist/commands/task/close-shared.js +1 -0
  193. package/dist/commands/task/derive.js +1 -1
  194. package/dist/commands/task/doc-template.d.ts.map +1 -1
  195. package/dist/commands/task/doc-template.js +7 -11
  196. package/dist/commands/task/findings-add.command.d.ts +20 -0
  197. package/dist/commands/task/findings-add.command.d.ts.map +1 -0
  198. package/dist/commands/task/findings-add.command.js +165 -0
  199. package/dist/commands/task/findings.command.d.ts +7 -0
  200. package/dist/commands/task/findings.command.d.ts.map +1 -0
  201. package/dist/commands/task/findings.command.js +20 -0
  202. package/dist/commands/task/findings.d.ts +63 -0
  203. package/dist/commands/task/findings.d.ts.map +1 -0
  204. package/dist/commands/task/findings.js +188 -0
  205. package/dist/commands/task/finish-shared.d.ts +1 -0
  206. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  207. package/dist/commands/task/finish-shared.js +60 -3
  208. package/dist/commands/task/finish.d.ts +10 -0
  209. package/dist/commands/task/finish.d.ts.map +1 -1
  210. package/dist/commands/task/finish.js +143 -0
  211. package/dist/commands/task/hosted-close-pr.command.d.ts +11 -0
  212. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -0
  213. package/dist/commands/task/hosted-close-pr.command.js +414 -0
  214. package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
  215. package/dist/commands/task/hosted-close.command.js +49 -1
  216. package/dist/commands/task/hosted-merge-sync.d.ts +38 -0
  217. package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
  218. package/dist/commands/task/hosted-merge-sync.js +249 -17
  219. package/dist/commands/task/index.d.ts +1 -0
  220. package/dist/commands/task/index.d.ts.map +1 -1
  221. package/dist/commands/task/index.js +1 -0
  222. package/dist/commands/task/new.d.ts +1 -0
  223. package/dist/commands/task/new.d.ts.map +1 -1
  224. package/dist/commands/task/new.js +140 -30
  225. package/dist/commands/task/new.spec.d.ts.map +1 -1
  226. package/dist/commands/task/new.spec.js +7 -0
  227. package/dist/commands/task/normalize.command.d.ts +2 -0
  228. package/dist/commands/task/normalize.command.d.ts.map +1 -1
  229. package/dist/commands/task/normalize.command.js +45 -0
  230. package/dist/commands/task/normalize.d.ts +2 -0
  231. package/dist/commands/task/normalize.d.ts.map +1 -1
  232. package/dist/commands/task/normalize.js +85 -8
  233. package/dist/commands/task/plan.d.ts.map +1 -1
  234. package/dist/commands/task/plan.js +7 -10
  235. package/dist/commands/task/set-status.d.ts.map +1 -1
  236. package/dist/commands/task/set-status.js +1 -0
  237. package/dist/commands/task/shared/docs.d.ts +6 -0
  238. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  239. package/dist/commands/task/shared/docs.js +14 -0
  240. package/dist/commands/task/shared/transition-command.d.ts +2 -0
  241. package/dist/commands/task/shared/transition-command.d.ts.map +1 -1
  242. package/dist/commands/task/shared/transition-command.js +1 -0
  243. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  244. package/dist/commands/task/shared/transitions.js +11 -1
  245. package/dist/commands/task/shared.d.ts +1 -1
  246. package/dist/commands/task/shared.d.ts.map +1 -1
  247. package/dist/commands/task/shared.js +1 -1
  248. package/dist/commands/task/start-ready.d.ts.map +1 -1
  249. package/dist/commands/task/start-ready.js +98 -1
  250. package/dist/commands/task/start.d.ts.map +1 -1
  251. package/dist/commands/task/start.js +18 -10
  252. package/dist/commands/task/task.command.d.ts.map +1 -1
  253. package/dist/commands/task/task.command.js +4 -0
  254. package/dist/commands/task/verify-command-shared.d.ts +19 -0
  255. package/dist/commands/task/verify-command-shared.d.ts.map +1 -1
  256. package/dist/commands/task/verify-command-shared.js +152 -1
  257. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  258. package/dist/commands/task/verify-ok.command.js +15 -2
  259. package/dist/commands/task/verify-record.d.ts +36 -0
  260. package/dist/commands/task/verify-record.d.ts.map +1 -1
  261. package/dist/commands/task/verify-record.js +193 -11
  262. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  263. package/dist/commands/task/verify-rework.command.js +15 -2
  264. package/dist/commands/task/verify-show.command.d.ts +1 -1
  265. package/dist/commands/task/verify-show.command.d.ts.map +1 -1
  266. package/dist/commands/task/verify-show.command.js +28 -1
  267. package/dist/commands/upgrade.d.ts.map +1 -1
  268. package/dist/commands/upgrade.js +6 -1
  269. package/dist/commands/verify.run.d.ts.map +1 -1
  270. package/dist/commands/verify.run.js +12 -0
  271. package/dist/commands/verify.spec.d.ts +2 -6
  272. package/dist/commands/verify.spec.d.ts.map +1 -1
  273. package/dist/commands/verify.spec.js +30 -3
  274. package/dist/policy/engine.d.ts +3 -1
  275. package/dist/policy/engine.d.ts.map +1 -1
  276. package/dist/policy/engine.js +5 -6
  277. package/dist/policy/taxonomy.d.ts +17 -0
  278. package/dist/policy/taxonomy.d.ts.map +1 -0
  279. package/dist/policy/taxonomy.js +302 -0
  280. package/dist/policy/types.d.ts +2 -1
  281. package/dist/policy/types.d.ts.map +1 -1
  282. package/dist/runner/artifacts.d.ts.map +1 -1
  283. package/dist/runner/artifacts.js +2 -0
  284. package/dist/runner/context/base-prompts.d.ts +25 -0
  285. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  286. package/dist/runner/context/base-prompts.js +182 -54
  287. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  288. package/dist/runner/context/recipe-context.js +5 -0
  289. package/dist/runner/types.d.ts +12 -0
  290. package/dist/runner/types.d.ts.map +1 -1
  291. package/dist/runner/usecases/scenario-materialize-task.d.ts.map +1 -1
  292. package/dist/runner/usecases/scenario-materialize-task.js +81 -11
  293. package/dist/runner/usecases/task-run-inspect.d.ts.map +1 -1
  294. package/dist/runner/usecases/task-run-inspect.js +9 -7
  295. package/dist/runner/usecases/task-run-lifecycle-shared.d.ts.map +1 -1
  296. package/dist/runner/usecases/task-run-lifecycle-shared.js +8 -6
  297. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  298. package/dist/runner/usecases/task-run.js +59 -12
  299. package/dist/runtime/approvals/index.d.ts +3 -0
  300. package/dist/runtime/approvals/index.d.ts.map +1 -0
  301. package/dist/runtime/approvals/index.js +1 -0
  302. package/dist/runtime/approvals/runtime.d.ts +12 -0
  303. package/dist/runtime/approvals/runtime.d.ts.map +1 -0
  304. package/dist/runtime/approvals/runtime.js +154 -0
  305. package/dist/runtime/approvals/types.d.ts +31 -0
  306. package/dist/runtime/approvals/types.d.ts.map +1 -0
  307. package/dist/runtime/approvals/types.js +1 -0
  308. package/dist/runtime/behavior/index.d.ts +3 -0
  309. package/dist/runtime/behavior/index.d.ts.map +1 -0
  310. package/dist/runtime/behavior/index.js +1 -0
  311. package/dist/runtime/behavior/resolve.d.ts +7 -0
  312. package/dist/runtime/behavior/resolve.d.ts.map +1 -0
  313. package/dist/runtime/behavior/resolve.js +66 -0
  314. package/dist/runtime/behavior/types.d.ts +25 -0
  315. package/dist/runtime/behavior/types.d.ts.map +1 -0
  316. package/dist/runtime/behavior/types.js +1 -0
  317. package/dist/runtime/capabilities/backend.d.ts +7 -0
  318. package/dist/runtime/capabilities/backend.d.ts.map +1 -0
  319. package/dist/runtime/capabilities/backend.js +104 -0
  320. package/dist/runtime/capabilities/index.d.ts +6 -0
  321. package/dist/runtime/capabilities/index.d.ts.map +1 -0
  322. package/dist/runtime/capabilities/index.js +4 -0
  323. package/dist/runtime/capabilities/recipe.d.ts +10 -0
  324. package/dist/runtime/capabilities/recipe.d.ts.map +1 -0
  325. package/dist/runtime/capabilities/recipe.js +123 -0
  326. package/dist/runtime/capabilities/registry.d.ts +6 -0
  327. package/dist/runtime/capabilities/registry.d.ts.map +1 -0
  328. package/dist/runtime/capabilities/registry.js +69 -0
  329. package/dist/runtime/capabilities/runner.d.ts +8 -0
  330. package/dist/runtime/capabilities/runner.d.ts.map +1 -0
  331. package/dist/runtime/capabilities/runner.js +73 -0
  332. package/dist/runtime/capabilities/types.d.ts +28 -0
  333. package/dist/runtime/capabilities/types.d.ts.map +1 -0
  334. package/dist/runtime/capabilities/types.js +1 -0
  335. package/dist/runtime/execution-profile/index.d.ts +3 -0
  336. package/dist/runtime/execution-profile/index.d.ts.map +1 -0
  337. package/dist/runtime/execution-profile/index.js +1 -0
  338. package/dist/runtime/execution-profile/resolve.d.ts +9 -0
  339. package/dist/runtime/execution-profile/resolve.d.ts.map +1 -0
  340. package/dist/runtime/execution-profile/resolve.js +80 -0
  341. package/dist/runtime/execution-profile/types.d.ts +27 -0
  342. package/dist/runtime/execution-profile/types.d.ts.map +1 -0
  343. package/dist/runtime/execution-profile/types.js +1 -0
  344. package/dist/runtime/explain/index.d.ts +3 -0
  345. package/dist/runtime/explain/index.d.ts.map +1 -0
  346. package/dist/runtime/explain/index.js +1 -0
  347. package/dist/runtime/explain/resolve.d.ts +14 -0
  348. package/dist/runtime/explain/resolve.d.ts.map +1 -0
  349. package/dist/runtime/explain/resolve.js +50 -0
  350. package/dist/runtime/explain/types.d.ts +28 -0
  351. package/dist/runtime/explain/types.d.ts.map +1 -0
  352. package/dist/runtime/explain/types.js +1 -0
  353. package/dist/runtime/harness/index.d.ts +4 -0
  354. package/dist/runtime/harness/index.d.ts.map +1 -0
  355. package/dist/runtime/harness/index.js +2 -0
  356. package/dist/runtime/harness/resolve-from-command-context.d.ts +4 -0
  357. package/dist/runtime/harness/resolve-from-command-context.d.ts.map +1 -0
  358. package/dist/runtime/harness/resolve-from-command-context.js +11 -0
  359. package/dist/runtime/harness/resolve.d.ts +13 -0
  360. package/dist/runtime/harness/resolve.d.ts.map +1 -0
  361. package/dist/runtime/harness/resolve.js +146 -0
  362. package/dist/runtime/harness/types.d.ts +65 -0
  363. package/dist/runtime/harness/types.d.ts.map +1 -0
  364. package/dist/runtime/harness/types.js +1 -0
  365. package/dist/runtime/incidents/index.d.ts +3 -0
  366. package/dist/runtime/incidents/index.d.ts.map +1 -0
  367. package/dist/runtime/incidents/index.js +1 -0
  368. package/dist/runtime/incidents/resolve.d.ts +26 -0
  369. package/dist/runtime/incidents/resolve.d.ts.map +1 -0
  370. package/dist/runtime/incidents/resolve.js +683 -0
  371. package/dist/runtime/incidents/types.d.ts +84 -0
  372. package/dist/runtime/incidents/types.d.ts.map +1 -0
  373. package/dist/runtime/incidents/types.js +1 -0
  374. package/dist/runtime/protocol/index.d.ts +3 -0
  375. package/dist/runtime/protocol/index.d.ts.map +1 -0
  376. package/dist/runtime/protocol/index.js +2 -0
  377. package/dist/runtime/protocol/resolve.d.ts +16 -0
  378. package/dist/runtime/protocol/resolve.d.ts.map +1 -0
  379. package/dist/runtime/protocol/resolve.js +36 -0
  380. package/dist/runtime/protocol/types.d.ts +36 -0
  381. package/dist/runtime/protocol/types.d.ts.map +1 -0
  382. package/dist/runtime/protocol/types.js +1 -0
  383. package/dist/runtime/task-intake/index.d.ts +3 -0
  384. package/dist/runtime/task-intake/index.d.ts.map +1 -0
  385. package/dist/runtime/task-intake/index.js +1 -0
  386. package/dist/runtime/task-intake/resolve.d.ts +48 -0
  387. package/dist/runtime/task-intake/resolve.d.ts.map +1 -0
  388. package/dist/runtime/task-intake/resolve.js +316 -0
  389. package/dist/runtime/task-intake/types.d.ts +117 -0
  390. package/dist/runtime/task-intake/types.d.ts.map +1 -0
  391. package/dist/runtime/task-intake/types.js +1 -0
  392. package/dist/shared/env.d.ts +1 -0
  393. package/dist/shared/env.d.ts.map +1 -1
  394. package/dist/shared/env.js +22 -1
  395. package/dist/shared/protected-paths.d.ts +4 -0
  396. package/dist/shared/protected-paths.d.ts.map +1 -1
  397. package/dist/shared/protected-paths.js +8 -4
  398. package/dist/usecases/context/resolve-context.d.ts +55 -6
  399. package/dist/usecases/context/resolve-context.d.ts.map +1 -1
  400. package/dist/usecases/context/resolve-context.js +96 -6
  401. package/dist/usecases/task/task-list-usecase.d.ts.map +1 -1
  402. package/dist/usecases/task/task-list-usecase.js +8 -2
  403. package/dist/usecases/task/task-new-usecase.js +4 -4
  404. package/package.json +2 -2
@@ -1,11 +1,29 @@
1
1
  import { setMarkdownSection } from "@agentplaneorg/core";
2
2
  import { mapBackendError } from "../../cli/error-map.js";
3
3
  import { backendNotSupportedMessage, warnMessage } from "../../cli/output.js";
4
+ import { createClarificationContract, createTaskGraphDraft, createTaskIntakeContext, materializeTaskGraphDraft, } from "../../runtime/task-intake/index.js";
4
5
  import { CliError } from "../../shared/errors.js";
5
6
  import { buildTaskDocState } from "../../shared/task-doc-state.js";
7
+ import { makeReadOnlyUsecaseContext } from "../../usecases/context/resolve-context.js";
6
8
  import { loadCommandContext } from "../shared/task-backend.js";
7
9
  import { ensureTaskDependsOnGraphIsAcyclic, nowIso, requiresVerifyStepsByPrimary, resolvePrimaryTag, warnIfUnknownOwner, } from "./shared.js";
8
10
  import { buildDefaultVerifyStepsSection, defaultTaskDocV3, TASK_DOC_VERSION_V3, } from "./doc-template.js";
11
+ const TASK_NEW_DUPLICATE_THRESHOLD = 0.75;
12
+ const TASK_NEW_DUPLICATE_STOPWORDS = new Set([
13
+ "a",
14
+ "an",
15
+ "and",
16
+ "for",
17
+ "from",
18
+ "in",
19
+ "is",
20
+ "of",
21
+ "on",
22
+ "the",
23
+ "to",
24
+ "when",
25
+ "with",
26
+ ]);
9
27
  function dedupeTrimmed(values) {
10
28
  const seen = new Set();
11
29
  const out = [];
@@ -53,11 +71,65 @@ function sanitizeTaskNewParsed(p) {
53
71
  const verify = dedupeTrimmed(p.verify);
54
72
  return { ...p, title, description, owner, tags, dependsOn, verify };
55
73
  }
74
+ function normalizeDuplicateTitleTokens(value) {
75
+ return value
76
+ .trim()
77
+ .toLowerCase()
78
+ .replaceAll(/[^a-z0-9]+/g, " ")
79
+ .split(/\s+/)
80
+ .map((token) => token.trim())
81
+ .filter((token) => token.length > 0 &&
82
+ (token.length > 2 || /\d/.test(token)) &&
83
+ !TASK_NEW_DUPLICATE_STOPWORDS.has(token));
84
+ }
85
+ function duplicateSimilarity(left, right) {
86
+ const leftTokens = normalizeDuplicateTitleTokens(left);
87
+ const rightTokens = normalizeDuplicateTitleTokens(right);
88
+ if (leftTokens.length === 0 || rightTokens.length === 0) {
89
+ return left.trim().toLowerCase() === right.trim().toLowerCase() ? 1 : 0;
90
+ }
91
+ const leftSet = new Set(leftTokens);
92
+ const rightSet = new Set(rightTokens);
93
+ const intersection = [...leftSet].filter((token) => rightSet.has(token)).length;
94
+ const union = new Set([...leftSet, ...rightSet]).size;
95
+ return union === 0 ? 0 : intersection / union;
96
+ }
97
+ function listOpenTaskDuplicates(tasks, title) {
98
+ return tasks
99
+ .filter((task) => String(task.status ?? "").toUpperCase() !== "DONE")
100
+ .map((task) => ({
101
+ task,
102
+ score: duplicateSimilarity(task.title ?? "", title),
103
+ }))
104
+ .filter(({ score }) => score >= TASK_NEW_DUPLICATE_THRESHOLD)
105
+ .toSorted((left, right) => right.score - left.score || left.task.id.localeCompare(right.task.id));
106
+ }
107
+ function formatDuplicateTaskMessage(duplicates, allowDuplicate) {
108
+ const summary = duplicates
109
+ .slice(0, 3)
110
+ .map(({ task, score }) => `${task.id} (${Math.round(score * 100)}% title overlap, status=${String(task.status || "TODO").toUpperCase()}): ${task.title}`)
111
+ .join("; ");
112
+ const tail = allowDuplicate
113
+ ? "creating a duplicate because --allow-duplicate was passed"
114
+ : "rerun with --allow-duplicate only when intentional or close the extra task with `agentplane task close-duplicate`";
115
+ return `potential duplicate open task detected: ${summary}; ${tail}.`;
116
+ }
56
117
  export async function runTaskNewParsed(opts) {
57
118
  const p = sanitizeTaskNewParsed(opts.parsed);
58
119
  try {
59
120
  const ctx = opts.ctx ??
60
121
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
122
+ const duplicateTasks = listOpenTaskDuplicates(await ctx.taskBackend.listTasks(), p.title);
123
+ if (duplicateTasks.length > 0 && !p.allowDuplicate) {
124
+ throw new CliError({
125
+ exitCode: 3,
126
+ code: "E_VALIDATION",
127
+ message: formatDuplicateTaskMessage(duplicateTasks, false),
128
+ });
129
+ }
130
+ if (duplicateTasks.length > 0 && p.allowDuplicate) {
131
+ process.stderr.write(`${warnMessage(formatDuplicateTaskMessage(duplicateTasks, true))}\n`);
132
+ }
61
133
  const suffixLength = ctx.config.tasks.id_suffix_length_default;
62
134
  if (!ctx.taskBackend.generateTaskId) {
63
135
  throw new CliError({
@@ -67,32 +139,16 @@ export async function runTaskNewParsed(opts) {
67
139
  });
68
140
  }
69
141
  const taskId = await ctx.taskBackend.generateTaskId({ length: suffixLength, attempts: 1000 });
142
+ const executionContext = await makeReadOnlyUsecaseContext(ctx);
143
+ const createdAt = nowIso();
70
144
  const docState = buildTaskDocState({
71
145
  doc: defaultTaskDocV3({ title: p.title, description: p.description }),
72
146
  owner: p.owner,
73
147
  updatedBy: p.owner,
74
148
  version: TASK_DOC_VERSION_V3,
75
- updatedAt: nowIso(),
149
+ updatedAt: createdAt,
76
150
  });
77
- const task = {
78
- id: taskId,
79
- title: p.title,
80
- description: p.description,
81
- status: "TODO",
82
- priority: p.priority,
83
- owner: p.owner,
84
- revision: 1,
85
- origin: { system: "manual" },
86
- tags: p.tags,
87
- depends_on: p.dependsOn,
88
- verify: p.verify,
89
- comments: [],
90
- doc_version: docState.doc_version,
91
- doc_updated_at: docState.doc_updated_at,
92
- doc_updated_by: docState.doc_updated_by,
93
- id_source: "generated",
94
- doc: docState.doc,
95
- };
151
+ let taskDoc = docState.doc;
96
152
  const spikeTag = (ctx.config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
97
153
  const primary = resolvePrimaryTag(p.tags, ctx);
98
154
  if (primary.usedFallback) {
@@ -106,11 +162,11 @@ export async function runTaskNewParsed(opts) {
106
162
  dependsOn: p.dependsOn,
107
163
  });
108
164
  if (requiresVerifySteps) {
109
- task.doc = setMarkdownSection(task.doc ?? "", "Verify Steps", buildDefaultVerifyStepsSection({
165
+ taskDoc = setMarkdownSection(taskDoc, "Verify Steps", buildDefaultVerifyStepsSection({
110
166
  primary: primary.primary,
111
167
  verifyCommands: p.verify,
112
168
  }));
113
- process.stderr.write(`${warnMessage("task requires Verify Steps by primary tag; seeded a default ## Verify Steps section in README (review and refine before approval/start)")}\n`);
169
+ process.stderr.write(`${warnMessage("task requires Verify Steps by primary tag; seeded a concrete ## Verify Steps section in README (refine it only if the task needs stricter acceptance coverage)")}\n`);
114
170
  }
115
171
  const hasSpike = p.tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
116
172
  const hasImplementationTags = requiresVerifyStepsByPrimary(p.tags, ctx.config);
@@ -118,17 +174,71 @@ export async function runTaskNewParsed(opts) {
118
174
  process.stderr.write(`${warnMessage("spike is combined with a primary tag that requires verify steps; consider splitting spike vs implementation tasks")}\n`);
119
175
  }
120
176
  const normalizedDoc = buildTaskDocState({
121
- doc: task.doc ?? "",
177
+ doc: taskDoc,
122
178
  owner: p.owner,
123
- updatedBy: task.doc_updated_by,
179
+ updatedBy: p.owner,
124
180
  version: TASK_DOC_VERSION_V3,
125
- updatedAt: task.doc_updated_at,
181
+ updatedAt: createdAt,
182
+ });
183
+ const intakeContext = createTaskIntakeContext({
184
+ runtime: executionContext.taskIntake,
185
+ source: {
186
+ id: "task_new",
187
+ detail: "task new",
188
+ },
189
+ requested_outcome: p.title,
190
+ requested_owner: p.owner,
191
+ requested_tags: p.tags,
192
+ requested_verify: p.verify,
193
+ requested_dependencies: p.dependsOn,
194
+ inputs: [
195
+ {
196
+ kind: "text",
197
+ label: "description",
198
+ value: p.description,
199
+ required: true,
200
+ },
201
+ ],
202
+ });
203
+ const clarification = createClarificationContract({
204
+ context: intakeContext,
205
+ });
206
+ const draft = createTaskGraphDraft({
207
+ context: intakeContext,
208
+ clarification,
209
+ summary: p.title,
210
+ tasks: [
211
+ {
212
+ draft_id: "task_1",
213
+ title: p.title,
214
+ description: p.description,
215
+ owner: p.owner,
216
+ priority: p.priority,
217
+ origin: { system: "manual" },
218
+ tags: p.tags,
219
+ depends_on: p.dependsOn,
220
+ verify: p.verify,
221
+ doc: normalizedDoc.doc,
222
+ doc_version: normalizedDoc.doc_version,
223
+ id_source: "generated",
224
+ },
225
+ ],
226
+ });
227
+ const materialization = await materializeTaskGraphDraft({
228
+ draft,
229
+ task_ids: {
230
+ task_1: taskId,
231
+ },
232
+ created_at: createdAt,
126
233
  });
127
- task.doc = normalizedDoc.doc;
128
- task.sections = normalizedDoc.sections;
129
- task.doc_version = normalizedDoc.doc_version;
130
- task.doc_updated_at = normalizedDoc.doc_updated_at;
131
- task.doc_updated_by = normalizedDoc.doc_updated_by;
234
+ const task = materialization.tasks[0]?.task;
235
+ if (!task) {
236
+ throw new CliError({
237
+ exitCode: 3,
238
+ code: "E_VALIDATION",
239
+ message: "Task intake materialization unexpectedly produced no tasks.",
240
+ });
241
+ }
132
242
  await ctx.taskBackend.writeTask(task);
133
243
  process.stdout.write(`${taskId}\n`);
134
244
  return 0;
@@ -1 +1 @@
1
- {"version":3,"file":"new.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CA+ElD,CAAC"}
1
+ {"version":3,"file":"new.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAuFlD,CAAC"}
@@ -57,6 +57,12 @@ export const taskNewSpec = {
57
57
  repeatable: true,
58
58
  description: "Repeatable. Verification commands/checks to run for this task.",
59
59
  },
60
+ {
61
+ kind: "boolean",
62
+ name: "allow-duplicate",
63
+ default: false,
64
+ description: "Allow creating a task even when an open task with a highly similar title already exists.",
65
+ },
60
66
  ],
61
67
  examples: [
62
68
  {
@@ -76,5 +82,6 @@ export const taskNewSpec = {
76
82
  tags: (raw.opts.tag ?? []),
77
83
  dependsOn: (raw.opts["depends-on"] ?? []),
78
84
  verify: (raw.opts.verify ?? []),
85
+ allowDuplicate: raw.opts["allow-duplicate"] === true,
79
86
  }),
80
87
  };
@@ -5,6 +5,8 @@ export type TaskNormalizeParsed = {
5
5
  force: boolean;
6
6
  yes: boolean;
7
7
  syncHostedMerges: boolean;
8
+ syncBranchPrState: boolean;
9
+ taskIds: string[];
8
10
  };
9
11
  export declare const taskNormalizeSpec: CommandSpec<TaskNormalizeParsed>;
10
12
  export declare function makeRunTaskNormalizeHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskNormalizeParsed) => Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/normalize.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CA6C9D,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC5E,KAAK,UAAU,EAAE,GAAG,mBAAmB,KAAG,OAAO,CAAC,MAAM,CAAC,CAWxE"}
1
+ {"version":3,"file":"normalize.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/normalize.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CA2F9D,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC5E,KAAK,UAAU,EAAE,GAAG,mBAAmB,KAAG,OAAO,CAAC,MAAM,CAAC,CAaxE"}
@@ -1,3 +1,4 @@
1
+ import { usageError } from "../../cli/spec/errors.js";
1
2
  import { cmdTaskNormalize } from "./normalize.js";
2
3
  export const taskNormalizeSpec = {
3
4
  id: ["task", "normalize"],
@@ -28,6 +29,19 @@ export const taskNormalizeSpec = {
28
29
  default: false,
29
30
  description: "Query GitHub for merged hosted PRs referenced by local PR artifacts and reconcile stale branch_pr task state before normalization.",
30
31
  },
32
+ {
33
+ kind: "boolean",
34
+ name: "sync-branch-pr-state",
35
+ default: false,
36
+ description: "Reconcile stale local branch_pr task state when verified task commits already landed on the base branch.",
37
+ },
38
+ {
39
+ kind: "string",
40
+ name: "task-id",
41
+ valueHint: "<task-id>",
42
+ repeatable: true,
43
+ description: "Repeatable. Limit reconcile modes to explicit task ids instead of scanning every task.",
44
+ },
31
45
  ],
32
46
  examples: [
33
47
  { cmd: "agentplane task normalize", why: "Normalize tasks and print a short summary." },
@@ -36,12 +50,41 @@ export const taskNormalizeSpec = {
36
50
  cmd: "agentplane task normalize --sync-hosted-merges",
37
51
  why: "Reconcile stale branch_pr task state from hosted PR merges, then normalize the local projection.",
38
52
  },
53
+ {
54
+ cmd: "agentplane task normalize --sync-branch-pr-state",
55
+ why: "Reconcile locally shipped branch_pr task state when task commits already reached the base branch.",
56
+ },
57
+ {
58
+ cmd: "agentplane task normalize --sync-hosted-merges --task-id 202604071853-XGX2YJ",
59
+ why: "Reconcile only known stale tasks instead of scanning unrelated historical PR metadata.",
60
+ },
39
61
  ],
62
+ validateRaw: (raw) => {
63
+ const taskIds = raw.opts["task-id"] ?? [];
64
+ if (taskIds.length > 0 &&
65
+ raw.opts["sync-hosted-merges"] !== true &&
66
+ raw.opts["sync-branch-pr-state"] !== true) {
67
+ throw usageError({
68
+ spec: taskNormalizeSpec,
69
+ message: "--task-id requires --sync-hosted-merges and/or --sync-branch-pr-state.",
70
+ });
71
+ }
72
+ for (const taskId of taskIds) {
73
+ if (typeof taskId !== "string" || taskId.trim().length === 0) {
74
+ throw usageError({
75
+ spec: taskNormalizeSpec,
76
+ message: "Invalid value for --task-id: empty.",
77
+ });
78
+ }
79
+ }
80
+ },
40
81
  parse: (raw) => ({
41
82
  quiet: raw.opts.quiet === true,
42
83
  force: raw.opts.force === true,
43
84
  yes: raw.opts.yes === true,
44
85
  syncHostedMerges: raw.opts["sync-hosted-merges"] === true,
86
+ syncBranchPrState: raw.opts["sync-branch-pr-state"] === true,
87
+ taskIds: (raw.opts["task-id"] ?? []).map((taskId) => taskId.trim()),
45
88
  }),
46
89
  };
47
90
  export function makeRunTaskNormalizeHandler(getCtx) {
@@ -54,6 +97,8 @@ export function makeRunTaskNormalizeHandler(getCtx) {
54
97
  force: p.force,
55
98
  yes: p.yes,
56
99
  syncHostedMerges: p.syncHostedMerges,
100
+ syncBranchPrState: p.syncBranchPrState,
101
+ taskIds: p.taskIds,
57
102
  });
58
103
  };
59
104
  }
@@ -7,5 +7,7 @@ export declare function cmdTaskNormalize(opts: {
7
7
  force: boolean;
8
8
  yes?: boolean;
9
9
  syncHostedMerges?: boolean;
10
+ syncBranchPrState?: boolean;
11
+ taskIds?: string[];
10
12
  }): Promise<number>;
11
13
  //# sourceMappingURL=normalize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/task/normalize.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIpF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDlB"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/task/normalize.ts"],"names":[],"mappings":"AAKA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAgDpF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqGlB"}
@@ -1,13 +1,55 @@
1
1
  import { mapBackendError } from "../../cli/error-map.js";
2
2
  import { successMessage } from "../../cli/output.js";
3
+ import { CliError } from "../../shared/errors.js";
3
4
  import { ensureActionApproved } from "../shared/approval-requirements.js";
4
5
  import { loadCommandContext } from "../shared/task-backend.js";
5
6
  import { applyTaskCollectionMutation } from "../shared/task-mutation.js";
6
- import { syncHostedMergedTasks } from "./hosted-merge-sync.js";
7
+ import { collectTaskIncidents } from "../incidents/shared.js";
8
+ import { syncHostedMergedTasks, syncLocallyShippedBranchPrTasks } from "./hosted-merge-sync.js";
9
+ function dedupeTaskIds(taskIds) {
10
+ const seen = new Set();
11
+ const result = [];
12
+ for (const rawTaskId of taskIds) {
13
+ const taskId = rawTaskId.trim();
14
+ if (!taskId || seen.has(taskId))
15
+ continue;
16
+ seen.add(taskId);
17
+ result.push(taskId);
18
+ }
19
+ return result;
20
+ }
21
+ function selectTasksForNormalize(current, taskIds) {
22
+ if (taskIds.length === 0)
23
+ return current.map((task) => ({ ...task }));
24
+ const byId = new Map(current.map((task) => [task.id, task]));
25
+ const missing = [];
26
+ const selected = [];
27
+ for (const taskId of taskIds) {
28
+ const task = byId.get(taskId);
29
+ if (!task) {
30
+ missing.push(taskId);
31
+ continue;
32
+ }
33
+ selected.push({ ...task });
34
+ }
35
+ if (missing.length > 0) {
36
+ throw new CliError({
37
+ exitCode: 2,
38
+ code: "E_USAGE",
39
+ message: `Unknown task${missing.length === 1 ? "" : "s"}: ${missing.join(", ")}`,
40
+ });
41
+ }
42
+ return selected;
43
+ }
44
+ function diffTasksToWrite(current, next) {
45
+ const previousById = new Map(current.map((task) => [task.id, JSON.stringify(task)]));
46
+ return next.filter((task) => previousById.get(task.id) !== JSON.stringify(task));
47
+ }
7
48
  export async function cmdTaskNormalize(opts) {
8
49
  try {
9
50
  const ctx = opts.ctx ??
10
51
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
52
+ const selectedTaskIds = dedupeTaskIds(opts.taskIds ?? []);
11
53
  if (opts.force) {
12
54
  await ensureActionApproved({
13
55
  action: "force_action",
@@ -16,7 +58,9 @@ export async function cmdTaskNormalize(opts) {
16
58
  reason: "task normalize --force",
17
59
  });
18
60
  }
19
- if (ctx.taskBackend.normalizeTasks && opts.syncHostedMerges !== true) {
61
+ if (ctx.taskBackend.normalizeTasks &&
62
+ opts.syncHostedMerges !== true &&
63
+ opts.syncBranchPrState !== true) {
20
64
  const result = await ctx.taskBackend.normalizeTasks();
21
65
  if (!opts.quiet) {
22
66
  process.stdout.write(`${successMessage("normalized tasks", undefined, `scanned=${result.scanned} changed=${result.changed}`)}\n`);
@@ -24,24 +68,57 @@ export async function cmdTaskNormalize(opts) {
24
68
  return 0;
25
69
  }
26
70
  let syncedHostedMerges = 0;
71
+ let syncedBranchPrState = 0;
72
+ let promotedIncidents = 0;
73
+ const passThroughNormalizeWrite = opts.syncHostedMerges !== true && opts.syncBranchPrState !== true;
27
74
  const { result, tasksToWrite } = await applyTaskCollectionMutation({
28
75
  ctx,
29
76
  build: async (tasks) => {
30
- let nextTasks = tasks;
77
+ const scopedTasks = selectTasksForNormalize(tasks, selectedTaskIds);
78
+ let nextTasks = scopedTasks;
31
79
  if (opts.syncHostedMerges === true) {
32
- const synced = await syncHostedMergedTasks({ ctx, tasks });
80
+ const synced = await syncHostedMergedTasks({ ctx, tasks: nextTasks });
33
81
  nextTasks = synced.tasks;
34
82
  syncedHostedMerges = synced.synced;
35
83
  }
84
+ if (opts.syncBranchPrState === true) {
85
+ const synced = await syncLocallyShippedBranchPrTasks({ ctx, tasks: nextTasks });
86
+ nextTasks = synced.tasks;
87
+ syncedBranchPrState = synced.synced;
88
+ }
89
+ const nextTasksToWrite = passThroughNormalizeWrite
90
+ ? nextTasks
91
+ : diffTasksToWrite(scopedTasks, nextTasks);
92
+ const incidentCandidates = opts.syncHostedMerges === true || opts.syncBranchPrState === true
93
+ ? nextTasksToWrite.filter((task) => String(task.status || "TODO").toUpperCase() === "DONE")
94
+ : [];
95
+ for (const task of incidentCandidates) {
96
+ await collectTaskIncidents({
97
+ ctx,
98
+ taskId: task.id,
99
+ task,
100
+ write: false,
101
+ });
102
+ }
36
103
  return {
37
- result: null,
38
- tasksToWrite: nextTasks,
104
+ result: { incidentCandidates },
105
+ tasksToWrite: nextTasksToWrite,
39
106
  };
40
107
  },
41
108
  });
42
- void result;
109
+ for (const task of result.incidentCandidates) {
110
+ const collected = await collectTaskIncidents({
111
+ ctx,
112
+ taskId: task.id,
113
+ task,
114
+ write: true,
115
+ });
116
+ promotedIncidents += collected.plan.promotable.length;
117
+ }
43
118
  if (!opts.quiet) {
44
- process.stdout.write(`${successMessage("normalized tasks", undefined, `count=${tasksToWrite.length}${opts.syncHostedMerges === true ? ` synced_hosted_merges=${syncedHostedMerges}` : ""}`)}\n`);
119
+ process.stdout.write(`${successMessage("normalized tasks", undefined, `count=${tasksToWrite.length}${opts.syncHostedMerges === true ? ` synced_hosted_merges=${syncedHostedMerges}` : ""}${opts.syncBranchPrState === true ? ` synced_branch_pr_state=${syncedBranchPrState}` : ""}${opts.syncHostedMerges === true || opts.syncBranchPrState === true
120
+ ? ` promoted_incidents=${promotedIncidents}`
121
+ : ""}`)}\n`);
45
122
  }
46
123
  return 0;
47
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AA8InC,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuHlB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAgElB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAuElB"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AA0InC,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuHlB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAgElB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAuElB"}
@@ -7,7 +7,7 @@ import { CliError } from "../../shared/errors.js";
7
7
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
8
8
  import { applyTaskMutation, withTaskMutationStorage } from "../shared/task-mutation.js";
9
9
  import { setTaskFieldsIntent, setTaskSectionIntent, touchTaskDocMetaIntent, } from "../shared/task-store.js";
10
- import { decodeEscapedTaskTextNewlines, ensureAgentFilledRequiredDocSections, extractDocSection, extractTaskObservationSection, isVerifyStepsFilled, nowIso, normalizeTaskDocVersion, taskObservationSectionName, requiresVerifyStepsByPrimary, toStringArray, } from "./shared.js";
10
+ import { assertVerifyStepsFilled, decodeEscapedTaskTextNewlines, ensureAgentFilledRequiredDocSections, extractDocSection, extractTaskObservationSection, nowIso, normalizeTaskDocVersion, taskObservationSectionName, requiresVerifyStepsByPrimary, toStringArray, } from "./shared.js";
11
11
  async function loadPlanBackend(opts) {
12
12
  const ctx = opts.ctx ??
13
13
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
@@ -63,15 +63,12 @@ function assertPlanCanBeApproved(opts) {
63
63
  const verifyRequired = requiresVerifyStepsByPrimary(tags, opts.config);
64
64
  const isSpike = tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
65
65
  if (verifyRequired || isSpike) {
66
- const verifySteps = extractDocSection(opts.doc, "Verify Steps");
67
- if (!isVerifyStepsFilled(verifySteps)) {
68
- throw new CliError({
69
- exitCode: 3,
70
- code: "E_VALIDATION",
71
- message: `${opts.task.id}: cannot approve plan: ## Verify Steps section is missing/empty/unfilled ` +
72
- "(fill it before approving plan)",
73
- });
74
- }
66
+ assertVerifyStepsFilled({
67
+ taskId: opts.task.id,
68
+ sectionText: extractDocSection(opts.doc, "Verify Steps"),
69
+ action: "approve plan",
70
+ guidance: "fill it before approving plan",
71
+ });
75
72
  }
76
73
  if (!isSpike)
77
74
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAYnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmHlB"}
1
+ {"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAYnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoHlB"}
@@ -50,6 +50,7 @@ export async function cmdTaskSetStatus(opts) {
50
50
  ctx,
51
51
  taskId: opts.taskId,
52
52
  quiet: opts.quiet,
53
+ policyAction: "task_set_status",
53
54
  build: (current) => {
54
55
  const currentEventAuthor = resolveDocUpdatedBy(current, opts.author);
55
56
  return {
@@ -8,6 +8,12 @@ export type TaskDocVersion = 2 | 3;
8
8
  export declare function decodeEscapedTaskTextNewlines(text: string): string;
9
9
  export declare function extractDocSection(doc: string, sectionName: string): string | null;
10
10
  export declare function isVerifyStepsFilled(sectionText: string | null): boolean;
11
+ export declare function assertVerifyStepsFilled(opts: {
12
+ taskId: string;
13
+ sectionText: string | null;
14
+ action: string;
15
+ guidance?: string;
16
+ }): void;
11
17
  export declare function normalizeTaskDocVersion(value: unknown, fallback?: TaskDocVersion): TaskDocVersion;
12
18
  export declare function normalizeVerificationSectionLayout(sectionText: string | null, version: TaskDocVersion): string;
13
19
  export declare function taskObservationSectionName(version: TaskDocVersion): "Notes" | "Findings";
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../../src/commands/task/shared/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIrF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAElE,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,eAAO,MAAM,wBAAwB,+DACyB,CAAC;AAC/D,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AAChF,eAAO,MAAM,wBAAwB,sCAAsC,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,CAAC;AAEnC,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjF;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAKvE;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,cAAkB,GAC3B,cAAc,CAEhB;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,EAAE,cAAc,GACtB,MAAM,CAyCR;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,GAAG,UAAU,CAExF;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAIjG;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,EAAE,CAaX;AAMD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAKtE;AAED,wBAAgB,oCAAoC,CAAC,IAAI,EAAE;IACzD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CA6BP"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../../src/commands/task/shared/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIrF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAElE,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,eAAO,MAAM,wBAAwB,+DACyB,CAAC;AAC/D,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AAChF,eAAO,MAAM,wBAAwB,sCAAsC,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,CAAC;AAGnC,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjF;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAMvE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAUP;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,cAAkB,GAC3B,cAAc,CAEhB;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,EAAE,cAAc,GACtB,MAAM,CAyCR;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,GAAG,UAAU,CAExF;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAIjG;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,EAAE,CAaX;AAMD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAKtE;AAED,wBAAgB,oCAAoC,CAAC,IAAI,EAAE;IACzD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CA6BP"}
@@ -7,6 +7,7 @@ export function nowIso() {
7
7
  export const VERIFY_STEPS_PLACEHOLDER = "<!-- TODO: REPLACE WITH TASK-SPECIFIC ACCEPTANCE STEPS -->";
8
8
  export const VERIFICATION_RESULTS_BEGIN = "<!-- BEGIN VERIFICATION RESULTS -->";
9
9
  export const VERIFICATION_RESULTS_END = "<!-- END VERIFICATION RESULTS -->";
10
+ const VERIFY_STEPS_TEMPLATE_LINE_RE = /^\d+\.\s*<[^>\n]+>\.\s*Expected:\s*<[^>\n]+>\.?$/m;
10
11
  export function decodeEscapedTaskTextNewlines(text) {
11
12
  const normalized = text.replaceAll("\r\n", "\n");
12
13
  if (!normalized.includes(String.raw `\n`) && !normalized.includes(String.raw `\r\n`)) {
@@ -39,8 +40,21 @@ export function isVerifyStepsFilled(sectionText) {
39
40
  return false;
40
41
  if (normalized.includes(VERIFY_STEPS_PLACEHOLDER))
41
42
  return false;
43
+ if (VERIFY_STEPS_TEMPLATE_LINE_RE.test(normalized))
44
+ return false;
42
45
  return true;
43
46
  }
47
+ export function assertVerifyStepsFilled(opts) {
48
+ if (isVerifyStepsFilled(opts.sectionText))
49
+ return;
50
+ const guidance = opts.guidance ? ` (${opts.guidance})` : "";
51
+ throw new CliError({
52
+ exitCode: 3,
53
+ code: "E_VALIDATION",
54
+ message: `${opts.taskId}: cannot ${opts.action}: ## Verify Steps section is missing/empty/unfilled` +
55
+ guidance,
56
+ });
57
+ }
44
58
  export function normalizeTaskDocVersion(value, fallback = 3) {
45
59
  return value === 3 ? 3 : value === 2 ? 2 : fallback;
46
60
  }
@@ -1,4 +1,5 @@
1
1
  import type { TaskData } from "../../../backends/task-backend.js";
2
+ import type { PolicyActionId } from "../../../policy/taxonomy.js";
2
3
  import type { CommandContext } from "../../shared/task-backend.js";
3
4
  import { type ExecuteTaskStatusTransitionRequest, type TaskStatusTransitionExecution } from "./workflow-transition-service.js";
4
5
  type TaskStatusTransitionCommandRequest = Omit<ExecuteTaskStatusTransitionRequest, "task" | "backend" | "config">;
@@ -6,6 +7,7 @@ export declare function applyTaskStatusTransitionCommand(opts: {
6
7
  ctx: CommandContext;
7
8
  taskId: string;
8
9
  quiet: boolean;
10
+ policyAction?: PolicyActionId;
9
11
  build: (current: TaskData) => TaskStatusTransitionCommandRequest | Promise<TaskStatusTransitionCommandRequest>;
10
12
  }): Promise<{
11
13
  execution: TaskStatusTransitionExecution;
@@ -1 +1 @@
1
- {"version":3,"file":"transition-command.d.ts","sourceRoot":"","sources":["../../../../src/commands/task/shared/transition-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAGlE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,EAGL,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EACnC,MAAM,kCAAkC,CAAC;AAE1C,KAAK,kCAAkC,GAAG,IAAI,CAC5C,kCAAkC,EAClC,MAAM,GAAG,SAAS,GAAG,QAAQ,CAC9B,CAAC;AAEF,wBAAsB,gCAAgC,CAAC,IAAI,EAAE;IAC3D,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,CACL,OAAO,EAAE,QAAQ,KACd,kCAAkC,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;CACvF,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,6BAA6B,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAwCD"}
1
+ {"version":3,"file":"transition-command.d.ts","sourceRoot":"","sources":["../../../../src/commands/task/shared/transition-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,EAGL,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EACnC,MAAM,kCAAkC,CAAC;AAE1C,KAAK,kCAAkC,GAAG,IAAI,CAC5C,kCAAkC,EAClC,MAAM,GAAG,SAAS,GAAG,QAAQ,CAC9B,CAAC;AAEF,wBAAsB,gCAAgC,CAAC,IAAI,EAAE;IAC3D,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,KAAK,EAAE,CACL,OAAO,EAAE,QAAQ,KACd,kCAAkC,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;CACvF,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,6BAA6B,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAyCD"}
@@ -11,6 +11,7 @@ export async function applyTaskStatusTransitionCommand(opts) {
11
11
  await applyTaskMutation({
12
12
  ctx: opts.ctx,
13
13
  taskId: opts.taskId,
14
+ policyAction: opts.policyAction ?? "task_status_transition",
14
15
  build: async (current) => {
15
16
  const request = await opts.build(current);
16
17
  execution = await executeTaskStatusTransitionRequest({