agentplane 0.3.11 → 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/incidents.md +1 -0
- package/bin/agentplane.js +58 -3
- package/bin/stale-dist-policy.js +6 -1
- package/dist/.build-manifest.json +88 -68
- 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.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -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 +14 -0
- package/dist/commands/branch/cleanup-merged.d.ts +1 -0
- package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
- package/dist/commands/branch/cleanup-merged.js +18 -9
- package/dist/commands/branch/work-start.d.ts.map +1 -1
- package/dist/commands/branch/work-start.js +82 -5
- package/dist/commands/doctor/branch-pr.js +2 -2
- 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 +78 -8
- 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 +48 -12
- package/dist/commands/pr/check.d.ts.map +1 -1
- package/dist/commands/pr/check.js +3 -0
- package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +27 -2
- 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 +3 -0
- 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/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 +1 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +8 -0
- 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 +1 -0
- package/dist/commands/pr/internal/freshness.d.ts.map +1 -1
- package/dist/commands/pr/internal/freshness.js +2 -0
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +93 -26
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +11 -0
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +13 -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 +354 -18
- 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.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/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.map +1 -1
- package/dist/commands/shared/post-commit-pr-artifacts.js +35 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +37 -5
- 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/finish-shared.d.ts +1 -0
- package/dist/commands/task/finish-shared.d.ts.map +1 -1
- package/dist/commands/task/finish-shared.js +1 -0
- package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close-pr.command.js +35 -0
- package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close.command.js +185 -18
- package/dist/commands/task/hosted-merge-sync.d.ts +4 -1
- package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
- package/dist/commands/task/hosted-merge-sync.js +52 -10
- package/dist/commands/task/start-ready.d.ts.map +1 -1
- package/dist/commands/task/start-ready.js +0 -86
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
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";
|
|
@@ -8,6 +9,7 @@ import { execFileAsync, gitEnv } from "../../shared/git.js";
|
|
|
8
9
|
import { gitRevParse } from "../../shared/git-ops.js";
|
|
9
10
|
import { finalizeIntegrate } from "./internal/finalize.js";
|
|
10
11
|
import { runMergeCommit, runRebaseFastForward, runSquashMerge } from "./internal/merge.js";
|
|
12
|
+
import { maybeRunPreIntegrateBootstrap } from "./internal/pre-integrate-bootstrap.js";
|
|
11
13
|
import { maybeRunPostIntegrateBootstrap } from "./internal/post-integrate-bootstrap.js";
|
|
12
14
|
import { prepareIntegrate } from "./internal/prepare.js";
|
|
13
15
|
import { resolveWorktreeForIntegrate } from "./internal/worktree.js";
|
|
@@ -26,7 +28,7 @@ export async function cmdIntegrate(opts) {
|
|
|
26
28
|
base: opts.base,
|
|
27
29
|
runVerify: opts.runVerify,
|
|
28
30
|
});
|
|
29
|
-
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;
|
|
30
32
|
const verifyCommands = prepared.verifyCommands;
|
|
31
33
|
let alreadyVerifiedSha = prepared.alreadyVerifiedSha;
|
|
32
34
|
let shouldRunVerify = prepared.shouldRunVerify;
|
|
@@ -34,10 +36,21 @@ export async function cmdIntegrate(opts) {
|
|
|
34
36
|
const changedPaths = prepared.changedPaths;
|
|
35
37
|
if (opts.dryRun) {
|
|
36
38
|
if (!opts.quiet) {
|
|
37
|
-
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"}`);
|
|
38
40
|
}
|
|
39
41
|
return 0;
|
|
40
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
|
+
}
|
|
41
54
|
const wt = await resolveWorktreeForIntegrate({
|
|
42
55
|
gitRoot: resolved.gitRoot,
|
|
43
56
|
worktreesDirRel: loadedConfig.paths.worktrees_dir,
|
|
@@ -66,6 +79,18 @@ export async function cmdIntegrate(opts) {
|
|
|
66
79
|
taskId: task.id,
|
|
67
80
|
})));
|
|
68
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
|
+
}
|
|
69
94
|
const baseShaBeforeMerge = await gitRevParse(resolved.gitRoot, [base]);
|
|
70
95
|
const headBeforeMerge = await gitRevParse(resolved.gitRoot, ["HEAD"]);
|
|
71
96
|
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":"
|
|
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;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,
|
|
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 @@
|
|
|
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
|
+
}
|
|
@@ -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;
|
|
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;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,CAgP7B"}
|
|
@@ -17,6 +17,7 @@ import { readAndValidatePrArtifacts, ensureCommittedPrArtifactsOnBranch } from "
|
|
|
17
17
|
import { computeVerifyState } from "../verify.js";
|
|
18
18
|
import { parsePrMetaForwardCompatible } from "../../../shared/pr-meta.js";
|
|
19
19
|
import { assessPrArtifactFreshness } from "../../internal/freshness.js";
|
|
20
|
+
import { requiresPullRequestMergePath } from "./github-protection.js";
|
|
20
21
|
export async function prepareIntegrate(opts) {
|
|
21
22
|
const ctx = opts.ctx ??
|
|
22
23
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
@@ -132,6 +133,10 @@ export async function prepareIntegrate(opts) {
|
|
|
132
133
|
preferBranchSnapshot: true,
|
|
133
134
|
branchSnapshotBranch: branch,
|
|
134
135
|
});
|
|
136
|
+
const protectedBaseRequiresPrMerge = await requiresPullRequestMergePath({
|
|
137
|
+
gitRoot: resolved.gitRoot,
|
|
138
|
+
baseBranch: base,
|
|
139
|
+
});
|
|
135
140
|
const changedPaths = await gitDiffNames(resolved.gitRoot, base, branch);
|
|
136
141
|
const tasksPath = loadedConfig.paths.tasks_path;
|
|
137
142
|
if (changedPaths.includes(tasksPath)) {
|
|
@@ -145,6 +150,7 @@ export async function prepareIntegrate(opts) {
|
|
|
145
150
|
let freshness = await assessPrArtifactFreshness({
|
|
146
151
|
gitRoot: resolved.gitRoot,
|
|
147
152
|
workflowDir: loadedConfig.paths.workflow_dir,
|
|
153
|
+
tasksPath: loadedConfig.paths.tasks_path,
|
|
148
154
|
taskId: opts.taskId,
|
|
149
155
|
branchHeadSha,
|
|
150
156
|
metaHeadSha: metaSource.head_sha ?? null,
|
|
@@ -181,6 +187,7 @@ export async function prepareIntegrate(opts) {
|
|
|
181
187
|
freshness = await assessPrArtifactFreshness({
|
|
182
188
|
gitRoot: resolved.gitRoot,
|
|
183
189
|
workflowDir: loadedConfig.paths.workflow_dir,
|
|
190
|
+
tasksPath: loadedConfig.paths.tasks_path,
|
|
184
191
|
taskId: opts.taskId,
|
|
185
192
|
branchHeadSha,
|
|
186
193
|
metaHeadSha: repairedMetaSource.head_sha ?? null,
|
|
@@ -218,6 +225,7 @@ export async function prepareIntegrate(opts) {
|
|
|
218
225
|
task,
|
|
219
226
|
baseBranch,
|
|
220
227
|
currentBranch,
|
|
228
|
+
protectedBaseRequiresPrMerge,
|
|
221
229
|
prDir,
|
|
222
230
|
metaPath,
|
|
223
231
|
diffstatPath,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-commit.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/auto-commit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA6BnE,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,OAAO,CAAC,CA8CnB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { extractTaskSuffix } from "@agentplaneorg/core";
|
|
3
|
+
import { buildGitCommitEnv } from "../../guard/impl/env.js";
|
|
4
|
+
import { toGitPath } from "../../shared/git-diff.js";
|
|
5
|
+
import { execFileAsync, gitEnv } from "../../shared/git.js";
|
|
6
|
+
import { gitCurrentBranch } from "../../shared/git-ops.js";
|
|
7
|
+
function taskPrDirPrefix(workflowDir, taskId) {
|
|
8
|
+
return `${toGitPath(path.join(workflowDir, taskId, "pr"))}/`;
|
|
9
|
+
}
|
|
10
|
+
function isTaskPrArtifactPath(opts) {
|
|
11
|
+
return toGitPath(opts.relPath).startsWith(taskPrDirPrefix(opts.workflowDir, opts.taskId));
|
|
12
|
+
}
|
|
13
|
+
async function readCachedPaths(gitRoot) {
|
|
14
|
+
const { stdout } = await execFileAsync("git", ["diff", "--cached", "--name-only", "--relative"], {
|
|
15
|
+
cwd: gitRoot,
|
|
16
|
+
env: gitEnv(),
|
|
17
|
+
});
|
|
18
|
+
return stdout
|
|
19
|
+
.split("\n")
|
|
20
|
+
.map((line) => line.trim())
|
|
21
|
+
.filter((line) => line.length > 0);
|
|
22
|
+
}
|
|
23
|
+
function taskPrArtifactRefreshMessage(taskId) {
|
|
24
|
+
return `📝 ${extractTaskSuffix(taskId)} task: refresh PR artifacts`;
|
|
25
|
+
}
|
|
26
|
+
export async function maybeAutoCommitTaskPrArtifacts(opts) {
|
|
27
|
+
if (opts.ctx.config.workflow_mode !== "branch_pr")
|
|
28
|
+
return false;
|
|
29
|
+
const branchText = await gitCurrentBranch(opts.ctx.resolvedProject.gitRoot);
|
|
30
|
+
const currentBranch = branchText.trim();
|
|
31
|
+
if (!currentBranch || currentBranch !== opts.branch.trim())
|
|
32
|
+
return false;
|
|
33
|
+
const changedPaths = await opts.ctx.git.statusChangedPaths();
|
|
34
|
+
const prArtifactPaths = changedPaths.filter((relPath) => isTaskPrArtifactPath({
|
|
35
|
+
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
36
|
+
taskId: opts.taskId,
|
|
37
|
+
relPath,
|
|
38
|
+
}));
|
|
39
|
+
if (prArtifactPaths.length === 0)
|
|
40
|
+
return false;
|
|
41
|
+
const cachedPaths = await readCachedPaths(opts.ctx.resolvedProject.gitRoot);
|
|
42
|
+
if (cachedPaths.some((relPath) => !isTaskPrArtifactPath({
|
|
43
|
+
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
44
|
+
taskId: opts.taskId,
|
|
45
|
+
relPath,
|
|
46
|
+
}))) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
await opts.ctx.git.stage(prArtifactPaths);
|
|
50
|
+
await opts.ctx.git.commit({
|
|
51
|
+
message: taskPrArtifactRefreshMessage(opts.taskId),
|
|
52
|
+
env: buildGitCommitEnv({
|
|
53
|
+
taskId: opts.taskId,
|
|
54
|
+
allowTasks: true,
|
|
55
|
+
allowBase: false,
|
|
56
|
+
allowPolicy: false,
|
|
57
|
+
allowConfig: false,
|
|
58
|
+
allowHooks: false,
|
|
59
|
+
allowCI: false,
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
opts.ctx.git.invalidateStatus();
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"freshness.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/freshness.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"freshness.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/freshness.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkD/B"}
|
|
@@ -15,6 +15,7 @@ export async function assessPrArtifactFreshness(opts) {
|
|
|
15
15
|
(await isTaskLocalOnlyAdvance({
|
|
16
16
|
gitRoot: opts.gitRoot,
|
|
17
17
|
workflowDir: opts.workflowDir,
|
|
18
|
+
tasksPath: opts.tasksPath,
|
|
18
19
|
taskId: opts.taskId,
|
|
19
20
|
fromRef: metaHeadSha,
|
|
20
21
|
toRef: opts.branchHeadSha,
|
|
@@ -33,6 +34,7 @@ export async function assessPrArtifactFreshness(opts) {
|
|
|
33
34
|
(await isTaskLocalOnlyAdvance({
|
|
34
35
|
gitRoot: opts.gitRoot,
|
|
35
36
|
workflowDir: opts.workflowDir,
|
|
37
|
+
tasksPath: opts.tasksPath,
|
|
36
38
|
taskId: opts.taskId,
|
|
37
39
|
fromRef: metaLastVerifiedSha,
|
|
38
40
|
toRef: opts.branchHeadSha,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,MAAM,EACZ,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,MAAM,EACZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAoFtC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAySF,KAAK,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAmCpC,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B,GAAG,IAAI,CAAC,CAmDR;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B,GAAG,OAAO,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B,CAAC,CA4TD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { resolveBaseBranch } from "@agentplaneorg/core";
|
|
3
|
+
import { extractTaskSuffix, resolveBaseBranch } from "@agentplaneorg/core";
|
|
4
4
|
import { mapBackendError } from "../../../cli/error-map.js";
|
|
5
5
|
import { exitCodeForError } from "../../../cli/exit-codes.js";
|
|
6
6
|
import { fileExists } from "../../../cli/fs-utils.js";
|
|
@@ -9,13 +9,13 @@ import { CliError } from "../../../shared/errors.js";
|
|
|
9
9
|
import { writeJsonStableIfChanged, writeTextIfChanged } from "../../../shared/write-if-changed.js";
|
|
10
10
|
import { execFileAsync, gitEnv } from "../../shared/git.js";
|
|
11
11
|
import { gitDiffStat } from "../../shared/git-diff.js";
|
|
12
|
-
import { gitCurrentBranch } from "../../shared/git-ops.js";
|
|
12
|
+
import { gitBranchUpstream, gitCurrentBranch } from "../../shared/git-ops.js";
|
|
13
13
|
import { parseTaskIdFromBranch } from "../../shared/git-worktree.js";
|
|
14
14
|
import { isTransientGhTransportError, normalizeGhTransportError, withGhTransportRetry, } from "../../shared/gh-transport.js";
|
|
15
15
|
import { INCIDENTS_POLICY_PATH } from "../../incidents/shared.js";
|
|
16
|
-
import { buildObservedGithubPrMeta, buildOpenedPrMeta,
|
|
17
|
-
import { loadBackendTask, loadCommandContext, } from "../../shared/task-backend.js";
|
|
16
|
+
import { buildObservedGithubPrMeta, buildOpenedPrMeta, buildUpdatedPrMeta, resolvePrArtifactHeadSha, parsePrMeta, } from "../../shared/pr-meta.js";
|
|
18
17
|
import { isTaskLocalOnlyAdvance } from "../../shared/task-local-freshness.js";
|
|
18
|
+
import { loadBackendTask, loadCommandContext, } from "../../shared/task-backend.js";
|
|
19
19
|
import { resolvePrPaths } from "./pr-paths.js";
|
|
20
20
|
import { readPrHandoffNotes } from "./note-store.js";
|
|
21
21
|
import { ghEnv } from "./gh-api.js";
|
|
@@ -147,6 +147,36 @@ function formatGithubPrLink(prNumber, prUrl, verb) {
|
|
|
147
147
|
? `${verb} GitHub PR #${prNumber}: ${prUrl.trim()}`
|
|
148
148
|
: `${verb} GitHub PR #${prNumber}`;
|
|
149
149
|
}
|
|
150
|
+
function shouldPersistObservedGithubPrMeta(observed) {
|
|
151
|
+
if (!observed)
|
|
152
|
+
return false;
|
|
153
|
+
return observed.status === "MERGED";
|
|
154
|
+
}
|
|
155
|
+
function taskPrArtifactRefreshMessage(taskId) {
|
|
156
|
+
return `📝 ${extractTaskSuffix(taskId)} task: refresh PR artifacts`;
|
|
157
|
+
}
|
|
158
|
+
async function resolveRenderableBranchHead(opts) {
|
|
159
|
+
const branchHeadSha = await resolveBranchHeadSha({
|
|
160
|
+
gitRoot: opts.gitRoot,
|
|
161
|
+
branch: opts.branch,
|
|
162
|
+
});
|
|
163
|
+
if (!branchHeadSha)
|
|
164
|
+
return { headSha: null, artifactRefresh: false };
|
|
165
|
+
try {
|
|
166
|
+
const { stdout: subjectStdout } = await execFileAsync("git", ["log", "-1", "--pretty=%s", branchHeadSha], {
|
|
167
|
+
cwd: opts.gitRoot,
|
|
168
|
+
env: gitEnv(),
|
|
169
|
+
});
|
|
170
|
+
const subject = subjectStdout.trim();
|
|
171
|
+
return {
|
|
172
|
+
headSha: branchHeadSha,
|
|
173
|
+
artifactRefresh: subject === taskPrArtifactRefreshMessage(opts.taskId),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return { headSha: branchHeadSha, artifactRefresh: false };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
150
180
|
function formatUnpublishedRemoteHeadReason(branch) {
|
|
151
181
|
return (`task branch ${branch} is not yet published on origin; push it with ` +
|
|
152
182
|
`\`git push -u origin ${branch}\` and rerun \`agentplane pr open\``);
|
|
@@ -248,8 +278,12 @@ async function resolveBranchHeadSha(opts) {
|
|
|
248
278
|
}
|
|
249
279
|
}
|
|
250
280
|
async function computePrDiffstat(opts) {
|
|
281
|
+
const diffBaseRef = await resolvePrDiffBaseRef({
|
|
282
|
+
gitRoot: opts.gitRoot,
|
|
283
|
+
baseBranch: opts.baseBranch,
|
|
284
|
+
});
|
|
251
285
|
try {
|
|
252
|
-
return await gitDiffStat(opts.gitRoot,
|
|
286
|
+
return await gitDiffStat(opts.gitRoot, diffBaseRef, opts.branch, {
|
|
253
287
|
excludePaths: [path.relative(opts.gitRoot, opts.prDir)],
|
|
254
288
|
});
|
|
255
289
|
}
|
|
@@ -259,6 +293,24 @@ async function computePrDiffstat(opts) {
|
|
|
259
293
|
return "";
|
|
260
294
|
}
|
|
261
295
|
}
|
|
296
|
+
async function resolvePrDiffBaseRef(opts) {
|
|
297
|
+
const upstreamRef = await gitBranchUpstream(opts.gitRoot, opts.baseBranch);
|
|
298
|
+
const candidate = upstreamRef?.trim() ?? "";
|
|
299
|
+
if (!candidate)
|
|
300
|
+
return opts.baseBranch;
|
|
301
|
+
try {
|
|
302
|
+
const { stdout } = await execFileAsync("git", ["rev-parse", "--verify", candidate], {
|
|
303
|
+
cwd: opts.gitRoot,
|
|
304
|
+
env: gitEnv(),
|
|
305
|
+
});
|
|
306
|
+
return stdout.trim() ? candidate : opts.baseBranch;
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
if (!isUnknownRevisionError(err))
|
|
310
|
+
throw err;
|
|
311
|
+
return opts.baseBranch;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
262
314
|
async function resolvePrSyncBranch(opts) {
|
|
263
315
|
const explicitBranch = opts.branch?.trim() ?? "";
|
|
264
316
|
if (explicitBranch) {
|
|
@@ -386,21 +438,28 @@ export async function syncPrArtifacts(opts) {
|
|
|
386
438
|
cliBaseOpt: null,
|
|
387
439
|
mode: config.workflow_mode,
|
|
388
440
|
});
|
|
389
|
-
const headSha = await
|
|
441
|
+
const { headSha, artifactRefresh } = await resolveRenderableBranchHead({
|
|
442
|
+
gitRoot: resolved.gitRoot,
|
|
443
|
+
taskId: task.id,
|
|
444
|
+
branch,
|
|
445
|
+
});
|
|
390
446
|
const preservePreviousHead = Boolean(existingMeta?.head_sha) &&
|
|
391
447
|
Boolean(headSha) &&
|
|
392
448
|
(await isTaskLocalOnlyAdvance({
|
|
393
449
|
gitRoot: resolved.gitRoot,
|
|
394
450
|
workflowDir: config.paths.workflow_dir,
|
|
451
|
+
tasksPath: config.paths.tasks_path,
|
|
395
452
|
taskId: task.id,
|
|
396
453
|
fromRef: existingMeta?.head_sha ?? null,
|
|
397
454
|
toRef: headSha,
|
|
398
455
|
}));
|
|
399
|
-
const renderedHeadSha =
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
456
|
+
const renderedHeadSha = artifactRefresh
|
|
457
|
+
? (existingMeta?.head_sha ?? undefined)
|
|
458
|
+
: resolvePrArtifactHeadSha({
|
|
459
|
+
previousHeadSha: existingMeta?.head_sha ?? null,
|
|
460
|
+
currentHeadSha: headSha,
|
|
461
|
+
preservePrevious: preservePreviousHead,
|
|
462
|
+
});
|
|
404
463
|
const preservedRenderUpdatedAt = existingMeta &&
|
|
405
464
|
(existingMeta.branch ?? null) === branch &&
|
|
406
465
|
(existingMeta.base ?? null) === (baseBranch ?? null) &&
|
|
@@ -418,7 +477,9 @@ export async function syncPrArtifacts(opts) {
|
|
|
418
477
|
prDir,
|
|
419
478
|
})
|
|
420
479
|
: "";
|
|
421
|
-
const renderedSummaryHeadSha =
|
|
480
|
+
const renderedSummaryHeadSha = artifactRefresh
|
|
481
|
+
? renderedHeadSha
|
|
482
|
+
: (renderedHeadSha ?? headSha);
|
|
422
483
|
let nextMeta = buildOpenedPrMeta({
|
|
423
484
|
taskId: task.id,
|
|
424
485
|
branch,
|
|
@@ -441,7 +502,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
441
502
|
autoSummary: renderPrAutoSummary({
|
|
442
503
|
updatedAt: renderUpdatedAt,
|
|
443
504
|
branch,
|
|
444
|
-
headSha: renderedSummaryHeadSha,
|
|
505
|
+
headSha: renderedSummaryHeadSha ?? null,
|
|
445
506
|
diffstat,
|
|
446
507
|
}),
|
|
447
508
|
});
|
|
@@ -451,11 +512,13 @@ export async function syncPrArtifacts(opts) {
|
|
|
451
512
|
baseBranch,
|
|
452
513
|
});
|
|
453
514
|
if (observedGithubPr) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
515
|
+
if (shouldPersistObservedGithubPrMeta(observedGithubPr)) {
|
|
516
|
+
nextMeta = buildObservedGithubPrMeta({
|
|
517
|
+
meta: nextMeta,
|
|
518
|
+
observed: observedGithubPr,
|
|
519
|
+
at: now,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
459
522
|
openOutcome = {
|
|
460
523
|
action: "linked-existing",
|
|
461
524
|
message: formatGithubPrLink(observedGithubPr.prNumber, observedGithubPr.prUrl, "linked to"),
|
|
@@ -476,11 +539,13 @@ export async function syncPrArtifacts(opts) {
|
|
|
476
539
|
body: githubBody,
|
|
477
540
|
});
|
|
478
541
|
if (createdGithubPr.observed) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
542
|
+
if (shouldPersistObservedGithubPrMeta(createdGithubPr.observed)) {
|
|
543
|
+
nextMeta = buildObservedGithubPrMeta({
|
|
544
|
+
meta: nextMeta,
|
|
545
|
+
observed: createdGithubPr.observed,
|
|
546
|
+
at: now,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
484
549
|
openOutcome = {
|
|
485
550
|
action: "created",
|
|
486
551
|
message: formatGithubPrLink(createdGithubPr.observed.prNumber, createdGithubPr.observed.prUrl, "created"),
|
|
@@ -496,7 +561,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
496
561
|
const nextAutoSummary = renderPrAutoSummary({
|
|
497
562
|
updatedAt: renderUpdatedAt,
|
|
498
563
|
branch,
|
|
499
|
-
headSha: renderedSummaryHeadSha,
|
|
564
|
+
headSha: renderedSummaryHeadSha ?? null,
|
|
500
565
|
diffstat,
|
|
501
566
|
});
|
|
502
567
|
const nextReview = renderPrReviewDocument({
|
|
@@ -550,7 +615,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
550
615
|
branch,
|
|
551
616
|
baseBranch,
|
|
552
617
|
});
|
|
553
|
-
if (observedGithubPr) {
|
|
618
|
+
if (shouldPersistObservedGithubPrMeta(observedGithubPr)) {
|
|
554
619
|
nextMeta = buildObservedGithubPrMeta({
|
|
555
620
|
meta: nextMeta,
|
|
556
621
|
observed: observedGithubPr,
|
|
@@ -560,7 +625,9 @@ export async function syncPrArtifacts(opts) {
|
|
|
560
625
|
const nextAutoSummary = renderPrAutoSummary({
|
|
561
626
|
updatedAt: nextMeta.updated_at,
|
|
562
627
|
branch,
|
|
563
|
-
headSha:
|
|
628
|
+
headSha: artifactRefresh
|
|
629
|
+
? (nextMeta.head_sha ?? renderedHeadSha ?? null)
|
|
630
|
+
: (nextMeta.head_sha ?? renderedHeadSha ?? headSha ?? null),
|
|
564
631
|
diffstat,
|
|
565
632
|
});
|
|
566
633
|
const nextReview = renderPrReviewDocument({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAkBpF,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB"}
|