agentplane 0.3.10 → 0.3.12
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.
- package/assets/AGENTS.md +2 -2
- package/assets/agents/CODER.json +4 -0
- package/assets/agents/CREATOR.json +1 -0
- package/assets/agents/DOCS.json +2 -1
- package/assets/agents/INTEGRATOR.json +2 -1
- package/assets/agents/ORCHESTRATOR.json +2 -0
- package/assets/agents/PLANNER.json +3 -1
- package/assets/agents/REVIEWER.json +1 -0
- package/assets/agents/TESTER.json +2 -2
- package/assets/agents/UPDATER.json +1 -0
- package/assets/agents/UPGRADER.json +1 -1
- package/assets/policy/governance.md +3 -4
- package/assets/policy/incidents.md +20 -88
- package/assets/policy/workflow.branch_pr.md +1 -1
- package/assets/policy/workflow.direct.md +2 -2
- package/bin/agentplane.js +114 -4
- package/bin/runtime-watch.js +1 -0
- package/bin/stale-dist-policy.d.ts +1 -1
- package/bin/stale-dist-policy.js +19 -1
- package/dist/.build-manifest.json +251 -166
- package/dist/cli/bootstrap-guide.d.ts.map +1 -1
- package/dist/cli/bootstrap-guide.js +3 -2
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +2 -1
- package/dist/cli/command-invocations.d.ts.map +1 -1
- package/dist/cli/command-invocations.js +4 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/core.js +6 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/project.js +3 -1
- package/dist/cli/run-cli/command-catalog/task.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/task.js +10 -0
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core/preflight.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core/preflight.js +44 -1
- package/dist/cli/run-cli.test-helpers.d.ts +1 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +26 -0
- package/dist/commands/branch/cleanup-merged.d.ts +3 -0
- package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
- package/dist/commands/branch/cleanup-merged.js +149 -36
- package/dist/commands/branch/work-start.d.ts.map +1 -1
- package/dist/commands/branch/work-start.js +137 -1
- package/dist/commands/cleanup/merged.command.d.ts +2 -0
- package/dist/commands/cleanup/merged.command.d.ts.map +1 -1
- package/dist/commands/cleanup/merged.command.js +24 -0
- package/dist/commands/doctor/branch-pr.d.ts +4 -0
- package/dist/commands/doctor/branch-pr.d.ts.map +1 -0
- package/dist/commands/doctor/branch-pr.js +96 -0
- package/dist/commands/doctor/fixes.d.ts +5 -0
- package/dist/commands/doctor/fixes.d.ts.map +1 -1
- package/dist/commands/doctor/fixes.js +70 -0
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +6 -1
- package/dist/commands/finish.run.d.ts.map +1 -1
- package/dist/commands/finish.run.js +11 -0
- package/dist/commands/finish.spec.d.ts +11 -0
- package/dist/commands/finish.spec.d.ts.map +1 -1
- package/dist/commands/finish.spec.js +51 -0
- package/dist/commands/guard/impl/close-message.d.ts.map +1 -1
- package/dist/commands/guard/impl/close-message.js +23 -6
- package/dist/commands/guard/impl/commands.d.ts +1 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +94 -2
- package/dist/commands/guard/impl/env.d.ts +1 -0
- package/dist/commands/guard/impl/env.d.ts.map +1 -1
- package/dist/commands/guard/impl/env.js +1 -0
- package/dist/commands/hooks/index.d.ts +1 -1
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +139 -6
- package/dist/commands/incidents/collect.command.d.ts.map +1 -1
- package/dist/commands/incidents/collect.command.js +12 -7
- package/dist/commands/incidents/incidents.command.js +1 -1
- package/dist/commands/incidents/shared.d.ts +34 -0
- package/dist/commands/incidents/shared.d.ts.map +1 -1
- package/dist/commands/incidents/shared.js +166 -12
- package/dist/commands/pr/check.d.ts.map +1 -1
- package/dist/commands/pr/check.js +241 -135
- package/dist/commands/pr/close-superseded.d.ts +9 -0
- package/dist/commands/pr/close-superseded.d.ts.map +1 -0
- package/dist/commands/pr/close-superseded.js +129 -0
- package/dist/commands/pr/close.d.ts +11 -0
- package/dist/commands/pr/close.d.ts.map +1 -0
- package/dist/commands/pr/close.js +116 -0
- package/dist/commands/pr/index.d.ts +2 -0
- package/dist/commands/pr/index.d.ts.map +1 -1
- package/dist/commands/pr/index.js +2 -0
- package/dist/commands/pr/integrate/artifacts.d.ts +7 -0
- package/dist/commands/pr/integrate/artifacts.d.ts.map +1 -1
- package/dist/commands/pr/integrate/artifacts.js +66 -1
- package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +43 -2
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts +8 -0
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.js +59 -0
- package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
- package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
- package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/finalize.js +43 -12
- package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
- package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/merge.js +36 -13
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts +13 -0
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.js +25 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts +4 -2
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +109 -38
- package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
- package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
- package/dist/commands/pr/internal/auto-commit.js +64 -0
- package/dist/commands/pr/internal/freshness.d.ts +21 -0
- package/dist/commands/pr/internal/freshness.d.ts.map +1 -0
- package/dist/commands/pr/internal/freshness.js +52 -0
- package/dist/commands/pr/internal/gh-api.d.ts +6 -0
- package/dist/commands/pr/internal/gh-api.d.ts.map +1 -0
- package/dist/commands/pr/internal/gh-api.js +80 -0
- package/dist/commands/pr/internal/pr-paths.d.ts +10 -0
- package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
- package/dist/commands/pr/internal/pr-paths.js +10 -0
- package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
- package/dist/commands/pr/internal/review-template.js +37 -4
- package/dist/commands/pr/internal/sync.d.ts +9 -0
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +531 -124
- package/dist/commands/pr/open.d.ts +1 -0
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +24 -2
- package/dist/commands/pr/pr.command.d.ts +15 -0
- package/dist/commands/pr/pr.command.d.ts.map +1 -1
- package/dist/commands/pr/pr.command.js +118 -2
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +71 -2
- package/dist/commands/release/apply.command.d.ts +3 -1
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +356 -34
- package/dist/commands/release/apply.mutation.d.ts.map +1 -1
- package/dist/commands/release/apply.mutation.js +1 -0
- package/dist/commands/release/apply.preflight.d.ts.map +1 -1
- package/dist/commands/release/apply.preflight.js +1 -1
- package/dist/commands/release/apply.reporting.d.ts +1 -0
- package/dist/commands/release/apply.reporting.d.ts.map +1 -1
- package/dist/commands/release/apply.reporting.js +12 -8
- package/dist/commands/release/apply.types.d.ts +13 -0
- package/dist/commands/release/apply.types.d.ts.map +1 -1
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +48 -0
- package/dist/commands/shared/gh-transport.d.ts +16 -0
- package/dist/commands/shared/gh-transport.d.ts.map +1 -0
- package/dist/commands/shared/gh-transport.js +71 -0
- package/dist/commands/shared/git-diff.d.ts +3 -1
- package/dist/commands/shared/git-diff.d.ts.map +1 -1
- package/dist/commands/shared/git-diff.js +10 -2
- package/dist/commands/shared/git-ops.d.ts +1 -0
- package/dist/commands/shared/git-ops.d.ts.map +1 -1
- package/dist/commands/shared/git-ops.js +15 -0
- package/dist/commands/shared/git-worktree.d.ts +2 -0
- package/dist/commands/shared/git-worktree.d.ts.map +1 -1
- package/dist/commands/shared/git-worktree.js +22 -2
- package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
- package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
- package/dist/commands/shared/merged-branch-cleanup.js +46 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts +9 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -0
- package/dist/commands/shared/post-commit-pr-artifacts.js +57 -0
- package/dist/commands/shared/pr-meta.d.ts +20 -0
- package/dist/commands/shared/pr-meta.d.ts.map +1 -1
- package/dist/commands/shared/pr-meta.js +125 -0
- package/dist/commands/shared/task-backend.d.ts +7 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +71 -27
- package/dist/commands/shared/task-local-freshness.d.ts +2 -0
- package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
- package/dist/commands/shared/task-local-freshness.js +7 -1
- package/dist/commands/task/close-duplicate.d.ts.map +1 -1
- package/dist/commands/task/close-duplicate.js +34 -1
- package/dist/commands/task/derive.js +1 -1
- package/dist/commands/task/doc-template.d.ts.map +1 -1
- package/dist/commands/task/doc-template.js +7 -11
- package/dist/commands/task/findings-add.command.d.ts +20 -0
- package/dist/commands/task/findings-add.command.d.ts.map +1 -0
- package/dist/commands/task/findings-add.command.js +165 -0
- package/dist/commands/task/findings.command.d.ts +7 -0
- package/dist/commands/task/findings.command.d.ts.map +1 -0
- package/dist/commands/task/findings.command.js +20 -0
- package/dist/commands/task/findings.d.ts +63 -0
- package/dist/commands/task/findings.d.ts.map +1 -0
- package/dist/commands/task/findings.js +188 -0
- package/dist/commands/task/finish-shared.d.ts +2 -0
- package/dist/commands/task/finish-shared.d.ts.map +1 -1
- package/dist/commands/task/finish-shared.js +56 -1
- package/dist/commands/task/finish.d.ts +10 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +125 -6
- package/dist/commands/task/hosted-close-pr.command.d.ts +11 -0
- package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -0
- package/dist/commands/task/hosted-close-pr.command.js +449 -0
- package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close.command.js +234 -19
- package/dist/commands/task/hosted-merge-sync.d.ts +41 -0
- package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
- package/dist/commands/task/hosted-merge-sync.js +291 -17
- package/dist/commands/task/index.d.ts +1 -0
- package/dist/commands/task/index.d.ts.map +1 -1
- package/dist/commands/task/index.js +1 -0
- package/dist/commands/task/new.d.ts +1 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +71 -1
- package/dist/commands/task/new.spec.d.ts.map +1 -1
- package/dist/commands/task/new.spec.js +7 -0
- package/dist/commands/task/normalize.command.d.ts +2 -0
- package/dist/commands/task/normalize.command.d.ts.map +1 -1
- package/dist/commands/task/normalize.command.js +45 -0
- package/dist/commands/task/normalize.d.ts +2 -0
- package/dist/commands/task/normalize.d.ts.map +1 -1
- package/dist/commands/task/normalize.js +85 -8
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +7 -10
- package/dist/commands/task/shared/docs.d.ts +6 -0
- package/dist/commands/task/shared/docs.d.ts.map +1 -1
- package/dist/commands/task/shared/docs.js +14 -0
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +11 -1
- package/dist/commands/task/shared.d.ts +1 -1
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +1 -1
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +7 -10
- package/dist/commands/task/task.command.d.ts.map +1 -1
- package/dist/commands/task/task.command.js +4 -0
- package/dist/commands/task/verify-command-shared.d.ts +19 -0
- package/dist/commands/task/verify-command-shared.d.ts.map +1 -1
- package/dist/commands/task/verify-command-shared.js +152 -1
- package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
- package/dist/commands/task/verify-ok.command.js +15 -2
- package/dist/commands/task/verify-record.d.ts +36 -0
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +166 -11
- package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
- package/dist/commands/task/verify-rework.command.js +15 -2
- package/dist/commands/task/verify-show.command.d.ts +1 -1
- package/dist/commands/task/verify-show.command.d.ts.map +1 -1
- package/dist/commands/task/verify-show.command.js +28 -1
- package/dist/commands/verify.run.d.ts.map +1 -1
- package/dist/commands/verify.run.js +12 -0
- package/dist/commands/verify.spec.d.ts +2 -6
- package/dist/commands/verify.spec.d.ts.map +1 -1
- package/dist/commands/verify.spec.js +30 -3
- package/dist/runtime/incidents/index.d.ts +1 -1
- package/dist/runtime/incidents/index.d.ts.map +1 -1
- package/dist/runtime/incidents/resolve.d.ts.map +1 -1
- package/dist/runtime/incidents/resolve.js +319 -73
- package/dist/runtime/incidents/types.d.ts +14 -2
- package/dist/runtime/incidents/types.d.ts.map +1 -1
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.d.ts.map +1 -1
- package/dist/shared/env.js +22 -1
- package/dist/shared/protected-paths.d.ts +1 -1
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +4 -0
- package/package.json +2 -2
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { mapCoreError } from "../../cli/error-map.js";
|
|
3
|
+
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
4
|
+
import { createCliEmitter, infoMessage, workflowModeMessage } from "../../cli/output.js";
|
|
5
|
+
import { fileExists } from "../../cli/fs-utils.js";
|
|
6
|
+
import { CliError } from "../../shared/errors.js";
|
|
7
|
+
import { loadBackendTask, loadCommandContext, } from "../shared/task-backend.js";
|
|
8
|
+
import { parsePrMetaForwardCompatible } from "../shared/pr-meta.js";
|
|
9
|
+
import { cmdPrClose } from "./close.js";
|
|
10
|
+
import { isGhNotFound, resolveDefaultGithubRepo, runGhApiJson, runGhApiNoOutput, } from "./internal/gh-api.js";
|
|
11
|
+
import { resolvePrPaths } from "./internal/pr-paths.js";
|
|
12
|
+
async function deleteRemoteBranch(opts) {
|
|
13
|
+
const endpoint = `repos/${opts.repo}/git/refs/heads/${encodeURIComponent(opts.branch)}`;
|
|
14
|
+
try {
|
|
15
|
+
await runGhApiNoOutput(opts.cwd, [endpoint, "-X", "DELETE"]);
|
|
16
|
+
return "deleted";
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
if (isGhNotFound(err))
|
|
20
|
+
return "already-absent";
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function cmdPrCloseSuperseded(opts) {
|
|
25
|
+
try {
|
|
26
|
+
const output = createCliEmitter();
|
|
27
|
+
const ctx = opts.ctx ??
|
|
28
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
29
|
+
const { task } = await loadBackendTask({
|
|
30
|
+
ctx,
|
|
31
|
+
cwd: opts.cwd,
|
|
32
|
+
rootOverride: opts.rootOverride,
|
|
33
|
+
taskId: opts.taskId,
|
|
34
|
+
});
|
|
35
|
+
if (String(task.status ?? "")
|
|
36
|
+
.trim()
|
|
37
|
+
.toUpperCase() !== "DONE") {
|
|
38
|
+
throw new CliError({
|
|
39
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
40
|
+
code: "E_VALIDATION",
|
|
41
|
+
message: `Task ${opts.taskId} must be DONE before closing superseded PRs.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const { config, metaPath, resolved } = await resolvePrPaths({ ...opts, ctx });
|
|
45
|
+
if (config.workflow_mode !== "branch_pr") {
|
|
46
|
+
throw new CliError({
|
|
47
|
+
exitCode: exitCodeForError("E_USAGE"),
|
|
48
|
+
code: "E_USAGE",
|
|
49
|
+
message: workflowModeMessage(config.workflow_mode, "branch_pr"),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!(await fileExists(metaPath))) {
|
|
53
|
+
throw new CliError({
|
|
54
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
55
|
+
code: "E_VALIDATION",
|
|
56
|
+
message: `Missing PR metadata: ${metaPath}`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const meta = parsePrMetaForwardCompatible(await readFile(metaPath, "utf8"), opts.taskId);
|
|
60
|
+
const branch = meta.branch?.trim() ?? "";
|
|
61
|
+
if (!branch) {
|
|
62
|
+
throw new CliError({
|
|
63
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
64
|
+
code: "E_VALIDATION",
|
|
65
|
+
message: `Missing PR branch for ${opts.taskId}`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const repo = await resolveDefaultGithubRepo(resolved.gitRoot);
|
|
69
|
+
const owner = repo.split("/", 1)[0]?.trim() ?? "";
|
|
70
|
+
if (!owner) {
|
|
71
|
+
throw new CliError({
|
|
72
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
73
|
+
code: "E_VALIDATION",
|
|
74
|
+
message: "Could not derive GitHub owner from remote origin.",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const openPrs = await runGhApiJson(resolved.gitRoot, [
|
|
78
|
+
`repos/${repo}/pulls?head=${encodeURIComponent(`${owner}:${branch}`)}&state=open&per_page=100`,
|
|
79
|
+
]);
|
|
80
|
+
if (openPrs.length === 0) {
|
|
81
|
+
const remoteBranchAction = opts.deleteRemoteBranch
|
|
82
|
+
? await deleteRemoteBranch({ cwd: resolved.gitRoot, repo, branch })
|
|
83
|
+
: "skipped";
|
|
84
|
+
output.report([
|
|
85
|
+
{ label: "task", value: opts.taskId },
|
|
86
|
+
{ label: "branch", value: branch },
|
|
87
|
+
{ label: "state", value: "skipped" },
|
|
88
|
+
{ label: "reason", value: "no open task PR found" },
|
|
89
|
+
{ label: "remote_branch_action", value: remoteBranchAction },
|
|
90
|
+
], { header: infoMessage(`pr close-superseded ${opts.taskId}`) });
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
if (openPrs.length > 1) {
|
|
94
|
+
throw new CliError({
|
|
95
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
96
|
+
code: "E_VALIDATION",
|
|
97
|
+
message: `Multiple open PRs match task ${opts.taskId} branch ${branch}: ${openPrs
|
|
98
|
+
.map((pr) => pr.number)
|
|
99
|
+
.filter((value) => typeof value === "number" && Number.isInteger(value) && value > 0)
|
|
100
|
+
.map((value) => `#${value}`)
|
|
101
|
+
.join(", ")}`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const prNumber = Number(openPrs[0]?.number ?? 0);
|
|
105
|
+
if (!Number.isInteger(prNumber) || prNumber <= 0) {
|
|
106
|
+
throw new CliError({
|
|
107
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
108
|
+
code: "E_VALIDATION",
|
|
109
|
+
message: `Could not determine open PR number for task ${opts.taskId}.`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return await cmdPrClose({
|
|
113
|
+
ctx,
|
|
114
|
+
cwd: opts.cwd,
|
|
115
|
+
rootOverride: opts.rootOverride,
|
|
116
|
+
prNumber,
|
|
117
|
+
comment: `Superseded by protected-main closure of task ${opts.taskId}.`,
|
|
118
|
+
deleteRemoteBranch: opts.deleteRemoteBranch,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
if (err instanceof CliError)
|
|
123
|
+
throw err;
|
|
124
|
+
throw mapCoreError(err, {
|
|
125
|
+
command: "pr close-superseded",
|
|
126
|
+
root: opts.rootOverride ?? null,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CommandContext } from "../shared/task-backend.js";
|
|
2
|
+
export declare function cmdPrClose(opts: {
|
|
3
|
+
ctx?: CommandContext;
|
|
4
|
+
cwd: string;
|
|
5
|
+
rootOverride?: string;
|
|
6
|
+
prNumber: number;
|
|
7
|
+
repo?: string;
|
|
8
|
+
comment?: string;
|
|
9
|
+
deleteRemoteBranch: boolean;
|
|
10
|
+
}): Promise<number>;
|
|
11
|
+
//# sourceMappingURL=close.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/close.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AA+CpF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGlB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { mapCoreError } from "../../cli/error-map.js";
|
|
2
|
+
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
3
|
+
import { createCliEmitter, successMessage } from "../../cli/output.js";
|
|
4
|
+
import { CliError } from "../../shared/errors.js";
|
|
5
|
+
import { loadCommandContext } from "../shared/task-backend.js";
|
|
6
|
+
import { isGhNotFound, resolveDefaultGithubRepo, runGhApiJson, runGhApiNoOutput, } from "./internal/gh-api.js";
|
|
7
|
+
function ensureNonEmptyFlag(name, value) {
|
|
8
|
+
const trimmed = value.trim();
|
|
9
|
+
if (!trimmed) {
|
|
10
|
+
throw new CliError({
|
|
11
|
+
exitCode: exitCodeForError("E_USAGE"),
|
|
12
|
+
code: "E_USAGE",
|
|
13
|
+
message: `Invalid value for --${name}.`,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return trimmed;
|
|
17
|
+
}
|
|
18
|
+
export async function cmdPrClose(opts) {
|
|
19
|
+
try {
|
|
20
|
+
if (!Number.isInteger(opts.prNumber) || opts.prNumber <= 0) {
|
|
21
|
+
throw new CliError({
|
|
22
|
+
exitCode: exitCodeForError("E_USAGE"),
|
|
23
|
+
code: "E_USAGE",
|
|
24
|
+
message: "Invalid PR number.",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const output = createCliEmitter();
|
|
28
|
+
const ctx = opts.ctx ??
|
|
29
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
30
|
+
const commandCwd = ctx.resolvedProject.gitRoot;
|
|
31
|
+
const repo = opts.repo
|
|
32
|
+
? ensureNonEmptyFlag("repo", opts.repo)
|
|
33
|
+
: await resolveDefaultGithubRepo(commandCwd);
|
|
34
|
+
const comment = opts.comment?.trim() ? ensureNonEmptyFlag("comment", opts.comment) : null;
|
|
35
|
+
const pr = await runGhApiJson(commandCwd, [
|
|
36
|
+
`repos/${repo}/pulls/${opts.prNumber}`,
|
|
37
|
+
]);
|
|
38
|
+
if (!pr.number) {
|
|
39
|
+
throw new CliError({
|
|
40
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
41
|
+
code: "E_VALIDATION",
|
|
42
|
+
message: `GitHub pull request #${opts.prNumber} was not found in ${repo}.`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (comment) {
|
|
46
|
+
await runGhApiNoOutput(commandCwd, [
|
|
47
|
+
`repos/${repo}/issues/${opts.prNumber}/comments`,
|
|
48
|
+
"-X",
|
|
49
|
+
"POST",
|
|
50
|
+
"-f",
|
|
51
|
+
`body=${comment}`,
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
const closed = await runGhApiJson(commandCwd, [
|
|
55
|
+
`repos/${repo}/pulls/${opts.prNumber}`,
|
|
56
|
+
"-X",
|
|
57
|
+
"PATCH",
|
|
58
|
+
"-f",
|
|
59
|
+
"state=closed",
|
|
60
|
+
]);
|
|
61
|
+
const headRepo = closed.head?.repo?.full_name?.trim() ?? pr.head?.repo?.full_name?.trim() ?? null;
|
|
62
|
+
const headRef = closed.head?.ref?.trim() ?? pr.head?.ref?.trim() ?? null;
|
|
63
|
+
let remoteBranchAction = "skipped";
|
|
64
|
+
if (opts.deleteRemoteBranch) {
|
|
65
|
+
if (!headRef) {
|
|
66
|
+
remoteBranchAction = "skipped-missing-head";
|
|
67
|
+
}
|
|
68
|
+
else if (headRepo && headRepo !== repo) {
|
|
69
|
+
remoteBranchAction = "skipped-fork";
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
try {
|
|
73
|
+
await runGhApiNoOutput(commandCwd, [
|
|
74
|
+
`repos/${repo}/git/refs/heads/${encodeURIComponent(headRef)}`,
|
|
75
|
+
"-X",
|
|
76
|
+
"DELETE",
|
|
77
|
+
]);
|
|
78
|
+
remoteBranchAction = "deleted";
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
if (isGhNotFound(err)) {
|
|
82
|
+
remoteBranchAction = "already-absent";
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const result = {
|
|
91
|
+
repo,
|
|
92
|
+
prNumber: opts.prNumber,
|
|
93
|
+
url: closed.html_url?.trim() ?? pr.html_url?.trim() ?? null,
|
|
94
|
+
state: closed.state?.trim() ?? pr.state?.trim() ?? "closed",
|
|
95
|
+
comment: comment ? "added" : "skipped",
|
|
96
|
+
remoteBranch: headRef,
|
|
97
|
+
remoteBranchAction,
|
|
98
|
+
};
|
|
99
|
+
output.report([
|
|
100
|
+
{ label: "repo", value: result.repo },
|
|
101
|
+
{ label: "state", value: result.state },
|
|
102
|
+
{ label: "url", value: result.url ?? "unknown" },
|
|
103
|
+
{ label: "comment", value: result.comment },
|
|
104
|
+
{ label: "remote_branch", value: result.remoteBranch ?? "unknown" },
|
|
105
|
+
{ label: "remote_branch_action", value: result.remoteBranchAction },
|
|
106
|
+
], {
|
|
107
|
+
header: successMessage("pr close", `#${result.prNumber}`),
|
|
108
|
+
});
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (err instanceof CliError)
|
|
113
|
+
throw err;
|
|
114
|
+
throw mapCoreError(err, { command: "pr close", root: opts.rootOverride ?? null });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -2,5 +2,7 @@ export { cmdPrOpen } from "./open.js";
|
|
|
2
2
|
export { cmdPrUpdate } from "./update.js";
|
|
3
3
|
export { cmdPrCheck } from "./check.js";
|
|
4
4
|
export { cmdPrNote } from "./note.js";
|
|
5
|
+
export { cmdPrClose } from "./close.js";
|
|
6
|
+
export { cmdPrCloseSuperseded } from "./close-superseded.js";
|
|
5
7
|
export { cmdIntegrate } from "./integrate.js";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -2,4 +2,6 @@ export { cmdPrOpen } from "./open.js";
|
|
|
2
2
|
export { cmdPrUpdate } from "./update.js";
|
|
3
3
|
export { cmdPrCheck } from "./check.js";
|
|
4
4
|
export { cmdPrNote } from "./note.js";
|
|
5
|
+
export { cmdPrClose } from "./close.js";
|
|
6
|
+
export { cmdPrCloseSuperseded } from "./close-superseded.js";
|
|
5
7
|
export { cmdIntegrate } from "./integrate.js";
|
|
@@ -11,4 +11,11 @@ export declare function readAndValidatePrArtifacts(opts: {
|
|
|
11
11
|
}): Promise<{
|
|
12
12
|
verifyLogText: string | null;
|
|
13
13
|
}>;
|
|
14
|
+
export declare function ensureCommittedPrArtifactsOnBranch(opts: {
|
|
15
|
+
resolved: {
|
|
16
|
+
gitRoot: string;
|
|
17
|
+
};
|
|
18
|
+
prDir: string;
|
|
19
|
+
branch: string;
|
|
20
|
+
}): Promise<void>;
|
|
14
21
|
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/artifacts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/artifacts.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAYnE,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC,CAkDD;AAED,wBAAsB,kCAAkC,CAAC,IAAI,EAAE;IAC7D,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEhB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { exitCodeForError } from "../../../cli/exit-codes.js";
|
|
3
3
|
import { CliError } from "../../../shared/errors.js";
|
|
4
|
-
import { readPrArtifact } from "../internal/pr-paths.js";
|
|
4
|
+
import { readPrArtifact, readPrArtifactFromBranch } from "../internal/pr-paths.js";
|
|
5
|
+
import { findWorktreeForBranch } from "../../shared/git-worktree.js";
|
|
5
6
|
import { validateReviewContents } from "../internal/review-template.js";
|
|
6
7
|
export async function readAndValidatePrArtifacts(opts) {
|
|
7
8
|
const readPrArtifactTyped = readPrArtifact;
|
|
@@ -9,6 +10,7 @@ export async function readAndValidatePrArtifacts(opts) {
|
|
|
9
10
|
const diffstatPath = path.join(prDir, "diffstat.txt");
|
|
10
11
|
const verifyLogPath = path.join(prDir, "verify.log");
|
|
11
12
|
const reviewPath = path.join(prDir, "review.md");
|
|
13
|
+
const worktreePath = await findWorktreeForBranch(opts.resolved.gitRoot, opts.branch);
|
|
12
14
|
const errors = [];
|
|
13
15
|
const relDiffstat = path.relative(opts.resolved.gitRoot, diffstatPath);
|
|
14
16
|
const relVerifyLog = path.relative(opts.resolved.gitRoot, verifyLogPath);
|
|
@@ -18,6 +20,7 @@ export async function readAndValidatePrArtifacts(opts) {
|
|
|
18
20
|
prDir,
|
|
19
21
|
fileName: "diffstat.txt",
|
|
20
22
|
branch: opts.branch,
|
|
23
|
+
worktreePath,
|
|
21
24
|
});
|
|
22
25
|
if (diffstatText === null)
|
|
23
26
|
errors.push(`Missing ${relDiffstat}`);
|
|
@@ -26,6 +29,7 @@ export async function readAndValidatePrArtifacts(opts) {
|
|
|
26
29
|
prDir,
|
|
27
30
|
fileName: "verify.log",
|
|
28
31
|
branch: opts.branch,
|
|
32
|
+
worktreePath,
|
|
29
33
|
});
|
|
30
34
|
if (verifyLogText === null)
|
|
31
35
|
errors.push(`Missing ${relVerifyLog}`);
|
|
@@ -34,6 +38,7 @@ export async function readAndValidatePrArtifacts(opts) {
|
|
|
34
38
|
prDir,
|
|
35
39
|
fileName: "review.md",
|
|
36
40
|
branch: opts.branch,
|
|
41
|
+
worktreePath,
|
|
37
42
|
});
|
|
38
43
|
if (reviewText === null)
|
|
39
44
|
errors.push(`Missing ${relReview}`);
|
|
@@ -48,3 +53,63 @@ export async function readAndValidatePrArtifacts(opts) {
|
|
|
48
53
|
}
|
|
49
54
|
return { verifyLogText };
|
|
50
55
|
}
|
|
56
|
+
export async function ensureCommittedPrArtifactsOnBranch(opts) {
|
|
57
|
+
const readCommittedPrArtifact = readPrArtifactFromBranch;
|
|
58
|
+
const { prDir } = opts;
|
|
59
|
+
const diffstatPath = path.join(prDir, "diffstat.txt");
|
|
60
|
+
const verifyLogPath = path.join(prDir, "verify.log");
|
|
61
|
+
const reviewPath = path.join(prDir, "review.md");
|
|
62
|
+
const metaPath = path.join(prDir, "meta.json");
|
|
63
|
+
const errors = [];
|
|
64
|
+
const relMeta = path.relative(opts.resolved.gitRoot, metaPath);
|
|
65
|
+
const relDiffstat = path.relative(opts.resolved.gitRoot, diffstatPath);
|
|
66
|
+
const relVerifyLog = path.relative(opts.resolved.gitRoot, verifyLogPath);
|
|
67
|
+
const relReview = path.relative(opts.resolved.gitRoot, reviewPath);
|
|
68
|
+
const metaText = await readCommittedPrArtifact({
|
|
69
|
+
resolved: opts.resolved,
|
|
70
|
+
prDir,
|
|
71
|
+
fileName: "meta.json",
|
|
72
|
+
branch: opts.branch,
|
|
73
|
+
});
|
|
74
|
+
if (metaText === null)
|
|
75
|
+
errors.push(`Missing committed ${relMeta} on branch ${opts.branch}`);
|
|
76
|
+
const diffstatText = await readCommittedPrArtifact({
|
|
77
|
+
resolved: opts.resolved,
|
|
78
|
+
prDir,
|
|
79
|
+
fileName: "diffstat.txt",
|
|
80
|
+
branch: opts.branch,
|
|
81
|
+
});
|
|
82
|
+
if (diffstatText === null) {
|
|
83
|
+
errors.push(`Missing committed ${relDiffstat} on branch ${opts.branch}`);
|
|
84
|
+
}
|
|
85
|
+
const verifyLogText = await readCommittedPrArtifact({
|
|
86
|
+
resolved: opts.resolved,
|
|
87
|
+
prDir,
|
|
88
|
+
fileName: "verify.log",
|
|
89
|
+
branch: opts.branch,
|
|
90
|
+
});
|
|
91
|
+
if (verifyLogText === null) {
|
|
92
|
+
errors.push(`Missing committed ${relVerifyLog} on branch ${opts.branch}`);
|
|
93
|
+
}
|
|
94
|
+
const reviewText = await readCommittedPrArtifact({
|
|
95
|
+
resolved: opts.resolved,
|
|
96
|
+
prDir,
|
|
97
|
+
fileName: "review.md",
|
|
98
|
+
branch: opts.branch,
|
|
99
|
+
});
|
|
100
|
+
if (reviewText === null) {
|
|
101
|
+
errors.push(`Missing committed ${relReview} on branch ${opts.branch}`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
validateReviewContents(reviewText, errors);
|
|
105
|
+
}
|
|
106
|
+
if (errors.length > 0) {
|
|
107
|
+
throw new CliError({
|
|
108
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
109
|
+
code: "E_VALIDATION",
|
|
110
|
+
message: `Task branch ${opts.branch} is missing committed PR artifacts required for integrate.\n` +
|
|
111
|
+
`${errors.join("\n")}\n` +
|
|
112
|
+
"Commit the task README/PR artifacts on the task branch (for example via `agentplane pr open` + git add/commit) before rerunning integrate.",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAUnE,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,CA+OlB"}
|
|
@@ -1,12 +1,16 @@
|
|
|
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";
|
|
4
5
|
import { CliError } from "../../../shared/errors.js";
|
|
5
6
|
import { cleanupIntegratedBranch } from "./internal/cleanup.js";
|
|
7
|
+
import { renderPostIntegrateBootstrapFailureGuidance, renderPostIntegrateBootstrapGuidance, shouldRecommendPostIntegrateBootstrap, } from "./internal/bootstrap-guidance.js";
|
|
6
8
|
import { execFileAsync, gitEnv } from "../../shared/git.js";
|
|
7
9
|
import { gitRevParse } from "../../shared/git-ops.js";
|
|
8
10
|
import { finalizeIntegrate } from "./internal/finalize.js";
|
|
9
11
|
import { runMergeCommit, runRebaseFastForward, runSquashMerge } from "./internal/merge.js";
|
|
12
|
+
import { maybeRunPreIntegrateBootstrap } from "./internal/pre-integrate-bootstrap.js";
|
|
13
|
+
import { maybeRunPostIntegrateBootstrap } from "./internal/post-integrate-bootstrap.js";
|
|
10
14
|
import { prepareIntegrate } from "./internal/prepare.js";
|
|
11
15
|
import { resolveWorktreeForIntegrate } from "./internal/worktree.js";
|
|
12
16
|
import { runVerifyCommands } from "./verify.js";
|
|
@@ -24,7 +28,7 @@ export async function cmdIntegrate(opts) {
|
|
|
24
28
|
base: opts.base,
|
|
25
29
|
runVerify: opts.runVerify,
|
|
26
30
|
});
|
|
27
|
-
const { resolved, loadedConfig, task, prDir, metaPath, diffstatPath, verifyLogPath, metaSource, branch, base, verifyLogText, } = prepared;
|
|
31
|
+
const { resolved, loadedConfig, task, prDir, metaPath, diffstatPath, verifyLogPath, metaSource, branch, base, verifyLogText, protectedBaseRequiresPrMerge, } = prepared;
|
|
28
32
|
const verifyCommands = prepared.verifyCommands;
|
|
29
33
|
let alreadyVerifiedSha = prepared.alreadyVerifiedSha;
|
|
30
34
|
let shouldRunVerify = prepared.shouldRunVerify;
|
|
@@ -32,10 +36,21 @@ export async function cmdIntegrate(opts) {
|
|
|
32
36
|
const changedPaths = prepared.changedPaths;
|
|
33
37
|
if (opts.dryRun) {
|
|
34
38
|
if (!opts.quiet) {
|
|
35
|
-
output.success("integrate dry-run", task.id, `base=${base} branch=${branch} verify=${shouldRunVerify ? "yes" : "no"}`);
|
|
39
|
+
output.success("integrate dry-run", task.id, `base=${base} branch=${branch} verify=${shouldRunVerify ? "yes" : "no"} route=${protectedBaseRequiresPrMerge ? "github-pr" : "local"}`);
|
|
36
40
|
}
|
|
37
41
|
return 0;
|
|
38
42
|
}
|
|
43
|
+
if (protectedBaseRequiresPrMerge) {
|
|
44
|
+
const prHint = typeof metaSource.pr_number === "number" && metaSource.pr_number > 0
|
|
45
|
+
? `GitHub PR #${metaSource.pr_number}`
|
|
46
|
+
: `the GitHub PR for branch ${branch}`;
|
|
47
|
+
throw new CliError({
|
|
48
|
+
exitCode: exitCodeForError("E_GIT"),
|
|
49
|
+
code: "E_GIT",
|
|
50
|
+
message: `Base branch ${base} requires GitHub pull-request merges; integrate will not mutate it locally. ` +
|
|
51
|
+
`Merge ${prHint} on GitHub, let Task Hosted Close finish the closure tail, then pull ${base}.`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
39
54
|
const wt = await resolveWorktreeForIntegrate({
|
|
40
55
|
gitRoot: resolved.gitRoot,
|
|
41
56
|
worktreesDirRel: loadedConfig.paths.worktrees_dir,
|
|
@@ -64,6 +79,18 @@ export async function cmdIntegrate(opts) {
|
|
|
64
79
|
taskId: task.id,
|
|
65
80
|
})));
|
|
66
81
|
}
|
|
82
|
+
const preBootstrapResult = await maybeRunPreIntegrateBootstrap({
|
|
83
|
+
gitRoot: resolved.gitRoot,
|
|
84
|
+
changedPaths,
|
|
85
|
+
});
|
|
86
|
+
if (preBootstrapResult.status === "failed") {
|
|
87
|
+
throw new CliError({
|
|
88
|
+
exitCode: 8,
|
|
89
|
+
code: "E_RUNTIME",
|
|
90
|
+
message: "Unable to prepare the base worktree for integrate: automatic repo-local runtime refresh " +
|
|
91
|
+
`failed (${preBootstrapResult.error}). Run \`bun run framework:dev:bootstrap\` in ${resolved.gitRoot} and retry integrate.`,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
67
94
|
const baseShaBeforeMerge = await gitRevParse(resolved.gitRoot, [base]);
|
|
68
95
|
const headBeforeMerge = await gitRevParse(resolved.gitRoot, ["HEAD"]);
|
|
69
96
|
let mergeHash = "";
|
|
@@ -159,6 +186,20 @@ export async function cmdIntegrate(opts) {
|
|
|
159
186
|
tempWorktreePath = null;
|
|
160
187
|
createdTempWorktree = false;
|
|
161
188
|
}
|
|
189
|
+
if (shouldRecommendPostIntegrateBootstrap(changedPaths)) {
|
|
190
|
+
const bootstrapResult = await maybeRunPostIntegrateBootstrap({
|
|
191
|
+
gitRoot: resolved.gitRoot,
|
|
192
|
+
changedPaths,
|
|
193
|
+
});
|
|
194
|
+
if (!opts.quiet) {
|
|
195
|
+
if (bootstrapResult.status === "skipped") {
|
|
196
|
+
output.warn(renderPostIntegrateBootstrapGuidance());
|
|
197
|
+
}
|
|
198
|
+
else if (bootstrapResult.status === "failed") {
|
|
199
|
+
output.warn(renderPostIntegrateBootstrapFailureGuidance(bootstrapResult.error));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
162
203
|
return 0;
|
|
163
204
|
}
|
|
164
205
|
catch (err) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function shouldRecommendPostIntegrateBootstrap(changedPaths: string[]): boolean;
|
|
2
|
+
export declare function shouldAutoBootstrapAfterIntegrate(opts: {
|
|
3
|
+
changedPaths: string[];
|
|
4
|
+
gitRoot: string;
|
|
5
|
+
}): boolean;
|
|
6
|
+
export declare function renderPostIntegrateBootstrapGuidance(): string;
|
|
7
|
+
export declare function renderPostIntegrateBootstrapFailureGuidance(reason: string): string;
|
|
8
|
+
//# sourceMappingURL=bootstrap-guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-guidance.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/bootstrap-guidance.ts"],"names":[],"mappings":"AA4CA,wBAAgB,qCAAqC,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAErF;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CASV;AAED,wBAAgB,oCAAoC,IAAI,MAAM,CAK7D;AAED,wBAAgB,2CAA2C,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKlF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { isRuntimeRelevantWatchedFile } from "../../../../../bin/runtime-watch.js";
|
|
4
|
+
const WATCHED_RUNTIME_PACKAGES = [
|
|
5
|
+
{
|
|
6
|
+
packageRoot: "packages/agentplane",
|
|
7
|
+
watchedPaths: [
|
|
8
|
+
"src",
|
|
9
|
+
"bin/agentplane.js",
|
|
10
|
+
"bin/dist-guard.js",
|
|
11
|
+
"bin/runtime-context.js",
|
|
12
|
+
"bin/stale-dist-policy.js",
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
packageRoot: "packages/core",
|
|
17
|
+
watchedPaths: ["src"],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
function normalizeRepoPath(filePath) {
|
|
21
|
+
return filePath.replaceAll("\\", "/");
|
|
22
|
+
}
|
|
23
|
+
function isWatchedRuntimeSourcePath(filePath) {
|
|
24
|
+
const normalized = normalizeRepoPath(filePath);
|
|
25
|
+
for (const watchedPackage of WATCHED_RUNTIME_PACKAGES) {
|
|
26
|
+
for (const watchedPath of watchedPackage.watchedPaths) {
|
|
27
|
+
if (watchedPath === "src") {
|
|
28
|
+
const sourcePrefix = `${watchedPackage.packageRoot}/src/`;
|
|
29
|
+
if (!normalized.startsWith(sourcePrefix))
|
|
30
|
+
continue;
|
|
31
|
+
const packageRelativePath = normalized.slice(watchedPackage.packageRoot.length + 1);
|
|
32
|
+
return isRuntimeRelevantWatchedFile(packageRelativePath);
|
|
33
|
+
}
|
|
34
|
+
if (normalized === `${watchedPackage.packageRoot}/${watchedPath}`) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
export function shouldRecommendPostIntegrateBootstrap(changedPaths) {
|
|
42
|
+
return changedPaths.some((changedPath) => isWatchedRuntimeSourcePath(changedPath));
|
|
43
|
+
}
|
|
44
|
+
export function shouldAutoBootstrapAfterIntegrate(opts) {
|
|
45
|
+
if (!shouldRecommendPostIntegrateBootstrap(opts.changedPaths)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return (existsSync(path.join(opts.gitRoot, "package.json")) &&
|
|
49
|
+
existsSync(path.join(opts.gitRoot, "packages", "agentplane", "package.json")) &&
|
|
50
|
+
existsSync(path.join(opts.gitRoot, "scripts", "bootstrap-framework-dev.mjs")));
|
|
51
|
+
}
|
|
52
|
+
export function renderPostIntegrateBootstrapGuidance() {
|
|
53
|
+
return ("This merge changed watched runtime sources. Run `bun run framework:dev:bootstrap` " +
|
|
54
|
+
"before the next command so the repo-local build stays current.");
|
|
55
|
+
}
|
|
56
|
+
export function renderPostIntegrateBootstrapFailureGuidance(reason) {
|
|
57
|
+
return ("This merge changed watched runtime sources and the automatic repo-local runtime refresh " +
|
|
58
|
+
`failed (${reason}). Run \`bun run framework:dev:bootstrap\` manually before the next command.`);
|
|
59
|
+
}
|
|
@@ -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":"
|
|
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
|
-
|
|
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;
|
|
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"}
|