agentplane 0.3.10 → 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 (228) hide show
  1. package/assets/policy/governance.md +3 -4
  2. package/assets/policy/incidents.md +19 -88
  3. package/assets/policy/workflow.branch_pr.md +1 -1
  4. package/assets/policy/workflow.direct.md +2 -2
  5. package/bin/agentplane.js +56 -1
  6. package/bin/runtime-watch.js +1 -0
  7. package/bin/stale-dist-policy.d.ts +1 -1
  8. package/bin/stale-dist-policy.js +13 -0
  9. package/dist/.build-manifest.json +219 -154
  10. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  11. package/dist/cli/bootstrap-guide.js +3 -2
  12. package/dist/cli/command-guide.d.ts.map +1 -1
  13. package/dist/cli/command-guide.js +2 -1
  14. package/dist/cli/command-invocations.d.ts.map +1 -1
  15. package/dist/cli/command-invocations.js +4 -1
  16. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  17. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  18. package/dist/cli/run-cli/command-catalog/project.js +3 -1
  19. package/dist/cli/run-cli/command-catalog/task.d.ts +1 -1
  20. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -1
  21. package/dist/cli/run-cli/command-catalog/task.js +10 -0
  22. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  23. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  24. package/dist/cli/run-cli/commands/core/preflight.d.ts.map +1 -1
  25. package/dist/cli/run-cli/commands/core/preflight.js +44 -1
  26. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  27. package/dist/cli/run-cli.test-helpers.js +12 -0
  28. package/dist/commands/branch/cleanup-merged.d.ts +2 -0
  29. package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
  30. package/dist/commands/branch/cleanup-merged.js +132 -28
  31. package/dist/commands/branch/work-start.d.ts.map +1 -1
  32. package/dist/commands/branch/work-start.js +60 -1
  33. package/dist/commands/cleanup/merged.command.d.ts +2 -0
  34. package/dist/commands/cleanup/merged.command.d.ts.map +1 -1
  35. package/dist/commands/cleanup/merged.command.js +24 -0
  36. package/dist/commands/doctor/branch-pr.d.ts +4 -0
  37. package/dist/commands/doctor/branch-pr.d.ts.map +1 -0
  38. package/dist/commands/doctor/branch-pr.js +96 -0
  39. package/dist/commands/doctor/fixes.d.ts +5 -0
  40. package/dist/commands/doctor/fixes.d.ts.map +1 -1
  41. package/dist/commands/doctor/fixes.js +70 -0
  42. package/dist/commands/doctor.run.d.ts.map +1 -1
  43. package/dist/commands/doctor.run.js +6 -1
  44. package/dist/commands/finish.run.d.ts.map +1 -1
  45. package/dist/commands/finish.run.js +11 -0
  46. package/dist/commands/finish.spec.d.ts +11 -0
  47. package/dist/commands/finish.spec.d.ts.map +1 -1
  48. package/dist/commands/finish.spec.js +51 -0
  49. package/dist/commands/guard/impl/close-message.d.ts.map +1 -1
  50. package/dist/commands/guard/impl/close-message.js +23 -6
  51. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  52. package/dist/commands/guard/impl/commands.js +24 -2
  53. package/dist/commands/guard/impl/env.d.ts +1 -0
  54. package/dist/commands/guard/impl/env.d.ts.map +1 -1
  55. package/dist/commands/guard/impl/env.js +1 -0
  56. package/dist/commands/hooks/index.d.ts.map +1 -1
  57. package/dist/commands/hooks/index.js +98 -1
  58. package/dist/commands/incidents/collect.command.d.ts.map +1 -1
  59. package/dist/commands/incidents/collect.command.js +12 -7
  60. package/dist/commands/incidents/incidents.command.js +1 -1
  61. package/dist/commands/incidents/shared.d.ts +34 -0
  62. package/dist/commands/incidents/shared.d.ts.map +1 -1
  63. package/dist/commands/incidents/shared.js +166 -12
  64. package/dist/commands/pr/check.d.ts.map +1 -1
  65. package/dist/commands/pr/check.js +238 -135
  66. package/dist/commands/pr/close-superseded.d.ts +9 -0
  67. package/dist/commands/pr/close-superseded.d.ts.map +1 -0
  68. package/dist/commands/pr/close-superseded.js +129 -0
  69. package/dist/commands/pr/close.d.ts +11 -0
  70. package/dist/commands/pr/close.d.ts.map +1 -0
  71. package/dist/commands/pr/close.js +116 -0
  72. package/dist/commands/pr/index.d.ts +2 -0
  73. package/dist/commands/pr/index.d.ts.map +1 -1
  74. package/dist/commands/pr/index.js +2 -0
  75. package/dist/commands/pr/integrate/artifacts.d.ts +7 -0
  76. package/dist/commands/pr/integrate/artifacts.d.ts.map +1 -1
  77. package/dist/commands/pr/integrate/artifacts.js +66 -1
  78. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  79. package/dist/commands/pr/integrate/cmd.js +16 -0
  80. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts +8 -0
  81. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts.map +1 -0
  82. package/dist/commands/pr/integrate/internal/bootstrap-guidance.js +59 -0
  83. package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
  84. package/dist/commands/pr/integrate/internal/finalize.js +40 -12
  85. package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
  86. package/dist/commands/pr/integrate/internal/merge.js +36 -13
  87. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts +13 -0
  88. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts.map +1 -0
  89. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.js +25 -0
  90. package/dist/commands/pr/integrate/internal/prepare.d.ts +3 -2
  91. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  92. package/dist/commands/pr/integrate/internal/prepare.js +101 -38
  93. package/dist/commands/pr/internal/freshness.d.ts +20 -0
  94. package/dist/commands/pr/internal/freshness.d.ts.map +1 -0
  95. package/dist/commands/pr/internal/freshness.js +50 -0
  96. package/dist/commands/pr/internal/gh-api.d.ts +6 -0
  97. package/dist/commands/pr/internal/gh-api.d.ts.map +1 -0
  98. package/dist/commands/pr/internal/gh-api.js +80 -0
  99. package/dist/commands/pr/internal/pr-paths.d.ts +10 -0
  100. package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
  101. package/dist/commands/pr/internal/pr-paths.js +10 -0
  102. package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
  103. package/dist/commands/pr/internal/review-template.js +37 -4
  104. package/dist/commands/pr/internal/sync.d.ts +9 -0
  105. package/dist/commands/pr/internal/sync.d.ts.map +1 -1
  106. package/dist/commands/pr/internal/sync.js +462 -122
  107. package/dist/commands/pr/open.d.ts +1 -0
  108. package/dist/commands/pr/open.d.ts.map +1 -1
  109. package/dist/commands/pr/open.js +13 -2
  110. package/dist/commands/pr/pr.command.d.ts +15 -0
  111. package/dist/commands/pr/pr.command.d.ts.map +1 -1
  112. package/dist/commands/pr/pr.command.js +118 -2
  113. package/dist/commands/pr/update.d.ts.map +1 -1
  114. package/dist/commands/pr/update.js +59 -1
  115. package/dist/commands/release/apply.command.d.ts.map +1 -1
  116. package/dist/commands/release/apply.command.js +3 -17
  117. package/dist/commands/release/apply.preflight.d.ts.map +1 -1
  118. package/dist/commands/release/apply.preflight.js +1 -1
  119. package/dist/commands/shared/gh-transport.d.ts +16 -0
  120. package/dist/commands/shared/gh-transport.d.ts.map +1 -0
  121. package/dist/commands/shared/gh-transport.js +71 -0
  122. package/dist/commands/shared/git-diff.d.ts +3 -1
  123. package/dist/commands/shared/git-diff.d.ts.map +1 -1
  124. package/dist/commands/shared/git-diff.js +10 -2
  125. package/dist/commands/shared/git-ops.d.ts +1 -0
  126. package/dist/commands/shared/git-ops.d.ts.map +1 -1
  127. package/dist/commands/shared/git-ops.js +15 -0
  128. package/dist/commands/shared/git-worktree.d.ts +2 -0
  129. package/dist/commands/shared/git-worktree.d.ts.map +1 -1
  130. package/dist/commands/shared/git-worktree.js +22 -2
  131. package/dist/commands/shared/post-commit-pr-artifacts.d.ts +9 -0
  132. package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -0
  133. package/dist/commands/shared/post-commit-pr-artifacts.js +22 -0
  134. package/dist/commands/shared/pr-meta.d.ts +20 -0
  135. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  136. package/dist/commands/shared/pr-meta.js +125 -0
  137. package/dist/commands/shared/task-backend.d.ts +7 -0
  138. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  139. package/dist/commands/shared/task-backend.js +34 -22
  140. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  141. package/dist/commands/task/close-duplicate.js +34 -1
  142. package/dist/commands/task/derive.js +1 -1
  143. package/dist/commands/task/doc-template.d.ts.map +1 -1
  144. package/dist/commands/task/doc-template.js +7 -11
  145. package/dist/commands/task/findings-add.command.d.ts +20 -0
  146. package/dist/commands/task/findings-add.command.d.ts.map +1 -0
  147. package/dist/commands/task/findings-add.command.js +165 -0
  148. package/dist/commands/task/findings.command.d.ts +7 -0
  149. package/dist/commands/task/findings.command.d.ts.map +1 -0
  150. package/dist/commands/task/findings.command.js +20 -0
  151. package/dist/commands/task/findings.d.ts +63 -0
  152. package/dist/commands/task/findings.d.ts.map +1 -0
  153. package/dist/commands/task/findings.js +188 -0
  154. package/dist/commands/task/finish-shared.d.ts +1 -0
  155. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  156. package/dist/commands/task/finish-shared.js +55 -1
  157. package/dist/commands/task/finish.d.ts +10 -0
  158. package/dist/commands/task/finish.d.ts.map +1 -1
  159. package/dist/commands/task/finish.js +125 -6
  160. package/dist/commands/task/hosted-close-pr.command.d.ts +11 -0
  161. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -0
  162. package/dist/commands/task/hosted-close-pr.command.js +414 -0
  163. package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
  164. package/dist/commands/task/hosted-close.command.js +49 -1
  165. package/dist/commands/task/hosted-merge-sync.d.ts +38 -0
  166. package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
  167. package/dist/commands/task/hosted-merge-sync.js +249 -17
  168. package/dist/commands/task/index.d.ts +1 -0
  169. package/dist/commands/task/index.d.ts.map +1 -1
  170. package/dist/commands/task/index.js +1 -0
  171. package/dist/commands/task/new.d.ts +1 -0
  172. package/dist/commands/task/new.d.ts.map +1 -1
  173. package/dist/commands/task/new.js +71 -1
  174. package/dist/commands/task/new.spec.d.ts.map +1 -1
  175. package/dist/commands/task/new.spec.js +7 -0
  176. package/dist/commands/task/normalize.command.d.ts +2 -0
  177. package/dist/commands/task/normalize.command.d.ts.map +1 -1
  178. package/dist/commands/task/normalize.command.js +45 -0
  179. package/dist/commands/task/normalize.d.ts +2 -0
  180. package/dist/commands/task/normalize.d.ts.map +1 -1
  181. package/dist/commands/task/normalize.js +85 -8
  182. package/dist/commands/task/plan.d.ts.map +1 -1
  183. package/dist/commands/task/plan.js +7 -10
  184. package/dist/commands/task/shared/docs.d.ts +6 -0
  185. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  186. package/dist/commands/task/shared/docs.js +14 -0
  187. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  188. package/dist/commands/task/shared/transitions.js +11 -1
  189. package/dist/commands/task/shared.d.ts +1 -1
  190. package/dist/commands/task/shared.d.ts.map +1 -1
  191. package/dist/commands/task/shared.js +1 -1
  192. package/dist/commands/task/start-ready.d.ts.map +1 -1
  193. package/dist/commands/task/start-ready.js +86 -0
  194. package/dist/commands/task/start.d.ts.map +1 -1
  195. package/dist/commands/task/start.js +7 -10
  196. package/dist/commands/task/task.command.d.ts.map +1 -1
  197. package/dist/commands/task/task.command.js +4 -0
  198. package/dist/commands/task/verify-command-shared.d.ts +19 -0
  199. package/dist/commands/task/verify-command-shared.d.ts.map +1 -1
  200. package/dist/commands/task/verify-command-shared.js +152 -1
  201. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  202. package/dist/commands/task/verify-ok.command.js +15 -2
  203. package/dist/commands/task/verify-record.d.ts +36 -0
  204. package/dist/commands/task/verify-record.d.ts.map +1 -1
  205. package/dist/commands/task/verify-record.js +166 -11
  206. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  207. package/dist/commands/task/verify-rework.command.js +15 -2
  208. package/dist/commands/task/verify-show.command.d.ts +1 -1
  209. package/dist/commands/task/verify-show.command.d.ts.map +1 -1
  210. package/dist/commands/task/verify-show.command.js +28 -1
  211. package/dist/commands/verify.run.d.ts.map +1 -1
  212. package/dist/commands/verify.run.js +12 -0
  213. package/dist/commands/verify.spec.d.ts +2 -6
  214. package/dist/commands/verify.spec.d.ts.map +1 -1
  215. package/dist/commands/verify.spec.js +30 -3
  216. package/dist/runtime/incidents/index.d.ts +1 -1
  217. package/dist/runtime/incidents/index.d.ts.map +1 -1
  218. package/dist/runtime/incidents/resolve.d.ts.map +1 -1
  219. package/dist/runtime/incidents/resolve.js +319 -73
  220. package/dist/runtime/incidents/types.d.ts +14 -2
  221. package/dist/runtime/incidents/types.d.ts.map +1 -1
  222. package/dist/shared/env.d.ts +1 -0
  223. package/dist/shared/env.d.ts.map +1 -1
  224. package/dist/shared/env.js +22 -1
  225. package/dist/shared/protected-paths.d.ts +1 -1
  226. package/dist/shared/protected-paths.d.ts.map +1 -1
  227. package/dist/shared/protected-paths.js +4 -0
  228. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-guide.d.ts","sourceRoot":"","sources":["../../src/cli/bootstrap-guide.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,4CAA4C,CAAC;AAClF,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,4BAA4B,iHAM/B,CAAC;AAEX,eAAO,MAAM,4BAA4B,UAIxC,CAAC;AAEF,eAAO,MAAM,oCAAoC,4JAMvC,CAAC;AAEX,eAAO,MAAM,+BAA+B,0HAOlC,CAAC;AAEX,eAAO,MAAM,2BAA2B,sFAI9B,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EA+ChD,CAAC;AAEX,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAiB3F;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CA2B3C"}
1
+ {"version":3,"file":"bootstrap-guide.d.ts","sourceRoot":"","sources":["../../src/cli/bootstrap-guide.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,4CAA4C,CAAC;AAClF,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,4BAA4B,iHAM/B,CAAC;AAEX,eAAO,MAAM,4BAA4B,UAIxC,CAAC;AAEF,eAAO,MAAM,oCAAoC,4JAMvC,CAAC;AAEX,eAAO,MAAM,+BAA+B,0HAOlC,CAAC;AAEX,eAAO,MAAM,2BAA2B,sFAI9B,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAgDhD,CAAC;AAEX,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAiB3F;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CA2B3C"}
@@ -58,11 +58,12 @@ export const BOOTSTRAP_SECTIONS = [
58
58
  },
59
59
  {
60
60
  heading: "3. Verification and incident reuse",
61
- summary: "Reuse historical incident advice only through targeted lookup, and validate promotable external incident candidates before `finish`.",
61
+ summary: "Reuse historical incident advice only through targeted lookup, and validate promotable resolved external findings before `finish`.",
62
62
  commands: BOOTSTRAP_VERIFICATION_COMMANDS,
63
63
  notes: [
64
64
  "Use `agentplane incidents advise <task-id>` after `start-ready` when analogous scope or tags might have prior external failure modes.",
65
- "Use `agentplane incidents collect <task-id> --check` before `finish` when task `Findings` contains reusable external `incident-candidate` blocks.",
65
+ 'Use `agentplane task findings add <task-id> --observation "..." --impact "..." --resolution "..."` to append reusable structured Findings blocks without replacing the whole README; promotion is the default unless you pass `--local-only`.',
66
+ "Use `agentplane incidents collect <task-id> --check` before `finish` when task `Findings` contains reusable external `Observation` / `Impact` / `Resolution` blocks. Plain prose in `Findings` stays task-local and does not update `.agentplane/policy/incidents.md`.",
66
67
  "Keep repository-fixable defects task-local; only external or process incidents belong in `.agentplane/policy/incidents.md`.",
67
68
  ],
68
69
  },
@@ -1 +1 @@
1
- {"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAoGF,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMvE;AAMD,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAO,GAC/C,MAAM,GAAG,IAAI,CA6Bf;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAqCzC"}
1
+ {"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAqGF,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMvE;AAMD,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAO,GAC/C,MAAM,GAAG,IAAI,CA6Bf;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAqCzC"}
@@ -20,6 +20,7 @@ const ROLE_GUIDES = [
20
20
  SHARED_STARTUP_NOTE,
21
21
  '- Create executable tasks with `agentplane task new --title "..." --description "..." --priority med --owner <ROLE> --tag <tag>`.',
22
22
  '- Fill docs with `agentplane task doc set <task-id> --section <name> --text "..."` and set plan text with `agentplane task plan set <task-id> --text "..." --updated-by <ROLE>`.',
23
+ '- Append reusable incident-ready Findings via `agentplane task findings add <task-id> --observation "..." --impact "..." --resolution "..."`; promotion is the default unless `--local-only` is set.',
23
24
  "- Approve plan only after required sections and Verify Steps are ready.",
24
25
  ],
25
26
  },
@@ -48,7 +49,7 @@ const ROLE_GUIDES = [
48
49
  role: "DOCS",
49
50
  lines: [
50
51
  SHARED_STARTUP_NOTE,
51
- '- Keep task docs and user docs aligned with runtime behavior via `agentplane task doc set <task-id> --section <name> --text "..."`.',
52
+ '- Keep task docs and user docs aligned with runtime behavior via `agentplane task doc set <task-id> --section <name> --text "..."`; use `task findings add` for append-only incident-ready Findings blocks.',
52
53
  "- For implementation tasks, verify generated/help surfaces after changing CLI-facing text.",
53
54
  "- The docs site may expand CLI behavior, but installed runtime guidance must stay self-contained and must not depend on repo-only docs paths.",
54
55
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"command-invocations.d.ts","sourceRoot":"","sources":["../../src/cli/command-invocations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA+BhD,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAE1E;AAED,wBAAgB,iCAAiC,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAMvE"}
1
+ {"version":3,"file":"command-invocations.d.ts","sourceRoot":"","sources":["../../src/cli/command-invocations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAkChD,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAE1E;AAED,wBAAgB,iCAAiC,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAMvE"}
@@ -20,7 +20,10 @@ const COMMAND_INVOCATIONS = new Map([
20
20
  ["task show", "agentplane task show <task-id>"],
21
21
  ["task start-ready", 'agentplane task start-ready <task-id> --author <ROLE> --body "Start: ..."'],
22
22
  ["task verify-show", "agentplane task verify-show <task-id>"],
23
- ["verify", 'agentplane verify <task-id> --ok|--rework --by <ROLE> --note "..."'],
23
+ [
24
+ "verify",
25
+ 'agentplane verify <task-id> --ok|--rework --by <ROLE> --note "..." [--observation "..." --impact "..." --resolution "..."] [--local-only]',
26
+ ],
24
27
  ]);
25
28
  function formatCommandId(id) {
26
29
  return id.join(" ");
@@ -1,3 +1,3 @@
1
1
  import { type CommandEntry } from "./shared.js";
2
- export declare const PROJECT_COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
2
+ export declare const PROJECT_COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
3
3
  //# sourceMappingURL=project.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/command-catalog/project.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,gBAAgB,ydAsJe,CAAC"}
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/command-catalog/project.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,gBAAgB,qfA8Je,CAAC"}
@@ -5,7 +5,7 @@ import { branchRemoveSpec } from "../../../commands/branch/remove.command.js";
5
5
  import { branchStatusSpec } from "../../../commands/branch/status.command.js";
6
6
  import { workStartSpec } from "../../../commands/branch/work-start.command.js";
7
7
  import { integrateSpec } from "../../../commands/integrate.command.js";
8
- import { prCheckSpec, prNoteSpec, prOpenSpec, prSpec, prUpdateSpec, } from "../../../commands/pr/pr.command.js";
8
+ import { prCheckSpec, prCloseSpec, prCloseSupersededSpec, prNoteSpec, prOpenSpec, prSpec, prUpdateSpec, } from "../../../commands/pr/pr.command.js";
9
9
  import { recipesCachePruneSpec } from "../../../commands/recipes/cache-prune.command.js";
10
10
  import { recipesCacheSpec } from "../../../commands/recipes/cache.command.js";
11
11
  import { recipesExplainSpec } from "../../../commands/recipes/explain.command.js";
@@ -77,6 +77,8 @@ export const PROJECT_COMMANDS = [
77
77
  entry(prOpenSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrOpenHandler(deps.getCtx))),
78
78
  entry(prUpdateSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrUpdateHandler(deps.getCtx))),
79
79
  entry(prCheckSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrCheckHandler(deps.getCtx))),
80
+ entry(prCloseSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrCloseHandler(deps.getCtx))),
81
+ entry(prCloseSupersededSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrCloseSupersededHandler(deps.getCtx))),
80
82
  entry(prNoteSpec, (deps) => import("../../../commands/pr/pr.command.js").then((m) => m.makeRunPrNoteHandler(deps.getCtx))),
81
83
  entry(integrateSpec, (deps) => import("../../../commands/integrate.command.js").then((m) => m.makeRunIntegrateHandler(deps.getCtx))),
82
84
  ];
@@ -1,3 +1,3 @@
1
1
  import { type CommandEntry } from "./shared.js";
2
- export declare const TASK_COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
2
+ export declare const TASK_COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
3
3
  //# sourceMappingURL=task.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/command-catalog/task.ts"],"names":[],"mappings":"AAgDA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,aAAa,+oBAoPkB,CAAC"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/command-catalog/task.ts"],"names":[],"mappings":"AAmDA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,aAAa,yrBAuQkB,CAAC"}
@@ -3,6 +3,8 @@ import { taskCloseDuplicateSpec } from "../../../commands/task/close-duplicate.c
3
3
  import { taskCloseNoopSpec } from "../../../commands/task/close-noop.command.js";
4
4
  import { taskCommentSpec } from "../../../commands/task/comment.command.js";
5
5
  import { taskDeriveSpec } from "../../../commands/task/derive.command.js";
6
+ import { taskFindingsAddSpec } from "../../../commands/task/findings-add.command.js";
7
+ import { taskFindingsSpec } from "../../../commands/task/findings.command.js";
6
8
  import { taskDocSetSpec } from "../../../commands/task/doc-set.command.js";
7
9
  import { taskDocShowSpec } from "../../../commands/task/doc-show.command.js";
8
10
  import { taskDocSpec } from "../../../commands/task/doc.command.js";
@@ -11,6 +13,7 @@ import { taskHandoffRecordSpec } from "../../../commands/task/handoff-record.com
11
13
  import { taskHandoffShowSpec } from "../../../commands/task/handoff-show.command.js";
12
14
  import { taskHandoffSpec } from "../../../commands/task/handoff.command.js";
13
15
  import { taskHostedCloseSpec } from "../../../commands/task/hosted-close.command.js";
16
+ import { taskHostedClosePrSpec } from "../../../commands/task/hosted-close-pr.command.js";
14
17
  import { taskLintSpec } from "../../../commands/task/lint.command.js";
15
18
  import { taskListSpec } from "../../../commands/task/list.spec.js";
16
19
  import { taskMigrateDocSpec } from "../../../commands/task/migrate-doc.command.js";
@@ -60,6 +63,7 @@ export const TASK_COMMANDS = [
60
63
  entry(taskHandoffRecordSpec, () => import("../../../commands/task/handoff-record.command.js").then((m) => m.runTaskHandoffRecord)),
61
64
  entry(taskHandoffShowSpec, () => import("../../../commands/task/handoff-show.command.js").then((m) => m.runTaskHandoffShow)),
62
65
  entry(taskHostedCloseSpec, (deps) => import("../../../commands/task/hosted-close.command.js").then((m) => m.makeRunTaskHostedCloseHandler(deps.getCtx))),
66
+ entry(taskHostedClosePrSpec, (deps) => import("../../../commands/task/hosted-close-pr.command.js").then((m) => m.makeRunTaskHostedClosePrHandler(deps.getCtx))),
63
67
  entry(taskListSpec, (deps) => import("../../../commands/task/list.run.js").then((m) => m.makeRunTaskListHandler(deps.getCtx)), { invocation: requireCanonicalCommandInvocation(["task", "list"]) }),
64
68
  entry(taskNextSpec, (deps) => import("../../../commands/task/next.run.js").then((m) => m.makeRunTaskNextHandler(deps.getCtx))),
65
69
  entry(taskSearchSpec, (deps) => import("../../../commands/task/search.run.js").then((m) => m.makeRunTaskSearchHandler(deps.getCtx))),
@@ -84,6 +88,12 @@ export const TASK_COMMANDS = [
84
88
  entry(taskUpdateSpec, (deps) => import("../../../commands/task/update.command.js").then((m) => m.makeRunTaskUpdateHandler(deps.getCtx))),
85
89
  entry(taskCommentSpec, (deps) => import("../../../commands/task/comment.command.js").then((m) => m.makeRunTaskCommentHandler(deps.getCtx))),
86
90
  entry(taskSetStatusSpec, (deps) => import("../../../commands/task/set-status.command.js").then((m) => m.makeRunTaskSetStatusHandler(deps.getCtx))),
91
+ entry(taskFindingsSpec, () => import("../../../commands/task/findings.command.js").then((m) => m.runTaskFindings), {
92
+ needsProject: false,
93
+ needsLoadedConfig: false,
94
+ needsTaskContext: false,
95
+ }),
96
+ entry(taskFindingsAddSpec, (deps) => import("../../../commands/task/findings-add.command.js").then((m) => m.makeRunTaskFindingsAddHandler(deps.getCtx))),
87
97
  entry(taskDocSpec, () => import("../../../commands/task/doc.command.js").then((m) => m.runTaskDoc), {
88
98
  needsProject: false,
89
99
  needsLoadedConfig: false,
@@ -1,7 +1,7 @@
1
1
  import type { CommandId } from "../spec/spec.js";
2
2
  import type { CommandEntry } from "./command-catalog/shared.js";
3
3
  export type { CommandEntry, RunDeps } from "./command-catalog/shared.js";
4
- export declare const COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
4
+ export declare const COMMANDS: readonly [CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry, CommandEntry];
5
5
  export type CatalogMatch = {
6
6
  entry: (typeof COMMANDS)[number];
7
7
  consumed: number;
@@ -1 +1 @@
1
- {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../../src/cli/run-cli/command-catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAOhE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEzE,eAAO,MAAM,QAAQ,qsDAKuB,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAYlF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,GAAG,IAAI,CAGlF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAEnE;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,GAAE,SAAc,GAAG,SAAS,YAAY,EAAE,CAE9F;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,GAAE,SAAc,GAAG,SAAS,MAAM,EAAE,CAEtF;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAM1D"}
1
+ {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../../src/cli/run-cli/command-catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAOhE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEzE,eAAO,MAAM,QAAQ,2wDAKuB,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAYlF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,GAAG,IAAI,CAGlF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAEnE;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,GAAE,SAAc,GAAG,SAAS,YAAY,EAAE,CAE9F;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,GAAE,SAAc,GAAG,SAAS,MAAM,EAAE,CAEtF;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAM1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/core/preflight.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAMzE,KAAK,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AACtC,KAAK,eAAe,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAyO9D,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,eAAe,CAuCtD,CAAC;AAoDF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,eAAe,CAOxD,CAAC"}
1
+ {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/core/preflight.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAMzE,KAAK,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AACtC,KAAK,eAAe,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AA8R9D,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,eAAe,CAuCtD,CAAC;AAqDF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,eAAe,CAOxD,CAAC"}
@@ -43,6 +43,30 @@ function inferApprovals(config) {
43
43
  require_network: approvals.require_network,
44
44
  };
45
45
  }
46
+ function normalizeRepoPath(value) {
47
+ return value.replaceAll("\\", "/");
48
+ }
49
+ function detectTaskArtifactDrift(opts) {
50
+ const workflowDir = normalizeRepoPath(opts.workflowDir).replace(/\/+$/, "");
51
+ const prefix = `${workflowDir}/`;
52
+ const matched = opts.changedPaths
53
+ .map((value) => normalizeRepoPath(value))
54
+ .filter((value) => value.startsWith(prefix))
55
+ .toSorted((a, b) => a.localeCompare(b));
56
+ const taskIds = new Set();
57
+ for (const matchedPath of matched) {
58
+ const relative = matchedPath.slice(prefix.length);
59
+ const [taskId] = relative.split("/", 1);
60
+ if (taskId && taskId !== "." && taskId !== "..") {
61
+ taskIds.add(taskId);
62
+ }
63
+ }
64
+ return {
65
+ present: matched.length > 0,
66
+ task_ids: [...taskIds].toSorted((a, b) => a.localeCompare(b)),
67
+ paths: matched,
68
+ };
69
+ }
46
70
  async function buildPreflightReport(opts) {
47
71
  const nextActions = [];
48
72
  const harnessHealthReasons = [];
@@ -145,6 +169,11 @@ async function buildPreflightReport(opts) {
145
169
  ok: false,
146
170
  error: "project not resolved",
147
171
  };
172
+ let taskArtifactDrift = {
173
+ present: false,
174
+ task_ids: [],
175
+ paths: [],
176
+ };
148
177
  let branch = {
149
178
  ok: false,
150
179
  error: "project not resolved",
@@ -152,10 +181,15 @@ async function buildPreflightReport(opts) {
152
181
  if (resolved) {
153
182
  try {
154
183
  const git = new GitContext({ gitRoot: resolved.gitRoot });
155
- const [staged, unstagedTracked] = await Promise.all([
184
+ const [changed, staged, unstagedTracked] = await Promise.all([
185
+ git.statusChangedPaths(),
156
186
  git.statusStagedPaths(),
157
187
  git.statusUnstagedTrackedPaths(),
158
188
  ]);
189
+ taskArtifactDrift = detectTaskArtifactDrift({
190
+ changedPaths: changed,
191
+ workflowDir: config?.paths.workflow_dir ?? ".agentplane/tasks",
192
+ });
159
193
  workingTree = { ok: true, value: staged.length === 0 && unstagedTracked.length === 0 };
160
194
  if (!workingTree.value) {
161
195
  harnessHealthReasons.push("working_tree_dirty");
@@ -164,6 +198,13 @@ async function buildPreflightReport(opts) {
164
198
  reason: "tracked changes detected",
165
199
  });
166
200
  }
201
+ if (taskArtifactDrift.present) {
202
+ harnessHealthReasons.push("task_artifact_drift");
203
+ nextActions.push({
204
+ command: `git status --short --untracked-files=all -- ${config?.paths.workflow_dir ?? ".agentplane/tasks"}`,
205
+ reason: `task artifact drift detected for ${taskArtifactDrift.task_ids.join(", ")}`,
206
+ });
207
+ }
167
208
  }
168
209
  catch (err) {
169
210
  const message = compactError(err);
@@ -189,6 +230,7 @@ async function buildPreflightReport(opts) {
189
230
  workflow_loaded: workflowLoaded,
190
231
  task_list_loaded: taskListLoaded,
191
232
  working_tree_clean_tracked: workingTree,
233
+ task_artifact_drift: taskArtifactDrift,
192
234
  current_branch: branch,
193
235
  workflow_mode: inferWorkflowMode(config),
194
236
  approvals: inferApprovals(config),
@@ -258,6 +300,7 @@ async function cmdPreflight(opts) {
258
300
  `- workflow loaded: ${probeYesNo(report.workflow_loaded)}`,
259
301
  `- task list loaded: ${probeYesNo(report.task_list_loaded)}`,
260
302
  `- working tree clean (tracked-only): ${probeValueOrUnknown(report.working_tree_clean_tracked)}`,
303
+ `- task artifact drift: ${report.task_artifact_drift.present ? report.task_artifact_drift.task_ids.join(", ") : "none"}`,
261
304
  `- current git branch: ${probeValueOrUnknown(report.current_branch)}`,
262
305
  `- workflow_mode: ${report.workflow_mode}`,
263
306
  `- harness engeneering health: ${report.harness_health.status}`,
@@ -1 +1 @@
1
- {"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"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"}
@@ -274,6 +274,18 @@ export async function approveTaskPlan(root, taskId) {
274
274
  ]);
275
275
  }
276
276
  export async function recordVerificationOk(root, taskId) {
277
+ await runCliSilent([
278
+ "task",
279
+ "doc",
280
+ "set",
281
+ taskId,
282
+ "--section",
283
+ "Verify Steps",
284
+ "--text",
285
+ "Run verify for this task. Expected: verification records successfully.",
286
+ "--root",
287
+ root,
288
+ ]);
277
289
  await runCliSilent([
278
290
  "verify",
279
291
  taskId,
@@ -6,6 +6,8 @@ export declare function cmdCleanupMerged(opts: {
6
6
  base?: string;
7
7
  yes: boolean;
8
8
  archive: boolean;
9
+ deleteRemoteBranches: boolean;
10
+ fetch: boolean;
9
11
  quiet: boolean;
10
12
  }): Promise<number>;
11
13
  //# sourceMappingURL=cleanup-merged.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup-merged.d.ts","sourceRoot":"","sources":["../../../src/commands/branch/cleanup-merged.ts"],"names":[],"mappings":"AAiBA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAKnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsIlB"}
1
+ {"version":3,"file":"cleanup-merged.d.ts","sourceRoot":"","sources":["../../../src/commands/branch/cleanup-merged.ts"],"names":[],"mappings":"AAqBA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgInC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiJlB"}
@@ -1,3 +1,4 @@
1
+ import { readFile } from "node:fs/promises";
1
2
  import path from "node:path";
2
3
  import { resolveBaseBranch } from "@agentplaneorg/core";
3
4
  import { mapBackendError } from "../../cli/error-map.js";
@@ -6,12 +7,109 @@ import { CliError } from "../../shared/errors.js";
6
7
  import { ensureGitClean } from "../guard/index.js";
7
8
  import { execFileAsync, gitEnv } from "../shared/git.js";
8
9
  import { gitDiffNames } from "../shared/git-diff.js";
9
- import { gitBranchExists, gitCurrentBranch } from "../shared/git-ops.js";
10
- import { findWorktreeForBranch, gitListTaskBranches, parseTaskIdFromBranch, } from "../shared/git-worktree.js";
10
+ import { gitBranchExists, gitCurrentBranch, gitIsAncestor } from "../shared/git-ops.js";
11
+ import { findWorktreeForBranch, gitListBranchesByPrefixes, parseTaskIdFromCloseBranch, parseTaskIdFromBranch, } from "../shared/git-worktree.js";
11
12
  import { isPathWithin, resolvePathFallback } from "../shared/path.js";
12
- import { listTaskProjection, loadCommandContext, } from "../shared/task-backend.js";
13
+ import { parsePrMeta } from "../shared/pr-meta.js";
14
+ import { loadTaskFromContext, loadCommandContext, } from "../shared/task-backend.js";
13
15
  import { archivePrArtifacts } from "./internal/archive-pr.js";
14
16
  const output = createCliEmitter();
17
+ function resolveCleanupBranchTaskId(opts) {
18
+ const taskId = parseTaskIdFromBranch(opts.prefix, opts.branch);
19
+ if (taskId)
20
+ return { taskId, kind: "task" };
21
+ const closeTaskId = parseTaskIdFromCloseBranch(opts.branch);
22
+ if (closeTaskId)
23
+ return { taskId: closeTaskId, kind: "task-close" };
24
+ return null;
25
+ }
26
+ async function readCleanupPrMetaIfPresent(opts) {
27
+ const metaPath = path.join(opts.gitRoot, opts.workflowDir, opts.taskId, "pr", "meta.json");
28
+ try {
29
+ const raw = await readFile(metaPath, "utf8");
30
+ return parsePrMeta(raw, opts.taskId);
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ async function taskLifecycleIsOnBase(opts) {
37
+ const taskCommitHash = opts.task.commit?.hash?.trim() ?? "";
38
+ if (taskCommitHash && (await gitIsAncestor(opts.gitRoot, taskCommitHash, opts.baseBranch))) {
39
+ return true;
40
+ }
41
+ const meta = await readCleanupPrMetaIfPresent({
42
+ gitRoot: opts.gitRoot,
43
+ workflowDir: opts.workflowDir,
44
+ taskId: opts.taskId,
45
+ });
46
+ const mergeCommit = meta?.status === "MERGED" ? (meta.merge_commit?.trim() ?? "") : "";
47
+ return (mergeCommit.length > 0 && (await gitIsAncestor(opts.gitRoot, mergeCommit, opts.baseBranch)));
48
+ }
49
+ async function resolveCleanupCandidates(opts) {
50
+ const prefix = opts.ctx.config.branch.task_prefix;
51
+ const branches = await gitListBranchesByPrefixes(opts.gitRoot, [prefix, "task-close"]);
52
+ const taskCache = new Map();
53
+ const candidates = [];
54
+ for (const branch of branches) {
55
+ if (branch === opts.baseBranch)
56
+ continue;
57
+ const target = resolveCleanupBranchTaskId({ branch, prefix });
58
+ if (!target)
59
+ continue;
60
+ let task = taskCache.get(target.taskId) ?? null;
61
+ if (!taskCache.has(target.taskId)) {
62
+ try {
63
+ task = await loadTaskFromContext({ ctx: opts.ctx, taskId: target.taskId });
64
+ }
65
+ catch {
66
+ task = null;
67
+ }
68
+ taskCache.set(target.taskId, task);
69
+ }
70
+ if (!task)
71
+ continue;
72
+ const status = String(task.status || "").toUpperCase();
73
+ if (status !== "DONE")
74
+ continue;
75
+ const diff = await gitDiffNames(opts.gitRoot, opts.baseBranch, branch);
76
+ const lifecycleOnBase = await taskLifecycleIsOnBase({
77
+ gitRoot: opts.gitRoot,
78
+ workflowDir: opts.workflowDir,
79
+ baseBranch: opts.baseBranch,
80
+ task,
81
+ taskId: target.taskId,
82
+ });
83
+ if (diff.length > 0 && !lifecycleOnBase)
84
+ continue;
85
+ const worktreePath = await findWorktreeForBranch(opts.gitRoot, branch);
86
+ candidates.push({ taskId: target.taskId, branch, worktreePath });
87
+ }
88
+ return candidates;
89
+ }
90
+ function isMissingRemoteBranchDelete(error) {
91
+ const stdout = String(error?.stdout ?? "");
92
+ const stderr = String(error?.stderr ?? "");
93
+ const text = `${stdout}\n${stderr}`;
94
+ return (text.includes("remote ref does not exist") ||
95
+ text.includes("unable to delete") ||
96
+ text.includes("remote reference is not a full refname"));
97
+ }
98
+ async function deleteRemoteBranchIfPresent(gitRoot, branch) {
99
+ try {
100
+ await execFileAsync("git", ["push", "origin", "--delete", branch], {
101
+ cwd: gitRoot,
102
+ env: gitEnv(),
103
+ });
104
+ return true;
105
+ }
106
+ catch (error) {
107
+ if (isMissingRemoteBranchDelete(error)) {
108
+ return false;
109
+ }
110
+ throw error;
111
+ }
112
+ }
15
113
  export async function cmdCleanupMerged(opts) {
16
114
  try {
17
115
  const ctx = opts.ctx ??
@@ -26,6 +124,12 @@ export async function cmdCleanupMerged(opts) {
26
124
  });
27
125
  }
28
126
  await ensureGitClean({ cwd: opts.cwd, rootOverride: opts.rootOverride });
127
+ if (opts.fetch) {
128
+ await execFileAsync("git", ["fetch", "--prune", "origin"], {
129
+ cwd: resolved.gitRoot,
130
+ env: gitEnv(),
131
+ });
132
+ }
29
133
  const baseBranch = await resolveBaseBranch({
30
134
  cwd: opts.cwd,
31
135
  rootOverride: opts.rootOverride ?? null,
@@ -55,33 +159,18 @@ export async function cmdCleanupMerged(opts) {
55
159
  });
56
160
  }
57
161
  const repoRoot = await resolvePathFallback(resolved.gitRoot);
58
- const tasks = (await listTaskProjection(ctx)) ?? [];
59
- const tasksById = new Map(tasks.map((task) => [task.id, task]));
60
- const prefix = config.branch.task_prefix;
61
- const branches = await gitListTaskBranches(resolved.gitRoot, prefix);
62
- const candidates = [];
63
- for (const branch of branches) {
64
- if (branch === baseBranch)
65
- continue;
66
- const taskId = parseTaskIdFromBranch(prefix, branch);
67
- if (!taskId)
68
- continue;
69
- const task = tasksById.get(taskId);
70
- if (!task)
71
- continue;
72
- const status = String(task.status || "").toUpperCase();
73
- if (status !== "DONE")
74
- continue;
75
- const diff = await gitDiffNames(resolved.gitRoot, baseBranch, branch);
76
- if (diff.length > 0)
77
- continue;
78
- const worktreePath = await findWorktreeForBranch(resolved.gitRoot, branch);
79
- candidates.push({ taskId, branch, worktreePath });
80
- }
162
+ const candidates = await resolveCleanupCandidates({
163
+ ctx,
164
+ gitRoot: resolved.gitRoot,
165
+ workflowDir: config.paths.workflow_dir,
166
+ baseBranch,
167
+ });
81
168
  const sortedCandidates = candidates.toSorted((a, b) => a.taskId.localeCompare(b.taskId));
82
169
  if (!opts.quiet) {
83
170
  const archiveLabel = opts.archive ? " archive=on" : "";
84
- output.line(`cleanup merged (base=${baseBranch}${archiveLabel})`);
171
+ const fetchLabel = opts.fetch ? " fetch=on" : "";
172
+ const remoteLabel = opts.deleteRemoteBranches ? " remote=delete" : "";
173
+ output.line(`cleanup merged (base=${baseBranch}${archiveLabel}${fetchLabel}${remoteLabel})`);
85
174
  if (sortedCandidates.length === 0) {
86
175
  output.line("no candidates");
87
176
  return 0;
@@ -96,6 +185,7 @@ export async function cmdCleanupMerged(opts) {
96
185
  }
97
186
  return 0;
98
187
  }
188
+ let deletedRemoteBranches = 0;
99
189
  for (const item of sortedCandidates) {
100
190
  const worktreePath = item.worktreePath ? await resolvePathFallback(item.worktreePath) : null;
101
191
  if (worktreePath) {
@@ -128,9 +218,23 @@ export async function cmdCleanupMerged(opts) {
128
218
  cwd: resolved.gitRoot,
129
219
  env: gitEnv(),
130
220
  });
221
+ if (opts.deleteRemoteBranches) {
222
+ deletedRemoteBranches += (await deleteRemoteBranchIfPresent(resolved.gitRoot, item.branch))
223
+ ? 1
224
+ : 0;
225
+ }
226
+ }
227
+ if (opts.deleteRemoteBranches) {
228
+ await execFileAsync("git", ["fetch", "--prune", "origin"], {
229
+ cwd: resolved.gitRoot,
230
+ env: gitEnv(),
231
+ });
131
232
  }
132
233
  if (!opts.quiet) {
133
- output.success("cleanup merged", undefined, `deleted=${candidates.length}`);
234
+ const remoteDetail = opts.deleteRemoteBranches
235
+ ? ` remote_deleted=${deletedRemoteBranches}`
236
+ : "";
237
+ output.success("cleanup merged", undefined, `deleted=${candidates.length}${remoteDetail}`);
134
238
  }
135
239
  return 0;
136
240
  }
@@ -1 +1 @@
1
- {"version":3,"file":"work-start.d.ts","sourceRoot":"","sources":["../../../src/commands/branch/work-start.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAiInC,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqJlB"}
1
+ {"version":3,"file":"work-start.d.ts","sourceRoot":"","sources":["../../../src/commands/branch/work-start.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAkMnC,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6JlB"}
@@ -1,4 +1,4 @@
1
- import { copyFile, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
1
+ import { copyFile, cp, mkdir, readFile, readdir, symlink, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { resolveBaseBranch } from "@agentplaneorg/core";
4
4
  import { LocalBackend } from "../../backends/task-backend.js";
@@ -62,6 +62,57 @@ async function materializeLocalBackendReadmesForWorktree(opts) {
62
62
  await copyFile(sourceReadme, targetReadme);
63
63
  }
64
64
  }
65
+ async function materializeRepoLocalDistForWorktree(opts) {
66
+ const sourceRoots = [path.resolve(opts.repoRoot), path.resolve(process.cwd())];
67
+ const copyTargets = [
68
+ ["packages/core/dist", "packages/core/dist"],
69
+ ["packages/agentplane/dist", "packages/agentplane/dist"],
70
+ ["packages/agentplane/bin", "packages/agentplane/bin"],
71
+ ];
72
+ for (const [sourceRelativePath, targetRelativePath] of copyTargets) {
73
+ let sourcePath = "";
74
+ for (const sourceRoot of sourceRoots) {
75
+ const candidate = path.join(sourceRoot, sourceRelativePath);
76
+ if (await fileExists(candidate)) {
77
+ sourcePath = candidate;
78
+ break;
79
+ }
80
+ }
81
+ if (!sourcePath)
82
+ continue;
83
+ const targetPath = path.join(opts.worktreePath, targetRelativePath);
84
+ if (await fileExists(targetPath))
85
+ continue;
86
+ await mkdir(path.dirname(targetPath), { recursive: true });
87
+ await cp(sourcePath, targetPath, { recursive: true });
88
+ }
89
+ }
90
+ async function linkDirectoryIntoWorktree(opts) {
91
+ const sourcePath = path.join(opts.repoRoot, opts.relativePath);
92
+ if (!(await fileExists(sourcePath)))
93
+ return false;
94
+ const targetPath = path.join(opts.worktreePath, opts.relativePath);
95
+ if (await fileExists(targetPath))
96
+ return false;
97
+ await mkdir(path.dirname(targetPath), { recursive: true });
98
+ await symlink(sourcePath, targetPath, process.platform === "win32" ? "junction" : "dir");
99
+ return true;
100
+ }
101
+ async function materializeRepoLocalInstallLayoutForWorktree(opts) {
102
+ const linkTargets = [
103
+ "node_modules",
104
+ path.join("packages", "core", "node_modules"),
105
+ path.join("packages", "agentplane", "node_modules"),
106
+ "agentplane-recipes",
107
+ ];
108
+ for (const relativePath of linkTargets) {
109
+ await linkDirectoryIntoWorktree({
110
+ repoRoot: opts.repoRoot,
111
+ worktreePath: opts.worktreePath,
112
+ relativePath,
113
+ });
114
+ }
115
+ }
65
116
  async function ensureGitClean(gitRoot) {
66
117
  const { stdout } = await execFileAsync("git", ["status", "--porcelain"], {
67
118
  cwd: gitRoot,
@@ -228,6 +279,14 @@ export async function cmdWorkStart(opts) {
228
279
  repoRoot: resolved.gitRoot,
229
280
  worktreePath,
230
281
  });
282
+ await materializeRepoLocalDistForWorktree({
283
+ repoRoot: resolved.gitRoot,
284
+ worktreePath,
285
+ });
286
+ await materializeRepoLocalInstallLayoutForWorktree({
287
+ repoRoot: resolved.gitRoot,
288
+ worktreePath,
289
+ });
231
290
  }
232
291
  else {
233
292
  if (branchExists) {
@@ -7,6 +7,8 @@ export type CleanupMergedParsed = {
7
7
  base: string | null;
8
8
  yes: boolean;
9
9
  archive: boolean;
10
+ deleteRemoteBranches: boolean;
11
+ fetch: boolean;
10
12
  quiet: boolean;
11
13
  };
12
14
  export declare const cleanupMergedSpec: CommandSpec<CleanupMergedParsed>;