agentplane 0.4.2 → 0.4.4

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.
@@ -15,21 +15,21 @@ Use AgentPlane through its CLI instead of editing `.agentplane/` state directly.
15
15
 
16
16
  ## Startup
17
17
 
18
- 1. If the repository is not initialized, run `agentplane init`.
19
- 2. Run `agentplane quickstart`.
20
- 3. Inspect `AGENTS.md`, `agentplane task list`, `git status --short --untracked-files=no`, and `git rev-parse --abbrev-ref HEAD`.
21
- 4. Use `agentplane role ORCHESTRATOR` while planning and approvals are active.
22
- 5. Switch to `agentplane role <ROLE>` before owner-scoped execution or verification.
18
+ 1. If the repository is not initialized, run `ap init` or `agentplane init`.
19
+ 2. Run `ap quickstart`.
20
+ 3. Inspect `AGENTS.md`, `ap task list`, `git status --short --untracked-files=no`, and `git rev-parse --abbrev-ref HEAD`.
21
+ 4. Use `ap role ORCHESTRATOR` while planning and approvals are active.
22
+ 5. Switch to `ap role <ROLE>` before owner-scoped execution or verification.
23
23
 
24
24
  ## Rules
25
25
 
26
- - Treat `AGENTS.md`, `agentplane quickstart`, and `agentplane role <ROLE>` as the policy surface.
27
- - Use `agentplane task ...`, `agentplane work ...`, `agentplane verify ...`, and `agentplane finish ...`; do not edit `.agentplane/tasks.json` manually.
28
- - In `branch_pr`, start from `agentplane work start <task-id> --agent <ROLE> --slug <slug> --worktree`.
26
+ - Treat `AGENTS.md`, `ap quickstart`, and `ap role <ROLE>` as the policy surface.
27
+ - Use `ap task ...`, `ap work ...`, `ap verify ...`, and `ap finish ...`; do not edit `.agentplane/tasks.json` manually.
28
+ - In `branch_pr`, start from `ap work start <task-id> --agent <ROLE> --slug <slug> --worktree`.
29
29
  - Keep repository artifacts in English unless the user explicitly requests another language for a specific artifact.
30
- - Record verification evidence in the task README and through `agentplane verify`.
30
+ - Record verification evidence in the task README and through `ap verify`.
31
31
 
32
32
  ## Limits
33
33
 
34
- - This plugin bundles workflow guidance only. It does not install the `agentplane` binary for you.
35
- - If `agentplane` is missing from `PATH`, install it first, then use the workflow commands above.
34
+ - This plugin bundles workflow guidance only. It does not install the `ap`/`agentplane` binary for you.
35
+ - If both `ap` and `agentplane` are missing from `PATH`, install AgentPlane first, then use the workflow commands above.
@@ -34,6 +34,46 @@ function assertFilesExist(repoRoot, paths, label, errors) {
34
34
  }
35
35
  }
36
36
 
37
+ function remediationForRoutingError(error) {
38
+ if (error.includes("exceeds policy budget")) {
39
+ return {
40
+ code: "POLICY_ROUTING_BUDGET",
41
+ why: "Large gateway or policy modules make agent startup context harder to route deterministically.",
42
+ fix: "Move scenario-specific detail into the correct canonical module or shorten duplicate rule text.",
43
+ safeCommand: "node .agentplane/policy/check-routing.mjs",
44
+ stopCondition:
45
+ "Stop if the size reduction would remove a hard constraint or source-of-truth rule.",
46
+ };
47
+ }
48
+ if (error.includes("path does not exist") || error.includes("Missing canonical")) {
49
+ return {
50
+ code: "POLICY_ROUTING_MISSING_PATH",
51
+ why: "AGENTS.md references a policy file that agents cannot load.",
52
+ fix: "Restore the referenced file or update the gateway reference to the canonical existing path.",
53
+ safeCommand: "agentplane doctor",
54
+ stopCondition: "Stop if the missing file is a policy module deleted by another active task.",
55
+ };
56
+ }
57
+ return {
58
+ code: "POLICY_ROUTING_FAILED",
59
+ why: "The policy gateway no longer matches the deterministic load-rule contract.",
60
+ fix: "Repair AGENTS.md load rules, canonical docs, examples, or policy module layout.",
61
+ safeCommand: "node .agentplane/policy/check-routing.mjs",
62
+ stopCondition: "Stop if the repair changes workflow mode, approval gates, or policy ownership.",
63
+ };
64
+ }
65
+
66
+ function renderRemediation(error) {
67
+ const r = remediationForRoutingError(error);
68
+ return [
69
+ ` Code: ${r.code}`,
70
+ ` Why: ${r.why}`,
71
+ ` Fix: ${r.fix}`,
72
+ ` Safe command: ${r.safeCommand}`,
73
+ ` Stop condition: ${r.stopCondition}`,
74
+ ].join("\n");
75
+ }
76
+
37
77
  function listFilesRecursive(dirPath, relPrefix = "") {
38
78
  if (!fs.existsSync(dirPath)) return [];
39
79
  const entries = fs.readdirSync(dirPath).toSorted((a, b) => a.localeCompare(b));
@@ -171,7 +211,11 @@ function main() {
171
211
  }
172
212
 
173
213
  if (errors.length > 0) {
174
- throw new Error(`Policy routing check failed:\n- ${errors.join("\n- ")}`);
214
+ throw new Error(
215
+ `Policy routing check failed:\n${errors
216
+ .map((error) => `- ${error}\n${renderRemediation(error)}`)
217
+ .join("\n")}`,
218
+ );
175
219
  }
176
220
 
177
221
  process.stdout.write("policy routing OK\n");
@@ -13,3 +13,6 @@
13
13
  - id: INC-20260501-03 | date: 2026-05-01 | scope: Make post-publish release evidence PR recovery authenticate gh so successful releases do not end as failed after publication. | tags: ci, release, workflow | match: ci, release, workflow, make, post, publish, evidence, recovery, authenticate, successful, releases, not, end, failed, after, publication | failure: Release evidence gh CLI steps now set GH_TOKEN from github.token. | advice: Added GH_TOKEN env to release evidence PR check/create/merge steps and contract coverage. | rule: Analogous Make post-publish release evidence PR recovery authenticate gh so successful releases do not end as failed after publication. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605012054-HS993A; commit c329da9be70f | enforcement: manual | fixability: external | state: open
14
14
  - id: INC-20260501-04 | date: 2026-05-01 | scope: Update the Homebrew formula renderer and tap formula so fresh AgentPlane releases install without Homebrew npm min-release-age blocking fresh package dependencies. | tags: release, workflow | match: release, workflow, update, the, homebrew, formula, renderer, and, tap, fresh, agentplane, releases, install, without, npm, min | failure: Updated render-homebrew-formula to install the cached npm tarball without std_npm_args/min-release-age, added contract coverage, and pushed basilisk-labs/homebrew-tap c6d3e94 for v0.4.1. Local Homebrew install reached Cellar successfully; final link was blocked only by an existing /opt/homebrew/bin/agentplane npm-global symlink. | advice: Run brew link --overwrite agentplane when an old npm-global symlink is present; standalone no-Node install requires a future native/bundled CLI artifact. | rule: Analogous Update the Homebrew formula renderer and tap formula so fresh AgentPlane releases install without Homebrew npm min-release-age blocking fresh package dependencies. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605012143-NEK3E8; commit 43bc2ed84a23 | enforcement: manual | fixability: external | state: open
15
15
  - id: INC-20260503-01 | date: 2026-05-03 | scope: Port the artifacts_language configuration and PR artifact language validation from the stale cli-artifacts branch onto current main, preserving current v0.4.2 release state. | tags: code, release, workflow | match: code, release, workflow, port, the, artifacts, language, configuration, and, artifact, validation, from, stale, cli, branch, onto | failure: Ported artifacts_language=en and PR artifact language validation onto current main; stale trust branch was not merged because it would reintroduce old task states. | advice: No rework required before PR. | rule: Analogous Port the artifacts_language configuration and PR artifact language validation from the stale cli-artifacts branch onto current main, preserving current v0.4.2 release state. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605030733-BHD4S4; commit c66cff3d6f16 | enforcement: manual | fixability: external | state: open
16
+ - id: INC-20260503-02 | date: 2026-05-03 | scope: Update standalone release artifact smoke testing to accept the current doctor OK output and surface doctor output on failures so v0.4.2 publish can complete. | tags: code, release, testing | match: code, release, testing, update, standalone, artifact, smoke, accept, the, current, doctor, output, and, surface, failures, publish | failure: Publish run 25273723107 failed before npm/tag at standalone linux-x64 doctor smoke because the script expected 'doctor OK' but current CLI emits 'doctor (OK)'. | advice: Smoke now accepts both legacy and current doctor OK markers and includes doctor output on failure. | rule: Analogous Update standalone release artifact smoke testing to accept the current doctor OK output and surface doctor output on failures so v0.4.2 publish can complete. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605030807-DBY2RS; commit 2c98719336c8 | enforcement: manual | fixability: external | state: open
17
+ - id: INC-20260503-03 | date: 2026-05-03 | scope: Split AgentPlane default sign-off identity from repo-wide manual DCO validation and make .agentplane/tasks.json an optional generated export snapshot rather than tracked required state. | tags: code, git, tasks | match: code, git, tasks, split, agentplane, default, sign, off, identity, from, repo, wide, manual, dco, validation, and | failure: Full hook-run suite was not used as final evidence because an unrelated existing pre-push scenario still tries to git add .agentplane/config.json after the WORKFLOW-only migration. | advice: Focused checks pass; remaining doctor warning is outside this task scope. | rule: Analogous Split AgentPlane default sign-off identity from repo-wide manual DCO validation and make .agentplane/tasks.json an optional generated export snapshot rather than tracked required state. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605031737-9A4FWX; commit eda55d00831b | enforcement: manual | fixability: external | state: open
18
+ - id: INC-20260504-01 | date: 2026-05-04 | scope: Introduce a shared agent-facing remediation contract for diagnostic failures and apply it to high-value doctor, workflow, ACR, and policy routing surfaces. | tags: code | match: code, introduce, shared, agent, facing, remediation, contract, for, diagnostic, failures, and, apply, high, value, doctor, workflow | failure: Commands passed: focused bun tests for workflow/ACR/policy routing plus targeted stale-dist workspace dependency test; bun run typecheck; Prettier check on touched files; ESLint on touched files; bun run arch:check; git diff --check; bun run framework:dev:bootstrap; agentplane doctor; node .agentplane/policy/check-routing.mjs. | advice: No mandatory check remains skipped. The full stale-dist-readonly file still contains an unrelated pre-existing auto-bootstrap timeout when run under this ad hoc focused bundle; the new workspace dependency test passes independently. | rule: Analogous Introduce a shared agent-facing remediation contract for diagnostic failures and apply it to high-value doctor, workflow, ACR, and policy routing surfaces. work MUST review and apply the recorded external incident advice before retrying. | evidence: task 202605041849-WF1Q77; commit cc2c971ed53e | enforcement: manual | fixability: external | state: open
package/bin/agentplane.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { existsSync } from "node:fs";
4
4
  import path from "node:path";
5
- import { stat } from "node:fs/promises";
5
+ import { mkdir, rm, stat } from "node:fs/promises";
6
6
  import { createRequire } from "node:module";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { distExists, isPackageBuildFresh } from "./dist-guard.js";
@@ -186,6 +186,95 @@ function renderStalePolicyWarning(reason) {
186
186
  return "warning: allowing read-only diagnostic command to run with a stale repo build inside the framework checkout.\n";
187
187
  }
188
188
 
189
+ function staleAutoBootstrapEnabled() {
190
+ return (process.env.AGENTPLANE_DEV_AUTO_BOOTSTRAP ?? "1").trim() !== "0";
191
+ }
192
+
193
+ function alreadyTriedStaleAutoBootstrap() {
194
+ return (process.env.AGENTPLANE_DEV_AUTO_BOOTSTRAPPED ?? "").trim() === "1";
195
+ }
196
+
197
+ async function withBootstrapLock(repoRoot, fn) {
198
+ const lockParent = path.join(repoRoot, ".agentplane", "cache");
199
+ const lockDir = path.join(lockParent, "framework-dev-bootstrap.lock");
200
+ await mkdir(lockParent, { recursive: true });
201
+ try {
202
+ await mkdir(lockDir, { recursive: false });
203
+ } catch (error) {
204
+ if (error?.code !== "EEXIST") throw error;
205
+ process.stderr.write(
206
+ "error: another framework dev bootstrap is already running.\n" +
207
+ `Retry after the lock is released: ${path.relative(repoRoot, lockDir)}\n`,
208
+ );
209
+ process.exitCode = 2;
210
+ return true;
211
+ }
212
+
213
+ try {
214
+ return await fn();
215
+ } finally {
216
+ await rm(lockDir, { recursive: true, force: true });
217
+ }
218
+ }
219
+
220
+ async function autoBootstrapAndRerun(repoRoot, staleReasons, commandPolicy) {
221
+ if (!staleAutoBootstrapEnabled() || alreadyTriedStaleAutoBootstrap()) return false;
222
+
223
+ const commandText = process.argv
224
+ .slice(2)
225
+ .map((value) => String(value ?? "").trim())
226
+ .filter(Boolean)
227
+ .join(" ");
228
+ process.stderr.write(
229
+ "info: stale repo build detected; running framework dev bootstrap before command.\n" +
230
+ `command: ${commandText || "<unknown>"}\n` +
231
+ `detected: ${staleReasons.join(", ")}\n` +
232
+ `reason: ${commandPolicy.reason}\n`,
233
+ );
234
+
235
+ return await withBootstrapLock(repoRoot, async () => {
236
+ const bootstrap = spawnSync("bun", ["run", "framework:dev:bootstrap"], {
237
+ cwd: repoRoot,
238
+ stdio: "inherit",
239
+ env: {
240
+ ...process.env,
241
+ AGENTPLANE_DEV_AUTO_BOOTSTRAP: "0",
242
+ },
243
+ });
244
+
245
+ if (bootstrap.error || bootstrap.status !== 0) {
246
+ const reason = bootstrap.error?.message ?? `exit ${bootstrap.status ?? "unknown"}`;
247
+ process.stderr.write(
248
+ `error: automatic framework dev bootstrap failed (${reason}).\n` +
249
+ "Manual fallback:\n" +
250
+ FRAMEWORK_DEV_MANUAL_REPAIR_COMMANDS.map((command) => ` ${command}\n`).join(""),
251
+ );
252
+ process.exitCode = bootstrap.status ?? 2;
253
+ return true;
254
+ }
255
+
256
+ const rerun = spawnSync(
257
+ process.execPath,
258
+ [fileURLToPath(import.meta.url), ...process.argv.slice(2)],
259
+ {
260
+ cwd: process.cwd(),
261
+ stdio: "inherit",
262
+ env: {
263
+ ...process.env,
264
+ AGENTPLANE_DEV_AUTO_BOOTSTRAPPED: "1",
265
+ },
266
+ },
267
+ );
268
+ if (rerun.error) {
269
+ process.stderr.write(`error: failed to rerun after bootstrap: ${rerun.error.message}\n`);
270
+ process.exitCode = 2;
271
+ return true;
272
+ }
273
+ process.exitCode = rerun.status ?? (rerun.signal ? 1 : 0);
274
+ return true;
275
+ });
276
+ }
277
+
189
278
  function missingRepoRuntimeDependencies(agentplaneRoot) {
190
279
  const requireFromAgentplane = createRequire(path.join(agentplaneRoot, "package.json"));
191
280
  const frameworkRoot = path.resolve(agentplaneRoot, "..", "..");
@@ -208,7 +297,7 @@ function missingRepoRuntimeDependencies(agentplaneRoot) {
208
297
  const requiredSpecifiers = ["@agentplaneorg/core"];
209
298
  return requiredSpecifiers.filter((specifier) => {
210
299
  try {
211
- const resolved = requireFromAgentplane.resolve(specifier);
300
+ const resolved = requireFromAgentplane.resolve(`${specifier}/package.json`);
212
301
  if (isPathInside(frameworkRoot, resolved)) return false;
213
302
  return !existsSync(path.join(agentplaneRoot, "node_modules", ...specifier.split("/")));
214
303
  } catch {
@@ -243,6 +332,11 @@ async function assertDistUpToDate() {
243
332
  if (missingDeps.length > 0) {
244
333
  process.stderr.write(
245
334
  "error: repo-local runtime dependencies are missing for this framework checkout.\n" +
335
+ "Code: FRAMEWORK_RUNTIME_DEPENDENCY_MISSING\n" +
336
+ "Why: the repo-local CLI cannot resolve its workspace runtime packages from this checkout.\n" +
337
+ "Fix: restore the framework install layout, then rebuild the repo-local packages.\n" +
338
+ `Safe command: ${FRAMEWORK_DEV_BOOTSTRAP_COMMAND}\n` +
339
+ "Stop condition: stop if the missing package resolves outside this repository or bun install would need unapproved network access.\n" +
246
340
  "This worktree is not bootstrapped yet.\n" +
247
341
  "Missing module resolution:\n" +
248
342
  missingDeps.map((specifier) => ` ${specifier}\n`).join("") +
@@ -300,6 +394,10 @@ async function assertDistUpToDate() {
300
394
 
301
395
  const commandPolicy = classifyStaleDistPolicy(process.argv);
302
396
  if (commandPolicy.mode === "warn_and_run") {
397
+ if (await autoBootstrapAndRerun(repoRoot, staleReasons, commandPolicy)) {
398
+ return false;
399
+ }
400
+
303
401
  const commandText = process.argv
304
402
  .slice(2)
305
403
  .map((value) => String(value ?? "").trim())
package/bin/ap.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ process.env.AGENTPLANE_CLI_ALIAS = "ap";
3
+ process.env.AGENTPLANE_AGENT_MODE = "1";
4
+ process.env.AGENTPLANE_PROMPTS ??= "plain";
5
+ process.env.AGENTPLANE_NO_UPDATE_CHECK ??= "1";
6
+
7
+ await import("./agentplane.js");
@@ -5,6 +5,7 @@ import path from "node:path";
5
5
  const WATCHED_RUNTIME_PATHS = {
6
6
  agentplane: [
7
7
  "src",
8
+ "bin/ap.js",
8
9
  "bin/agentplane.js",
9
10
  "bin/dist-guard.js",
10
11
  "bin/runtime-context.js",
@@ -2,7 +2,7 @@
2
2
  "schema_version": 1,
3
3
  "manifest_kind": "package",
4
4
  "package_name": "agentplane",
5
- "package_version": "0.4.2",
6
- "git_head": "2c98719336c87cbe2aaf196d14b32c841a9defa1",
7
- "watched_runtime_snapshot_hash": "56c2045c93aa3da808e26b1dc2396f28fbdcbe7a9c1ba9db50362d2432b0f257"
5
+ "package_version": "0.4.4",
6
+ "git_head": "dfe70bf54c4612e25ccac8aea363a744b4bed245",
7
+ "watched_runtime_snapshot_hash": "1a9fc1a9c09926b82cd9510670d6fea8600c41462b2ba9efec04965a879a5fcc"
8
8
  }