agentplane 0.3.11 → 0.3.13

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 (259) hide show
  1. package/assets/AGENTS.md +2 -2
  2. package/assets/RUNNER.md +1 -1
  3. package/assets/agents/CODER.json +4 -0
  4. package/assets/agents/CREATOR.json +1 -0
  5. package/assets/agents/DOCS.json +2 -1
  6. package/assets/agents/INTEGRATOR.json +2 -1
  7. package/assets/agents/ORCHESTRATOR.json +3 -1
  8. package/assets/agents/PLANNER.json +3 -1
  9. package/assets/agents/REVIEWER.json +1 -0
  10. package/assets/agents/TESTER.json +2 -2
  11. package/assets/agents/UPDATER.json +1 -0
  12. package/assets/agents/UPGRADER.json +1 -1
  13. package/assets/codex-plugin/assets/header.png +0 -0
  14. package/assets/codex-plugin/assets/icon.svg +1 -0
  15. package/assets/codex-plugin/assets/logo.svg +1 -0
  16. package/assets/codex-plugin/skills/agentplane/SKILL.md +35 -0
  17. package/assets/policy/governance.md +4 -2
  18. package/assets/policy/incidents.md +3 -19
  19. package/assets/policy/workflow.release.md +5 -2
  20. package/bin/agentplane.js +58 -3
  21. package/bin/stale-dist-policy.js +6 -1
  22. package/dist/.build-manifest.json +271 -161
  23. package/dist/cli/exit-codes.d.ts.map +1 -1
  24. package/dist/cli/exit-codes.js +1 -0
  25. package/dist/cli/reason-codes.d.ts +1 -1
  26. package/dist/cli/reason-codes.d.ts.map +1 -1
  27. package/dist/cli/reason-codes.js +12 -0
  28. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  29. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  30. package/dist/cli/run-cli/command-catalog/core.js +22 -1
  31. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  32. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  33. package/dist/cli/run-cli/command-catalog/project.js +21 -3
  34. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  35. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  36. package/dist/cli/run-cli/commands/codex.d.ts +14 -0
  37. package/dist/cli/run-cli/commands/codex.d.ts.map +1 -0
  38. package/dist/cli/run-cli/commands/codex.js +100 -0
  39. package/dist/cli/run-cli/commands/core.d.ts +1 -0
  40. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  41. package/dist/cli/run-cli/commands/core.js +1 -0
  42. package/dist/cli/run-cli/commands/init/recipes.d.ts +9 -1
  43. package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
  44. package/dist/cli/run-cli/commands/init/recipes.js +32 -22
  45. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  46. package/dist/cli/run-cli/commands/init.js +26 -21
  47. package/dist/cli/run-cli/error-guidance.js +20 -0
  48. package/dist/cli/run-cli.test-helpers.d.ts +1 -0
  49. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  50. package/dist/cli/run-cli.test-helpers.js +36 -19
  51. package/dist/commands/branch/cleanup-merged.d.ts +1 -0
  52. package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
  53. package/dist/commands/branch/cleanup-merged.js +18 -9
  54. package/dist/commands/branch/work-start.d.ts.map +1 -1
  55. package/dist/commands/branch/work-start.js +82 -5
  56. package/dist/commands/codex/plugin-install.d.ts +26 -0
  57. package/dist/commands/codex/plugin-install.d.ts.map +1 -0
  58. package/dist/commands/codex/plugin-install.js +209 -0
  59. package/dist/commands/doctor/branch-pr.js +2 -2
  60. package/dist/commands/guard/impl/commands.d.ts +1 -0
  61. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  62. package/dist/commands/guard/impl/commands.js +78 -8
  63. package/dist/commands/hooks/index.d.ts +1 -1
  64. package/dist/commands/hooks/index.d.ts.map +1 -1
  65. package/dist/commands/hooks/index.js +48 -12
  66. package/dist/commands/pr/check.d.ts.map +1 -1
  67. package/dist/commands/pr/check.js +3 -0
  68. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  69. package/dist/commands/pr/integrate/cmd.js +103 -2
  70. package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
  71. package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
  72. package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
  73. package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
  74. package/dist/commands/pr/integrate/internal/finalize.js +3 -0
  75. package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
  76. package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
  77. package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
  78. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
  79. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
  80. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
  81. package/dist/commands/pr/integrate/internal/prepare.d.ts +1 -0
  82. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  83. package/dist/commands/pr/integrate/internal/prepare.js +46 -7
  84. package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
  85. package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
  86. package/dist/commands/pr/internal/auto-commit.js +69 -0
  87. package/dist/commands/pr/internal/freshness.d.ts +1 -0
  88. package/dist/commands/pr/internal/freshness.d.ts.map +1 -1
  89. package/dist/commands/pr/internal/freshness.js +2 -0
  90. package/dist/commands/pr/internal/sync.d.ts.map +1 -1
  91. package/dist/commands/pr/internal/sync.js +98 -27
  92. package/dist/commands/pr/open.d.ts.map +1 -1
  93. package/dist/commands/pr/open.js +52 -3
  94. package/dist/commands/pr/update.d.ts.map +1 -1
  95. package/dist/commands/pr/update.js +13 -2
  96. package/dist/commands/recipes/active.command.d.ts +7 -0
  97. package/dist/commands/recipes/active.command.d.ts.map +1 -0
  98. package/dist/commands/recipes/active.command.js +12 -0
  99. package/dist/commands/recipes/add.command.d.ts +8 -0
  100. package/dist/commands/recipes/add.command.d.ts.map +1 -0
  101. package/dist/commands/recipes/add.command.js +33 -0
  102. package/dist/commands/recipes/detach.command.d.ts +7 -0
  103. package/dist/commands/recipes/detach.command.d.ts.map +1 -0
  104. package/dist/commands/recipes/detach.command.js +19 -0
  105. package/dist/commands/recipes/disable.command.d.ts +7 -0
  106. package/dist/commands/recipes/disable.command.d.ts.map +1 -0
  107. package/dist/commands/recipes/disable.command.js +10 -0
  108. package/dist/commands/recipes/enable.command.d.ts +7 -0
  109. package/dist/commands/recipes/enable.command.d.ts.map +1 -0
  110. package/dist/commands/recipes/enable.command.js +10 -0
  111. package/dist/commands/recipes/explain-active.command.d.ts +5 -0
  112. package/dist/commands/recipes/explain-active.command.d.ts.map +1 -0
  113. package/dist/commands/recipes/explain-active.command.js +11 -0
  114. package/dist/commands/recipes/explain.command.d.ts.map +1 -1
  115. package/dist/commands/recipes/explain.command.js +4 -2
  116. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  117. package/dist/commands/recipes/impl/apply.js +33 -14
  118. package/dist/commands/recipes/impl/commands/active.d.ts +6 -0
  119. package/dist/commands/recipes/impl/commands/active.d.ts.map +1 -0
  120. package/dist/commands/recipes/impl/commands/active.js +46 -0
  121. package/dist/commands/recipes/impl/commands/add.d.ts +7 -0
  122. package/dist/commands/recipes/impl/commands/add.d.ts.map +1 -0
  123. package/dist/commands/recipes/impl/commands/add.js +100 -0
  124. package/dist/commands/recipes/impl/commands/detach.d.ts +6 -0
  125. package/dist/commands/recipes/impl/commands/detach.d.ts.map +1 -0
  126. package/dist/commands/recipes/impl/commands/detach.js +85 -0
  127. package/dist/commands/recipes/impl/commands/disable.d.ts +6 -0
  128. package/dist/commands/recipes/impl/commands/disable.d.ts.map +1 -0
  129. package/dist/commands/recipes/impl/commands/disable.js +21 -0
  130. package/dist/commands/recipes/impl/commands/enable.d.ts +6 -0
  131. package/dist/commands/recipes/impl/commands/enable.d.ts.map +1 -0
  132. package/dist/commands/recipes/impl/commands/enable.js +39 -0
  133. package/dist/commands/recipes/impl/commands/explain-active.d.ts +5 -0
  134. package/dist/commands/recipes/impl/commands/explain-active.d.ts.map +1 -0
  135. package/dist/commands/recipes/impl/commands/explain-active.js +20 -0
  136. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  137. package/dist/commands/recipes/impl/commands/explain.js +40 -3
  138. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  139. package/dist/commands/recipes/impl/commands/info.js +21 -8
  140. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  141. package/dist/commands/recipes/impl/commands/install.js +32 -29
  142. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  143. package/dist/commands/recipes/impl/commands/list.js +11 -11
  144. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  145. package/dist/commands/recipes/impl/commands/remove.js +5 -0
  146. package/dist/commands/recipes/impl/commands/update.d.ts +7 -0
  147. package/dist/commands/recipes/impl/commands/update.d.ts.map +1 -0
  148. package/dist/commands/recipes/impl/commands/update.js +93 -0
  149. package/dist/commands/recipes/impl/commands.d.ts +7 -0
  150. package/dist/commands/recipes/impl/commands.d.ts.map +1 -1
  151. package/dist/commands/recipes/impl/commands.js +7 -0
  152. package/dist/commands/recipes/impl/constants.d.ts +1 -14
  153. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  154. package/dist/commands/recipes/impl/constants.js +1 -18
  155. package/dist/commands/recipes/impl/manifest.d.ts +2 -2
  156. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  157. package/dist/commands/recipes/impl/manifest.js +4 -226
  158. package/dist/commands/recipes/impl/overlay-project.d.ts +32 -0
  159. package/dist/commands/recipes/impl/overlay-project.d.ts.map +1 -0
  160. package/dist/commands/recipes/impl/overlay-project.js +282 -0
  161. package/dist/commands/recipes/impl/paths.d.ts +20 -2
  162. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  163. package/dist/commands/recipes/impl/paths.js +23 -5
  164. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +2 -4
  165. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
  166. package/dist/commands/recipes/impl/project-installed-recipes.js +30 -74
  167. package/dist/commands/recipes/impl/project-recipe-state.d.ts +18 -0
  168. package/dist/commands/recipes/impl/project-recipe-state.d.ts.map +1 -0
  169. package/dist/commands/recipes/impl/project-recipe-state.js +94 -0
  170. package/dist/commands/recipes/impl/project-registry.d.ts +20 -0
  171. package/dist/commands/recipes/impl/project-registry.d.ts.map +1 -0
  172. package/dist/commands/recipes/impl/project-registry.js +104 -0
  173. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
  174. package/dist/commands/recipes/impl/resolver.js +5 -3
  175. package/dist/commands/recipes/impl/types.d.ts +1 -240
  176. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  177. package/dist/commands/recipes/info.command.js +2 -2
  178. package/dist/commands/recipes/install.spec.js +4 -4
  179. package/dist/commands/recipes/list.command.js +4 -4
  180. package/dist/commands/recipes/remove.command.js +2 -2
  181. package/dist/commands/recipes/update.command.d.ts +8 -0
  182. package/dist/commands/recipes/update.command.d.ts.map +1 -0
  183. package/dist/commands/recipes/update.command.js +35 -0
  184. package/dist/commands/recipes.d.ts +7 -4
  185. package/dist/commands/recipes.d.ts.map +1 -1
  186. package/dist/commands/recipes.js +6 -3
  187. package/dist/commands/recipes.test-helpers.d.ts +3 -3
  188. package/dist/commands/recipes.test-helpers.d.ts.map +1 -1
  189. package/dist/commands/recipes.test-helpers.js +105 -15
  190. package/dist/commands/release/apply.command.d.ts +3 -1
  191. package/dist/commands/release/apply.command.d.ts.map +1 -1
  192. package/dist/commands/release/apply.command.js +354 -18
  193. package/dist/commands/release/apply.mutation.d.ts.map +1 -1
  194. package/dist/commands/release/apply.mutation.js +1 -0
  195. package/dist/commands/release/apply.reporting.d.ts +1 -0
  196. package/dist/commands/release/apply.reporting.d.ts.map +1 -1
  197. package/dist/commands/release/apply.reporting.js +12 -8
  198. package/dist/commands/release/apply.types.d.ts +13 -0
  199. package/dist/commands/release/apply.types.d.ts.map +1 -1
  200. package/dist/commands/release/plan.command.d.ts.map +1 -1
  201. package/dist/commands/release/plan.command.js +48 -0
  202. package/dist/commands/scenario/execute.command.js +4 -4
  203. package/dist/commands/scenario/impl/commands.js +4 -4
  204. package/dist/commands/scenario/info.command.js +4 -4
  205. package/dist/commands/scenario/list.command.js +3 -3
  206. package/dist/commands/scenario/run.command.js +5 -5
  207. package/dist/commands/scenario/scenario.command.js +7 -7
  208. package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
  209. package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
  210. package/dist/commands/shared/merged-branch-cleanup.js +46 -0
  211. package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -1
  212. package/dist/commands/shared/post-commit-pr-artifacts.js +35 -0
  213. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  214. package/dist/commands/shared/task-backend.js +37 -5
  215. package/dist/commands/shared/task-handoff.d.ts +2 -1
  216. package/dist/commands/shared/task-handoff.d.ts.map +1 -1
  217. package/dist/commands/shared/task-handoff.js +15 -0
  218. package/dist/commands/shared/task-local-freshness.d.ts +2 -0
  219. package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
  220. package/dist/commands/shared/task-local-freshness.js +7 -1
  221. package/dist/commands/task/finish-shared.d.ts +1 -0
  222. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  223. package/dist/commands/task/finish-shared.js +1 -0
  224. package/dist/commands/task/handoff-show.command.d.ts.map +1 -1
  225. package/dist/commands/task/handoff-show.command.js +24 -0
  226. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
  227. package/dist/commands/task/hosted-close-pr.command.js +35 -0
  228. package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
  229. package/dist/commands/task/hosted-close.command.js +185 -18
  230. package/dist/commands/task/hosted-merge-sync.d.ts +4 -1
  231. package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
  232. package/dist/commands/task/hosted-merge-sync.js +52 -10
  233. package/dist/commands/task/start-ready.d.ts.map +1 -1
  234. package/dist/commands/task/start-ready.js +0 -86
  235. package/dist/runner/context/base-prompts.d.ts +2 -1
  236. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  237. package/dist/runner/context/base-prompts.js +109 -13
  238. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  239. package/dist/runner/context/recipe-context.js +40 -8
  240. package/dist/runner/types.d.ts +4 -0
  241. package/dist/runner/types.d.ts.map +1 -1
  242. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  243. package/dist/runner/usecases/task-run.js +2 -1
  244. package/dist/runtime/behavior/resolve.d.ts +2 -1
  245. package/dist/runtime/behavior/resolve.d.ts.map +1 -1
  246. package/dist/runtime/behavior/resolve.js +25 -5
  247. package/dist/runtime/behavior/types.d.ts +1 -0
  248. package/dist/runtime/behavior/types.d.ts.map +1 -1
  249. package/dist/runtime/capabilities/recipe.d.ts +2 -1
  250. package/dist/runtime/capabilities/recipe.d.ts.map +1 -1
  251. package/dist/runtime/capabilities/recipe.js +88 -28
  252. package/dist/shared/errors.d.ts +1 -1
  253. package/dist/shared/errors.d.ts.map +1 -1
  254. package/dist/shared/runtime-source.d.ts.map +1 -1
  255. package/dist/shared/runtime-source.js +8 -3
  256. package/package.json +3 -2
  257. package/dist/cli/recipes-bundled.d.ts +0 -10
  258. package/dist/cli/recipes-bundled.d.ts.map +0 -1
  259. package/dist/cli/recipes-bundled.js +0 -36
@@ -1,5 +1,6 @@
1
1
  import { mkdir, rm, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { extractTaskSuffix } from "@agentplaneorg/core";
3
4
  import { resolveTaskIndexPath } from "../../../backends/task-index.js";
4
5
  import { mapCoreError } from "../../../cli/error-map.js";
5
6
  import { infoMessage, successMessage } from "../../../cli/output.js";
@@ -7,6 +8,7 @@ import { stripAnsi } from "../../../cli/shared/ansi.js";
7
8
  import { withDiagnosticContext } from "../../../shared/diagnostics.js";
8
9
  import { CliError } from "../../../shared/errors.js";
9
10
  import { refreshBranchPrArtifactsAfterTaskCommit } from "../../shared/post-commit-pr-artifacts.js";
11
+ import { isTaskLocalAdvancePath } from "../../shared/task-local-freshness.js";
10
12
  import { loadCommandContext } from "../../shared/task-backend.js";
11
13
  import { loadTaskFromContext } from "../../shared/task-backend.js";
12
14
  import { execFileAsync, gitEnv } from "../../shared/git.js";
@@ -111,6 +113,64 @@ function detectCommitFailureSignal(output) {
111
113
  }
112
114
  return null;
113
115
  }
116
+ function taskArtifactRefreshCommitMessage(taskId) {
117
+ return `📝 ${extractTaskSuffix(taskId)} task: refresh PR artifacts`;
118
+ }
119
+ async function commitRefreshedTaskArtifacts(opts) {
120
+ const changedPaths = await opts.ctx.git.statusChangedPaths();
121
+ const taskArtifactPaths = changedPaths.filter((relPath) => isTaskLocalAdvancePath({
122
+ workflowDir: opts.ctx.config.paths.workflow_dir,
123
+ taskId: opts.taskId,
124
+ tasksPath: opts.ctx.config.paths.tasks_path,
125
+ relPath,
126
+ }));
127
+ if (taskArtifactPaths.length === 0)
128
+ return false;
129
+ await stageAllowlist({
130
+ ctx: opts.ctx,
131
+ allow: [],
132
+ allowTasks: true,
133
+ allowPolicy: false,
134
+ allowConfig: false,
135
+ allowHooks: false,
136
+ allowCI: false,
137
+ tasksPath: opts.ctx.config.paths.tasks_path,
138
+ workflowDir: opts.ctx.config.paths.workflow_dir,
139
+ taskId: opts.taskId,
140
+ allowTaskOnly: true,
141
+ emptyAllowMessage: "PR artifact refresh produced no task-local files to stage for the follow-up commit.",
142
+ noMatchMessage: "PR artifact refresh produced changes outside the active task artifact scope; inspect the working tree before retrying the commit flow.",
143
+ });
144
+ const message = taskArtifactRefreshCommitMessage(opts.taskId);
145
+ await guardCommitCheck({
146
+ ctx: opts.ctx,
147
+ cwd: opts.cwd,
148
+ rootOverride: opts.rootOverride,
149
+ baseBranchOverride: null,
150
+ taskId: opts.taskId,
151
+ message,
152
+ allow: [],
153
+ allowBase: false,
154
+ allowTasks: true,
155
+ allowPolicy: false,
156
+ allowConfig: false,
157
+ allowHooks: false,
158
+ allowCI: false,
159
+ requireClean: true,
160
+ quiet: opts.quiet,
161
+ });
162
+ const env = buildGitCommitEnv({
163
+ taskId: opts.taskId,
164
+ allowTasks: true,
165
+ allowBase: false,
166
+ allowPolicy: false,
167
+ allowConfig: false,
168
+ allowHooks: false,
169
+ allowCI: false,
170
+ });
171
+ await opts.ctx.git.commit({ message, env });
172
+ return true;
173
+ }
114
174
  function commitFailureDiagnostic(phase, output) {
115
175
  const signal = detectCommitFailureSignal(output);
116
176
  if (signal === "formatter") {
@@ -327,15 +387,17 @@ export async function cmdCommit(opts) {
327
387
  return 0;
328
388
  }
329
389
  if (opts.closeStageTaskArtifacts === true) {
330
- await refreshBranchPrArtifactsAfterTaskCommit({
331
- ctx,
332
- cwd: opts.cwd,
333
- rootOverride: opts.rootOverride,
334
- taskId: opts.taskId,
335
- quiet: opts.quiet,
336
- });
390
+ if (opts.closeRefreshTaskArtifacts !== false) {
391
+ await refreshBranchPrArtifactsAfterTaskCommit({
392
+ ctx,
393
+ cwd: opts.cwd,
394
+ rootOverride: opts.rootOverride,
395
+ taskId: opts.taskId,
396
+ quiet: opts.quiet,
397
+ });
398
+ }
337
399
  // Artifact refresh writes tracked task files on disk; invalidate the memoized
338
- // porcelain snapshot so staging/cleanliness checks see the refreshed state.
400
+ // porcelain snapshot so staging/cleanliness checks see the current task artifact state.
339
401
  ctx.git.invalidateStatus();
340
402
  }
341
403
  await (opts.closeStageTaskArtifacts === true
@@ -459,6 +521,14 @@ export async function cmdCommit(opts) {
459
521
  taskId: opts.taskId,
460
522
  quiet: opts.quiet,
461
523
  });
524
+ ctx.git.invalidateStatus();
525
+ await commitRefreshedTaskArtifacts({
526
+ ctx,
527
+ cwd: opts.cwd,
528
+ rootOverride: opts.rootOverride,
529
+ taskId: opts.taskId,
530
+ quiet: opts.quiet,
531
+ });
462
532
  if (!opts.quiet) {
463
533
  const { hash, subject } = await ctx.git.headHashSubject();
464
534
  process.stdout.write(`${successMessage("committed", `${hash?.slice(0, 12) ?? ""} ${subject ?? ""}`.trim(), autoStaged.length > 0 ? `staged=${autoStaged.join(", ")}` : undefined)}\n`);
@@ -1,4 +1,4 @@
1
- export declare const HOOK_NAMES: readonly ["commit-msg", "pre-commit", "pre-push"];
1
+ export declare const HOOK_NAMES: readonly ["commit-msg", "pre-commit", "pre-push", "post-merge"];
2
2
  export declare function cmdHooksInstall(opts: {
3
3
  cwd: string;
4
4
  rootOverride?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,UAAU,mDAAoD,CAAC;AA8K5E,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiJlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,UAAU,iEAAkE,CAAC;AA8K1F,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoLlB"}
@@ -8,14 +8,16 @@ import { mapBackendError, mapCoreError } from "../../cli/error-map.js";
8
8
  import { fileExists } from "../../cli/fs-utils.js";
9
9
  import { infoMessage, successMessage } from "../../cli/output.js";
10
10
  import { CliError } from "../../shared/errors.js";
11
+ import { cmdCleanupMerged } from "../branch/index.js";
11
12
  import { GitContext } from "../shared/git-context.js";
12
13
  import { throwIfPolicyDenied } from "../shared/policy-deny.js";
13
14
  import { gitCurrentBranch, gitRevParse } from "../shared/git-ops.js";
14
15
  import { parseTaskIdFromBranch, parseTaskIdFromCloseBranch } from "../shared/git-worktree.js";
15
16
  import { isPathWithin } from "../shared/path.js";
17
+ import { loadCommandContext } from "../shared/task-backend.js";
16
18
  const HOOK_MARKER = "agentplane-hook";
17
19
  const SHIM_MARKER = "agentplane-hook-shim";
18
- export const HOOK_NAMES = ["commit-msg", "pre-commit", "pre-push"];
20
+ export const HOOK_NAMES = ["commit-msg", "pre-commit", "pre-push", "post-merge"];
19
21
  async function inferTaskIdFromBranchContext(opts) {
20
22
  try {
21
23
  const branch = await gitCurrentBranch(opts.gitRoot);
@@ -83,14 +85,14 @@ function shimScriptText() {
83
85
  "set -e",
84
86
  'SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"',
85
87
  'REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"',
86
- 'ENV_BIN="${AGENTPLANE_HOOK_RUNNER:-}"',
87
- 'if [ -n "$ENV_BIN" ] && command -v node >/dev/null 2>&1 && [ -f "$ENV_BIN" ]; then',
88
- ' exec node "$ENV_BIN" "$@"',
89
- "fi",
90
88
  'LOCAL_BIN="$REPO_ROOT/packages/agentplane/bin/agentplane.js"',
91
89
  'if command -v node >/dev/null 2>&1 && [ -f "$LOCAL_BIN" ]; then',
92
90
  ' exec node "$LOCAL_BIN" "$@"',
93
91
  "fi",
92
+ 'ENV_BIN="${AGENTPLANE_HOOK_RUNNER:-}"',
93
+ 'if [ -n "$ENV_BIN" ] && command -v node >/dev/null 2>&1 && [ -f "$ENV_BIN" ]; then',
94
+ ' exec node "$ENV_BIN" "$@"',
95
+ "fi",
94
96
  "if command -v agentplane >/dev/null 2>&1; then",
95
97
  ' exec agentplane "$@"',
96
98
  "fi",
@@ -344,18 +346,52 @@ export async function cmdHooksRun(opts) {
344
346
  env: process.env,
345
347
  encoding: "utf8",
346
348
  input: await readHookStdinUtf8(),
347
- stdio: "pipe",
349
+ stdio: ["pipe", "inherit", "inherit"],
348
350
  });
349
- if (typeof result.stdout === "string" && result.stdout.length > 0) {
350
- process.stdout.write(result.stdout);
351
- }
352
- if (typeof result.stderr === "string" && result.stderr.length > 0) {
353
- process.stderr.write(result.stderr);
354
- }
355
351
  if (result.error)
356
352
  throw result.error;
357
353
  return result.status ?? (result.signal ? 1 : 0);
358
354
  }
355
+ if (opts.hook === "post-merge") {
356
+ try {
357
+ const ctx = await loadCommandContext({
358
+ cwd: opts.cwd,
359
+ rootOverride: opts.rootOverride ?? null,
360
+ });
361
+ if (ctx.config.workflow_mode !== "branch_pr")
362
+ return 0;
363
+ const baseBranch = await resolveBaseBranch({
364
+ cwd: opts.cwd,
365
+ rootOverride: opts.rootOverride ?? null,
366
+ cliBaseOpt: null,
367
+ mode: ctx.config.workflow_mode,
368
+ });
369
+ if (!baseBranch)
370
+ return 0;
371
+ const currentBranch = await gitCurrentBranch(ctx.resolvedProject.gitRoot);
372
+ if (currentBranch !== baseBranch)
373
+ return 0;
374
+ return await cmdCleanupMerged({
375
+ ctx,
376
+ cwd: opts.cwd,
377
+ rootOverride: opts.rootOverride,
378
+ base: baseBranch,
379
+ yes: true,
380
+ archive: false,
381
+ deleteRemoteBranches: false,
382
+ fetch: false,
383
+ quiet: true,
384
+ skipUnsafeWorktrees: true,
385
+ });
386
+ }
387
+ catch (error) {
388
+ const message = error instanceof Error && error.message.trim().length > 0
389
+ ? error.message.trim()
390
+ : String(error);
391
+ process.stderr.write(`warning: post-merge cleanup skipped: ${message}\n`);
392
+ return 0;
393
+ }
394
+ }
359
395
  return 0;
360
396
  }
361
397
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/check.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgLnC,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2NlB"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/check.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAkLnC,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6NlB"}
@@ -79,6 +79,7 @@ async function evaluateSnapshotFreshness(opts) {
79
79
  const freshness = await assessPrArtifactFreshness({
80
80
  gitRoot: opts.gitRoot,
81
81
  workflowDir: opts.workflowDir,
82
+ tasksPath: opts.tasksPath,
82
83
  taskId: opts.taskId,
83
84
  branchHeadSha: opts.branchHeadSha,
84
85
  metaHeadSha: opts.snapshot.meta.head_sha ?? null,
@@ -212,6 +213,7 @@ export async function cmdPrCheck(opts) {
212
213
  snapshot: localSnapshot,
213
214
  gitRoot: resolved.gitRoot,
214
215
  workflowDir: config.paths.workflow_dir,
216
+ tasksPath: config.paths.tasks_path,
215
217
  taskId: task.id,
216
218
  branchHeadSha,
217
219
  taskVerificationState: task.verification?.state ?? null,
@@ -294,6 +296,7 @@ export async function cmdPrCheck(opts) {
294
296
  snapshot: branchSnapshot,
295
297
  gitRoot: resolved.gitRoot,
296
298
  workflowDir: config.paths.workflow_dir,
299
+ tasksPath: config.paths.tasks_path,
297
300
  taskId: task.id,
298
301
  branchHeadSha,
299
302
  taskVerificationState: task.verification?.state ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AASnE,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,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkNlB"}
1
+ {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA0EnE,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,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6QlB"}
@@ -1,17 +1,69 @@
1
1
  import path from "node:path";
2
2
  import { mapBackendError } from "../../../cli/error-map.js";
3
+ import { exitCodeForError } from "../../../cli/exit-codes.js";
3
4
  import { createCliEmitter } from "../../../cli/output.js";
5
+ import { withDiagnosticContext } from "../../../shared/diagnostics.js";
4
6
  import { CliError } from "../../../shared/errors.js";
5
7
  import { cleanupIntegratedBranch } from "./internal/cleanup.js";
6
8
  import { renderPostIntegrateBootstrapFailureGuidance, renderPostIntegrateBootstrapGuidance, shouldRecommendPostIntegrateBootstrap, } from "./internal/bootstrap-guidance.js";
7
9
  import { execFileAsync, gitEnv } from "../../shared/git.js";
8
10
  import { gitRevParse } from "../../shared/git-ops.js";
11
+ import { buildTaskHandoffArtifact, resolveTaskHandoffPaths, writeTaskHandoff, } from "../../shared/task-handoff.js";
9
12
  import { finalizeIntegrate } from "./internal/finalize.js";
10
13
  import { runMergeCommit, runRebaseFastForward, runSquashMerge } from "./internal/merge.js";
14
+ import { maybeRunPreIntegrateBootstrap } from "./internal/pre-integrate-bootstrap.js";
11
15
  import { maybeRunPostIntegrateBootstrap } from "./internal/post-integrate-bootstrap.js";
12
16
  import { prepareIntegrate } from "./internal/prepare.js";
13
17
  import { resolveWorktreeForIntegrate } from "./internal/worktree.js";
14
18
  import { runVerifyCommands } from "./verify.js";
19
+ async function recordProtectedBaseIntegrateHandoff(opts) {
20
+ const paths = resolveTaskHandoffPaths({
21
+ git_root: opts.ctx.resolvedProject.gitRoot,
22
+ workflow_dir: opts.ctx.config.paths.workflow_dir,
23
+ task_id: opts.taskId,
24
+ });
25
+ const handoffShowCommand = `agentplane task handoff show ${opts.taskId}`;
26
+ const prLabel = typeof opts.prNumber === "number" && opts.prNumber > 0
27
+ ? `GitHub PR #${opts.prNumber}`
28
+ : `the GitHub PR for branch ${opts.branch}`;
29
+ const prUrl = opts.prUrl?.trim() ?? "";
30
+ const prMetaPath = path.join(opts.ctx.config.paths.workflow_dir, opts.taskId, "pr", "meta.json");
31
+ const taskReadmePath = path.join(opts.ctx.config.paths.workflow_dir, opts.taskId, "README.md");
32
+ await writeTaskHandoff({
33
+ paths,
34
+ handoff: buildTaskHandoffArtifact({
35
+ task_id: opts.taskId,
36
+ created_at: new Date().toISOString(),
37
+ from_role: "INTEGRATOR",
38
+ reason: `Protected base ${opts.base} requires GitHub pull-request merges.`,
39
+ note: prUrl.length > 0
40
+ ? `Merge ${prLabel}: ${prUrl}. After GitHub merge, wait for Task Hosted Close, then pull ${opts.base}.`
41
+ : `Merge ${prLabel} on GitHub. After GitHub merge, wait for Task Hosted Close, then pull ${opts.base}.`,
42
+ branch: opts.branch,
43
+ base_branch: opts.base,
44
+ head_sha: opts.branchHeadSha,
45
+ workspace_root: opts.ctx.resolvedProject.gitRoot,
46
+ pr_branch: opts.branch,
47
+ route: {
48
+ kind: "protected_base_integrate",
49
+ status: "awaiting_github_merge",
50
+ local_mutation: "not_performed",
51
+ finalize_via: "github_pr_merge_then_hosted_close",
52
+ pr_number: opts.prNumber,
53
+ pr_url: prUrl.length > 0 ? prUrl : null,
54
+ handoff_show_command: handoffShowCommand,
55
+ base_pull_command: "git pull --ff-only",
56
+ },
57
+ next_actions: [
58
+ handoffShowCommand,
59
+ prUrl.length > 0 ? `Merge ${prLabel}: ${prUrl}` : `Merge ${prLabel} on GitHub`,
60
+ `Wait for Task Hosted Close to finish`,
61
+ `git pull --ff-only`,
62
+ ],
63
+ evidence_paths: [taskReadmePath, prMetaPath],
64
+ }),
65
+ });
66
+ }
15
67
  export async function cmdIntegrate(opts) {
16
68
  let tempWorktreePath = null;
17
69
  let createdTempWorktree = false;
@@ -26,7 +78,7 @@ export async function cmdIntegrate(opts) {
26
78
  base: opts.base,
27
79
  runVerify: opts.runVerify,
28
80
  });
29
- const { resolved, loadedConfig, task, prDir, metaPath, diffstatPath, verifyLogPath, metaSource, branch, base, verifyLogText, } = prepared;
81
+ const { resolved, loadedConfig, task, prDir, metaPath, diffstatPath, verifyLogPath, metaSource, branch, base, verifyLogText, protectedBaseRequiresPrMerge, } = prepared;
30
82
  const verifyCommands = prepared.verifyCommands;
31
83
  let alreadyVerifiedSha = prepared.alreadyVerifiedSha;
32
84
  let shouldRunVerify = prepared.shouldRunVerify;
@@ -34,10 +86,47 @@ export async function cmdIntegrate(opts) {
34
86
  const changedPaths = prepared.changedPaths;
35
87
  if (opts.dryRun) {
36
88
  if (!opts.quiet) {
37
- output.success("integrate dry-run", task.id, `base=${base} branch=${branch} verify=${shouldRunVerify ? "yes" : "no"}`);
89
+ output.success("integrate dry-run", task.id, `base=${base} branch=${branch} verify=${shouldRunVerify ? "yes" : "no"} route=${protectedBaseRequiresPrMerge ? "github-pr" : "local"}`);
38
90
  }
39
91
  return 0;
40
92
  }
93
+ if (protectedBaseRequiresPrMerge) {
94
+ const prNumber = typeof metaSource.pr_number === "number" && metaSource.pr_number > 0
95
+ ? metaSource.pr_number
96
+ : null;
97
+ const prUrl = typeof metaSource.pr_url === "string" ? metaSource.pr_url : null;
98
+ const prHint = prNumber === null ? `the GitHub PR for branch ${branch}` : `GitHub PR #${prNumber}`;
99
+ await recordProtectedBaseIntegrateHandoff({
100
+ ctx: prepared.ctx,
101
+ taskId: task.id,
102
+ branch,
103
+ base,
104
+ branchHeadSha,
105
+ prNumber,
106
+ prUrl,
107
+ });
108
+ throw new CliError({
109
+ exitCode: exitCodeForError("E_HANDOFF"),
110
+ code: "E_HANDOFF",
111
+ message: `Base branch ${base} requires GitHub pull-request merges; integrate will not mutate it locally. ` +
112
+ `Merge ${prHint} on GitHub, let Task Hosted Close finish the closure tail, then pull ${base}.`,
113
+ context: withDiagnosticContext({
114
+ task_id: task.id,
115
+ branch,
116
+ base_branch: base,
117
+ reason_code: "protected_base_integrate_handoff",
118
+ }, {
119
+ state: `protected-base integrate routed to GitHub merge handoff for ${task.id}`,
120
+ likelyCause: `base branch ${base} is protected by a GitHub pull-request merge policy, so local integrate must stop before mutating ${base}`,
121
+ hint: "Inspect the persisted handoff artifact for the canonical finalize route, then merge the PR on GitHub and let Task Hosted Close finish the close tail.",
122
+ nextAction: {
123
+ command: `agentplane task handoff show ${task.id}`,
124
+ reason: "inspect the persisted protected-base finalize route before continuing",
125
+ reasonCode: "protected_base_integrate_handoff",
126
+ },
127
+ }),
128
+ });
129
+ }
41
130
  const wt = await resolveWorktreeForIntegrate({
42
131
  gitRoot: resolved.gitRoot,
43
132
  worktreesDirRel: loadedConfig.paths.worktrees_dir,
@@ -66,6 +155,18 @@ export async function cmdIntegrate(opts) {
66
155
  taskId: task.id,
67
156
  })));
68
157
  }
158
+ const preBootstrapResult = await maybeRunPreIntegrateBootstrap({
159
+ gitRoot: resolved.gitRoot,
160
+ changedPaths,
161
+ });
162
+ if (preBootstrapResult.status === "failed") {
163
+ throw new CliError({
164
+ exitCode: 8,
165
+ code: "E_RUNTIME",
166
+ message: "Unable to prepare the base worktree for integrate: automatic repo-local runtime refresh " +
167
+ `failed (${preBootstrapResult.error}). Run \`bun run framework:dev:bootstrap\` in ${resolved.gitRoot} and retry integrate.`,
168
+ });
169
+ }
69
170
  const baseShaBeforeMerge = await gitRevParse(resolved.gitRoot, [base]);
70
171
  const headBeforeMerge = await gitRevParse(resolved.gitRoot, ["HEAD"]);
71
172
  let mergeHash = "";
@@ -1,12 +1,2 @@
1
- export type IntegrateCleanupResult = {
2
- removedBranch: boolean;
3
- removedWorktree: boolean;
4
- worktreePath: string | null;
5
- skippedReason: "outside_repo" | "current_worktree" | null;
6
- };
7
- export declare function cleanupIntegratedBranch(opts: {
8
- gitRoot: string;
9
- branch: string;
10
- worktreePathHint?: string | null;
11
- }): Promise<IntegrateCleanupResult>;
1
+ export { cleanupMergedLocalBranch as cleanupIntegratedBranch, type MergedBranchCleanupResult as IntegrateCleanupResult, } from "../../../shared/merged-branch-cleanup.js";
12
2
  //# sourceMappingURL=cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/cleanup.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,cAAc,GAAG,kBAAkB,GAAG,IAAI,CAAC;CAC3D,CAAC;AAEF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA4ClC"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,IAAI,uBAAuB,EACnD,KAAK,yBAAyB,IAAI,sBAAsB,GACzD,MAAM,0CAA0C,CAAC"}
@@ -1,46 +1 @@
1
- import { execFileAsync, gitEnv } from "../../../shared/git.js";
2
- import { gitBranchExists } from "../../../shared/git-ops.js";
3
- import { findWorktreeForBranch } from "../../../shared/git-worktree.js";
4
- import { isPathWithin, resolvePathFallback } from "../../../shared/path.js";
5
- export async function cleanupIntegratedBranch(opts) {
6
- const repoRoot = await resolvePathFallback(opts.gitRoot);
7
- const discoveredWorktree = await findWorktreeForBranch(opts.gitRoot, opts.branch);
8
- const rawWorktreePath = discoveredWorktree ?? opts.worktreePathHint ?? null;
9
- const worktreePath = rawWorktreePath ? await resolvePathFallback(rawWorktreePath) : null;
10
- if (worktreePath) {
11
- if (!isPathWithin(repoRoot, worktreePath)) {
12
- return {
13
- removedBranch: false,
14
- removedWorktree: false,
15
- worktreePath,
16
- skippedReason: "outside_repo",
17
- };
18
- }
19
- if (worktreePath === repoRoot) {
20
- return {
21
- removedBranch: false,
22
- removedWorktree: false,
23
- worktreePath,
24
- skippedReason: "current_worktree",
25
- };
26
- }
27
- await execFileAsync("git", ["worktree", "remove", "--force", worktreePath], {
28
- cwd: opts.gitRoot,
29
- env: gitEnv(),
30
- });
31
- }
32
- let removedBranch = false;
33
- if (await gitBranchExists(opts.gitRoot, opts.branch)) {
34
- await execFileAsync("git", ["branch", "-D", opts.branch], {
35
- cwd: opts.gitRoot,
36
- env: gitEnv(),
37
- });
38
- removedBranch = true;
39
- }
40
- return {
41
- removedBranch,
42
- removedWorktree: Boolean(worktreePath),
43
- worktreePath,
44
- skippedReason: null,
45
- };
46
- }
1
+ export { cleanupMergedLocalBranch as cleanupIntegratedBranch, } from "../../../shared/merged-branch-cleanup.js";
@@ -1 +1 @@
1
- {"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/finalize.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAiBrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAUtE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAE3B,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IAEzB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGhB"}
1
+ {"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/finalize.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAiBrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAUtE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAE3B,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IAEzB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GhB"}
@@ -101,6 +101,9 @@ export async function finalizeIntegrate(opts) {
101
101
  baseBranchOverride: opts.base,
102
102
  quiet: opts.quiet,
103
103
  allowPolicy: collectedIncidents.wrote,
104
+ // finalizeIntegrate already wrote the canonical MERGED task packet on the base checkout.
105
+ // Re-running branch-side PR artifact refresh here can regress pr/meta.json back to OPEN.
106
+ closeRefreshTaskArtifacts: false,
104
107
  });
105
108
  if (!opts.quiet) {
106
109
  output.success("integrate", opts.taskId, `merge=${opts.mergeHash.slice(0, 12)}`);
@@ -0,0 +1,5 @@
1
+ export declare function requiresPullRequestMergePath(opts: {
2
+ gitRoot: string;
3
+ baseBranch: string;
4
+ }): Promise<boolean>;
5
+ //# sourceMappingURL=github-protection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-protection.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/github-protection.ts"],"names":[],"mappings":"AAMA,wBAAsB,4BAA4B,CAAC,IAAI,EAAE;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,OAAO,CAAC,CAUnB"}
@@ -0,0 +1,13 @@
1
+ import { resolveDefaultGithubRepo, runGhApiJson } from "../../internal/gh-api.js";
2
+ export async function requiresPullRequestMergePath(opts) {
3
+ try {
4
+ const repo = await resolveDefaultGithubRepo(opts.gitRoot);
5
+ const protection = await runGhApiJson(opts.gitRoot, [
6
+ `repos/${repo}/branches/${opts.baseBranch}/protection`,
7
+ ]);
8
+ return protection.required_pull_request_reviews !== undefined;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ export type PreIntegrateBootstrapResult = {
2
+ status: "not-needed";
3
+ } | {
4
+ status: "skipped";
5
+ } | {
6
+ status: "ran";
7
+ } | {
8
+ status: "failed";
9
+ error: string;
10
+ };
11
+ export declare function maybeRunPreIntegrateBootstrap(opts: {
12
+ gitRoot: string;
13
+ changedPaths: string[];
14
+ }): Promise<PreIntegrateBootstrapResult>;
15
+ //# sourceMappingURL=pre-integrate-bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-integrate-bootstrap.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/pre-integrate-bootstrap.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,2BAA2B,GACnC;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBxC,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAiBvC"}
@@ -0,0 +1,35 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { execFileAsync } from "../../../shared/git.js";
4
+ import { shouldAutoBootstrapAfterIntegrate } from "./bootstrap-guidance.js";
5
+ function compactError(err) {
6
+ if (err instanceof Error) {
7
+ const text = err.message.trim();
8
+ return text.length > 0 ? text : err.name;
9
+ }
10
+ return String(err);
11
+ }
12
+ function baseRuntimeReady(gitRoot) {
13
+ return (existsSync(path.join(gitRoot, "node_modules")) &&
14
+ existsSync(path.join(gitRoot, "packages", "agentplane", "node_modules")) &&
15
+ existsSync(path.join(gitRoot, "packages", "agentplane", "dist", "cli.js")));
16
+ }
17
+ export async function maybeRunPreIntegrateBootstrap(opts) {
18
+ if (baseRuntimeReady(opts.gitRoot)) {
19
+ return { status: "not-needed" };
20
+ }
21
+ if (!shouldAutoBootstrapAfterIntegrate(opts)) {
22
+ return { status: "skipped" };
23
+ }
24
+ try {
25
+ await execFileAsync("bun", ["run", "framework:dev:bootstrap"], {
26
+ cwd: opts.gitRoot,
27
+ env: { ...process.env },
28
+ maxBuffer: 50 * 1024 * 1024,
29
+ });
30
+ return { status: "ran" };
31
+ }
32
+ catch (err) {
33
+ return { status: "failed", error: compactError(err) };
34
+ }
35
+ }
@@ -8,6 +8,7 @@ export type PreparedIntegrate = {
8
8
  task: TaskData;
9
9
  baseBranch: string;
10
10
  currentBranch: string;
11
+ protectedBaseRequiresPrMerge: boolean;
11
12
  prDir: string;
12
13
  metaPath: string;
13
14
  diffstatPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/prepare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAUrE,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGvF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,EAAE,QAAQ,CAAC;IAEf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IAEtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyO7B"}
1
+ {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/prepare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAWrE,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAIvF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,EAAE,QAAQ,CAAC;IAEf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B,EAAE,OAAO,CAAC;IAEtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqR7B"}