agentplane 0.3.11 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/AGENTS.md +2 -2
- package/assets/RUNNER.md +1 -1
- 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 +3 -1
- 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/codex-plugin/assets/header.png +0 -0
- package/assets/codex-plugin/assets/icon.svg +1 -0
- package/assets/codex-plugin/assets/logo.svg +1 -0
- package/assets/codex-plugin/skills/agentplane/SKILL.md +35 -0
- package/assets/policy/governance.md +4 -2
- package/assets/policy/incidents.md +3 -19
- package/assets/policy/workflow.release.md +5 -2
- package/bin/agentplane.js +58 -3
- package/bin/stale-dist-policy.js +6 -1
- package/dist/.build-manifest.json +271 -161
- package/dist/cli/exit-codes.d.ts.map +1 -1
- package/dist/cli/exit-codes.js +1 -0
- package/dist/cli/reason-codes.d.ts +1 -1
- package/dist/cli/reason-codes.d.ts.map +1 -1
- package/dist/cli/reason-codes.js +12 -0
- 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 +22 -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 +21 -3
- 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/codex.d.ts +14 -0
- package/dist/cli/run-cli/commands/codex.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/codex.js +100 -0
- package/dist/cli/run-cli/commands/core.d.ts +1 -0
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +1 -0
- package/dist/cli/run-cli/commands/init/recipes.d.ts +9 -1
- package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/recipes.js +32 -22
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +26 -21
- package/dist/cli/run-cli/error-guidance.js +20 -0
- 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 +36 -19
- 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/codex/plugin-install.d.ts +26 -0
- package/dist/commands/codex/plugin-install.d.ts.map +1 -0
- package/dist/commands/codex/plugin-install.js +209 -0
- 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 +103 -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 +46 -7
- 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 +69 -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 +98 -27
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +52 -3
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +13 -2
- package/dist/commands/recipes/active.command.d.ts +7 -0
- package/dist/commands/recipes/active.command.d.ts.map +1 -0
- package/dist/commands/recipes/active.command.js +12 -0
- package/dist/commands/recipes/add.command.d.ts +8 -0
- package/dist/commands/recipes/add.command.d.ts.map +1 -0
- package/dist/commands/recipes/add.command.js +33 -0
- package/dist/commands/recipes/detach.command.d.ts +7 -0
- package/dist/commands/recipes/detach.command.d.ts.map +1 -0
- package/dist/commands/recipes/detach.command.js +19 -0
- package/dist/commands/recipes/disable.command.d.ts +7 -0
- package/dist/commands/recipes/disable.command.d.ts.map +1 -0
- package/dist/commands/recipes/disable.command.js +10 -0
- package/dist/commands/recipes/enable.command.d.ts +7 -0
- package/dist/commands/recipes/enable.command.d.ts.map +1 -0
- package/dist/commands/recipes/enable.command.js +10 -0
- package/dist/commands/recipes/explain-active.command.d.ts +5 -0
- package/dist/commands/recipes/explain-active.command.d.ts.map +1 -0
- package/dist/commands/recipes/explain-active.command.js +11 -0
- package/dist/commands/recipes/explain.command.d.ts.map +1 -1
- package/dist/commands/recipes/explain.command.js +4 -2
- package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
- package/dist/commands/recipes/impl/apply.js +33 -14
- package/dist/commands/recipes/impl/commands/active.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/active.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/active.js +46 -0
- package/dist/commands/recipes/impl/commands/add.d.ts +7 -0
- package/dist/commands/recipes/impl/commands/add.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/add.js +100 -0
- package/dist/commands/recipes/impl/commands/detach.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/detach.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/detach.js +85 -0
- package/dist/commands/recipes/impl/commands/disable.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/disable.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/disable.js +21 -0
- package/dist/commands/recipes/impl/commands/enable.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/enable.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/enable.js +39 -0
- package/dist/commands/recipes/impl/commands/explain-active.d.ts +5 -0
- package/dist/commands/recipes/impl/commands/explain-active.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/explain-active.js +20 -0
- package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/explain.js +40 -3
- package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/info.js +21 -8
- package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/install.js +32 -29
- package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/list.js +11 -11
- package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/remove.js +5 -0
- package/dist/commands/recipes/impl/commands/update.d.ts +7 -0
- package/dist/commands/recipes/impl/commands/update.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/update.js +93 -0
- package/dist/commands/recipes/impl/commands.d.ts +7 -0
- package/dist/commands/recipes/impl/commands.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands.js +7 -0
- package/dist/commands/recipes/impl/constants.d.ts +1 -14
- package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
- package/dist/commands/recipes/impl/constants.js +1 -18
- package/dist/commands/recipes/impl/manifest.d.ts +2 -2
- package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
- package/dist/commands/recipes/impl/manifest.js +4 -226
- package/dist/commands/recipes/impl/overlay-project.d.ts +32 -0
- package/dist/commands/recipes/impl/overlay-project.d.ts.map +1 -0
- package/dist/commands/recipes/impl/overlay-project.js +282 -0
- package/dist/commands/recipes/impl/paths.d.ts +20 -2
- package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
- package/dist/commands/recipes/impl/paths.js +23 -5
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts +2 -4
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
- package/dist/commands/recipes/impl/project-installed-recipes.js +30 -74
- package/dist/commands/recipes/impl/project-recipe-state.d.ts +18 -0
- package/dist/commands/recipes/impl/project-recipe-state.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-recipe-state.js +94 -0
- package/dist/commands/recipes/impl/project-registry.d.ts +20 -0
- package/dist/commands/recipes/impl/project-registry.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-registry.js +104 -0
- package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
- package/dist/commands/recipes/impl/resolver.js +5 -3
- package/dist/commands/recipes/impl/types.d.ts +1 -240
- package/dist/commands/recipes/impl/types.d.ts.map +1 -1
- package/dist/commands/recipes/info.command.js +2 -2
- package/dist/commands/recipes/install.spec.js +4 -4
- package/dist/commands/recipes/list.command.js +4 -4
- package/dist/commands/recipes/remove.command.js +2 -2
- package/dist/commands/recipes/update.command.d.ts +8 -0
- package/dist/commands/recipes/update.command.d.ts.map +1 -0
- package/dist/commands/recipes/update.command.js +35 -0
- package/dist/commands/recipes.d.ts +7 -4
- package/dist/commands/recipes.d.ts.map +1 -1
- package/dist/commands/recipes.js +6 -3
- package/dist/commands/recipes.test-helpers.d.ts +3 -3
- package/dist/commands/recipes.test-helpers.d.ts.map +1 -1
- package/dist/commands/recipes.test-helpers.js +105 -15
- 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/scenario/execute.command.js +4 -4
- package/dist/commands/scenario/impl/commands.js +4 -4
- package/dist/commands/scenario/info.command.js +4 -4
- package/dist/commands/scenario/list.command.js +3 -3
- package/dist/commands/scenario/run.command.js +5 -5
- package/dist/commands/scenario/scenario.command.js +7 -7
- 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-handoff.d.ts +2 -1
- package/dist/commands/shared/task-handoff.d.ts.map +1 -1
- package/dist/commands/shared/task-handoff.js +15 -0
- 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/handoff-show.command.d.ts.map +1 -1
- package/dist/commands/task/handoff-show.command.js +24 -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/dist/runner/context/base-prompts.d.ts +2 -1
- package/dist/runner/context/base-prompts.d.ts.map +1 -1
- package/dist/runner/context/base-prompts.js +109 -13
- package/dist/runner/context/recipe-context.d.ts.map +1 -1
- package/dist/runner/context/recipe-context.js +40 -8
- package/dist/runner/types.d.ts +4 -0
- package/dist/runner/types.d.ts.map +1 -1
- package/dist/runner/usecases/task-run.d.ts.map +1 -1
- package/dist/runner/usecases/task-run.js +2 -1
- package/dist/runtime/behavior/resolve.d.ts +2 -1
- package/dist/runtime/behavior/resolve.d.ts.map +1 -1
- package/dist/runtime/behavior/resolve.js +25 -5
- package/dist/runtime/behavior/types.d.ts +1 -0
- package/dist/runtime/behavior/types.d.ts.map +1 -1
- package/dist/runtime/capabilities/recipe.d.ts +2 -1
- package/dist/runtime/capabilities/recipe.d.ts.map +1 -1
- package/dist/runtime/capabilities/recipe.js +88 -28
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/runtime-source.d.ts.map +1 -1
- package/dist/shared/runtime-source.js +8 -3
- package/package.json +3 -2
- package/dist/cli/recipes-bundled.d.ts +0 -10
- package/dist/cli/recipes-bundled.d.ts.map +0 -1
- package/dist/cli/recipes-bundled.js +0 -36
|
@@ -4,6 +4,7 @@ import { resolveBaseBranch } from "@agentplaneorg/core";
|
|
|
4
4
|
import { fileExists } from "../../../../cli/fs-utils.js";
|
|
5
5
|
import { exitCodeForError } from "../../../../cli/exit-codes.js";
|
|
6
6
|
import { unknownEntityMessage, workflowModeMessage } from "../../../../cli/output.js";
|
|
7
|
+
import { withDiagnosticContext } from "../../../../shared/diagnostics.js";
|
|
7
8
|
import { CliError } from "../../../../shared/errors.js";
|
|
8
9
|
import { ensureGitClean } from "../../../guard/index.js";
|
|
9
10
|
import { gitDiffNames } from "../../../shared/git-diff.js";
|
|
@@ -17,6 +18,7 @@ import { readAndValidatePrArtifacts, ensureCommittedPrArtifactsOnBranch } from "
|
|
|
17
18
|
import { computeVerifyState } from "../verify.js";
|
|
18
19
|
import { parsePrMetaForwardCompatible } from "../../../shared/pr-meta.js";
|
|
19
20
|
import { assessPrArtifactFreshness } from "../../internal/freshness.js";
|
|
21
|
+
import { requiresPullRequestMergePath } from "./github-protection.js";
|
|
20
22
|
export async function prepareIntegrate(opts) {
|
|
21
23
|
const ctx = opts.ctx ??
|
|
22
24
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
@@ -51,13 +53,6 @@ export async function prepareIntegrate(opts) {
|
|
|
51
53
|
});
|
|
52
54
|
}
|
|
53
55
|
const currentBranch = await gitCurrentBranch(resolved.gitRoot);
|
|
54
|
-
if (currentBranch !== baseBranch) {
|
|
55
|
-
throw new CliError({
|
|
56
|
-
exitCode: exitCodeForError("E_GIT"),
|
|
57
|
-
code: "E_GIT",
|
|
58
|
-
message: `integrate must run on base branch ${baseBranch} (current: ${currentBranch})`,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
56
|
const { prDir, metaPath, diffstatPath, verifyLogPath } = await resolvePrPaths({
|
|
62
57
|
ctx,
|
|
63
58
|
cwd: opts.cwd,
|
|
@@ -91,6 +86,43 @@ export async function prepareIntegrate(opts) {
|
|
|
91
86
|
message: unknownEntityMessage("branch", branch),
|
|
92
87
|
});
|
|
93
88
|
}
|
|
89
|
+
if (currentBranch !== baseBranch) {
|
|
90
|
+
if (currentBranch === branch) {
|
|
91
|
+
const baseWorktreePath = await findWorktreeForBranch(resolved.gitRoot, baseBranch);
|
|
92
|
+
const rerunCommand = baseWorktreePath && baseWorktreePath.trim().length > 0
|
|
93
|
+
? `agentplane integrate ${opts.taskId} --branch ${branch} --root ${baseWorktreePath}`
|
|
94
|
+
: `git checkout ${baseBranch} && agentplane integrate ${opts.taskId} --branch ${branch}`;
|
|
95
|
+
throw new CliError({
|
|
96
|
+
exitCode: exitCodeForError("E_GIT"),
|
|
97
|
+
code: "E_GIT",
|
|
98
|
+
message: `integrate must run from the ${baseBranch} base checkout, not from task branch ${branch}. ` +
|
|
99
|
+
`Rerun it against the base checkout after leaving this task worktree.`,
|
|
100
|
+
context: withDiagnosticContext({
|
|
101
|
+
command: "integrate",
|
|
102
|
+
task_id: opts.taskId,
|
|
103
|
+
branch,
|
|
104
|
+
base_branch: baseBranch,
|
|
105
|
+
current_branch: currentBranch,
|
|
106
|
+
...(baseWorktreePath ? { base_worktree_path: baseWorktreePath } : {}),
|
|
107
|
+
reason_code: "integrate_base_checkout_required",
|
|
108
|
+
}, {
|
|
109
|
+
state: `integrate was invoked from task branch ${branch} instead of base branch ${baseBranch}`,
|
|
110
|
+
likelyCause: "the operator is inside the task worktree, but branch_pr integrate is only valid from the registered base checkout",
|
|
111
|
+
hint: "Use the base checkout/worktree for the resolved base branch, not the task branch worktree, when running integrate.",
|
|
112
|
+
nextAction: {
|
|
113
|
+
command: rerunCommand,
|
|
114
|
+
reason: "rerun integrate against the base checkout route",
|
|
115
|
+
reasonCode: "integrate_base_checkout_required",
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
throw new CliError({
|
|
121
|
+
exitCode: exitCodeForError("E_GIT"),
|
|
122
|
+
code: "E_GIT",
|
|
123
|
+
message: `integrate must run on base branch ${baseBranch} (current: ${currentBranch})`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
94
126
|
await ensureCommittedPrArtifactsOnBranch({
|
|
95
127
|
resolved,
|
|
96
128
|
prDir,
|
|
@@ -132,6 +164,10 @@ export async function prepareIntegrate(opts) {
|
|
|
132
164
|
preferBranchSnapshot: true,
|
|
133
165
|
branchSnapshotBranch: branch,
|
|
134
166
|
});
|
|
167
|
+
const protectedBaseRequiresPrMerge = await requiresPullRequestMergePath({
|
|
168
|
+
gitRoot: resolved.gitRoot,
|
|
169
|
+
baseBranch: base,
|
|
170
|
+
});
|
|
135
171
|
const changedPaths = await gitDiffNames(resolved.gitRoot, base, branch);
|
|
136
172
|
const tasksPath = loadedConfig.paths.tasks_path;
|
|
137
173
|
if (changedPaths.includes(tasksPath)) {
|
|
@@ -145,6 +181,7 @@ export async function prepareIntegrate(opts) {
|
|
|
145
181
|
let freshness = await assessPrArtifactFreshness({
|
|
146
182
|
gitRoot: resolved.gitRoot,
|
|
147
183
|
workflowDir: loadedConfig.paths.workflow_dir,
|
|
184
|
+
tasksPath: loadedConfig.paths.tasks_path,
|
|
148
185
|
taskId: opts.taskId,
|
|
149
186
|
branchHeadSha,
|
|
150
187
|
metaHeadSha: metaSource.head_sha ?? null,
|
|
@@ -181,6 +218,7 @@ export async function prepareIntegrate(opts) {
|
|
|
181
218
|
freshness = await assessPrArtifactFreshness({
|
|
182
219
|
gitRoot: resolved.gitRoot,
|
|
183
220
|
workflowDir: loadedConfig.paths.workflow_dir,
|
|
221
|
+
tasksPath: loadedConfig.paths.tasks_path,
|
|
184
222
|
taskId: opts.taskId,
|
|
185
223
|
branchHeadSha,
|
|
186
224
|
metaHeadSha: repairedMetaSource.head_sha ?? null,
|
|
@@ -218,6 +256,7 @@ export async function prepareIntegrate(opts) {
|
|
|
218
256
|
task,
|
|
219
257
|
baseBranch,
|
|
220
258
|
currentBranch,
|
|
259
|
+
protectedBaseRequiresPrMerge,
|
|
221
260
|
prDir,
|
|
222
261
|
metaPath,
|
|
223
262
|
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;AAiCnE,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,69 @@
|
|
|
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 taskReadmePath(workflowDir, taskId) {
|
|
11
|
+
return toGitPath(path.join(workflowDir, taskId, "README.md"));
|
|
12
|
+
}
|
|
13
|
+
function isTaskPacketPath(opts) {
|
|
14
|
+
const normalized = toGitPath(opts.relPath);
|
|
15
|
+
return (normalized === taskReadmePath(opts.workflowDir, opts.taskId) ||
|
|
16
|
+
normalized.startsWith(taskPrDirPrefix(opts.workflowDir, opts.taskId)));
|
|
17
|
+
}
|
|
18
|
+
async function readCachedPaths(gitRoot) {
|
|
19
|
+
const { stdout } = await execFileAsync("git", ["diff", "--cached", "--name-only", "--relative"], {
|
|
20
|
+
cwd: gitRoot,
|
|
21
|
+
env: gitEnv(),
|
|
22
|
+
});
|
|
23
|
+
return stdout
|
|
24
|
+
.split("\n")
|
|
25
|
+
.map((line) => line.trim())
|
|
26
|
+
.filter((line) => line.length > 0);
|
|
27
|
+
}
|
|
28
|
+
function taskPrArtifactRefreshMessage(taskId) {
|
|
29
|
+
return `📝 ${extractTaskSuffix(taskId)} task: refresh PR artifacts`;
|
|
30
|
+
}
|
|
31
|
+
export async function maybeAutoCommitTaskPrArtifacts(opts) {
|
|
32
|
+
if (opts.ctx.config.workflow_mode !== "branch_pr")
|
|
33
|
+
return false;
|
|
34
|
+
const branchText = await gitCurrentBranch(opts.ctx.resolvedProject.gitRoot);
|
|
35
|
+
const currentBranch = branchText.trim();
|
|
36
|
+
if (!currentBranch || currentBranch !== opts.branch.trim())
|
|
37
|
+
return false;
|
|
38
|
+
const changedPaths = await opts.ctx.git.statusChangedPaths();
|
|
39
|
+
const taskPacketPaths = changedPaths.filter((relPath) => isTaskPacketPath({
|
|
40
|
+
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
41
|
+
taskId: opts.taskId,
|
|
42
|
+
relPath,
|
|
43
|
+
}));
|
|
44
|
+
if (taskPacketPaths.length === 0)
|
|
45
|
+
return false;
|
|
46
|
+
const cachedPaths = await readCachedPaths(opts.ctx.resolvedProject.gitRoot);
|
|
47
|
+
if (cachedPaths.some((relPath) => !isTaskPacketPath({
|
|
48
|
+
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
49
|
+
taskId: opts.taskId,
|
|
50
|
+
relPath,
|
|
51
|
+
}))) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
await opts.ctx.git.stage(taskPacketPaths);
|
|
55
|
+
await opts.ctx.git.commit({
|
|
56
|
+
message: taskPrArtifactRefreshMessage(opts.taskId),
|
|
57
|
+
env: buildGitCommitEnv({
|
|
58
|
+
taskId: opts.taskId,
|
|
59
|
+
allowTasks: true,
|
|
60
|
+
allowBase: false,
|
|
61
|
+
allowPolicy: false,
|
|
62
|
+
allowConfig: false,
|
|
63
|
+
allowHooks: false,
|
|
64
|
+
allowCI: false,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
opts.ctx.git.invalidateStatus();
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
@@ -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;AA6SF,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,9 +278,17 @@ 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
|
+
});
|
|
285
|
+
const taskDir = path.dirname(opts.prDir);
|
|
251
286
|
try {
|
|
252
|
-
return await gitDiffStat(opts.gitRoot,
|
|
253
|
-
excludePaths: [
|
|
287
|
+
return await gitDiffStat(opts.gitRoot, diffBaseRef, opts.branch, {
|
|
288
|
+
excludePaths: [
|
|
289
|
+
path.relative(opts.gitRoot, opts.prDir),
|
|
290
|
+
path.relative(opts.gitRoot, path.join(taskDir, "README.md")),
|
|
291
|
+
],
|
|
254
292
|
});
|
|
255
293
|
}
|
|
256
294
|
catch (err) {
|
|
@@ -259,6 +297,24 @@ async function computePrDiffstat(opts) {
|
|
|
259
297
|
return "";
|
|
260
298
|
}
|
|
261
299
|
}
|
|
300
|
+
async function resolvePrDiffBaseRef(opts) {
|
|
301
|
+
const upstreamRef = await gitBranchUpstream(opts.gitRoot, opts.baseBranch);
|
|
302
|
+
const candidate = upstreamRef?.trim() ?? "";
|
|
303
|
+
if (!candidate)
|
|
304
|
+
return opts.baseBranch;
|
|
305
|
+
try {
|
|
306
|
+
const { stdout } = await execFileAsync("git", ["rev-parse", "--verify", candidate], {
|
|
307
|
+
cwd: opts.gitRoot,
|
|
308
|
+
env: gitEnv(),
|
|
309
|
+
});
|
|
310
|
+
return stdout.trim() ? candidate : opts.baseBranch;
|
|
311
|
+
}
|
|
312
|
+
catch (err) {
|
|
313
|
+
if (!isUnknownRevisionError(err))
|
|
314
|
+
throw err;
|
|
315
|
+
return opts.baseBranch;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
262
318
|
async function resolvePrSyncBranch(opts) {
|
|
263
319
|
const explicitBranch = opts.branch?.trim() ?? "";
|
|
264
320
|
if (explicitBranch) {
|
|
@@ -386,21 +442,28 @@ export async function syncPrArtifacts(opts) {
|
|
|
386
442
|
cliBaseOpt: null,
|
|
387
443
|
mode: config.workflow_mode,
|
|
388
444
|
});
|
|
389
|
-
const headSha = await
|
|
445
|
+
const { headSha, artifactRefresh } = await resolveRenderableBranchHead({
|
|
446
|
+
gitRoot: resolved.gitRoot,
|
|
447
|
+
taskId: task.id,
|
|
448
|
+
branch,
|
|
449
|
+
});
|
|
390
450
|
const preservePreviousHead = Boolean(existingMeta?.head_sha) &&
|
|
391
451
|
Boolean(headSha) &&
|
|
392
452
|
(await isTaskLocalOnlyAdvance({
|
|
393
453
|
gitRoot: resolved.gitRoot,
|
|
394
454
|
workflowDir: config.paths.workflow_dir,
|
|
455
|
+
tasksPath: config.paths.tasks_path,
|
|
395
456
|
taskId: task.id,
|
|
396
457
|
fromRef: existingMeta?.head_sha ?? null,
|
|
397
458
|
toRef: headSha,
|
|
398
459
|
}));
|
|
399
|
-
const renderedHeadSha =
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
460
|
+
const renderedHeadSha = artifactRefresh
|
|
461
|
+
? (existingMeta?.head_sha ?? undefined)
|
|
462
|
+
: resolvePrArtifactHeadSha({
|
|
463
|
+
previousHeadSha: existingMeta?.head_sha ?? null,
|
|
464
|
+
currentHeadSha: headSha,
|
|
465
|
+
preservePrevious: preservePreviousHead,
|
|
466
|
+
});
|
|
404
467
|
const preservedRenderUpdatedAt = existingMeta &&
|
|
405
468
|
(existingMeta.branch ?? null) === branch &&
|
|
406
469
|
(existingMeta.base ?? null) === (baseBranch ?? null) &&
|
|
@@ -418,7 +481,9 @@ export async function syncPrArtifacts(opts) {
|
|
|
418
481
|
prDir,
|
|
419
482
|
})
|
|
420
483
|
: "";
|
|
421
|
-
const renderedSummaryHeadSha =
|
|
484
|
+
const renderedSummaryHeadSha = artifactRefresh
|
|
485
|
+
? renderedHeadSha
|
|
486
|
+
: (renderedHeadSha ?? headSha);
|
|
422
487
|
let nextMeta = buildOpenedPrMeta({
|
|
423
488
|
taskId: task.id,
|
|
424
489
|
branch,
|
|
@@ -441,7 +506,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
441
506
|
autoSummary: renderPrAutoSummary({
|
|
442
507
|
updatedAt: renderUpdatedAt,
|
|
443
508
|
branch,
|
|
444
|
-
headSha: renderedSummaryHeadSha,
|
|
509
|
+
headSha: renderedSummaryHeadSha ?? null,
|
|
445
510
|
diffstat,
|
|
446
511
|
}),
|
|
447
512
|
});
|
|
@@ -451,11 +516,13 @@ export async function syncPrArtifacts(opts) {
|
|
|
451
516
|
baseBranch,
|
|
452
517
|
});
|
|
453
518
|
if (observedGithubPr) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
519
|
+
if (shouldPersistObservedGithubPrMeta(observedGithubPr)) {
|
|
520
|
+
nextMeta = buildObservedGithubPrMeta({
|
|
521
|
+
meta: nextMeta,
|
|
522
|
+
observed: observedGithubPr,
|
|
523
|
+
at: now,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
459
526
|
openOutcome = {
|
|
460
527
|
action: "linked-existing",
|
|
461
528
|
message: formatGithubPrLink(observedGithubPr.prNumber, observedGithubPr.prUrl, "linked to"),
|
|
@@ -476,11 +543,13 @@ export async function syncPrArtifacts(opts) {
|
|
|
476
543
|
body: githubBody,
|
|
477
544
|
});
|
|
478
545
|
if (createdGithubPr.observed) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
546
|
+
if (shouldPersistObservedGithubPrMeta(createdGithubPr.observed)) {
|
|
547
|
+
nextMeta = buildObservedGithubPrMeta({
|
|
548
|
+
meta: nextMeta,
|
|
549
|
+
observed: createdGithubPr.observed,
|
|
550
|
+
at: now,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
484
553
|
openOutcome = {
|
|
485
554
|
action: "created",
|
|
486
555
|
message: formatGithubPrLink(createdGithubPr.observed.prNumber, createdGithubPr.observed.prUrl, "created"),
|
|
@@ -496,7 +565,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
496
565
|
const nextAutoSummary = renderPrAutoSummary({
|
|
497
566
|
updatedAt: renderUpdatedAt,
|
|
498
567
|
branch,
|
|
499
|
-
headSha: renderedSummaryHeadSha,
|
|
568
|
+
headSha: renderedSummaryHeadSha ?? null,
|
|
500
569
|
diffstat,
|
|
501
570
|
});
|
|
502
571
|
const nextReview = renderPrReviewDocument({
|
|
@@ -550,7 +619,7 @@ export async function syncPrArtifacts(opts) {
|
|
|
550
619
|
branch,
|
|
551
620
|
baseBranch,
|
|
552
621
|
});
|
|
553
|
-
if (observedGithubPr) {
|
|
622
|
+
if (shouldPersistObservedGithubPrMeta(observedGithubPr)) {
|
|
554
623
|
nextMeta = buildObservedGithubPrMeta({
|
|
555
624
|
meta: nextMeta,
|
|
556
625
|
observed: observedGithubPr,
|
|
@@ -560,7 +629,9 @@ export async function syncPrArtifacts(opts) {
|
|
|
560
629
|
const nextAutoSummary = renderPrAutoSummary({
|
|
561
630
|
updatedAt: nextMeta.updated_at,
|
|
562
631
|
branch,
|
|
563
|
-
headSha:
|
|
632
|
+
headSha: artifactRefresh
|
|
633
|
+
? (nextMeta.head_sha ?? renderedHeadSha ?? null)
|
|
634
|
+
: (nextMeta.head_sha ?? renderedHeadSha ?? headSha ?? null),
|
|
564
635
|
diffstat,
|
|
565
636
|
});
|
|
566
637
|
const nextReview = renderPrReviewDocument({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/open.ts"],"names":[],"mappings":"AAQA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAuCpF,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,CAgElB"}
|
package/dist/commands/pr/open.js
CHANGED
|
@@ -3,6 +3,10 @@ import { mapBackendError } from "../../cli/error-map.js";
|
|
|
3
3
|
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
4
4
|
import { createCliEmitter } from "../../cli/output.js";
|
|
5
5
|
import { CliError } from "../../shared/errors.js";
|
|
6
|
+
import { execFileAsync, gitEnv } from "../shared/git.js";
|
|
7
|
+
import { gitBranchUpstream } from "../shared/git-ops.js";
|
|
8
|
+
import { loadCommandContext } from "../shared/task-backend.js";
|
|
9
|
+
import { maybeAutoCommitTaskPrArtifacts } from "./internal/auto-commit.js";
|
|
6
10
|
import { syncPrArtifacts } from "./internal/sync.js";
|
|
7
11
|
function prOpenOutcomeDetails(meta, openOutcome) {
|
|
8
12
|
if (openOutcome)
|
|
@@ -14,6 +18,24 @@ function prOpenOutcomeDetails(meta, openOutcome) {
|
|
|
14
18
|
}
|
|
15
19
|
return "local PR artifacts synced; remote PR creation staged";
|
|
16
20
|
}
|
|
21
|
+
async function pushTaskBranchUpstreamIfConfigured(opts) {
|
|
22
|
+
const upstream = await gitBranchUpstream(opts.gitRoot, opts.branch);
|
|
23
|
+
const trimmed = upstream?.trim() ?? "";
|
|
24
|
+
if (!trimmed)
|
|
25
|
+
return false;
|
|
26
|
+
const slashIndex = trimmed.indexOf("/");
|
|
27
|
+
if (slashIndex <= 0 || slashIndex === trimmed.length - 1)
|
|
28
|
+
return false;
|
|
29
|
+
const remote = trimmed.slice(0, slashIndex);
|
|
30
|
+
const upstreamBranch = trimmed.slice(slashIndex + 1);
|
|
31
|
+
if (!remote || !upstreamBranch)
|
|
32
|
+
return false;
|
|
33
|
+
await execFileAsync("git", ["push", "--no-verify", remote, `HEAD:${upstreamBranch}`], {
|
|
34
|
+
cwd: opts.gitRoot,
|
|
35
|
+
env: gitEnv(),
|
|
36
|
+
});
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
17
39
|
export async function cmdPrOpen(opts) {
|
|
18
40
|
try {
|
|
19
41
|
const output = createCliEmitter();
|
|
@@ -25,16 +47,43 @@ export async function cmdPrOpen(opts) {
|
|
|
25
47
|
message: "Invalid value for --author.",
|
|
26
48
|
});
|
|
27
49
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
50
|
+
const commandCtx = opts.ctx ??
|
|
51
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
52
|
+
const initialSync = await syncPrArtifacts({
|
|
53
|
+
ctx: commandCtx,
|
|
30
54
|
cwd: opts.cwd,
|
|
31
55
|
rootOverride: opts.rootOverride,
|
|
32
56
|
taskId: opts.taskId,
|
|
33
57
|
mode: "open",
|
|
34
58
|
author,
|
|
35
59
|
branch: opts.branch,
|
|
36
|
-
remoteMode:
|
|
60
|
+
remoteMode: "sync-only",
|
|
37
61
|
});
|
|
62
|
+
const didAutoCommit = initialSync.meta.branch
|
|
63
|
+
? await maybeAutoCommitTaskPrArtifacts({
|
|
64
|
+
ctx: commandCtx,
|
|
65
|
+
taskId: opts.taskId,
|
|
66
|
+
branch: initialSync.meta.branch,
|
|
67
|
+
})
|
|
68
|
+
: false;
|
|
69
|
+
if (didAutoCommit && !opts.syncOnly && initialSync.meta.branch) {
|
|
70
|
+
await pushTaskBranchUpstreamIfConfigured({
|
|
71
|
+
gitRoot: commandCtx.resolvedProject.gitRoot,
|
|
72
|
+
branch: initialSync.meta.branch,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const { meta, prDir, resolved, openOutcome } = opts.syncOnly
|
|
76
|
+
? initialSync
|
|
77
|
+
: await syncPrArtifacts({
|
|
78
|
+
ctx: commandCtx,
|
|
79
|
+
cwd: opts.cwd,
|
|
80
|
+
rootOverride: opts.rootOverride,
|
|
81
|
+
taskId: opts.taskId,
|
|
82
|
+
mode: "open",
|
|
83
|
+
author,
|
|
84
|
+
branch: opts.branch,
|
|
85
|
+
remoteMode: "auto",
|
|
86
|
+
});
|
|
38
87
|
output.success("pr open", path.relative(resolved.gitRoot, prDir), prOpenOutcomeDetails(meta, openOutcome ?? null));
|
|
39
88
|
return 0;
|
|
40
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/update.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/update.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAqEnC,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsClB"}
|
|
@@ -5,6 +5,7 @@ import { createCliEmitter } from "../../cli/output.js";
|
|
|
5
5
|
import { CliError } from "../../shared/errors.js";
|
|
6
6
|
import { gitRevParse } from "../shared/git-ops.js";
|
|
7
7
|
import { loadBackendTask, loadCommandContext, } from "../shared/task-backend.js";
|
|
8
|
+
import { maybeAutoCommitTaskPrArtifacts } from "./internal/auto-commit.js";
|
|
8
9
|
import { assessPrArtifactFreshness } from "./internal/freshness.js";
|
|
9
10
|
import { syncPrArtifacts } from "./internal/sync.js";
|
|
10
11
|
async function readTextIfExists(filePath) {
|
|
@@ -38,6 +39,7 @@ async function warnOnStaleVerifyAfterUpdate(opts) {
|
|
|
38
39
|
const freshness = await assessPrArtifactFreshness({
|
|
39
40
|
gitRoot: opts.resolved.gitRoot,
|
|
40
41
|
workflowDir: path.join(opts.resolved.gitRoot, config.paths.workflow_dir),
|
|
42
|
+
tasksPath: config.paths.tasks_path,
|
|
41
43
|
taskId: opts.taskId,
|
|
42
44
|
branchHeadSha,
|
|
43
45
|
metaHeadSha: opts.meta.head_sha ?? null,
|
|
@@ -54,16 +56,25 @@ async function warnOnStaleVerifyAfterUpdate(opts) {
|
|
|
54
56
|
export async function cmdPrUpdate(opts) {
|
|
55
57
|
try {
|
|
56
58
|
const output = createCliEmitter();
|
|
59
|
+
const commandCtx = opts.ctx ??
|
|
60
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
57
61
|
const { meta, prDir, resolved } = await syncPrArtifacts({
|
|
58
|
-
ctx:
|
|
62
|
+
ctx: commandCtx,
|
|
59
63
|
cwd: opts.cwd,
|
|
60
64
|
rootOverride: opts.rootOverride,
|
|
61
65
|
taskId: opts.taskId,
|
|
62
66
|
mode: "update",
|
|
63
67
|
});
|
|
68
|
+
if (meta.branch) {
|
|
69
|
+
await maybeAutoCommitTaskPrArtifacts({
|
|
70
|
+
ctx: commandCtx,
|
|
71
|
+
taskId: opts.taskId,
|
|
72
|
+
branch: meta.branch,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
64
75
|
await warnOnStaleVerifyAfterUpdate({
|
|
65
76
|
output,
|
|
66
|
-
ctx:
|
|
77
|
+
ctx: commandCtx,
|
|
67
78
|
cwd: opts.cwd,
|
|
68
79
|
rootOverride: opts.rootOverride,
|
|
69
80
|
taskId: opts.taskId,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
|
+
export type RecipesActiveParsed = {
|
|
3
|
+
full: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare const recipesActiveSpec: CommandSpec<RecipesActiveParsed>;
|
|
6
|
+
export declare const runRecipesActive: CommandHandler<RecipesActiveParsed>;
|
|
7
|
+
//# sourceMappingURL=active.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/active.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,mBAAmB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAS9D,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,mBAAmB,CAC2B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { cmdRecipeActiveParsed } from "../recipes.js";
|
|
2
|
+
export const recipesActiveSpec = {
|
|
3
|
+
id: ["recipes", "active"],
|
|
4
|
+
group: "Recipes",
|
|
5
|
+
summary: "List active project overlays.",
|
|
6
|
+
options: [
|
|
7
|
+
{ kind: "boolean", name: "full", default: false, description: "Print full JSON payload." },
|
|
8
|
+
],
|
|
9
|
+
examples: [{ cmd: "agentplane recipes active", why: "Show overlays active for the project." }],
|
|
10
|
+
parse: (raw) => ({ full: raw.opts.full === true }),
|
|
11
|
+
};
|
|
12
|
+
export const runRecipesActive = (ctx, parsed) => cmdRecipeActiveParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, full: parsed.full });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
|
+
export type RecipesAddParsed = {
|
|
3
|
+
recipeRef: string;
|
|
4
|
+
mode?: "copy" | "link";
|
|
5
|
+
};
|
|
6
|
+
export declare const recipesAddSpec: CommandSpec<RecipesAddParsed>;
|
|
7
|
+
export declare const runRecipesAdd: CommandHandler<RecipesAddParsed>;
|
|
8
|
+
//# sourceMappingURL=add.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/add.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAyBxD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,gBAAgB,CAMvD,CAAC"}
|