agentplane 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/assets/policy/governance.md +3 -4
  2. package/assets/policy/incidents.md +19 -88
  3. package/assets/policy/workflow.branch_pr.md +1 -1
  4. package/assets/policy/workflow.direct.md +2 -2
  5. package/bin/agentplane.js +56 -1
  6. package/bin/runtime-watch.js +1 -0
  7. package/bin/stale-dist-policy.d.ts +1 -1
  8. package/bin/stale-dist-policy.js +13 -0
  9. package/dist/.build-manifest.json +219 -154
  10. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  11. package/dist/cli/bootstrap-guide.js +3 -2
  12. package/dist/cli/command-guide.d.ts.map +1 -1
  13. package/dist/cli/command-guide.js +2 -1
  14. package/dist/cli/command-invocations.d.ts.map +1 -1
  15. package/dist/cli/command-invocations.js +4 -1
  16. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  17. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  18. package/dist/cli/run-cli/command-catalog/project.js +3 -1
  19. package/dist/cli/run-cli/command-catalog/task.d.ts +1 -1
  20. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -1
  21. package/dist/cli/run-cli/command-catalog/task.js +10 -0
  22. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  23. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  24. package/dist/cli/run-cli/commands/core/preflight.d.ts.map +1 -1
  25. package/dist/cli/run-cli/commands/core/preflight.js +44 -1
  26. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  27. package/dist/cli/run-cli.test-helpers.js +12 -0
  28. package/dist/commands/branch/cleanup-merged.d.ts +2 -0
  29. package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
  30. package/dist/commands/branch/cleanup-merged.js +132 -28
  31. package/dist/commands/branch/work-start.d.ts.map +1 -1
  32. package/dist/commands/branch/work-start.js +60 -1
  33. package/dist/commands/cleanup/merged.command.d.ts +2 -0
  34. package/dist/commands/cleanup/merged.command.d.ts.map +1 -1
  35. package/dist/commands/cleanup/merged.command.js +24 -0
  36. package/dist/commands/doctor/branch-pr.d.ts +4 -0
  37. package/dist/commands/doctor/branch-pr.d.ts.map +1 -0
  38. package/dist/commands/doctor/branch-pr.js +96 -0
  39. package/dist/commands/doctor/fixes.d.ts +5 -0
  40. package/dist/commands/doctor/fixes.d.ts.map +1 -1
  41. package/dist/commands/doctor/fixes.js +70 -0
  42. package/dist/commands/doctor.run.d.ts.map +1 -1
  43. package/dist/commands/doctor.run.js +6 -1
  44. package/dist/commands/finish.run.d.ts.map +1 -1
  45. package/dist/commands/finish.run.js +11 -0
  46. package/dist/commands/finish.spec.d.ts +11 -0
  47. package/dist/commands/finish.spec.d.ts.map +1 -1
  48. package/dist/commands/finish.spec.js +51 -0
  49. package/dist/commands/guard/impl/close-message.d.ts.map +1 -1
  50. package/dist/commands/guard/impl/close-message.js +23 -6
  51. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  52. package/dist/commands/guard/impl/commands.js +24 -2
  53. package/dist/commands/guard/impl/env.d.ts +1 -0
  54. package/dist/commands/guard/impl/env.d.ts.map +1 -1
  55. package/dist/commands/guard/impl/env.js +1 -0
  56. package/dist/commands/hooks/index.d.ts.map +1 -1
  57. package/dist/commands/hooks/index.js +98 -1
  58. package/dist/commands/incidents/collect.command.d.ts.map +1 -1
  59. package/dist/commands/incidents/collect.command.js +12 -7
  60. package/dist/commands/incidents/incidents.command.js +1 -1
  61. package/dist/commands/incidents/shared.d.ts +34 -0
  62. package/dist/commands/incidents/shared.d.ts.map +1 -1
  63. package/dist/commands/incidents/shared.js +166 -12
  64. package/dist/commands/pr/check.d.ts.map +1 -1
  65. package/dist/commands/pr/check.js +238 -135
  66. package/dist/commands/pr/close-superseded.d.ts +9 -0
  67. package/dist/commands/pr/close-superseded.d.ts.map +1 -0
  68. package/dist/commands/pr/close-superseded.js +129 -0
  69. package/dist/commands/pr/close.d.ts +11 -0
  70. package/dist/commands/pr/close.d.ts.map +1 -0
  71. package/dist/commands/pr/close.js +116 -0
  72. package/dist/commands/pr/index.d.ts +2 -0
  73. package/dist/commands/pr/index.d.ts.map +1 -1
  74. package/dist/commands/pr/index.js +2 -0
  75. package/dist/commands/pr/integrate/artifacts.d.ts +7 -0
  76. package/dist/commands/pr/integrate/artifacts.d.ts.map +1 -1
  77. package/dist/commands/pr/integrate/artifacts.js +66 -1
  78. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  79. package/dist/commands/pr/integrate/cmd.js +16 -0
  80. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts +8 -0
  81. package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts.map +1 -0
  82. package/dist/commands/pr/integrate/internal/bootstrap-guidance.js +59 -0
  83. package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
  84. package/dist/commands/pr/integrate/internal/finalize.js +40 -12
  85. package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
  86. package/dist/commands/pr/integrate/internal/merge.js +36 -13
  87. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts +13 -0
  88. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts.map +1 -0
  89. package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.js +25 -0
  90. package/dist/commands/pr/integrate/internal/prepare.d.ts +3 -2
  91. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  92. package/dist/commands/pr/integrate/internal/prepare.js +101 -38
  93. package/dist/commands/pr/internal/freshness.d.ts +20 -0
  94. package/dist/commands/pr/internal/freshness.d.ts.map +1 -0
  95. package/dist/commands/pr/internal/freshness.js +50 -0
  96. package/dist/commands/pr/internal/gh-api.d.ts +6 -0
  97. package/dist/commands/pr/internal/gh-api.d.ts.map +1 -0
  98. package/dist/commands/pr/internal/gh-api.js +80 -0
  99. package/dist/commands/pr/internal/pr-paths.d.ts +10 -0
  100. package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
  101. package/dist/commands/pr/internal/pr-paths.js +10 -0
  102. package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
  103. package/dist/commands/pr/internal/review-template.js +37 -4
  104. package/dist/commands/pr/internal/sync.d.ts +9 -0
  105. package/dist/commands/pr/internal/sync.d.ts.map +1 -1
  106. package/dist/commands/pr/internal/sync.js +462 -122
  107. package/dist/commands/pr/open.d.ts +1 -0
  108. package/dist/commands/pr/open.d.ts.map +1 -1
  109. package/dist/commands/pr/open.js +13 -2
  110. package/dist/commands/pr/pr.command.d.ts +15 -0
  111. package/dist/commands/pr/pr.command.d.ts.map +1 -1
  112. package/dist/commands/pr/pr.command.js +118 -2
  113. package/dist/commands/pr/update.d.ts.map +1 -1
  114. package/dist/commands/pr/update.js +59 -1
  115. package/dist/commands/release/apply.command.d.ts.map +1 -1
  116. package/dist/commands/release/apply.command.js +3 -17
  117. package/dist/commands/release/apply.preflight.d.ts.map +1 -1
  118. package/dist/commands/release/apply.preflight.js +1 -1
  119. package/dist/commands/shared/gh-transport.d.ts +16 -0
  120. package/dist/commands/shared/gh-transport.d.ts.map +1 -0
  121. package/dist/commands/shared/gh-transport.js +71 -0
  122. package/dist/commands/shared/git-diff.d.ts +3 -1
  123. package/dist/commands/shared/git-diff.d.ts.map +1 -1
  124. package/dist/commands/shared/git-diff.js +10 -2
  125. package/dist/commands/shared/git-ops.d.ts +1 -0
  126. package/dist/commands/shared/git-ops.d.ts.map +1 -1
  127. package/dist/commands/shared/git-ops.js +15 -0
  128. package/dist/commands/shared/git-worktree.d.ts +2 -0
  129. package/dist/commands/shared/git-worktree.d.ts.map +1 -1
  130. package/dist/commands/shared/git-worktree.js +22 -2
  131. package/dist/commands/shared/post-commit-pr-artifacts.d.ts +9 -0
  132. package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -0
  133. package/dist/commands/shared/post-commit-pr-artifacts.js +22 -0
  134. package/dist/commands/shared/pr-meta.d.ts +20 -0
  135. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  136. package/dist/commands/shared/pr-meta.js +125 -0
  137. package/dist/commands/shared/task-backend.d.ts +7 -0
  138. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  139. package/dist/commands/shared/task-backend.js +34 -22
  140. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  141. package/dist/commands/task/close-duplicate.js +34 -1
  142. package/dist/commands/task/derive.js +1 -1
  143. package/dist/commands/task/doc-template.d.ts.map +1 -1
  144. package/dist/commands/task/doc-template.js +7 -11
  145. package/dist/commands/task/findings-add.command.d.ts +20 -0
  146. package/dist/commands/task/findings-add.command.d.ts.map +1 -0
  147. package/dist/commands/task/findings-add.command.js +165 -0
  148. package/dist/commands/task/findings.command.d.ts +7 -0
  149. package/dist/commands/task/findings.command.d.ts.map +1 -0
  150. package/dist/commands/task/findings.command.js +20 -0
  151. package/dist/commands/task/findings.d.ts +63 -0
  152. package/dist/commands/task/findings.d.ts.map +1 -0
  153. package/dist/commands/task/findings.js +188 -0
  154. package/dist/commands/task/finish-shared.d.ts +1 -0
  155. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  156. package/dist/commands/task/finish-shared.js +55 -1
  157. package/dist/commands/task/finish.d.ts +10 -0
  158. package/dist/commands/task/finish.d.ts.map +1 -1
  159. package/dist/commands/task/finish.js +125 -6
  160. package/dist/commands/task/hosted-close-pr.command.d.ts +11 -0
  161. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -0
  162. package/dist/commands/task/hosted-close-pr.command.js +414 -0
  163. package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
  164. package/dist/commands/task/hosted-close.command.js +49 -1
  165. package/dist/commands/task/hosted-merge-sync.d.ts +38 -0
  166. package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
  167. package/dist/commands/task/hosted-merge-sync.js +249 -17
  168. package/dist/commands/task/index.d.ts +1 -0
  169. package/dist/commands/task/index.d.ts.map +1 -1
  170. package/dist/commands/task/index.js +1 -0
  171. package/dist/commands/task/new.d.ts +1 -0
  172. package/dist/commands/task/new.d.ts.map +1 -1
  173. package/dist/commands/task/new.js +71 -1
  174. package/dist/commands/task/new.spec.d.ts.map +1 -1
  175. package/dist/commands/task/new.spec.js +7 -0
  176. package/dist/commands/task/normalize.command.d.ts +2 -0
  177. package/dist/commands/task/normalize.command.d.ts.map +1 -1
  178. package/dist/commands/task/normalize.command.js +45 -0
  179. package/dist/commands/task/normalize.d.ts +2 -0
  180. package/dist/commands/task/normalize.d.ts.map +1 -1
  181. package/dist/commands/task/normalize.js +85 -8
  182. package/dist/commands/task/plan.d.ts.map +1 -1
  183. package/dist/commands/task/plan.js +7 -10
  184. package/dist/commands/task/shared/docs.d.ts +6 -0
  185. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  186. package/dist/commands/task/shared/docs.js +14 -0
  187. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  188. package/dist/commands/task/shared/transitions.js +11 -1
  189. package/dist/commands/task/shared.d.ts +1 -1
  190. package/dist/commands/task/shared.d.ts.map +1 -1
  191. package/dist/commands/task/shared.js +1 -1
  192. package/dist/commands/task/start-ready.d.ts.map +1 -1
  193. package/dist/commands/task/start-ready.js +86 -0
  194. package/dist/commands/task/start.d.ts.map +1 -1
  195. package/dist/commands/task/start.js +7 -10
  196. package/dist/commands/task/task.command.d.ts.map +1 -1
  197. package/dist/commands/task/task.command.js +4 -0
  198. package/dist/commands/task/verify-command-shared.d.ts +19 -0
  199. package/dist/commands/task/verify-command-shared.d.ts.map +1 -1
  200. package/dist/commands/task/verify-command-shared.js +152 -1
  201. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  202. package/dist/commands/task/verify-ok.command.js +15 -2
  203. package/dist/commands/task/verify-record.d.ts +36 -0
  204. package/dist/commands/task/verify-record.d.ts.map +1 -1
  205. package/dist/commands/task/verify-record.js +166 -11
  206. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  207. package/dist/commands/task/verify-rework.command.js +15 -2
  208. package/dist/commands/task/verify-show.command.d.ts +1 -1
  209. package/dist/commands/task/verify-show.command.d.ts.map +1 -1
  210. package/dist/commands/task/verify-show.command.js +28 -1
  211. package/dist/commands/verify.run.d.ts.map +1 -1
  212. package/dist/commands/verify.run.js +12 -0
  213. package/dist/commands/verify.spec.d.ts +2 -6
  214. package/dist/commands/verify.spec.d.ts.map +1 -1
  215. package/dist/commands/verify.spec.js +30 -3
  216. package/dist/runtime/incidents/index.d.ts +1 -1
  217. package/dist/runtime/incidents/index.d.ts.map +1 -1
  218. package/dist/runtime/incidents/resolve.d.ts.map +1 -1
  219. package/dist/runtime/incidents/resolve.js +319 -73
  220. package/dist/runtime/incidents/types.d.ts +14 -2
  221. package/dist/runtime/incidents/types.d.ts.map +1 -1
  222. package/dist/shared/env.d.ts +1 -0
  223. package/dist/shared/env.d.ts.map +1 -1
  224. package/dist/shared/env.js +22 -1
  225. package/dist/shared/protected-paths.d.ts +1 -1
  226. package/dist/shared/protected-paths.d.ts.map +1 -1
  227. package/dist/shared/protected-paths.js +4 -0
  228. package/package.json +2 -2
@@ -0,0 +1,414 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { usageError } from "../../cli/spec/errors.js";
3
+ import { createCliEmitter } from "../../cli/output.js";
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 { CliError } from "../../shared/errors.js";
8
+ import { execFileAsync, gitEnv } from "../shared/git.js";
9
+ import { loadTaskFromContext, resolveTaskBranchFromContext, } from "../shared/task-backend.js";
10
+ import { parseTaskIdFromCloseBranch } from "../shared/git-worktree.js";
11
+ import { parsePrMeta } from "../shared/pr-meta.js";
12
+ import { resolveDefaultGithubRepo, runGhApiJson } from "../pr/internal/gh-api.js";
13
+ import { resolvePrPaths } from "../pr/internal/pr-paths.js";
14
+ import { resolveBaseBranch } from "@agentplaneorg/core";
15
+ export const taskHostedClosePrSpec = {
16
+ id: ["task", "hosted-close-pr"],
17
+ group: "Task",
18
+ summary: "Open one or more follow-up hosted closure PRs from remote task-close branches.",
19
+ args: [{ name: "task-id", required: true, variadic: true, valueHint: "<task-id>" }],
20
+ options: [
21
+ {
22
+ kind: "string",
23
+ name: "branch",
24
+ valueHint: "<name>",
25
+ description: "Optional explicit task-close branch name (default: derive from task PR metadata or remote refs).",
26
+ },
27
+ {
28
+ kind: "string",
29
+ name: "repo",
30
+ valueHint: "<owner/name>",
31
+ description: "Optional GitHub owner/repo override (defaults to origin remote).",
32
+ },
33
+ ],
34
+ examples: [
35
+ {
36
+ cmd: "agentplane task hosted-close-pr 202604091218-JREJ4K",
37
+ why: "Open the hosted closure PR after the workflow left a manual handoff comment.",
38
+ },
39
+ {
40
+ cmd: "agentplane task hosted-close-pr 202604091725-CB0Y6S 202604091725-H21SCP",
41
+ why: "Open multiple pending hosted closure PRs in one batch after a closure-wave merge.",
42
+ },
43
+ ],
44
+ validateRaw: (raw) => {
45
+ const taskIds = Array.isArray(raw.args["task-id"])
46
+ ? raw.args["task-id"]
47
+ : typeof raw.args["task-id"] === "string"
48
+ ? [raw.args["task-id"]]
49
+ : [];
50
+ const normalizedTaskIds = taskIds.map((taskId) => String(taskId).trim()).filter(Boolean);
51
+ if (normalizedTaskIds.length === 0) {
52
+ throw usageError({
53
+ spec: taskHostedClosePrSpec,
54
+ message: "Invalid value for task-id: empty.",
55
+ });
56
+ }
57
+ if (typeof raw.opts.branch === "string" && raw.opts.branch.trim() === "") {
58
+ throw usageError({
59
+ spec: taskHostedClosePrSpec,
60
+ message: "Invalid value for --branch: empty.",
61
+ });
62
+ }
63
+ if (typeof raw.opts.repo === "string" && raw.opts.repo.trim() === "") {
64
+ throw usageError({
65
+ spec: taskHostedClosePrSpec,
66
+ message: "Invalid value for --repo: empty.",
67
+ });
68
+ }
69
+ },
70
+ parse: (raw) => ({
71
+ taskIds: (Array.isArray(raw.args["task-id"])
72
+ ? raw.args["task-id"]
73
+ : typeof raw.args["task-id"] === "string"
74
+ ? [raw.args["task-id"]]
75
+ : [])
76
+ .map((taskId) => String(taskId).trim())
77
+ .filter(Boolean),
78
+ branch: typeof raw.opts.branch === "string" ? raw.opts.branch : null,
79
+ repo: typeof raw.opts.repo === "string" ? raw.opts.repo : null,
80
+ }),
81
+ };
82
+ async function resolveGithubRepo(opts) {
83
+ const repo = opts.repoOverride?.trim() ?? "";
84
+ if (repo)
85
+ return repo;
86
+ return await resolveDefaultGithubRepo(opts.gitRoot);
87
+ }
88
+ function selectMergedPullRecord(opts) {
89
+ const merged = opts.pulls.filter((record) => {
90
+ if (typeof record.merged_at !== "string" || record.merged_at.trim().length === 0)
91
+ return false;
92
+ const headRef = record.head?.ref?.trim() ?? "";
93
+ if (opts.sourceBranch && headRef && headRef !== opts.sourceBranch)
94
+ return false;
95
+ const baseRef = record.base?.ref?.trim() ?? "";
96
+ if (opts.baseBranch && baseRef && baseRef !== opts.baseBranch)
97
+ return false;
98
+ return true;
99
+ });
100
+ if (merged.length === 0)
101
+ return null;
102
+ if (typeof opts.prNumber === "number" && opts.prNumber > 0) {
103
+ const exact = merged.find((record) => Number(record.number ?? 0) === opts.prNumber);
104
+ if (exact)
105
+ return exact;
106
+ }
107
+ return ([...merged].toSorted((left, right) => {
108
+ const leftAt = Date.parse(left.merged_at ?? "");
109
+ const rightAt = Date.parse(right.merged_at ?? "");
110
+ return Number.isNaN(rightAt) || Number.isNaN(leftAt) ? 0 : rightAt - leftAt;
111
+ })[0] ?? null);
112
+ }
113
+ async function resolveHostedCloseMergeRecord(opts) {
114
+ const owner = opts.repo.split("/")[0]?.trim() ?? "";
115
+ if (!owner)
116
+ return null;
117
+ const query = new URLSearchParams({
118
+ state: "closed",
119
+ head: `${owner}:${opts.sourceBranch}`,
120
+ });
121
+ if (opts.baseBranch)
122
+ query.set("base", opts.baseBranch);
123
+ const records = await runGhApiJson(opts.gitRoot, [
124
+ `repos/${opts.repo}/pulls?${query.toString()}`,
125
+ ]);
126
+ return selectMergedPullRecord({
127
+ pulls: Array.isArray(records) ? records : [],
128
+ sourceBranch: opts.sourceBranch,
129
+ baseBranch: opts.baseBranch,
130
+ prNumber: opts.prNumber,
131
+ });
132
+ }
133
+ async function resolveHostedCloseMergeRecordByCommit(opts) {
134
+ const records = await runGhApiJson(opts.gitRoot, [
135
+ `repos/${opts.repo}/commits/${opts.mergeCommit}/pulls`,
136
+ ]);
137
+ return selectMergedPullRecord({
138
+ pulls: Array.isArray(records) ? records : [],
139
+ sourceBranch: opts.sourceBranch,
140
+ baseBranch: opts.baseBranch,
141
+ prNumber: opts.prNumber,
142
+ });
143
+ }
144
+ async function readHostedCloseState(opts) {
145
+ const task = await loadTaskFromContext({ ctx: opts.ctx, taskId: opts.taskId });
146
+ const taskBranch = await resolveTaskBranchFromContext({ ctx: opts.ctx, taskId: opts.taskId });
147
+ const { metaPath, config } = await resolvePrPaths({
148
+ ctx: opts.ctx,
149
+ cwd: opts.cwd,
150
+ rootOverride: opts.rootOverride,
151
+ taskId: opts.taskId,
152
+ });
153
+ if (config.workflow_mode !== "branch_pr") {
154
+ throw new CliError({
155
+ exitCode: exitCodeForError("E_USAGE"),
156
+ code: "E_USAGE",
157
+ message: `Invalid workflow_mode: ${config.workflow_mode} (expected branch_pr)`,
158
+ });
159
+ }
160
+ if (!(await fileExists(metaPath))) {
161
+ return { meta: null, task, taskBranch };
162
+ }
163
+ const meta = parsePrMeta(await readFile(metaPath, "utf8"), opts.taskId);
164
+ return { meta, task, taskBranch };
165
+ }
166
+ async function listRemoteTaskCloseBranches(opts) {
167
+ const { stdout } = await execFileAsync("git", ["ls-remote", "--heads", "origin", `task-close/${opts.taskId}/*`], {
168
+ cwd: opts.gitRoot,
169
+ env: gitEnv(),
170
+ maxBuffer: 10 * 1024 * 1024,
171
+ });
172
+ return stdout
173
+ .split("\n")
174
+ .map((line) => line.trim())
175
+ .filter((line) => line.length > 0)
176
+ .map((line) => line.split(/\s+/, 2)[1] ?? "")
177
+ .map((ref) => ref.replace(/^refs\/heads\//, ""))
178
+ .filter((ref) => ref.length > 0);
179
+ }
180
+ function shortSha(value) {
181
+ return value.trim().slice(0, 12);
182
+ }
183
+ function stripBranchRef(branch) {
184
+ return branch.startsWith("refs/heads/") ? branch.slice("refs/heads/".length) : branch;
185
+ }
186
+ async function resolveHostedCloseBranch(opts) {
187
+ const remoteBranches = await listRemoteTaskCloseBranches({
188
+ gitRoot: opts.gitRoot,
189
+ taskId: opts.taskId,
190
+ });
191
+ const explicitBranch = stripBranchRef(opts.explicitBranch?.trim() ?? "");
192
+ if (explicitBranch) {
193
+ const parsedTaskId = parseTaskIdFromCloseBranch(explicitBranch);
194
+ if (parsedTaskId && parsedTaskId !== opts.taskId) {
195
+ throw new CliError({
196
+ exitCode: exitCodeForError("E_VALIDATION"),
197
+ code: "E_VALIDATION",
198
+ message: `Branch ${explicitBranch} does not belong to task ${opts.taskId}.`,
199
+ });
200
+ }
201
+ if (!remoteBranches.includes(explicitBranch)) {
202
+ throw new CliError({
203
+ exitCode: exitCodeForError("E_VALIDATION"),
204
+ code: "E_VALIDATION",
205
+ message: `Remote hosted closure branch not found: ${explicitBranch}.`,
206
+ });
207
+ }
208
+ return explicitBranch;
209
+ }
210
+ if (opts.mergeCommit) {
211
+ const expected = `task-close/${opts.taskId}/${shortSha(opts.mergeCommit)}`;
212
+ if (remoteBranches.includes(expected))
213
+ return expected;
214
+ if (remoteBranches.length === 1)
215
+ return remoteBranches[0] ?? expected;
216
+ if (remoteBranches.length > 1) {
217
+ throw new CliError({
218
+ exitCode: exitCodeForError("E_VALIDATION"),
219
+ code: "E_VALIDATION",
220
+ message: `Multiple remote hosted closure branches match ${opts.taskId}: ${remoteBranches.join(", ")} (use --branch).`,
221
+ });
222
+ }
223
+ throw new CliError({
224
+ exitCode: exitCodeForError("E_VALIDATION"),
225
+ code: "E_VALIDATION",
226
+ message: `Remote hosted closure branch not found for ${opts.taskId}: ${expected}.`,
227
+ });
228
+ }
229
+ if (remoteBranches.length === 1)
230
+ return remoteBranches[0] ?? "";
231
+ if (remoteBranches.length > 1) {
232
+ throw new CliError({
233
+ exitCode: exitCodeForError("E_VALIDATION"),
234
+ code: "E_VALIDATION",
235
+ message: `Multiple remote hosted closure branches match ${opts.taskId}: ${remoteBranches.join(", ")} (use --branch).`,
236
+ });
237
+ }
238
+ throw new CliError({
239
+ exitCode: exitCodeForError("E_VALIDATION"),
240
+ code: "E_VALIDATION",
241
+ message: `Could not resolve remote hosted closure branch for ${opts.taskId}.`,
242
+ });
243
+ }
244
+ function buildHostedClosePrTitle(taskId) {
245
+ return `📝 ${taskId} task: close after hosted merge`;
246
+ }
247
+ function buildHostedClosePrBody(opts) {
248
+ const prLine = typeof opts.prNumber === "number" && opts.prNumber > 0
249
+ ? `Automated closure for merged task PR #${opts.prNumber}.`
250
+ : "Automated closure for merged task PR.";
251
+ return [
252
+ prLine,
253
+ "",
254
+ `- task_id: \`${opts.taskId}\``,
255
+ `- source_branch: \`${opts.sourceBranch}\``,
256
+ `- merge_sha: \`${opts.mergeSha}\``,
257
+ "",
258
+ "This PR contains only tracked task artifacts produced by the hosted branch_pr closure flow.",
259
+ ].join("\n");
260
+ }
261
+ function normalizeGithubPrLink(prNumber, prUrl, verb) {
262
+ return prUrl?.trim()
263
+ ? `${verb} GitHub PR #${prNumber}: ${prUrl.trim()}`
264
+ : `${verb} GitHub PR #${prNumber}`;
265
+ }
266
+ async function openHostedClosePr(opts) {
267
+ const output = createCliEmitter();
268
+ const { meta, task, taskBranch } = await readHostedCloseState({
269
+ ctx: opts.ctx,
270
+ cwd: opts.cwd,
271
+ rootOverride: opts.rootOverride,
272
+ taskId: opts.taskId,
273
+ });
274
+ const gitRoot = opts.ctx.resolvedProject.gitRoot;
275
+ const repo = await resolveGithubRepo({ gitRoot, repoOverride: opts.repo ?? null });
276
+ const defaultBaseBranch = await resolveBaseBranch({
277
+ cwd: opts.cwd,
278
+ rootOverride: opts.rootOverride ?? null,
279
+ cliBaseOpt: null,
280
+ mode: opts.ctx.config.workflow_mode,
281
+ });
282
+ let sourceBranch = meta?.branch?.trim() ?? taskBranch?.trim() ?? "";
283
+ let baseBranch = meta?.base?.trim() ?? defaultBaseBranch?.trim() ?? "";
284
+ let mergedRecord = sourceBranch.length > 0 &&
285
+ (meta?.status !== "MERGED" || !(meta?.merge_commit?.trim() ?? task.commit?.hash?.trim() ?? ""))
286
+ ? await resolveHostedCloseMergeRecord({
287
+ gitRoot,
288
+ repo,
289
+ sourceBranch,
290
+ baseBranch: baseBranch || null,
291
+ prNumber: typeof meta?.pr_number === "number" ? meta.pr_number : null,
292
+ })
293
+ : null;
294
+ const localMergeCommit = meta?.merge_commit?.trim() ?? task.commit?.hash?.trim() ?? "";
295
+ if (!mergedRecord && localMergeCommit) {
296
+ mergedRecord = await resolveHostedCloseMergeRecordByCommit({
297
+ gitRoot,
298
+ repo,
299
+ mergeCommit: localMergeCommit,
300
+ sourceBranch: sourceBranch || null,
301
+ baseBranch: baseBranch || null,
302
+ prNumber: typeof meta?.pr_number === "number" ? meta.pr_number : null,
303
+ });
304
+ }
305
+ if (!sourceBranch) {
306
+ sourceBranch = mergedRecord?.head?.ref?.trim() ?? "";
307
+ }
308
+ if (!baseBranch) {
309
+ baseBranch = mergedRecord?.base?.ref?.trim() ?? defaultBaseBranch?.trim() ?? "";
310
+ }
311
+ const mergeCommit = meta?.merge_commit?.trim() ??
312
+ task.commit?.hash?.trim() ??
313
+ mergedRecord?.merge_commit_sha?.trim() ??
314
+ "";
315
+ if (!sourceBranch) {
316
+ throw new CliError({
317
+ exitCode: exitCodeForError("E_VALIDATION"),
318
+ code: "E_VALIDATION",
319
+ message: `Missing hosted close source branch for ${opts.taskId}.`,
320
+ });
321
+ }
322
+ if (!mergeCommit) {
323
+ throw new CliError({
324
+ exitCode: exitCodeForError("E_VALIDATION"),
325
+ code: "E_VALIDATION",
326
+ message: `Missing hosted close merge commit for ${opts.taskId}.`,
327
+ });
328
+ }
329
+ if (meta?.status !== "MERGED" && !mergedRecord?.merged_at) {
330
+ throw new CliError({
331
+ exitCode: exitCodeForError("E_USAGE"),
332
+ code: "E_USAGE",
333
+ message: `Task ${opts.taskId} is not in MERGED hosted-close state.`,
334
+ });
335
+ }
336
+ const branch = await resolveHostedCloseBranch({
337
+ gitRoot,
338
+ taskId: opts.taskId,
339
+ explicitBranch: opts.branch ?? null,
340
+ mergeCommit,
341
+ });
342
+ const owner = repo.split("/")[0]?.trim() ?? "";
343
+ const existingQuery = new URLSearchParams({
344
+ state: "open",
345
+ head: `${owner}:${branch}`,
346
+ });
347
+ const existing = await runGhApiJson(gitRoot, [
348
+ `repos/${repo}/pulls?${existingQuery.toString()}`,
349
+ ]);
350
+ const existingPr = Array.isArray(existing) ? (existing[0] ?? null) : null;
351
+ const existingNumber = Number(existingPr?.number ?? 0);
352
+ if (Number.isInteger(existingNumber) && existingNumber > 0) {
353
+ output.success("task hosted-close-pr", opts.taskId, normalizeGithubPrLink(existingNumber, existingPr?.html_url ?? null, "linked to"));
354
+ return 0;
355
+ }
356
+ const created = await runGhApiJson(gitRoot, [
357
+ `repos/${repo}/pulls`,
358
+ "-X",
359
+ "POST",
360
+ "-f",
361
+ `title=${buildHostedClosePrTitle(opts.taskId)}`,
362
+ "-f",
363
+ `body=${buildHostedClosePrBody({
364
+ taskId: opts.taskId,
365
+ prNumber: typeof meta?.pr_number === "number"
366
+ ? meta.pr_number
367
+ : typeof mergedRecord?.number === "number"
368
+ ? mergedRecord.number
369
+ : null,
370
+ sourceBranch,
371
+ mergeSha: mergeCommit,
372
+ })}`,
373
+ "-f",
374
+ `head=${branch}`,
375
+ "-f",
376
+ `base=${baseBranch}`,
377
+ ]);
378
+ const createdNumber = Number(created.number ?? 0);
379
+ if (!Number.isInteger(createdNumber) || createdNumber <= 0) {
380
+ throw new CliError({
381
+ exitCode: exitCodeForError("E_VALIDATION"),
382
+ code: "E_VALIDATION",
383
+ message: `GitHub did not return a valid PR number for hosted closure branch ${branch}.`,
384
+ });
385
+ }
386
+ output.success("task hosted-close-pr", opts.taskId, normalizeGithubPrLink(createdNumber, created.html_url ?? null, "created"));
387
+ return 0;
388
+ }
389
+ export function makeRunTaskHostedClosePrHandler(getCtx) {
390
+ return async (ctx, p) => {
391
+ try {
392
+ const commandCtx = await getCtx("task hosted-close-pr");
393
+ for (const taskId of p.taskIds) {
394
+ await openHostedClosePr({
395
+ ctx: commandCtx,
396
+ cwd: ctx.cwd,
397
+ rootOverride: ctx.rootOverride,
398
+ taskId,
399
+ branch: p.branch,
400
+ repo: p.repo,
401
+ });
402
+ }
403
+ return 0;
404
+ }
405
+ catch (err) {
406
+ if (err instanceof CliError)
407
+ throw err;
408
+ throw mapBackendError(err, {
409
+ command: "task hosted-close-pr",
410
+ root: ctx.rootOverride ?? null,
411
+ });
412
+ }
413
+ };
414
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-close.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-close.command.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAStE,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKrF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,qBAAqB,CAqClE,CAAC;AAyIF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC9E,KAAK,UAAU,EAAE,QAAQ,qBAAqB,KAAG,OAAO,CAAC,MAAM,CAAC,CA2B/E"}
1
+ {"version":3,"file":"hosted-close.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-close.command.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAStE,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMrF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,qBAAqB,CAqClE,CAAC;AAwMF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC9E,KAAK,UAAU,EAAE,QAAQ,qBAAqB,KAAG,OAAO,CAAC,MAAM,CAAC,CA2B/E"}
@@ -12,6 +12,7 @@ import { loadTaskFromContext } from "../shared/task-backend.js";
12
12
  import { createTaskCloseCommit, writeFinishedTasks } from "./finish-shared.js";
13
13
  import { resolveHostedMergeTargetFromEvent } from "./hosted-merge-sync.js";
14
14
  import { readCommitInfo } from "./shared.js";
15
+ import { collectTaskIncidents, renderIncidentCollectionPlanOutcome } from "../incidents/shared.js";
15
16
  export const taskHostedCloseSpec = {
16
17
  id: ["task", "hosted-close"],
17
18
  group: "Task",
@@ -50,6 +51,30 @@ export const taskHostedCloseSpec = {
50
51
  quiet: raw.opts.quiet === true,
51
52
  }),
52
53
  };
54
+ function isMissingCommitObjectError(err) {
55
+ const stderr = err.stderr;
56
+ const text = err instanceof Error
57
+ ? [err.message, typeof stderr === "string" ? stderr : ""]
58
+ .filter((part) => part.trim().length > 0)
59
+ .join("\n")
60
+ : String(err);
61
+ return (/bad object/i.test(text) || /unknown revision/i.test(text) || /ambiguous argument/i.test(text));
62
+ }
63
+ async function resolveHostedTaskCommitInfo(opts) {
64
+ const mergeHash = opts.mergedPr.mergeCommit?.oid ?? "";
65
+ try {
66
+ return await readCommitInfo(opts.gitRoot, mergeHash);
67
+ }
68
+ catch (err) {
69
+ if (!isMissingCommitObjectError(err))
70
+ throw err;
71
+ return {
72
+ hash: mergeHash,
73
+ message: opts.mergedPr.title?.trim() ??
74
+ `Hosted PR #${opts.mergedPr.number} merged on GitHub ${opts.mergedPr.baseRefName ?? "main"}`,
75
+ };
76
+ }
77
+ }
53
78
  async function hasTaskArtifactChanges(opts) {
54
79
  const { stdout } = await execFileAsync("git", ["status", "--short", "--", opts.taskDirRelative], {
55
80
  cwd: opts.gitRoot,
@@ -128,10 +153,19 @@ async function closeHostedTask(opts) {
128
153
  mergeHash: target.mergedPr.mergeCommit.oid,
129
154
  };
130
155
  }
131
- const taskCommitInfo = await readCommitInfo(gitRoot, target.mergedPr.mergeCommit.oid);
156
+ const taskCommitInfo = await resolveHostedTaskCommitInfo({
157
+ gitRoot,
158
+ mergedPr: target.mergedPr,
159
+ });
132
160
  const prLabel = `PR #${target.mergedPr.number}`;
133
161
  const finishBody = `Verified: ${prLabel} merged on GitHub ${target.mergedPr.baseRefName ?? "main"}; ` +
134
162
  "hosted closure automation recorded canonical task artifacts.";
163
+ await collectTaskIncidents({
164
+ ctx: opts.ctx,
165
+ taskId: target.taskId,
166
+ task,
167
+ write: false,
168
+ });
135
169
  await writeFinishedTasks({
136
170
  ctx: opts.ctx,
137
171
  loadedTasks: [{ taskId: target.taskId, task }],
@@ -145,6 +179,19 @@ async function closeHostedTask(opts) {
145
179
  breaking: false,
146
180
  taskCommitInfo,
147
181
  });
182
+ const collectedIncidents = await collectTaskIncidents({
183
+ ctx: opts.ctx,
184
+ taskId: target.taskId,
185
+ write: true,
186
+ });
187
+ if (!opts.quiet) {
188
+ process.stdout.write(`${infoMessage(renderIncidentCollectionPlanOutcome(collectedIncidents.plan, {
189
+ wrote: collectedIncidents.wrote,
190
+ context: "finish",
191
+ promotedIds: collectedIncidents.plan.promotable.map((item) => item.entry.id),
192
+ registryPaths: collectedIncidents.registryPaths,
193
+ }))}\n`);
194
+ }
148
195
  await createTaskCloseCommit({
149
196
  ctx: opts.ctx,
150
197
  cwd: opts.cwd,
@@ -152,6 +199,7 @@ async function closeHostedTask(opts) {
152
199
  taskId: target.taskId,
153
200
  baseBranchOverride: target.mergedPr.baseRefName ?? meta.base ?? "main",
154
201
  quiet: opts.quiet,
202
+ allowPolicy: collectedIncidents.wrote,
155
203
  });
156
204
  return {
157
205
  outcome: "closed",
@@ -1,3 +1,4 @@
1
+ import { type TaskPrMeta } from "@agentplaneorg/core";
1
2
  import type { TaskData } from "../../backends/task-backend.js";
2
3
  import type { CommandContext } from "../shared/task-backend.js";
3
4
  export type HostedMergedPr = {
@@ -21,10 +22,35 @@ type HostedMergeSyncResult = {
21
22
  tasks: TaskData[];
22
23
  synced: number;
23
24
  };
25
+ export type LocalBranchPrSyncCandidate = {
26
+ taskId: string;
27
+ branch: string;
28
+ base: string;
29
+ commitHash: string;
30
+ verificationSource: "task" | "pr";
31
+ };
32
+ export type LocalDoneBranchPrDrift = {
33
+ taskId: string;
34
+ branch: string;
35
+ base: string;
36
+ commitHash: string;
37
+ };
38
+ export type LocalMergedPrMeta = {
39
+ branch: string;
40
+ base?: string | null;
41
+ mergedAt?: string | null;
42
+ mergeCommit: string;
43
+ headSha?: string | null;
44
+ };
45
+ export declare function resolveLocalMergedPrMeta(meta: TaskPrMeta | null): LocalMergedPrMeta | null;
24
46
  export declare function resolveHostedMergeTargetFromEvent(opts: {
25
47
  event: unknown;
26
48
  branchPrefix: string;
27
49
  }): HostedMergeTarget | null;
50
+ export declare function resolveHostedMergedPr(opts: {
51
+ cwd: string;
52
+ branch: string;
53
+ }): Promise<HostedMergedPr | null>;
28
54
  export declare function syncHostedMergedTask(opts: {
29
55
  ctx: CommandContext;
30
56
  tasks: TaskData[];
@@ -32,6 +58,18 @@ export declare function syncHostedMergedTask(opts: {
32
58
  missingTask?: "noop" | "error";
33
59
  missingPrMeta?: "noop" | "error";
34
60
  }): Promise<HostedMergeSyncResult>;
61
+ export declare function findLocallyShippedBranchPrTasks(opts: {
62
+ ctx: CommandContext;
63
+ tasks: TaskData[];
64
+ }): Promise<LocalBranchPrSyncCandidate[]>;
65
+ export declare function findDoneBranchPrTasksWithOpenPrArtifacts(opts: {
66
+ ctx: CommandContext;
67
+ tasks: TaskData[];
68
+ }): Promise<LocalDoneBranchPrDrift[]>;
69
+ export declare function syncLocallyShippedBranchPrTasks(opts: {
70
+ ctx: CommandContext;
71
+ tasks: TaskData[];
72
+ }): Promise<HostedMergeSyncResult>;
35
73
  export declare function syncHostedMergedTasks(opts: {
36
74
  ctx: CommandContext;
37
75
  tasks: TaskData[];
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-merge-sync.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-merge-sync.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAM/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,iBAAiB,GAAG,IAAI,CAY3B;AA2HD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAuDjC;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA0CjC"}
1
+ {"version":3,"file":"hosted-merge-sync.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-merge-sync.ts"],"names":[],"mappings":"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"}