agentplane 0.3.8 → 0.3.10

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 (268) 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 +3 -0
  5. package/assets/policy/incidents.md +22 -11
  6. package/assets/policy/workflow.branch_pr.md +2 -0
  7. package/assets/policy/workflow.direct.md +3 -1
  8. package/dist/.build-manifest.json +323 -128
  9. package/dist/cli/bootstrap-guide.d.ts +1 -0
  10. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  11. package/dist/cli/bootstrap-guide.js +19 -1
  12. package/dist/cli/command-invocations.d.ts.map +1 -1
  13. package/dist/cli/command-invocations.js +2 -0
  14. package/dist/cli/command-snippets.d.ts +2 -0
  15. package/dist/cli/command-snippets.d.ts.map +1 -1
  16. package/dist/cli/command-snippets.js +2 -0
  17. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  18. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  19. package/dist/cli/run-cli/command-catalog/core.js +10 -0
  20. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  21. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  22. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  23. package/dist/cli/run-cli/commands/config.js +13 -0
  24. package/dist/cli/run-cli.js +2 -2
  25. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  26. package/dist/cli/run-cli.test-helpers.js +34 -8
  27. package/dist/commands/backend.d.ts.map +1 -1
  28. package/dist/commands/backend.js +4 -0
  29. package/dist/commands/hooks/index.d.ts.map +1 -1
  30. package/dist/commands/hooks/index.js +8 -4
  31. package/dist/commands/incidents/advise.command.d.ts +15 -0
  32. package/dist/commands/incidents/advise.command.d.ts.map +1 -0
  33. package/dist/commands/incidents/advise.command.js +139 -0
  34. package/dist/commands/incidents/collect.command.d.ts +11 -0
  35. package/dist/commands/incidents/collect.command.d.ts.map +1 -0
  36. package/dist/commands/incidents/collect.command.js +67 -0
  37. package/dist/commands/incidents/incidents.command.d.ts +5 -0
  38. package/dist/commands/incidents/incidents.command.d.ts.map +1 -0
  39. package/dist/commands/incidents/incidents.command.js +21 -0
  40. package/dist/commands/incidents/shared.d.ts +42 -0
  41. package/dist/commands/incidents/shared.d.ts.map +1 -0
  42. package/dist/commands/incidents/shared.js +107 -0
  43. package/dist/commands/pr/check.d.ts.map +1 -1
  44. package/dist/commands/pr/check.js +73 -2
  45. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  46. package/dist/commands/pr/integrate/cmd.js +4 -0
  47. package/dist/commands/pr/integrate/internal/merge.d.ts +4 -0
  48. package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
  49. package/dist/commands/pr/integrate/internal/merge.js +23 -2
  50. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  51. package/dist/commands/pr/integrate/internal/prepare.js +26 -1
  52. package/dist/commands/pr/internal/note-store.d.ts +18 -0
  53. package/dist/commands/pr/internal/note-store.d.ts.map +1 -0
  54. package/dist/commands/pr/internal/note-store.js +66 -0
  55. package/dist/commands/pr/internal/pr-paths.d.ts +3 -0
  56. package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
  57. package/dist/commands/pr/internal/pr-paths.js +3 -0
  58. package/dist/commands/pr/internal/review-template.d.ts +24 -4
  59. package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
  60. package/dist/commands/pr/internal/review-template.js +188 -33
  61. package/dist/commands/pr/internal/sync.d.ts +32 -0
  62. package/dist/commands/pr/internal/sync.d.ts.map +1 -0
  63. package/dist/commands/pr/internal/sync.js +258 -0
  64. package/dist/commands/pr/note.d.ts.map +1 -1
  65. package/dist/commands/pr/note.js +37 -4
  66. package/dist/commands/pr/open.d.ts.map +1 -1
  67. package/dist/commands/pr/open.js +7 -54
  68. package/dist/commands/pr/pr.command.d.ts.map +1 -1
  69. package/dist/commands/pr/pr.command.js +6 -3
  70. package/dist/commands/pr/update.d.ts.map +1 -1
  71. package/dist/commands/pr/update.js +5 -79
  72. package/dist/commands/recipes/impl/apply.d.ts +1 -1
  73. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  74. package/dist/commands/recipes/impl/apply.js +1 -1
  75. package/dist/commands/recipes/impl/commands/cache-prune.d.ts.map +1 -1
  76. package/dist/commands/recipes/impl/commands/cache-prune.js +14 -0
  77. package/dist/commands/recipes/impl/commands/explain.js +1 -1
  78. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  79. package/dist/commands/recipes/impl/commands/install.js +3 -2
  80. package/dist/commands/recipes/impl/commands/list-remote.d.ts.map +1 -1
  81. package/dist/commands/recipes/impl/commands/list-remote.js +1 -0
  82. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  83. package/dist/commands/recipes/impl/commands/remove.js +9 -1
  84. package/dist/commands/recipes/impl/installed-recipes.d.ts +1 -1
  85. package/dist/commands/recipes/impl/installed-recipes.d.ts.map +1 -1
  86. package/dist/commands/recipes/impl/installed-recipes.js +2 -1
  87. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +1 -1
  88. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
  89. package/dist/commands/recipes/impl/project-installed-recipes.js +2 -1
  90. package/dist/commands/recipes/impl/resolver.d.ts +1 -1
  91. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
  92. package/dist/commands/recipes/impl/resolver.js +1 -1
  93. package/dist/commands/recipes.d.ts +4 -4
  94. package/dist/commands/recipes.d.ts.map +1 -1
  95. package/dist/commands/recipes.js +3 -3
  96. package/dist/commands/release/apply.command.d.ts.map +1 -1
  97. package/dist/commands/release/apply.command.js +9 -0
  98. package/dist/commands/release.test-helpers.d.ts +14 -0
  99. package/dist/commands/release.test-helpers.d.ts.map +1 -1
  100. package/dist/commands/release.test-helpers.js +14 -3
  101. package/dist/commands/shared/approval-requirements.d.ts +5 -7
  102. package/dist/commands/shared/approval-requirements.d.ts.map +1 -1
  103. package/dist/commands/shared/approval-requirements.js +3 -73
  104. package/dist/commands/shared/network-approval.d.ts +2 -0
  105. package/dist/commands/shared/network-approval.d.ts.map +1 -1
  106. package/dist/commands/shared/network-approval.js +1 -1
  107. package/dist/commands/shared/pr-meta.d.ts +9 -0
  108. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  109. package/dist/commands/shared/pr-meta.js +27 -3
  110. package/dist/commands/shared/task-backend.d.ts +2 -0
  111. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  112. package/dist/commands/shared/task-local-freshness.d.ts +13 -0
  113. package/dist/commands/shared/task-local-freshness.d.ts.map +1 -0
  114. package/dist/commands/shared/task-local-freshness.js +20 -0
  115. package/dist/commands/shared/task-mutation.d.ts +2 -0
  116. package/dist/commands/shared/task-mutation.d.ts.map +1 -1
  117. package/dist/commands/shared/task-mutation.js +7 -0
  118. package/dist/commands/task/block.d.ts.map +1 -1
  119. package/dist/commands/task/block.js +1 -0
  120. package/dist/commands/task/close-shared.d.ts.map +1 -1
  121. package/dist/commands/task/close-shared.js +1 -0
  122. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  123. package/dist/commands/task/finish-shared.js +5 -2
  124. package/dist/commands/task/finish.d.ts.map +1 -1
  125. package/dist/commands/task/finish.js +24 -0
  126. package/dist/commands/task/new.d.ts.map +1 -1
  127. package/dist/commands/task/new.js +69 -29
  128. package/dist/commands/task/set-status.d.ts.map +1 -1
  129. package/dist/commands/task/set-status.js +1 -0
  130. package/dist/commands/task/shared/transition-command.d.ts +2 -0
  131. package/dist/commands/task/shared/transition-command.d.ts.map +1 -1
  132. package/dist/commands/task/shared/transition-command.js +1 -0
  133. package/dist/commands/task/start-ready.d.ts.map +1 -1
  134. package/dist/commands/task/start-ready.js +12 -1
  135. package/dist/commands/task/start.d.ts.map +1 -1
  136. package/dist/commands/task/start.js +11 -0
  137. package/dist/commands/task/verify-record.d.ts.map +1 -1
  138. package/dist/commands/task/verify-record.js +27 -0
  139. package/dist/commands/upgrade.d.ts.map +1 -1
  140. package/dist/commands/upgrade.js +6 -1
  141. package/dist/policy/engine.d.ts +3 -1
  142. package/dist/policy/engine.d.ts.map +1 -1
  143. package/dist/policy/engine.js +5 -6
  144. package/dist/policy/taxonomy.d.ts +17 -0
  145. package/dist/policy/taxonomy.d.ts.map +1 -0
  146. package/dist/policy/taxonomy.js +302 -0
  147. package/dist/policy/types.d.ts +2 -1
  148. package/dist/policy/types.d.ts.map +1 -1
  149. package/dist/runner/artifacts.d.ts.map +1 -1
  150. package/dist/runner/artifacts.js +2 -0
  151. package/dist/runner/context/base-prompts.d.ts +25 -0
  152. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  153. package/dist/runner/context/base-prompts.js +182 -54
  154. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  155. package/dist/runner/context/recipe-context.js +5 -0
  156. package/dist/runner/types.d.ts +12 -0
  157. package/dist/runner/types.d.ts.map +1 -1
  158. package/dist/runner/usecases/scenario-materialize-task.d.ts.map +1 -1
  159. package/dist/runner/usecases/scenario-materialize-task.js +81 -11
  160. package/dist/runner/usecases/task-run-inspect.d.ts.map +1 -1
  161. package/dist/runner/usecases/task-run-inspect.js +9 -7
  162. package/dist/runner/usecases/task-run-lifecycle-shared.d.ts.map +1 -1
  163. package/dist/runner/usecases/task-run-lifecycle-shared.js +8 -6
  164. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  165. package/dist/runner/usecases/task-run.js +59 -12
  166. package/dist/runtime/approvals/index.d.ts +3 -0
  167. package/dist/runtime/approvals/index.d.ts.map +1 -0
  168. package/dist/runtime/approvals/index.js +1 -0
  169. package/dist/runtime/approvals/runtime.d.ts +12 -0
  170. package/dist/runtime/approvals/runtime.d.ts.map +1 -0
  171. package/dist/runtime/approvals/runtime.js +154 -0
  172. package/dist/runtime/approvals/types.d.ts +31 -0
  173. package/dist/runtime/approvals/types.d.ts.map +1 -0
  174. package/dist/runtime/approvals/types.js +1 -0
  175. package/dist/runtime/behavior/index.d.ts +3 -0
  176. package/dist/runtime/behavior/index.d.ts.map +1 -0
  177. package/dist/runtime/behavior/index.js +1 -0
  178. package/dist/runtime/behavior/resolve.d.ts +7 -0
  179. package/dist/runtime/behavior/resolve.d.ts.map +1 -0
  180. package/dist/runtime/behavior/resolve.js +66 -0
  181. package/dist/runtime/behavior/types.d.ts +25 -0
  182. package/dist/runtime/behavior/types.d.ts.map +1 -0
  183. package/dist/runtime/behavior/types.js +1 -0
  184. package/dist/runtime/capabilities/backend.d.ts +7 -0
  185. package/dist/runtime/capabilities/backend.d.ts.map +1 -0
  186. package/dist/runtime/capabilities/backend.js +104 -0
  187. package/dist/runtime/capabilities/index.d.ts +6 -0
  188. package/dist/runtime/capabilities/index.d.ts.map +1 -0
  189. package/dist/runtime/capabilities/index.js +4 -0
  190. package/dist/runtime/capabilities/recipe.d.ts +10 -0
  191. package/dist/runtime/capabilities/recipe.d.ts.map +1 -0
  192. package/dist/runtime/capabilities/recipe.js +123 -0
  193. package/dist/runtime/capabilities/registry.d.ts +6 -0
  194. package/dist/runtime/capabilities/registry.d.ts.map +1 -0
  195. package/dist/runtime/capabilities/registry.js +69 -0
  196. package/dist/runtime/capabilities/runner.d.ts +8 -0
  197. package/dist/runtime/capabilities/runner.d.ts.map +1 -0
  198. package/dist/runtime/capabilities/runner.js +73 -0
  199. package/dist/runtime/capabilities/types.d.ts +28 -0
  200. package/dist/runtime/capabilities/types.d.ts.map +1 -0
  201. package/dist/runtime/capabilities/types.js +1 -0
  202. package/dist/runtime/execution-profile/index.d.ts +3 -0
  203. package/dist/runtime/execution-profile/index.d.ts.map +1 -0
  204. package/dist/runtime/execution-profile/index.js +1 -0
  205. package/dist/runtime/execution-profile/resolve.d.ts +9 -0
  206. package/dist/runtime/execution-profile/resolve.d.ts.map +1 -0
  207. package/dist/runtime/execution-profile/resolve.js +80 -0
  208. package/dist/runtime/execution-profile/types.d.ts +27 -0
  209. package/dist/runtime/execution-profile/types.d.ts.map +1 -0
  210. package/dist/runtime/execution-profile/types.js +1 -0
  211. package/dist/runtime/explain/index.d.ts +3 -0
  212. package/dist/runtime/explain/index.d.ts.map +1 -0
  213. package/dist/runtime/explain/index.js +1 -0
  214. package/dist/runtime/explain/resolve.d.ts +14 -0
  215. package/dist/runtime/explain/resolve.d.ts.map +1 -0
  216. package/dist/runtime/explain/resolve.js +50 -0
  217. package/dist/runtime/explain/types.d.ts +28 -0
  218. package/dist/runtime/explain/types.d.ts.map +1 -0
  219. package/dist/runtime/explain/types.js +1 -0
  220. package/dist/runtime/harness/index.d.ts +4 -0
  221. package/dist/runtime/harness/index.d.ts.map +1 -0
  222. package/dist/runtime/harness/index.js +2 -0
  223. package/dist/runtime/harness/resolve-from-command-context.d.ts +4 -0
  224. package/dist/runtime/harness/resolve-from-command-context.d.ts.map +1 -0
  225. package/dist/runtime/harness/resolve-from-command-context.js +11 -0
  226. package/dist/runtime/harness/resolve.d.ts +13 -0
  227. package/dist/runtime/harness/resolve.d.ts.map +1 -0
  228. package/dist/runtime/harness/resolve.js +146 -0
  229. package/dist/runtime/harness/types.d.ts +65 -0
  230. package/dist/runtime/harness/types.d.ts.map +1 -0
  231. package/dist/runtime/harness/types.js +1 -0
  232. package/dist/runtime/incidents/index.d.ts +3 -0
  233. package/dist/runtime/incidents/index.d.ts.map +1 -0
  234. package/dist/runtime/incidents/index.js +1 -0
  235. package/dist/runtime/incidents/resolve.d.ts +26 -0
  236. package/dist/runtime/incidents/resolve.d.ts.map +1 -0
  237. package/dist/runtime/incidents/resolve.js +437 -0
  238. package/dist/runtime/incidents/types.d.ts +72 -0
  239. package/dist/runtime/incidents/types.d.ts.map +1 -0
  240. package/dist/runtime/incidents/types.js +1 -0
  241. package/dist/runtime/protocol/index.d.ts +3 -0
  242. package/dist/runtime/protocol/index.d.ts.map +1 -0
  243. package/dist/runtime/protocol/index.js +2 -0
  244. package/dist/runtime/protocol/resolve.d.ts +16 -0
  245. package/dist/runtime/protocol/resolve.d.ts.map +1 -0
  246. package/dist/runtime/protocol/resolve.js +36 -0
  247. package/dist/runtime/protocol/types.d.ts +36 -0
  248. package/dist/runtime/protocol/types.d.ts.map +1 -0
  249. package/dist/runtime/protocol/types.js +1 -0
  250. package/dist/runtime/task-intake/index.d.ts +3 -0
  251. package/dist/runtime/task-intake/index.d.ts.map +1 -0
  252. package/dist/runtime/task-intake/index.js +1 -0
  253. package/dist/runtime/task-intake/resolve.d.ts +48 -0
  254. package/dist/runtime/task-intake/resolve.d.ts.map +1 -0
  255. package/dist/runtime/task-intake/resolve.js +316 -0
  256. package/dist/runtime/task-intake/types.d.ts +117 -0
  257. package/dist/runtime/task-intake/types.d.ts.map +1 -0
  258. package/dist/runtime/task-intake/types.js +1 -0
  259. package/dist/shared/protected-paths.d.ts +4 -0
  260. package/dist/shared/protected-paths.d.ts.map +1 -1
  261. package/dist/shared/protected-paths.js +4 -4
  262. package/dist/usecases/context/resolve-context.d.ts +55 -6
  263. package/dist/usecases/context/resolve-context.d.ts.map +1 -1
  264. package/dist/usecases/context/resolve-context.js +96 -6
  265. package/dist/usecases/task/task-list-usecase.d.ts.map +1 -1
  266. package/dist/usecases/task/task-list-usecase.js +8 -2
  267. package/dist/usecases/task/task-new-usecase.js +4 -4
  268. package/package.json +2 -3
@@ -1,9 +1,29 @@
1
- export declare function renderPrReviewTemplate(opts: {
2
- author: string;
3
- createdAt: string;
1
+ import type { TaskData } from "../../../backends/task-backend.js";
2
+ import type { PrHandoffNote } from "./note-store.js";
3
+ export declare function buildGithubPrTitle(task: TaskData): string;
4
+ export declare function renderPrAutoSummary(opts: {
5
+ updatedAt: string;
4
6
  branch: string;
7
+ headSha: string | null;
8
+ diffstat: string;
5
9
  }): string;
6
10
  export declare function updateAutoSummaryBlock(text: string, summary: string): string;
7
- export declare function appendHandoffNote(review: string, note: string): string;
11
+ export declare function extractAutoSummaryBlock(text: string): string | null;
12
+ export declare function renderPrHandoffNotes(notes: PrHandoffNote[]): string[];
13
+ export declare function updateHandoffNotesBlock(text: string, notes: PrHandoffNote[]): string;
14
+ export declare function renderPrReviewDocument(opts: {
15
+ task: TaskData;
16
+ author?: string;
17
+ createdAt: string;
18
+ branch: string;
19
+ handoffNotes?: PrHandoffNote[];
20
+ autoSummary: string;
21
+ }): string;
22
+ export declare function renderGithubPrBody(opts: {
23
+ task: TaskData;
24
+ handoffNotes?: PrHandoffNote[];
25
+ autoSummary: string;
26
+ }): string;
8
27
  export declare function validateReviewContents(review: string, errors: string[]): void;
28
+ export declare function validateGithubPrBodyContents(body: string, errors: string[]): void;
9
29
  //# sourceMappingURL=review-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"review-template.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/review-template.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CA0BT;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW5E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAW7E"}
1
+ {"version":3,"file":"review-template.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/review-template.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA4GrD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAeT;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAS5E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKnE;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAOrE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,CAgBpF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAgBT;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAST;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAiB7E;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAcjF"}
@@ -1,62 +1,217 @@
1
- export function renderPrReviewTemplate(opts) {
1
+ import { extractTaskSuffix } from "@agentplaneorg/core";
2
+ const AUTO_SUMMARY_START = "<!-- BEGIN AUTO SUMMARY -->";
3
+ const AUTO_SUMMARY_END = "<!-- END AUTO SUMMARY -->";
4
+ const SUMMARY_SECTION = "## Summary";
5
+ const SCOPE_SECTION = "## Scope";
6
+ const VERIFICATION_SECTION = "## Verification";
7
+ const RISKS_SECTION = "## Risks";
8
+ const HANDOFF_NOTES_MARKER = "## Handoff Notes";
9
+ function sectionText(task, name, fallback) {
10
+ const value = typeof task.sections?.[name] === "string" ? task.sections[name].trim() : "";
11
+ return value || fallback;
12
+ }
13
+ function normalizeOneLine(value, maxChars) {
14
+ const trimmed = value.trim().replaceAll(/\s+/g, " ");
15
+ if (!trimmed)
16
+ return "";
17
+ return trimmed.length > maxChars ? `${trimmed.slice(0, Math.max(1, maxChars - 3))}...` : trimmed;
18
+ }
19
+ function informativeTags(task) {
20
+ const seen = new Set();
21
+ const out = [];
22
+ for (const rawTag of Array.isArray(task.tags) ? task.tags : []) {
23
+ const tag = rawTag.trim().toLowerCase();
24
+ if (!tag || tag === "code" || seen.has(tag))
25
+ continue;
26
+ seen.add(tag);
27
+ out.push(tag);
28
+ }
29
+ return out;
30
+ }
31
+ function renderVerificationSummary(task) {
32
+ const state = task.verification?.state ?? "pending";
33
+ const note = typeof task.verification?.note === "string" ? task.verification.note.trim() : "";
34
+ const commands = Array.isArray(task.verify)
35
+ ? task.verify.filter((value) => typeof value === "string" && value.trim().length > 0)
36
+ : [];
37
+ const plan = sectionText(task, "Verify Steps", commands.length > 0
38
+ ? commands.map((command) => `- ${command.trim()}`).join("\n")
39
+ : "- Not recorded.");
40
+ const statusLine = state === "ok"
41
+ ? note || "Recorded as passed."
42
+ : state === "needs_rework"
43
+ ? note || "Recorded as needs rework."
44
+ : note || "Not recorded yet.";
2
45
  return [
3
- "# PR Review",
46
+ "### Plan",
47
+ "",
48
+ plan,
49
+ "",
50
+ "### Current Status",
51
+ "",
52
+ `- State: ${state}`,
53
+ `- Note: ${statusLine}`,
54
+ ].join("\n");
55
+ }
56
+ function renderRiskSummary(task) {
57
+ const riskLevel = typeof task.risk_level === "string" ? task.risk_level : "not recorded";
58
+ const rollbackPlan = sectionText(task, "Rollback Plan", "- Revert task-related commit(s) if rollback is required.");
59
+ return [
60
+ `- Risk level: ${riskLevel}`,
61
+ `- Breaking change: ${task.breaking === true ? "yes" : "no"}`,
4
62
  "",
5
- `Opened by ${opts.author} on ${opts.createdAt}`,
6
- `Branch: ${opts.branch}`,
63
+ "### Rollback",
7
64
  "",
8
- "## Summary",
65
+ rollbackPlan,
66
+ ].join("\n");
67
+ }
68
+ function renderSharedPrSections(opts) {
69
+ return [
70
+ SUMMARY_SECTION,
71
+ "",
72
+ sectionText(opts.task, "Summary", opts.task.title.trim() || "- Not recorded."),
73
+ "",
74
+ SCOPE_SECTION,
75
+ "",
76
+ sectionText(opts.task, "Scope", "- Not recorded."),
9
77
  "",
10
- "- ",
78
+ VERIFICATION_SECTION,
11
79
  "",
12
- "## Checklist",
80
+ renderVerificationSummary(opts.task),
13
81
  "",
14
- "- [ ] Tests added/updated",
15
- "- [ ] Lint/format passes",
16
- "- [ ] Verify passed",
17
- "- [ ] Docs updated (if needed)",
82
+ RISKS_SECTION,
18
83
  "",
19
- "## Handoff Notes",
84
+ renderRiskSummary(opts.task),
85
+ "",
86
+ HANDOFF_NOTES_MARKER,
87
+ "",
88
+ ...renderPrHandoffNotes(opts.handoffNotes),
89
+ "",
90
+ ];
91
+ }
92
+ export function buildGithubPrTitle(task) {
93
+ const suffix = extractTaskSuffix(task.id);
94
+ const scope = informativeTags(task).slice(0, 2).join("/");
95
+ const title = normalizeOneLine(task.title, scope ? 72 : 84);
96
+ return scope ? `${scope}: ${title} (${suffix})` : `${title} (${suffix})`;
97
+ }
98
+ export function renderPrAutoSummary(opts) {
99
+ return [
100
+ "<details>",
101
+ "<summary>Raw evidence</summary>",
20
102
  "",
21
- "<!-- Add review notes here. -->",
103
+ `- Updated: ${opts.updatedAt}`,
104
+ `- Branch: ${opts.branch}`,
105
+ `- Head: ${opts.headSha ? opts.headSha.slice(0, 12) : "No commits yet"}`,
22
106
  "",
23
- "<!-- BEGIN AUTO SUMMARY -->",
24
- "<!-- END AUTO SUMMARY -->",
107
+ "```text",
108
+ opts.diffstat || "No changes detected.",
109
+ "```",
25
110
  "",
111
+ "</details>",
26
112
  ].join("\n");
27
113
  }
28
114
  export function updateAutoSummaryBlock(text, summary) {
29
- const start = "<!-- BEGIN AUTO SUMMARY -->";
30
- const end = "<!-- END AUTO SUMMARY -->";
31
- const startIdx = text.indexOf(start);
32
- const endIdx = text.indexOf(end);
115
+ const startIdx = text.indexOf(AUTO_SUMMARY_START);
116
+ const endIdx = text.indexOf(AUTO_SUMMARY_END);
33
117
  if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
34
- return `${text.trimEnd()}\n\n${start}\n${summary}\n${end}\n`;
118
+ return `${text.trimEnd()}\n\n${AUTO_SUMMARY_START}\n${summary}\n${AUTO_SUMMARY_END}\n`;
35
119
  }
36
- const before = text.slice(0, startIdx + start.length);
120
+ const before = text.slice(0, startIdx + AUTO_SUMMARY_START.length);
37
121
  const after = text.slice(endIdx);
38
122
  return `${before}\n${summary}\n${after}`;
39
123
  }
40
- export function appendHandoffNote(review, note) {
41
- const marker = "## Handoff Notes";
42
- const idx = review.indexOf(marker);
43
- if (idx === -1)
44
- return `${review.trimEnd()}\n\n${marker}\n\n- ${note}\n`;
45
- const head = review.slice(0, idx + marker.length);
46
- const tail = review.slice(idx + marker.length);
47
- const trimmedTail = tail.startsWith("\n") ? tail.slice(1) : tail;
48
- return `${head}\n\n- ${note}\n${trimmedTail}`;
124
+ export function extractAutoSummaryBlock(text) {
125
+ const startIdx = text.indexOf(AUTO_SUMMARY_START);
126
+ const endIdx = text.indexOf(AUTO_SUMMARY_END);
127
+ if (startIdx === -1 || endIdx === -1 || endIdx < startIdx)
128
+ return null;
129
+ return text.slice(startIdx + AUTO_SUMMARY_START.length, endIdx).trim();
130
+ }
131
+ function formatNoteTimestamp(value) {
132
+ return value.replace(/\.\d{3}Z$/, "Z");
133
+ }
134
+ export function renderPrHandoffNotes(notes) {
135
+ if (notes.length === 0) {
136
+ return ["- No handoff notes recorded yet. Use `agentplane pr note ...` to append one."];
137
+ }
138
+ return notes.map((note) => `- ${formatNoteTimestamp(note.created_at)} ${note.author}: ${note.body}`);
139
+ }
140
+ export function updateHandoffNotesBlock(text, notes) {
141
+ const markerIdx = text.indexOf(HANDOFF_NOTES_MARKER);
142
+ const nextIdx = markerIdx === -1
143
+ ? text.indexOf(AUTO_SUMMARY_START)
144
+ : text.indexOf(AUTO_SUMMARY_START, markerIdx);
145
+ const renderedNotes = renderPrHandoffNotes(notes).join("\n");
146
+ if (markerIdx === -1) {
147
+ if (nextIdx === -1) {
148
+ return `${text.trimEnd()}\n\n${HANDOFF_NOTES_MARKER}\n\n${renderedNotes}\n`;
149
+ }
150
+ return `${text.slice(0, nextIdx).trimEnd()}\n\n${HANDOFF_NOTES_MARKER}\n\n${renderedNotes}\n\n${text.slice(nextIdx)}`;
151
+ }
152
+ const before = text.slice(0, markerIdx + HANDOFF_NOTES_MARKER.length);
153
+ const after = nextIdx === -1 ? "" : text.slice(nextIdx);
154
+ return `${before}\n\n${renderedNotes}\n\n${after}`.trimEnd() + "\n";
155
+ }
156
+ export function renderPrReviewDocument(opts) {
157
+ return [
158
+ "# PR Review",
159
+ "",
160
+ `Created: ${opts.createdAt || "UNKNOWN"}`,
161
+ `Branch: ${opts.branch || "UNKNOWN"}`,
162
+ "",
163
+ ...renderSharedPrSections({
164
+ task: opts.task,
165
+ handoffNotes: opts.handoffNotes ?? [],
166
+ }),
167
+ AUTO_SUMMARY_START,
168
+ opts.autoSummary,
169
+ AUTO_SUMMARY_END,
170
+ "",
171
+ ].join("\n");
172
+ }
173
+ export function renderGithubPrBody(opts) {
174
+ return [
175
+ ...renderSharedPrSections({
176
+ task: opts.task,
177
+ handoffNotes: opts.handoffNotes ?? [],
178
+ }),
179
+ opts.autoSummary,
180
+ "",
181
+ ].join("\n");
49
182
  }
50
183
  export function validateReviewContents(review, errors) {
51
- const requiredSections = ["## Summary", "## Checklist", "## Handoff Notes"];
184
+ const requiredSections = [
185
+ SUMMARY_SECTION,
186
+ SCOPE_SECTION,
187
+ VERIFICATION_SECTION,
188
+ RISKS_SECTION,
189
+ HANDOFF_NOTES_MARKER,
190
+ ];
52
191
  for (const section of requiredSections) {
53
192
  if (!review.includes(section))
54
193
  errors.push(`Missing section: ${section}`);
55
194
  }
56
- if (!review.includes("<!-- BEGIN AUTO SUMMARY -->")) {
195
+ if (!review.includes(AUTO_SUMMARY_START)) {
57
196
  errors.push("Missing auto summary start marker");
58
197
  }
59
- if (!review.includes("<!-- END AUTO SUMMARY -->")) {
198
+ if (!review.includes(AUTO_SUMMARY_END)) {
60
199
  errors.push("Missing auto summary end marker");
61
200
  }
62
201
  }
202
+ export function validateGithubPrBodyContents(body, errors) {
203
+ const requiredSections = [
204
+ SUMMARY_SECTION,
205
+ SCOPE_SECTION,
206
+ VERIFICATION_SECTION,
207
+ RISKS_SECTION,
208
+ HANDOFF_NOTES_MARKER,
209
+ ];
210
+ for (const section of requiredSections) {
211
+ if (!body.includes(section))
212
+ errors.push(`Missing section: ${section}`);
213
+ }
214
+ if (!body.includes("<details>")) {
215
+ errors.push("Missing raw evidence details block");
216
+ }
217
+ }
@@ -0,0 +1,32 @@
1
+ import { type CommandContext } from "../../shared/task-backend.js";
2
+ type PrSyncMode = "open" | "update";
3
+ export declare function ensurePrArtifactsSynced(opts: {
4
+ ctx?: CommandContext;
5
+ cwd: string;
6
+ rootOverride?: string;
7
+ taskId: string;
8
+ author?: string;
9
+ branch?: string;
10
+ }): Promise<{
11
+ branch: string;
12
+ prDir: string;
13
+ resolved: {
14
+ gitRoot: string;
15
+ };
16
+ } | null>;
17
+ export declare function syncPrArtifacts(opts: {
18
+ ctx?: CommandContext;
19
+ cwd: string;
20
+ rootOverride?: string;
21
+ taskId: string;
22
+ mode: PrSyncMode;
23
+ author?: string;
24
+ branch?: string;
25
+ }): Promise<{
26
+ prDir: string;
27
+ resolved: {
28
+ gitRoot: string;
29
+ };
30
+ }>;
31
+ export {};
32
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/sync.ts"],"names":[],"mappings":"AAoBA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAoCtC,KAAK,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAmCpC,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B,GAAG,IAAI,CAAC,CA8CR;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B,CAAC,CAkLD"}
@@ -0,0 +1,258 @@
1
+ import { mkdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { resolveBaseBranch } from "@agentplaneorg/core";
4
+ import { mapBackendError } from "../../../cli/error-map.js";
5
+ import { exitCodeForError } from "../../../cli/exit-codes.js";
6
+ import { fileExists } from "../../../cli/fs-utils.js";
7
+ import { workflowModeMessage } from "../../../cli/output.js";
8
+ import { CliError } from "../../../shared/errors.js";
9
+ import { writeJsonStableIfChanged, writeTextIfChanged } from "../../../shared/write-if-changed.js";
10
+ import { execFileAsync, gitEnv } from "../../shared/git.js";
11
+ import { gitCurrentBranch } from "../../shared/git-ops.js";
12
+ import { parseTaskIdFromBranch } from "../../shared/git-worktree.js";
13
+ import { buildOpenedPrMeta, buildUpdatedPrMeta, parsePrMeta, } from "../../shared/pr-meta.js";
14
+ import { loadBackendTask, loadCommandContext, } from "../../shared/task-backend.js";
15
+ import { resolvePrPaths } from "./pr-paths.js";
16
+ import { readPrHandoffNotes } from "./note-store.js";
17
+ import { buildGithubPrTitle, renderGithubPrBody, renderPrAutoSummary, renderPrReviewDocument, } from "./review-template.js";
18
+ function nowIso() {
19
+ return new Date().toISOString();
20
+ }
21
+ function isUnknownRevisionError(err) {
22
+ const message = err instanceof Error ? err.message : String(err);
23
+ return /unknown revision or path not in the working tree/i.test(message);
24
+ }
25
+ async function resolveBranchHeadSha(opts) {
26
+ try {
27
+ const { stdout } = await execFileAsync("git", ["rev-parse", opts.branch], {
28
+ cwd: opts.gitRoot,
29
+ env: gitEnv(),
30
+ });
31
+ return stdout.trim() || null;
32
+ }
33
+ catch (err) {
34
+ if (!isUnknownRevisionError(err))
35
+ throw err;
36
+ return null;
37
+ }
38
+ }
39
+ async function resolvePrSyncBranch(opts) {
40
+ const explicitBranch = opts.branch?.trim() ?? "";
41
+ if (explicitBranch) {
42
+ return { branch: explicitBranch, source: "explicit" };
43
+ }
44
+ if (await fileExists(opts.metaPath)) {
45
+ const metaBranch = parsePrMeta(await readFile(opts.metaPath, "utf8"), opts.taskId).branch?.trim() ?? "";
46
+ if (metaBranch) {
47
+ return { branch: metaBranch, source: "meta" };
48
+ }
49
+ }
50
+ const currentBranchValue = await gitCurrentBranch(opts.resolved.gitRoot);
51
+ const currentBranch = currentBranchValue.trim();
52
+ if (currentBranch) {
53
+ return { branch: currentBranch, source: "current" };
54
+ }
55
+ return { branch: null, source: "none" };
56
+ }
57
+ export async function ensurePrArtifactsSynced(opts) {
58
+ const ctx = opts.ctx ??
59
+ (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
60
+ const { resolved, config, metaPath } = await resolvePrPaths({ ...opts, ctx });
61
+ if (config.workflow_mode !== "branch_pr")
62
+ return null;
63
+ const resolvedBranch = await resolvePrSyncBranch({
64
+ resolved,
65
+ metaPath,
66
+ taskId: opts.taskId,
67
+ branch: opts.branch,
68
+ });
69
+ const branch = resolvedBranch.branch?.trim() ?? "";
70
+ if (!branch)
71
+ return null;
72
+ if (resolvedBranch.source === "current" &&
73
+ parseTaskIdFromBranch(config.branch.task_prefix, branch) !== opts.taskId) {
74
+ return null;
75
+ }
76
+ const baseBranch = await resolveBaseBranch({
77
+ cwd: opts.cwd,
78
+ rootOverride: opts.rootOverride ?? null,
79
+ cliBaseOpt: null,
80
+ mode: config.workflow_mode,
81
+ });
82
+ if (resolvedBranch.source === "current" && baseBranch && branch === baseBranch) {
83
+ return null;
84
+ }
85
+ await syncPrArtifacts({
86
+ ...opts,
87
+ ctx,
88
+ mode: "open",
89
+ author: opts.author,
90
+ branch,
91
+ });
92
+ const result = await syncPrArtifacts({
93
+ ...opts,
94
+ ctx,
95
+ mode: "update",
96
+ branch,
97
+ });
98
+ return { ...result, branch };
99
+ }
100
+ export async function syncPrArtifacts(opts) {
101
+ try {
102
+ const ctx = opts.ctx ??
103
+ (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
104
+ const { task } = await loadBackendTask({
105
+ ctx,
106
+ cwd: opts.cwd,
107
+ rootOverride: opts.rootOverride,
108
+ taskId: opts.taskId,
109
+ });
110
+ const { resolved, config, prDir, metaPath, diffstatPath, notesPath, verifyLogPath, reviewPath, githubTitlePath, githubBodyPath, } = await resolvePrPaths({ ...opts, ctx });
111
+ if (config.workflow_mode !== "branch_pr") {
112
+ throw new CliError({
113
+ exitCode: exitCodeForError("E_USAGE"),
114
+ code: "E_USAGE",
115
+ message: workflowModeMessage(config.workflow_mode, "branch_pr"),
116
+ });
117
+ }
118
+ const resolvedBranch = await resolvePrSyncBranch({
119
+ resolved,
120
+ metaPath,
121
+ taskId: task.id,
122
+ branch: opts.branch,
123
+ });
124
+ const branch = resolvedBranch.branch?.trim() ?? "";
125
+ if (!branch) {
126
+ throw new CliError({
127
+ exitCode: exitCodeForError("E_USAGE"),
128
+ code: "E_USAGE",
129
+ message: "Branch could not be resolved (use --branch).",
130
+ });
131
+ }
132
+ const metaExists = await fileExists(metaPath);
133
+ const reviewExists = await fileExists(reviewPath);
134
+ if (opts.mode === "update" && (!metaExists || !reviewExists)) {
135
+ const missing = [];
136
+ if (!metaExists)
137
+ missing.push(path.relative(resolved.gitRoot, metaPath));
138
+ if (!reviewExists)
139
+ missing.push(path.relative(resolved.gitRoot, reviewPath));
140
+ throw new CliError({
141
+ exitCode: exitCodeForError("E_VALIDATION"),
142
+ code: "E_VALIDATION",
143
+ message: `PR artifacts missing: ${missing.join(", ")} (run \`agentplane pr open\`)`,
144
+ });
145
+ }
146
+ await mkdir(prDir, { recursive: true });
147
+ const existingMeta = metaExists && (await fileExists(metaPath))
148
+ ? parsePrMeta(await readFile(metaPath, "utf8"), task.id)
149
+ : null;
150
+ const handoffNotes = await readPrHandoffNotes(notesPath);
151
+ const now = nowIso();
152
+ const createdAt = existingMeta?.created_at ?? now;
153
+ const baseBranch = await resolveBaseBranch({
154
+ cwd: opts.cwd,
155
+ rootOverride: opts.rootOverride ?? null,
156
+ cliBaseOpt: null,
157
+ mode: config.workflow_mode,
158
+ });
159
+ const headSha = await resolveBranchHeadSha({ gitRoot: resolved.gitRoot, branch });
160
+ if (opts.mode === "open") {
161
+ const nextMeta = buildOpenedPrMeta({
162
+ taskId: task.id,
163
+ branch,
164
+ at: now,
165
+ previousMeta: existingMeta,
166
+ base: baseBranch,
167
+ headSha,
168
+ });
169
+ const nextAutoSummary = renderPrAutoSummary({
170
+ updatedAt: nextMeta.updated_at,
171
+ branch,
172
+ headSha,
173
+ diffstat: "",
174
+ });
175
+ const nextReview = renderPrReviewDocument({
176
+ task,
177
+ author: opts.author,
178
+ createdAt,
179
+ branch,
180
+ handoffNotes,
181
+ autoSummary: nextAutoSummary,
182
+ });
183
+ const githubTitle = buildGithubPrTitle(task);
184
+ const githubBody = renderGithubPrBody({
185
+ task,
186
+ handoffNotes,
187
+ autoSummary: nextAutoSummary,
188
+ });
189
+ await writeJsonStableIfChanged(metaPath, nextMeta);
190
+ if (!(await fileExists(diffstatPath))) {
191
+ await writeTextIfChanged(diffstatPath, "");
192
+ }
193
+ if (!(await fileExists(notesPath))) {
194
+ await writeTextIfChanged(notesPath, "");
195
+ }
196
+ if (!(await fileExists(verifyLogPath))) {
197
+ await writeTextIfChanged(verifyLogPath, "");
198
+ }
199
+ await writeTextIfChanged(reviewPath, nextReview);
200
+ await writeTextIfChanged(githubTitlePath, `${githubTitle}\n`);
201
+ await writeTextIfChanged(githubBodyPath, githubBody);
202
+ return { prDir, resolved };
203
+ }
204
+ if (!baseBranch) {
205
+ throw new CliError({
206
+ exitCode: exitCodeForError("E_USAGE"),
207
+ code: "E_USAGE",
208
+ message: "Base branch could not be resolved (use `agentplane branch base set`).",
209
+ });
210
+ }
211
+ let diffstat = "";
212
+ try {
213
+ const { stdout: diffStatOut } = await execFileAsync("git", ["diff", "--stat", `${baseBranch}...${branch}`], { cwd: resolved.gitRoot, env: gitEnv() });
214
+ diffstat = diffStatOut.trimEnd();
215
+ }
216
+ catch (err) {
217
+ if (!isUnknownRevisionError(err))
218
+ throw err;
219
+ }
220
+ const nextMeta = buildUpdatedPrMeta({
221
+ meta: existingMeta,
222
+ branch,
223
+ at: now,
224
+ base: baseBranch,
225
+ headSha,
226
+ });
227
+ const nextAutoSummary = renderPrAutoSummary({
228
+ updatedAt: nextMeta.updated_at,
229
+ branch,
230
+ headSha,
231
+ diffstat,
232
+ });
233
+ const nextReview = renderPrReviewDocument({
234
+ task,
235
+ createdAt,
236
+ branch,
237
+ handoffNotes,
238
+ autoSummary: nextAutoSummary,
239
+ });
240
+ const githubTitle = buildGithubPrTitle(task);
241
+ const githubBody = renderGithubPrBody({
242
+ task,
243
+ handoffNotes,
244
+ autoSummary: nextAutoSummary,
245
+ });
246
+ await writeTextIfChanged(diffstatPath, diffstat ? `${diffstat}\n` : "");
247
+ await writeTextIfChanged(reviewPath, nextReview);
248
+ await writeTextIfChanged(githubTitlePath, `${githubTitle}\n`);
249
+ await writeTextIfChanged(githubBodyPath, githubBody);
250
+ await writeJsonStableIfChanged(metaPath, nextMeta);
251
+ return { prDir, resolved };
252
+ }
253
+ catch (err) {
254
+ if (err instanceof CliError)
255
+ throw err;
256
+ throw mapBackendError(err, { command: "pr sync", root: opts.rootOverride ?? null });
257
+ }
258
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/note.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKpF,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,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,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDlB"}
1
+ {"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/note.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgBnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,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,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFlB"}
@@ -6,9 +6,11 @@ import { exitCodeForError } from "../../cli/exit-codes.js";
6
6
  import { fileExists } from "../../cli/fs-utils.js";
7
7
  import { createCliEmitter, workflowModeMessage } from "../../cli/output.js";
8
8
  import { CliError } from "../../shared/errors.js";
9
- import { loadCommandContext } from "../shared/task-backend.js";
9
+ import { loadBackendTask, loadCommandContext, } from "../shared/task-backend.js";
10
10
  import { resolvePrPaths } from "./internal/pr-paths.js";
11
- import { appendHandoffNote } from "./internal/review-template.js";
11
+ import { appendPrHandoffNote, buildPrHandoffNote, readPrHandoffNotes, } from "./internal/note-store.js";
12
+ import { buildGithubPrTitle, extractAutoSummaryBlock, renderGithubPrBody, renderPrReviewDocument, } from "./internal/review-template.js";
13
+ import { parsePrMeta } from "../shared/pr-meta.js";
12
14
  export async function cmdPrNote(opts) {
13
15
  try {
14
16
  const output = createCliEmitter();
@@ -30,7 +32,13 @@ export async function cmdPrNote(opts) {
30
32
  }
31
33
  const ctx = opts.ctx ??
32
34
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
33
- const { config, reviewPath, resolved } = await resolvePrPaths({ ...opts, ctx });
35
+ const { task } = await loadBackendTask({
36
+ ctx,
37
+ cwd: opts.cwd,
38
+ rootOverride: opts.rootOverride,
39
+ taskId: opts.taskId,
40
+ });
41
+ const { config, reviewPath, notesPath, githubTitlePath, githubBodyPath, metaPath, resolved } = await resolvePrPaths({ ...opts, ctx });
34
42
  if (config.workflow_mode !== "branch_pr") {
35
43
  throw new CliError({
36
44
  exitCode: exitCodeForError("E_USAGE"),
@@ -47,8 +55,33 @@ export async function cmdPrNote(opts) {
47
55
  });
48
56
  }
49
57
  const review = await readFile(reviewPath, "utf8");
50
- const updated = appendHandoffNote(review, `${author}: ${body}`);
58
+ const meta = parsePrMeta(await readFile(metaPath, "utf8"), opts.taskId);
59
+ await appendPrHandoffNote({
60
+ notesPath,
61
+ note: buildPrHandoffNote({
62
+ createdAt: new Date().toISOString(),
63
+ author,
64
+ body,
65
+ }),
66
+ });
67
+ const handoffNotes = await readPrHandoffNotes(notesPath);
68
+ const autoSummary = extractAutoSummaryBlock(review) ?? "";
69
+ const updated = renderPrReviewDocument({
70
+ task,
71
+ createdAt: meta.created_at ?? "",
72
+ branch: meta.branch ?? "",
73
+ handoffNotes,
74
+ autoSummary,
75
+ });
76
+ const githubTitle = buildGithubPrTitle(task);
77
+ const githubBody = renderGithubPrBody({
78
+ task,
79
+ handoffNotes,
80
+ autoSummary,
81
+ });
51
82
  await atomicWriteFile(reviewPath, updated, "utf8");
83
+ await atomicWriteFile(githubTitlePath, `${githubTitle}\n`, "utf8");
84
+ await atomicWriteFile(githubBodyPath, githubBody, "utf8");
52
85
  output.success("pr note", opts.taskId);
53
86
  return 0;
54
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AASnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,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;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuElB"}
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,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;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB"}