agentplane 0.3.12 → 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/RUNNER.md +1 -1
- package/assets/agents/ORCHESTRATOR.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 -20
- package/assets/policy/workflow.release.md +5 -2
- package/dist/.build-manifest.json +203 -113
- 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 +16 -0
- 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.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +22 -19
- 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/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +81 -5
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +38 -7
- package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -1
- package/dist/commands/pr/internal/auto-commit.js +11 -6
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +5 -1
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +46 -8
- 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/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/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/task/handoff-show.command.d.ts.map +1 -1
- package/dist/commands/task/handoff-show.command.js +24 -0
- 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
|
@@ -308,7 +308,7 @@ export async function writeConfig(root, config) {
|
|
|
308
308
|
export async function resetAgentplaneHomeRecipes() {
|
|
309
309
|
if (!agentplaneHome)
|
|
310
310
|
return;
|
|
311
|
-
await rm(path.join(agentplaneHome, "recipes"), { recursive: true, force: true });
|
|
311
|
+
await rm(path.join(agentplaneHome, "recipes-store"), { recursive: true, force: true });
|
|
312
312
|
await rm(path.join(agentplaneHome, "recipes.json"), { force: true });
|
|
313
313
|
await rm(path.join(agentplaneHome, "recipes-index.json"), { force: true });
|
|
314
314
|
}
|
|
@@ -349,8 +349,7 @@ export async function createRecipeArchive(opts) {
|
|
|
349
349
|
{
|
|
350
350
|
id: "RECIPE_SKILL",
|
|
351
351
|
summary: "Recipe analysis skill",
|
|
352
|
-
|
|
353
|
-
file: "skills/analysis.json",
|
|
352
|
+
file: "skills/analysis.md",
|
|
354
353
|
},
|
|
355
354
|
],
|
|
356
355
|
agents: [
|
|
@@ -361,7 +360,7 @@ export async function createRecipeArchive(opts) {
|
|
|
361
360
|
summary: "Recipe agent",
|
|
362
361
|
skills: ["RECIPE_SKILL"],
|
|
363
362
|
tools: ["RECIPE_TOOL"],
|
|
364
|
-
file: "agents/recipe.
|
|
363
|
+
file: "agents/recipe.md",
|
|
365
364
|
},
|
|
366
365
|
],
|
|
367
366
|
tools: [
|
|
@@ -395,18 +394,23 @@ export async function createRecipeArchive(opts) {
|
|
|
395
394
|
await writeFile(path.join(recipeDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
396
395
|
const agentsDir = path.join(recipeDir, "agents");
|
|
397
396
|
await mkdir(agentsDir, { recursive: true });
|
|
398
|
-
await writeFile(path.join(agentsDir, "recipe.
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
397
|
+
await writeFile(path.join(agentsDir, "recipe.md"), [
|
|
398
|
+
"# Recipe Agent",
|
|
399
|
+
"",
|
|
400
|
+
"Role: executor",
|
|
401
|
+
"",
|
|
402
|
+
"Instructions:",
|
|
403
|
+
"- Use recipe local policy.",
|
|
404
|
+
"- Materialize the declared scenario artifacts.",
|
|
405
|
+
].join("\n"), "utf8");
|
|
403
406
|
const skillsDir = path.join(recipeDir, "skills");
|
|
404
407
|
await mkdir(skillsDir, { recursive: true });
|
|
405
|
-
await writeFile(path.join(skillsDir, "analysis.
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
408
|
+
await writeFile(path.join(skillsDir, "analysis.md"), [
|
|
409
|
+
"# Recipe Skill",
|
|
410
|
+
"",
|
|
411
|
+
"- Inspect the generated bundle before acting.",
|
|
412
|
+
"- Keep recipe-owned artifacts inside the declared output paths.",
|
|
413
|
+
].join("\n"), "utf8");
|
|
410
414
|
const toolsDir = path.join(recipeDir, "tools");
|
|
411
415
|
await mkdir(toolsDir, { recursive: true });
|
|
412
416
|
await writeFile(path.join(toolsDir, "run.js"), [
|
|
@@ -496,8 +500,7 @@ export async function createUnsafeRecipeArchive(opts) {
|
|
|
496
500
|
{
|
|
497
501
|
id: "RECIPE_SKILL",
|
|
498
502
|
summary: "Recipe skill",
|
|
499
|
-
|
|
500
|
-
file: "skills/recipe.json",
|
|
503
|
+
file: "skills/recipe.md",
|
|
501
504
|
},
|
|
502
505
|
],
|
|
503
506
|
agents: [
|
|
@@ -508,7 +511,7 @@ export async function createUnsafeRecipeArchive(opts) {
|
|
|
508
511
|
summary: "Recipe agent",
|
|
509
512
|
skills: ["RECIPE_SKILL"],
|
|
510
513
|
tools: ["RECIPE_TOOL"],
|
|
511
|
-
file: "agents/recipe.
|
|
514
|
+
file: "agents/recipe.md",
|
|
512
515
|
},
|
|
513
516
|
],
|
|
514
517
|
tools: [
|
|
@@ -535,10 +538,10 @@ export async function createUnsafeRecipeArchive(opts) {
|
|
|
535
538
|
await writeFile(path.join(recipeDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
536
539
|
const agentsDir = path.join(recipeDir, "agents");
|
|
537
540
|
await mkdir(agentsDir, { recursive: true });
|
|
538
|
-
await writeFile(path.join(agentsDir, "recipe.
|
|
541
|
+
await writeFile(path.join(agentsDir, "recipe.md"), "# Recipe Agent\n\nFollow the unsafe archive validation path.\n", "utf8");
|
|
539
542
|
const skillsDir = path.join(recipeDir, "skills");
|
|
540
543
|
await mkdir(skillsDir, { recursive: true });
|
|
541
|
-
await writeFile(path.join(skillsDir, "recipe.
|
|
544
|
+
await writeFile(path.join(skillsDir, "recipe.md"), "# Recipe Skill\n\nInspect archive contents before materialization.\n", "utf8");
|
|
542
545
|
const toolsDir = path.join(recipeDir, "tools");
|
|
543
546
|
await mkdir(toolsDir, { recursive: true });
|
|
544
547
|
await writeFile(path.join(toolsDir, "run.sh"), "#!/usr/bin/env bash\n", "utf8");
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const AGENTPLANE_CODEX_HOME_ENV = "AGENTPLANE_CODEX_HOME";
|
|
2
|
+
export type CodexPluginInstallScope = "user" | "repo";
|
|
3
|
+
export type CodexPluginInstallResult = {
|
|
4
|
+
scope: CodexPluginInstallScope;
|
|
5
|
+
installRoot: string;
|
|
6
|
+
pluginRoot: string;
|
|
7
|
+
manifestPath: string;
|
|
8
|
+
marketplacePath: string;
|
|
9
|
+
copiedAssets: string[];
|
|
10
|
+
};
|
|
11
|
+
type JsonObject = Record<string, unknown>;
|
|
12
|
+
export declare function buildCodexPluginManifest(version?: string): JsonObject;
|
|
13
|
+
export declare function resolveCodexInstallRoot(opts: {
|
|
14
|
+
scope: CodexPluginInstallScope;
|
|
15
|
+
repoRoot?: string;
|
|
16
|
+
env?: NodeJS.ProcessEnv;
|
|
17
|
+
}): string;
|
|
18
|
+
export declare function resolveCodexPluginRoot(installRoot: string): string;
|
|
19
|
+
export declare function resolveCodexMarketplacePath(installRoot: string): string;
|
|
20
|
+
export declare function installBundledCodexPlugin(opts: {
|
|
21
|
+
scope: CodexPluginInstallScope;
|
|
22
|
+
installRoot: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
}): Promise<CodexPluginInstallResult>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=plugin-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-install.d.ts","sourceRoot":"","sources":["../../../src/commands/codex/plugin-install.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtD,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,uBAAuB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAwG1C,wBAAgB,wBAAwB,CAAC,OAAO,SAAe,GAAG,UAAU,CA8B3E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,uBAAuB,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,MAAM,CAiBT;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,KAAK,EAAE,uBAAuB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAyCpC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { copyFile, mkdir, readFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { CliError } from "../../shared/errors.js";
|
|
6
|
+
import { getVersion } from "../../meta/version.js";
|
|
7
|
+
import { writeJsonStableIfChanged, writeTextIfChanged } from "../../shared/write-if-changed.js";
|
|
8
|
+
const PLUGIN_NAME = "agentplane";
|
|
9
|
+
const DEFAULT_MARKETPLACE_NAME = "agentplane-local-marketplace";
|
|
10
|
+
const DEFAULT_MARKETPLACE_DISPLAY_NAME = "AgentPlane Local Plugins";
|
|
11
|
+
const ASSET_ROOT_URL = new URL("../../../assets/codex-plugin/", import.meta.url);
|
|
12
|
+
const TEXT_ASSETS = [
|
|
13
|
+
{
|
|
14
|
+
source: new URL("skills/agentplane/SKILL.md", ASSET_ROOT_URL),
|
|
15
|
+
relativePath: "skills/agentplane/SKILL.md",
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
const BINARY_ASSETS = [
|
|
19
|
+
{
|
|
20
|
+
source: new URL("assets/icon.svg", ASSET_ROOT_URL),
|
|
21
|
+
relativePath: "assets/icon.svg",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
source: new URL("assets/logo.svg", ASSET_ROOT_URL),
|
|
25
|
+
relativePath: "assets/logo.svg",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
source: new URL("assets/header.png", ASSET_ROOT_URL),
|
|
29
|
+
relativePath: "assets/header.png",
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
export const AGENTPLANE_CODEX_HOME_ENV = "AGENTPLANE_CODEX_HOME";
|
|
33
|
+
function isJsonObject(value) {
|
|
34
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35
|
+
}
|
|
36
|
+
function invalidMarketplaceError(message) {
|
|
37
|
+
return new CliError({
|
|
38
|
+
exitCode: 3,
|
|
39
|
+
code: "E_VALIDATION",
|
|
40
|
+
message,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function readTextIfExists(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
return await readFile(filePath, "utf8");
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const code = err?.code;
|
|
49
|
+
if (code === "ENOENT")
|
|
50
|
+
return null;
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function defaultMarketplaceDocument() {
|
|
55
|
+
return {
|
|
56
|
+
name: DEFAULT_MARKETPLACE_NAME,
|
|
57
|
+
interface: {
|
|
58
|
+
displayName: DEFAULT_MARKETPLACE_DISPLAY_NAME,
|
|
59
|
+
},
|
|
60
|
+
plugins: [],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function parseMarketplaceDocument(text) {
|
|
64
|
+
if (text === null)
|
|
65
|
+
return defaultMarketplaceDocument();
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(text);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw invalidMarketplaceError(`Invalid Codex marketplace JSON: ${err instanceof Error ? err.message : "unknown parse error"}`);
|
|
72
|
+
}
|
|
73
|
+
if (!isJsonObject(parsed)) {
|
|
74
|
+
throw invalidMarketplaceError("Invalid Codex marketplace JSON: expected a top-level object.");
|
|
75
|
+
}
|
|
76
|
+
if ("plugins" in parsed && !Array.isArray(parsed.plugins)) {
|
|
77
|
+
throw invalidMarketplaceError("Invalid Codex marketplace JSON: `plugins` must be an array.");
|
|
78
|
+
}
|
|
79
|
+
if ("interface" in parsed && parsed.interface !== undefined && !isJsonObject(parsed.interface)) {
|
|
80
|
+
throw invalidMarketplaceError("Invalid Codex marketplace JSON: `interface` must be an object when present.");
|
|
81
|
+
}
|
|
82
|
+
return parsed;
|
|
83
|
+
}
|
|
84
|
+
function marketplaceEntry() {
|
|
85
|
+
return {
|
|
86
|
+
name: PLUGIN_NAME,
|
|
87
|
+
source: {
|
|
88
|
+
source: "local",
|
|
89
|
+
path: `./plugins/${PLUGIN_NAME}`,
|
|
90
|
+
},
|
|
91
|
+
policy: {
|
|
92
|
+
installation: "AVAILABLE",
|
|
93
|
+
authentication: "ON_INSTALL",
|
|
94
|
+
},
|
|
95
|
+
category: "Productivity",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function upsertMarketplaceDocument(text) {
|
|
99
|
+
const document = parseMarketplaceDocument(text);
|
|
100
|
+
const interfaceObject = isJsonObject(document.interface) ? { ...document.interface } : {};
|
|
101
|
+
if (typeof document.name !== "string" || document.name.trim().length === 0) {
|
|
102
|
+
document.name = DEFAULT_MARKETPLACE_NAME;
|
|
103
|
+
}
|
|
104
|
+
if (typeof interfaceObject.displayName !== "string" ||
|
|
105
|
+
interfaceObject.displayName.trim().length === 0) {
|
|
106
|
+
interfaceObject.displayName = DEFAULT_MARKETPLACE_DISPLAY_NAME;
|
|
107
|
+
}
|
|
108
|
+
const plugins = Array.isArray(document.plugins) ? document.plugins : [];
|
|
109
|
+
const nextEntry = marketplaceEntry();
|
|
110
|
+
const existingIndex = plugins.findIndex((entry) => isJsonObject(entry) && entry.name === PLUGIN_NAME);
|
|
111
|
+
if (existingIndex === -1) {
|
|
112
|
+
plugins.push(nextEntry);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
plugins.splice(existingIndex, 1, nextEntry);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
...document,
|
|
119
|
+
interface: interfaceObject,
|
|
120
|
+
plugins,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export function buildCodexPluginManifest(version = getVersion()) {
|
|
124
|
+
return {
|
|
125
|
+
name: PLUGIN_NAME,
|
|
126
|
+
version,
|
|
127
|
+
description: "Bundle AgentPlane workflow guidance for the Codex plugins UI.",
|
|
128
|
+
homepage: "https://github.com/basilisk-labs/agentplane",
|
|
129
|
+
repository: "https://github.com/basilisk-labs/agentplane",
|
|
130
|
+
license: "MIT",
|
|
131
|
+
keywords: ["agentplane", "codex", "workflow", "tasks", "git"],
|
|
132
|
+
skills: "./skills/",
|
|
133
|
+
interface: {
|
|
134
|
+
displayName: "AgentPlane",
|
|
135
|
+
shortDescription: "Governed git-native workflow guidance for Codex",
|
|
136
|
+
longDescription: "Install AgentPlane into Codex through a local marketplace and give Codex explicit task, planning, verification, and branch_pr workflow guidance.",
|
|
137
|
+
developerName: "basilisk-labs",
|
|
138
|
+
category: "Productivity",
|
|
139
|
+
capabilities: ["Read", "Write"],
|
|
140
|
+
websiteURL: "https://github.com/basilisk-labs/agentplane",
|
|
141
|
+
defaultPrompt: [
|
|
142
|
+
"Use AgentPlane to initialize a governed workflow in this repository.",
|
|
143
|
+
"Use AgentPlane to create a task, approve the plan, and start work in branch_pr mode.",
|
|
144
|
+
"Use AgentPlane to verify the active task and record evidence before finish.",
|
|
145
|
+
],
|
|
146
|
+
brandColor: "#111827",
|
|
147
|
+
composerIcon: "./assets/icon.svg",
|
|
148
|
+
logo: "./assets/logo.svg",
|
|
149
|
+
screenshots: ["./assets/header.png"],
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function resolveCodexInstallRoot(opts) {
|
|
154
|
+
if (opts.scope === "repo") {
|
|
155
|
+
const repoRoot = opts.repoRoot?.trim();
|
|
156
|
+
if (!repoRoot) {
|
|
157
|
+
throw new CliError({
|
|
158
|
+
exitCode: 2,
|
|
159
|
+
code: "E_USAGE",
|
|
160
|
+
message: "Repo scope requires a resolved repository root.",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return path.resolve(repoRoot);
|
|
164
|
+
}
|
|
165
|
+
const env = opts.env ?? process.env;
|
|
166
|
+
const overridden = env[AGENTPLANE_CODEX_HOME_ENV]?.trim();
|
|
167
|
+
if (overridden)
|
|
168
|
+
return path.resolve(overridden);
|
|
169
|
+
return os.homedir();
|
|
170
|
+
}
|
|
171
|
+
export function resolveCodexPluginRoot(installRoot) {
|
|
172
|
+
return path.join(installRoot, "plugins", PLUGIN_NAME);
|
|
173
|
+
}
|
|
174
|
+
export function resolveCodexMarketplacePath(installRoot) {
|
|
175
|
+
return path.join(installRoot, ".agents", "plugins", "marketplace.json");
|
|
176
|
+
}
|
|
177
|
+
export async function installBundledCodexPlugin(opts) {
|
|
178
|
+
const installRoot = path.resolve(opts.installRoot);
|
|
179
|
+
const pluginRoot = resolveCodexPluginRoot(installRoot);
|
|
180
|
+
const manifestPath = path.join(pluginRoot, ".codex-plugin", "plugin.json");
|
|
181
|
+
const marketplacePath = resolveCodexMarketplacePath(installRoot);
|
|
182
|
+
await mkdir(path.dirname(manifestPath), { recursive: true });
|
|
183
|
+
await mkdir(path.dirname(marketplacePath), { recursive: true });
|
|
184
|
+
await writeJsonStableIfChanged(manifestPath, buildCodexPluginManifest(opts.version ?? getVersion()));
|
|
185
|
+
const copiedAssets = [];
|
|
186
|
+
for (const asset of TEXT_ASSETS) {
|
|
187
|
+
const targetPath = path.join(pluginRoot, asset.relativePath);
|
|
188
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
189
|
+
const contents = await readFile(asset.source, "utf8");
|
|
190
|
+
await writeTextIfChanged(targetPath, contents);
|
|
191
|
+
copiedAssets.push(targetPath);
|
|
192
|
+
}
|
|
193
|
+
for (const asset of BINARY_ASSETS) {
|
|
194
|
+
const targetPath = path.join(pluginRoot, asset.relativePath);
|
|
195
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
196
|
+
await copyFile(fileURLToPath(asset.source), targetPath);
|
|
197
|
+
copiedAssets.push(targetPath);
|
|
198
|
+
}
|
|
199
|
+
const nextMarketplace = upsertMarketplaceDocument(await readTextIfExists(marketplacePath));
|
|
200
|
+
await writeJsonStableIfChanged(marketplacePath, nextMarketplace);
|
|
201
|
+
return {
|
|
202
|
+
scope: opts.scope,
|
|
203
|
+
installRoot,
|
|
204
|
+
pluginRoot,
|
|
205
|
+
manifestPath,
|
|
206
|
+
marketplacePath,
|
|
207
|
+
copiedAssets,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
@@ -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":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA0EnE,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6QlB"}
|
|
@@ -2,11 +2,13 @@ import path from "node:path";
|
|
|
2
2
|
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
|
+
import { withDiagnosticContext } from "../../../shared/diagnostics.js";
|
|
5
6
|
import { CliError } from "../../../shared/errors.js";
|
|
6
7
|
import { cleanupIntegratedBranch } from "./internal/cleanup.js";
|
|
7
8
|
import { renderPostIntegrateBootstrapFailureGuidance, renderPostIntegrateBootstrapGuidance, shouldRecommendPostIntegrateBootstrap, } from "./internal/bootstrap-guidance.js";
|
|
8
9
|
import { execFileAsync, gitEnv } from "../../shared/git.js";
|
|
9
10
|
import { gitRevParse } from "../../shared/git-ops.js";
|
|
11
|
+
import { buildTaskHandoffArtifact, resolveTaskHandoffPaths, writeTaskHandoff, } from "../../shared/task-handoff.js";
|
|
10
12
|
import { finalizeIntegrate } from "./internal/finalize.js";
|
|
11
13
|
import { runMergeCommit, runRebaseFastForward, runSquashMerge } from "./internal/merge.js";
|
|
12
14
|
import { maybeRunPreIntegrateBootstrap } from "./internal/pre-integrate-bootstrap.js";
|
|
@@ -14,6 +16,54 @@ import { maybeRunPostIntegrateBootstrap } from "./internal/post-integrate-bootst
|
|
|
14
16
|
import { prepareIntegrate } from "./internal/prepare.js";
|
|
15
17
|
import { resolveWorktreeForIntegrate } from "./internal/worktree.js";
|
|
16
18
|
import { runVerifyCommands } from "./verify.js";
|
|
19
|
+
async function recordProtectedBaseIntegrateHandoff(opts) {
|
|
20
|
+
const paths = resolveTaskHandoffPaths({
|
|
21
|
+
git_root: opts.ctx.resolvedProject.gitRoot,
|
|
22
|
+
workflow_dir: opts.ctx.config.paths.workflow_dir,
|
|
23
|
+
task_id: opts.taskId,
|
|
24
|
+
});
|
|
25
|
+
const handoffShowCommand = `agentplane task handoff show ${opts.taskId}`;
|
|
26
|
+
const prLabel = typeof opts.prNumber === "number" && opts.prNumber > 0
|
|
27
|
+
? `GitHub PR #${opts.prNumber}`
|
|
28
|
+
: `the GitHub PR for branch ${opts.branch}`;
|
|
29
|
+
const prUrl = opts.prUrl?.trim() ?? "";
|
|
30
|
+
const prMetaPath = path.join(opts.ctx.config.paths.workflow_dir, opts.taskId, "pr", "meta.json");
|
|
31
|
+
const taskReadmePath = path.join(opts.ctx.config.paths.workflow_dir, opts.taskId, "README.md");
|
|
32
|
+
await writeTaskHandoff({
|
|
33
|
+
paths,
|
|
34
|
+
handoff: buildTaskHandoffArtifact({
|
|
35
|
+
task_id: opts.taskId,
|
|
36
|
+
created_at: new Date().toISOString(),
|
|
37
|
+
from_role: "INTEGRATOR",
|
|
38
|
+
reason: `Protected base ${opts.base} requires GitHub pull-request merges.`,
|
|
39
|
+
note: prUrl.length > 0
|
|
40
|
+
? `Merge ${prLabel}: ${prUrl}. After GitHub merge, wait for Task Hosted Close, then pull ${opts.base}.`
|
|
41
|
+
: `Merge ${prLabel} on GitHub. After GitHub merge, wait for Task Hosted Close, then pull ${opts.base}.`,
|
|
42
|
+
branch: opts.branch,
|
|
43
|
+
base_branch: opts.base,
|
|
44
|
+
head_sha: opts.branchHeadSha,
|
|
45
|
+
workspace_root: opts.ctx.resolvedProject.gitRoot,
|
|
46
|
+
pr_branch: opts.branch,
|
|
47
|
+
route: {
|
|
48
|
+
kind: "protected_base_integrate",
|
|
49
|
+
status: "awaiting_github_merge",
|
|
50
|
+
local_mutation: "not_performed",
|
|
51
|
+
finalize_via: "github_pr_merge_then_hosted_close",
|
|
52
|
+
pr_number: opts.prNumber,
|
|
53
|
+
pr_url: prUrl.length > 0 ? prUrl : null,
|
|
54
|
+
handoff_show_command: handoffShowCommand,
|
|
55
|
+
base_pull_command: "git pull --ff-only",
|
|
56
|
+
},
|
|
57
|
+
next_actions: [
|
|
58
|
+
handoffShowCommand,
|
|
59
|
+
prUrl.length > 0 ? `Merge ${prLabel}: ${prUrl}` : `Merge ${prLabel} on GitHub`,
|
|
60
|
+
`Wait for Task Hosted Close to finish`,
|
|
61
|
+
`git pull --ff-only`,
|
|
62
|
+
],
|
|
63
|
+
evidence_paths: [taskReadmePath, prMetaPath],
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
17
67
|
export async function cmdIntegrate(opts) {
|
|
18
68
|
let tempWorktreePath = null;
|
|
19
69
|
let createdTempWorktree = false;
|
|
@@ -41,14 +91,40 @@ export async function cmdIntegrate(opts) {
|
|
|
41
91
|
return 0;
|
|
42
92
|
}
|
|
43
93
|
if (protectedBaseRequiresPrMerge) {
|
|
44
|
-
const
|
|
45
|
-
?
|
|
46
|
-
:
|
|
94
|
+
const prNumber = typeof metaSource.pr_number === "number" && metaSource.pr_number > 0
|
|
95
|
+
? metaSource.pr_number
|
|
96
|
+
: null;
|
|
97
|
+
const prUrl = typeof metaSource.pr_url === "string" ? metaSource.pr_url : null;
|
|
98
|
+
const prHint = prNumber === null ? `the GitHub PR for branch ${branch}` : `GitHub PR #${prNumber}`;
|
|
99
|
+
await recordProtectedBaseIntegrateHandoff({
|
|
100
|
+
ctx: prepared.ctx,
|
|
101
|
+
taskId: task.id,
|
|
102
|
+
branch,
|
|
103
|
+
base,
|
|
104
|
+
branchHeadSha,
|
|
105
|
+
prNumber,
|
|
106
|
+
prUrl,
|
|
107
|
+
});
|
|
47
108
|
throw new CliError({
|
|
48
|
-
exitCode: exitCodeForError("
|
|
49
|
-
code: "
|
|
109
|
+
exitCode: exitCodeForError("E_HANDOFF"),
|
|
110
|
+
code: "E_HANDOFF",
|
|
50
111
|
message: `Base branch ${base} requires GitHub pull-request merges; integrate will not mutate it locally. ` +
|
|
51
112
|
`Merge ${prHint} on GitHub, let Task Hosted Close finish the closure tail, then pull ${base}.`,
|
|
113
|
+
context: withDiagnosticContext({
|
|
114
|
+
task_id: task.id,
|
|
115
|
+
branch,
|
|
116
|
+
base_branch: base,
|
|
117
|
+
reason_code: "protected_base_integrate_handoff",
|
|
118
|
+
}, {
|
|
119
|
+
state: `protected-base integrate routed to GitHub merge handoff for ${task.id}`,
|
|
120
|
+
likelyCause: `base branch ${base} is protected by a GitHub pull-request merge policy, so local integrate must stop before mutating ${base}`,
|
|
121
|
+
hint: "Inspect the persisted handoff artifact for the canonical finalize route, then merge the PR on GitHub and let Task Hosted Close finish the close tail.",
|
|
122
|
+
nextAction: {
|
|
123
|
+
command: `agentplane task handoff show ${task.id}`,
|
|
124
|
+
reason: "inspect the persisted protected-base finalize route before continuing",
|
|
125
|
+
reasonCode: "protected_base_integrate_handoff",
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
52
128
|
});
|
|
53
129
|
}
|
|
54
130
|
const wt = await resolveWorktreeForIntegrate({
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/prepare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAWrE,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAIvF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,EAAE,QAAQ,CAAC;IAEf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B,EAAE,OAAO,CAAC;IAEtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqR7B"}
|
|
@@ -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";
|
|
@@ -52,13 +53,6 @@ export async function prepareIntegrate(opts) {
|
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
const currentBranch = await gitCurrentBranch(resolved.gitRoot);
|
|
55
|
-
if (currentBranch !== baseBranch) {
|
|
56
|
-
throw new CliError({
|
|
57
|
-
exitCode: exitCodeForError("E_GIT"),
|
|
58
|
-
code: "E_GIT",
|
|
59
|
-
message: `integrate must run on base branch ${baseBranch} (current: ${currentBranch})`,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
56
|
const { prDir, metaPath, diffstatPath, verifyLogPath } = await resolvePrPaths({
|
|
63
57
|
ctx,
|
|
64
58
|
cwd: opts.cwd,
|
|
@@ -92,6 +86,43 @@ export async function prepareIntegrate(opts) {
|
|
|
92
86
|
message: unknownEntityMessage("branch", branch),
|
|
93
87
|
});
|
|
94
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
|
+
}
|
|
95
126
|
await ensureCommittedPrArtifactsOnBranch({
|
|
96
127
|
resolved,
|
|
97
128
|
prDir,
|
|
@@ -1 +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;
|
|
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"}
|
|
@@ -7,8 +7,13 @@ import { gitCurrentBranch } from "../../shared/git-ops.js";
|
|
|
7
7
|
function taskPrDirPrefix(workflowDir, taskId) {
|
|
8
8
|
return `${toGitPath(path.join(workflowDir, taskId, "pr"))}/`;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return toGitPath(
|
|
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)));
|
|
12
17
|
}
|
|
13
18
|
async function readCachedPaths(gitRoot) {
|
|
14
19
|
const { stdout } = await execFileAsync("git", ["diff", "--cached", "--name-only", "--relative"], {
|
|
@@ -31,22 +36,22 @@ export async function maybeAutoCommitTaskPrArtifacts(opts) {
|
|
|
31
36
|
if (!currentBranch || currentBranch !== opts.branch.trim())
|
|
32
37
|
return false;
|
|
33
38
|
const changedPaths = await opts.ctx.git.statusChangedPaths();
|
|
34
|
-
const
|
|
39
|
+
const taskPacketPaths = changedPaths.filter((relPath) => isTaskPacketPath({
|
|
35
40
|
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
36
41
|
taskId: opts.taskId,
|
|
37
42
|
relPath,
|
|
38
43
|
}));
|
|
39
|
-
if (
|
|
44
|
+
if (taskPacketPaths.length === 0)
|
|
40
45
|
return false;
|
|
41
46
|
const cachedPaths = await readCachedPaths(opts.ctx.resolvedProject.gitRoot);
|
|
42
|
-
if (cachedPaths.some((relPath) => !
|
|
47
|
+
if (cachedPaths.some((relPath) => !isTaskPacketPath({
|
|
43
48
|
workflowDir: opts.ctx.config.paths.workflow_dir,
|
|
44
49
|
taskId: opts.taskId,
|
|
45
50
|
relPath,
|
|
46
51
|
}))) {
|
|
47
52
|
return false;
|
|
48
53
|
}
|
|
49
|
-
await opts.ctx.git.stage(
|
|
54
|
+
await opts.ctx.git.stage(taskPacketPaths);
|
|
50
55
|
await opts.ctx.git.commit({
|
|
51
56
|
message: taskPrArtifactRefreshMessage(opts.taskId),
|
|
52
57
|
env: buildGitCommitEnv({
|
|
@@ -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;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;
|
|
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"}
|
|
@@ -282,9 +282,13 @@ async function computePrDiffstat(opts) {
|
|
|
282
282
|
gitRoot: opts.gitRoot,
|
|
283
283
|
baseBranch: opts.baseBranch,
|
|
284
284
|
});
|
|
285
|
+
const taskDir = path.dirname(opts.prDir);
|
|
285
286
|
try {
|
|
286
287
|
return await gitDiffStat(opts.gitRoot, diffBaseRef, opts.branch, {
|
|
287
|
-
excludePaths: [
|
|
288
|
+
excludePaths: [
|
|
289
|
+
path.relative(opts.gitRoot, opts.prDir),
|
|
290
|
+
path.relative(opts.gitRoot, path.join(taskDir, "README.md")),
|
|
291
|
+
],
|
|
288
292
|
});
|
|
289
293
|
}
|
|
290
294
|
catch (err) {
|
|
@@ -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"}
|