agentplane 0.2.26 → 0.3.2

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.
Files changed (97) hide show
  1. package/README.md +3 -1
  2. package/assets/AGENTS.md +124 -526
  3. package/assets/agents/UPGRADER.json +10 -9
  4. package/assets/framework.manifest.json +112 -7
  5. package/assets/policy/check-routing.mjs +180 -0
  6. package/assets/policy/dod.code.md +25 -0
  7. package/assets/policy/dod.core.md +32 -0
  8. package/assets/policy/dod.docs.md +32 -0
  9. package/assets/policy/examples/migration-note.md +6 -0
  10. package/assets/policy/examples/pr-note.md +16 -0
  11. package/assets/policy/examples/unit-test-pattern.md +19 -0
  12. package/assets/policy/governance.md +37 -0
  13. package/assets/policy/incidents.md +36 -0
  14. package/assets/policy/security.must.md +7 -0
  15. package/assets/policy/workflow.branch_pr.md +34 -0
  16. package/assets/policy/workflow.direct.md +47 -0
  17. package/assets/policy/workflow.md +9 -0
  18. package/assets/policy/workflow.release.md +31 -0
  19. package/assets/policy/workflow.upgrade.md +20 -0
  20. package/bin/agentplane.js +88 -87
  21. package/bin/dist-guard.js +124 -0
  22. package/bin/runtime-context.d.ts +20 -0
  23. package/bin/runtime-context.js +81 -0
  24. package/dist/.build-manifest.json +5 -5
  25. package/dist/agents/agents-template.d.ts +7 -0
  26. package/dist/agents/agents-template.d.ts.map +1 -1
  27. package/dist/agents/agents-template.js +41 -2
  28. package/dist/cli/bootstrap-guide.d.ts +18 -0
  29. package/dist/cli/bootstrap-guide.d.ts.map +1 -0
  30. package/dist/cli/bootstrap-guide.js +132 -0
  31. package/dist/cli/command-guide.d.ts.map +1 -1
  32. package/dist/cli/command-guide.js +58 -183
  33. package/dist/cli/command-snippets.d.ts +3 -3
  34. package/dist/cli/command-snippets.js +3 -3
  35. package/dist/cli/run-cli/commands/core.js +3 -3
  36. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  37. package/dist/cli/run-cli/commands/ide.js +8 -3
  38. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
  39. package/dist/cli/run-cli/commands/init/ui.js +1 -2
  40. package/dist/cli/run-cli/commands/init/write-agents.d.ts +2 -0
  41. package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
  42. package/dist/cli/run-cli/commands/init/write-agents.js +24 -5
  43. package/dist/cli/run-cli/commands/init/write-workflow.d.ts +5 -0
  44. package/dist/cli/run-cli/commands/init/write-workflow.d.ts.map +1 -1
  45. package/dist/cli/run-cli/commands/init/write-workflow.js +6 -0
  46. package/dist/cli/run-cli/commands/init.d.ts +2 -0
  47. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  48. package/dist/cli/run-cli/commands/init.js +47 -19
  49. package/dist/cli/run-cli.d.ts.map +1 -1
  50. package/dist/cli/run-cli.js +125 -7
  51. package/dist/commands/doctor.run.d.ts.map +1 -1
  52. package/dist/commands/doctor.run.js +48 -6
  53. package/dist/commands/finish.run.d.ts.map +1 -1
  54. package/dist/commands/finish.run.js +1 -0
  55. package/dist/commands/finish.spec.d.ts +1 -0
  56. package/dist/commands/finish.spec.d.ts.map +1 -1
  57. package/dist/commands/finish.spec.js +23 -2
  58. package/dist/commands/release/apply.command.d.ts +1 -0
  59. package/dist/commands/release/apply.command.d.ts.map +1 -1
  60. package/dist/commands/release/apply.command.js +20 -9
  61. package/dist/commands/release/plan.command.d.ts.map +1 -1
  62. package/dist/commands/release/plan.command.js +9 -3
  63. package/dist/commands/task/add.d.ts.map +1 -1
  64. package/dist/commands/task/add.js +32 -0
  65. package/dist/commands/task/doc.command.d.ts.map +1 -1
  66. package/dist/commands/task/doc.command.js +1 -0
  67. package/dist/commands/task/finish.d.ts +1 -0
  68. package/dist/commands/task/finish.d.ts.map +1 -1
  69. package/dist/commands/task/finish.js +28 -7
  70. package/dist/commands/task/new.d.ts.map +1 -1
  71. package/dist/commands/task/new.js +41 -4
  72. package/dist/commands/task/plan.d.ts.map +1 -1
  73. package/dist/commands/task/plan.js +7 -1
  74. package/dist/commands/task/shared.d.ts +7 -0
  75. package/dist/commands/task/shared.d.ts.map +1 -1
  76. package/dist/commands/task/shared.js +37 -0
  77. package/dist/commands/task/start-ready.js +1 -1
  78. package/dist/commands/upgrade.command.d.ts.map +1 -1
  79. package/dist/commands/upgrade.command.js +11 -7
  80. package/dist/commands/upgrade.d.ts.map +1 -1
  81. package/dist/commands/upgrade.js +284 -296
  82. package/dist/commands/workflow-build.command.d.ts.map +1 -1
  83. package/dist/commands/workflow-build.command.js +7 -0
  84. package/dist/commands/workflow-playbook.command.d.ts.map +1 -1
  85. package/dist/commands/workflow-playbook.command.js +0 -1
  86. package/dist/shared/policy-gateway.d.ts +15 -0
  87. package/dist/shared/policy-gateway.d.ts.map +1 -0
  88. package/dist/shared/policy-gateway.js +49 -0
  89. package/dist/shared/protected-paths.d.ts.map +1 -1
  90. package/dist/shared/protected-paths.js +1 -0
  91. package/dist/shared/runtime-artifacts.d.ts +2 -2
  92. package/dist/shared/runtime-artifacts.d.ts.map +1 -1
  93. package/dist/shared/runtime-artifacts.js +4 -0
  94. package/dist/workflow-runtime/build.d.ts +1 -1
  95. package/dist/workflow-runtime/build.d.ts.map +1 -1
  96. package/dist/workflow-runtime/build.js +14 -2
  97. package/package.json +2 -2
@@ -145,6 +145,12 @@ export const finishSpec = {
145
145
  default: false,
146
146
  description: "After finishing, run a deterministic close commit for the task README (single-task only).",
147
147
  },
148
+ {
149
+ kind: "boolean",
150
+ name: "no-close-commit",
151
+ default: false,
152
+ description: "Disable the default deterministic close commit in direct mode (single-task only).",
153
+ },
148
154
  {
149
155
  kind: "boolean",
150
156
  name: "close-unstage-others",
@@ -228,12 +234,26 @@ export const finishSpec = {
228
234
  message: "--close-commit requires exactly one task id",
229
235
  });
230
236
  }
231
- if (raw.opts["close-commit"] === true &&
237
+ if (raw.opts["no-close-commit"] === true && taskIds.length !== 1) {
238
+ throw usageError({
239
+ spec: finishSpec,
240
+ command: "finish",
241
+ message: "--no-close-commit requires exactly one task id",
242
+ });
243
+ }
244
+ if (raw.opts["close-commit"] === true && raw.opts["no-close-commit"] === true) {
245
+ throw usageError({
246
+ spec: finishSpec,
247
+ command: "finish",
248
+ message: "--close-commit and --no-close-commit are mutually exclusive",
249
+ });
250
+ }
251
+ if ((raw.opts["close-commit"] === true || raw.opts["no-close-commit"] === true) &&
232
252
  (raw.opts["commit-from-comment"] === true || raw.opts["status-commit"] === true)) {
233
253
  throw usageError({
234
254
  spec: finishSpec,
235
255
  command: "finish",
236
- message: "--close-commit cannot be combined with --commit-from-comment/--status-commit",
256
+ message: "--close-commit/--no-close-commit cannot be combined with --commit-from-comment/--status-commit",
237
257
  });
238
258
  }
239
259
  if (raw.opts["close-unstage-others"] === true && raw.opts["close-commit"] !== true) {
@@ -279,6 +299,7 @@ export const finishSpec = {
279
299
  statusCommitRequireClean: raw.opts["status-commit-require-clean"] === true,
280
300
  confirmStatusCommit: raw.opts["confirm-status-commit"] === true,
281
301
  closeCommit: raw.opts["close-commit"] === true,
302
+ noCloseCommit: raw.opts["no-close-commit"] === true,
282
303
  closeUnstageOthers: raw.opts["close-unstage-others"] === true,
283
304
  quiet: raw.opts.quiet === true,
284
305
  }),
@@ -6,6 +6,7 @@ export type ReleaseApplyFlags = {
6
6
  remote: string;
7
7
  };
8
8
  export type ReleaseApplyParsed = ReleaseApplyFlags;
9
+ export declare function pushReleaseRefs(gitRoot: string, remote: string, tag: string): Promise<void>;
9
10
  export declare const releaseApplySpec: CommandSpec<ReleaseApplyParsed>;
10
11
  export declare const runReleaseApply: CommandHandler<ReleaseApplyParsed>;
11
12
  //# sourceMappingURL=apply.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAsVnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAiF5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CA+K9D,CAAC"}
1
+ {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AA4VnD,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjG;AAED,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAiF5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAgL9D,CAAC"}
@@ -136,7 +136,7 @@ function cleanHookEnv() {
136
136
  delete env.AGENTPLANE_AGENT_ID;
137
137
  return env;
138
138
  }
139
- async function validateReleaseNotes(notesPath) {
139
+ async function validateReleaseNotes(notesPath, minBullets) {
140
140
  const content = await readFile(notesPath, "utf8");
141
141
  if (!/release\s+notes/i.test(content)) {
142
142
  throw new CliError({
@@ -146,11 +146,11 @@ async function validateReleaseNotes(notesPath) {
146
146
  });
147
147
  }
148
148
  const bulletCount = content.split(/\r?\n/u).filter((line) => /^\s*[-*]\s+\S+/u.test(line)).length;
149
- if (bulletCount < 1) {
149
+ if (bulletCount < minBullets) {
150
150
  throw new CliError({
151
151
  exitCode: exitCodeForError("E_VALIDATION"),
152
152
  code: "E_VALIDATION",
153
- message: `Release notes must include at least one bullet point in ${notesPath}.`,
153
+ message: `Release notes must include at least ${minBullets} bullet points in ${notesPath}.`,
154
154
  });
155
155
  }
156
156
  if (/[\u0400-\u04FF]/u.test(content)) {
@@ -285,6 +285,16 @@ async function writeReleaseApplyReport(gitRoot, report) {
285
285
  await writeFile(latestPath, text, "utf8");
286
286
  return reportPath;
287
287
  }
288
+ export async function pushReleaseRefs(gitRoot, remote, tag) {
289
+ await execFileAsync("git", ["push", "--no-verify", remote, "HEAD"], {
290
+ cwd: gitRoot,
291
+ env: gitEnv(),
292
+ });
293
+ await execFileAsync("git", ["push", "--no-verify", remote, tag], {
294
+ cwd: gitRoot,
295
+ env: gitEnv(),
296
+ });
297
+ }
288
298
  export const releaseApplySpec = {
289
299
  id: ["release", "apply"],
290
300
  group: "Release",
@@ -383,6 +393,11 @@ export const runReleaseApply = async (ctx, flags) => {
383
393
  });
384
394
  }
385
395
  const plan = parseVersionPlan(await readJsonFile(versionJsonPath));
396
+ const changesJsonPath = path.join(planDir, "changes.json");
397
+ const changes = (await fileExists(changesJsonPath))
398
+ ? await readJsonFile(changesJsonPath)
399
+ : [];
400
+ const minBullets = Math.max(1, Array.isArray(changes) ? changes.length : 0);
386
401
  if ((plan.bump === "minor" || plan.bump === "major") && flags.yes !== true) {
387
402
  throw usageError({
388
403
  spec: releaseApplySpec,
@@ -406,7 +421,7 @@ export const runReleaseApply = async (ctx, flags) => {
406
421
  "Write this file using a DOCS agent before applying the release.",
407
422
  });
408
423
  }
409
- await validateReleaseNotes(notesPath);
424
+ await validateReleaseNotes(notesPath, minBullets);
410
425
  const corePkgPath = path.join(gitRoot, "packages", "core", "package.json");
411
426
  const agentplanePkgPath = path.join(gitRoot, "packages", "agentplane", "package.json");
412
427
  const [coreVersion, agentplaneVersion, coreDependencyVersion] = await Promise.all([
@@ -492,11 +507,7 @@ export const runReleaseApply = async (ctx, flags) => {
492
507
  await execFileAsync("git", ["tag", plan.nextTag], { cwd: gitRoot, env: gitEnv() });
493
508
  process.stdout.write(`Release tag created: ${plan.nextTag}\n`);
494
509
  if (flags.push) {
495
- await execFileAsync("git", ["push", flags.remote, "HEAD"], { cwd: gitRoot, env: gitEnv() });
496
- await execFileAsync("git", ["push", flags.remote, plan.nextTag], {
497
- cwd: gitRoot,
498
- env: gitEnv(),
499
- });
510
+ await pushReleaseRefs(gitRoot, flags.remote, plan.nextTag);
500
511
  process.stdout.write(`Pushed: ${flags.remote} HEAD + ${plan.nextTag}\n`);
501
512
  }
502
513
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"plan.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/plan.command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1E,KAAK,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAqIjD,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CA4E1D,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,iBAAiB,CAoE5D,CAAC"}
1
+ {"version":3,"file":"plan.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/plan.command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1E,KAAK,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AA4IjD,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CA4E1D,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,iBAAiB,CAqE5D,CAAC"}
@@ -92,6 +92,9 @@ function changesMarkdown(changes) {
92
92
  .join("\n")
93
93
  .trim() + "\n");
94
94
  }
95
+ function requiredBulletCount(changeCount) {
96
+ return Math.max(1, changeCount);
97
+ }
95
98
  function releaseInstructions(opts) {
96
99
  return (`# Release plan\n\n` +
97
100
  `## Target\n\n` +
@@ -103,8 +106,10 @@ function releaseInstructions(opts) {
103
106
  `## Agent task: write release notes\n\n` +
104
107
  `Write English release notes as \`docs/releases/${opts.nextTag}.md\`.\n\n` +
105
108
  `Rules:\n` +
106
- `- Use human-readable bullets focused on outcomes and user-facing improvements.\n` +
107
- `- Include as many bullets as needed; do not enforce a fixed bullet count.\n` +
109
+ `- Use detailed, human-readable bullets focused on outcomes and user-facing improvements.\n` +
110
+ `- Cover all listed differences from \`changes.md\`; do not omit commits.\n` +
111
+ `- Keep one concrete bullet per listed change in plain language.\n` +
112
+ `- Write at least ${opts.minBullets} bullet points.\n` +
108
113
  `- Do not include Cyrillic.\n` +
109
114
  `- Use \`docs/releases/TEMPLATE.md\` as the structure.\n\n` +
110
115
  `Inputs:\n` +
@@ -216,13 +221,14 @@ export const runReleasePlan = async (ctx, flags) => {
216
221
  const nextVersion = bumpVersion(coreVersion, flags.bump);
217
222
  const nextTag = `v${nextVersion}`;
218
223
  const changes = await listChanges(gitRoot, prevTag);
224
+ const minBullets = requiredBulletCount(changes.length);
219
225
  const runId = new Date().toISOString().replaceAll(":", "-").replaceAll(".", "-");
220
226
  const baseDir = path.join(gitRoot, ".agentplane", ".release", "plan", runId);
221
227
  await mkdir(baseDir, { recursive: true });
222
228
  await writeFile(path.join(baseDir, "version.json"), JSON.stringify({ prevTag, prevVersion: coreVersion, nextTag, nextVersion, bump: flags.bump }, null, 2) + "\n", "utf8");
223
229
  await writeFile(path.join(baseDir, "changes.json"), JSON.stringify(changes, null, 2) + "\n", "utf8");
224
230
  await writeFile(path.join(baseDir, "changes.md"), changesMarkdown(changes), "utf8");
225
- await writeFile(path.join(baseDir, "instructions.md"), releaseInstructions({ nextTag, prevTag, bump: flags.bump }), "utf8");
231
+ await writeFile(path.join(baseDir, "instructions.md"), releaseInstructions({ nextTag, prevTag, bump: flags.bump, minBullets }), "utf8");
226
232
  process.stdout.write(`Release plan written: ${path.relative(gitRoot, baseDir)}\n`);
227
233
  process.stdout.write(`Next tag: ${nextTag}\n`);
228
234
  process.stdout.write(`Hint: Create a DOCS task to write docs/releases/${nextTag}.md based on this plan.\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGpF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAAC,MAAM,CAAC,CAwDlB"}
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAoCpF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAAC,MAAM,CAAC,CA6DlB"}
@@ -2,6 +2,33 @@ import { mapBackendError } from "../../cli/error-map.js";
2
2
  import { CliError } from "../../shared/errors.js";
3
3
  import { loadCommandContext } from "../shared/task-backend.js";
4
4
  import { dedupeStrings, normalizeTaskStatus, nowIso } from "./shared.js";
5
+ import { ensureDocSections, setMarkdownSection } from "@agentplaneorg/core";
6
+ function defaultTaskDoc(opts) {
7
+ const baseDoc = ensureDocSections("", opts.requiredSections);
8
+ const summary = `${opts.title}\n\n${opts.description}`;
9
+ const scope = [
10
+ `- In scope: ${opts.description}.`,
11
+ `- Out of scope: unrelated refactors not required for "${opts.title}".`,
12
+ ].join("\n");
13
+ const plan = [
14
+ `1. Implement the change for "${opts.title}".`,
15
+ "2. Run required checks and capture verification evidence.",
16
+ "3. Finalize task notes and finish with traceable commit metadata.",
17
+ ].join("\n");
18
+ const risks = [
19
+ "- Risk: hidden regressions in touched paths.",
20
+ "- Mitigation: run required checks before finish and record evidence.",
21
+ ].join("\n");
22
+ const rollback = [
23
+ "- Revert task-related commit(s).",
24
+ "- Re-run required checks to confirm rollback safety.",
25
+ ].join("\n");
26
+ const withSummary = setMarkdownSection(baseDoc, "Summary", summary);
27
+ const withScope = setMarkdownSection(withSummary, "Scope", scope);
28
+ const withPlan = setMarkdownSection(withScope, "Plan", plan);
29
+ const withRisks = setMarkdownSection(withPlan, "Risks", risks);
30
+ return setMarkdownSection(withRisks, "Rollback Plan", rollback);
31
+ }
5
32
  export async function cmdTaskAdd(opts) {
6
33
  try {
7
34
  const ctx = opts.ctx ??
@@ -39,6 +66,11 @@ export async function cmdTaskAdd(opts) {
39
66
  doc_updated_at: nowIso(),
40
67
  doc_updated_by: docUpdatedBy,
41
68
  id_source: "explicit",
69
+ doc: defaultTaskDoc({
70
+ requiredSections: ctx.config.tasks.doc.required_sections,
71
+ title: opts.title,
72
+ description: opts.description,
73
+ }),
42
74
  }));
43
75
  if (ctx.taskBackend.writeTasks) {
44
76
  await ctx.taskBackend.writeTasks(tasks);
@@ -1 +1 @@
1
- {"version":3,"file":"doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAclD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9E"}
1
+ {"version":3,"file":"doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAelD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9E"}
@@ -6,6 +6,7 @@ export const taskDocSpec = {
6
6
  synopsis: [
7
7
  "agentplane task doc show <task-id> [--section <name>] [--quiet]",
8
8
  "agentplane task doc set <task-id> --section <name> (--text <text> | --file <path>) [--updated-by <id>]",
9
+ "agentplane task doc set <task-id> --section Summary --file ./task-readme.md # if payload contains multiple known ## headings, apply as full-doc update",
9
10
  ],
10
11
  args: [{ name: "subcommand", required: false, valueHint: "<show|set>" }],
11
12
  parse: (raw) => {
@@ -25,6 +25,7 @@ export declare function cmdFinish(opts: {
25
25
  statusCommitRequireClean: boolean;
26
26
  confirmStatusCommit: boolean;
27
27
  closeCommit?: boolean;
28
+ noCloseCommit?: boolean;
28
29
  closeUnstageOthers?: boolean;
29
30
  quiet: boolean;
30
31
  }): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAmCnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4VlB"}
1
+ {"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAoCnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsXlB"}
@@ -1,3 +1,4 @@
1
+ import { ensureDocSections } from "@agentplaneorg/core";
1
2
  import { mapBackendError } from "../../cli/error-map.js";
2
3
  import { invalidValueMessage, successMessage } from "../../cli/output.js";
3
4
  import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
@@ -10,7 +11,7 @@ import { ensureReconciledBeforeMutation } from "../shared/reconcile-check.js";
10
11
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
11
12
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
12
13
  import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
13
- import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureVerificationSatisfiedIfRequired, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
14
+ import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureAgentFilledRequiredDocSections, ensureVerificationSatisfiedIfRequired, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
14
15
  async function clearDirectWorkLockIfMatches(opts) {
15
16
  const lockPath = path.join(opts.agentplaneDir, "cache", "direct-work.json");
16
17
  try {
@@ -50,18 +51,25 @@ export async function cmdFinish(opts) {
50
51
  message: "--commit-from-comment/--status-commit requires exactly one task id",
51
52
  });
52
53
  }
53
- if (opts.closeCommit && opts.taskIds.length !== 1) {
54
+ if ((opts.closeCommit || opts.noCloseCommit) && opts.taskIds.length !== 1) {
54
55
  throw new CliError({
55
56
  exitCode: 2,
56
57
  code: "E_USAGE",
57
- message: "--close-commit requires exactly one task id",
58
+ message: "--close-commit/--no-close-commit requires exactly one task id",
58
59
  });
59
60
  }
60
- if (opts.closeCommit && (opts.commitFromComment || opts.statusCommit)) {
61
+ if (opts.closeCommit && opts.noCloseCommit) {
61
62
  throw new CliError({
62
63
  exitCode: 2,
63
64
  code: "E_USAGE",
64
- message: "--close-commit cannot be combined with --commit-from-comment/--status-commit",
65
+ message: "--close-commit and --no-close-commit are mutually exclusive",
66
+ });
67
+ }
68
+ if ((opts.closeCommit || opts.noCloseCommit) && (opts.commitFromComment || opts.statusCommit)) {
69
+ throw new CliError({
70
+ exitCode: 2,
71
+ code: "E_USAGE",
72
+ message: "--close-commit/--no-close-commit cannot be combined with --commit-from-comment/--status-commit",
65
73
  });
66
74
  }
67
75
  const primaryTaskId = opts.taskIds[0] ?? "";
@@ -106,6 +114,12 @@ export async function cmdFinish(opts) {
106
114
  : await readHeadCommit(gitRoot);
107
115
  const useStore = backendIsLocalFileBackend(ctx);
108
116
  const store = useStore ? getTaskStore(ctx) : null;
117
+ const defaultDirectCloseCommit = ctx.config.workflow_mode === "direct" &&
118
+ useStore &&
119
+ opts.taskIds.length === 1 &&
120
+ !opts.commitFromComment &&
121
+ !statusCommitRequested;
122
+ const shouldCloseCommit = opts.closeCommit === true || (defaultDirectCloseCommit && opts.noCloseCommit !== true);
109
123
  const metaTaskId = opts.taskIds.length === 1 ? (opts.taskIds[0] ?? "") : "";
110
124
  const wantMeta = typeof opts.result === "string" || typeof opts.risk === "string" || opts.breaking === true;
111
125
  if (wantMeta && opts.taskIds.length !== 1) {
@@ -139,6 +153,13 @@ export async function cmdFinish(opts) {
139
153
  primaryTag = resolvePrimaryTag(toStringArray(task.tags), ctx).primary;
140
154
  }
141
155
  ensureVerificationSatisfiedIfRequired(task, ctx.config);
156
+ const normalizedDoc = ensureDocSections(typeof task.doc === "string" ? task.doc : "", ctx.config.tasks.doc.required_sections);
157
+ ensureAgentFilledRequiredDocSections({
158
+ task,
159
+ config: ctx.config,
160
+ doc: normalizedDoc,
161
+ action: "finish task",
162
+ });
142
163
  if (taskId === metaTaskId) {
143
164
  const tags = Array.isArray(task.tags)
144
165
  ? task.tags.filter((t) => typeof t === "string")
@@ -300,7 +321,7 @@ export async function cmdFinish(opts) {
300
321
  config: ctx.config,
301
322
  });
302
323
  }
303
- if (opts.closeCommit && primaryTaskId) {
324
+ if (shouldCloseCommit && primaryTaskId) {
304
325
  await cmdCommit({
305
326
  ctx,
306
327
  cwd: opts.cwd,
@@ -318,7 +339,7 @@ export async function cmdFinish(opts) {
318
339
  allowCI: false,
319
340
  requireClean: true,
320
341
  quiet: opts.quiet,
321
- closeUnstageOthers: opts.closeUnstageOthers === true,
342
+ closeUnstageOthers: opts.closeCommit === true && opts.closeUnstageOthers === true,
322
343
  closeCheckOnly: false,
323
344
  });
324
345
  }
@@ -1 +1 @@
1
- {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AASpF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAuIF,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,aAAa,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgFlB"}
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AASpF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AA6LF,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,aAAa,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoFlB"}
@@ -66,7 +66,35 @@ function insertMarkdownSectionBefore(opts) {
66
66
  const out = [...lines.slice(0, beforeIdx), ...sectionLines, ...lines.slice(beforeIdx)];
67
67
  return `${out.join("\n").trimEnd()}\n`;
68
68
  }
69
- function defaultTaskDoc(requiredSections) {
69
+ function buildDefaultSummary(opts) {
70
+ return `${opts.title}\n\n${opts.description}`;
71
+ }
72
+ function buildDefaultScope(opts) {
73
+ return [
74
+ `- In scope: ${opts.description}.`,
75
+ `- Out of scope: unrelated refactors not required for "${opts.title}".`,
76
+ ].join("\n");
77
+ }
78
+ function buildDefaultPlan(opts) {
79
+ return [
80
+ `1. Implement the change for "${opts.title}".`,
81
+ "2. Run required checks and capture verification evidence.",
82
+ "3. Finalize task notes and finish with traceable commit metadata.",
83
+ ].join("\n");
84
+ }
85
+ function buildDefaultRisks() {
86
+ return [
87
+ "- Risk: hidden regressions in touched paths.",
88
+ "- Mitigation: run required checks before finish and record evidence.",
89
+ ].join("\n");
90
+ }
91
+ function buildDefaultRollbackPlan() {
92
+ return [
93
+ "- Revert task-related commit(s).",
94
+ "- Re-run required checks to confirm rollback safety.",
95
+ ].join("\n");
96
+ }
97
+ function defaultTaskDoc(opts) {
70
98
  const verifyStepsTemplate = [
71
99
  "<!-- TODO: FILL VERIFY STEPS -->",
72
100
  "",
@@ -93,14 +121,19 @@ function defaultTaskDoc(requiredSections) {
93
121
  "<!-- BEGIN VERIFICATION RESULTS -->",
94
122
  "<!-- END VERIFICATION RESULTS -->",
95
123
  ].join("\n");
96
- const baseDoc = ensureDocSections("", requiredSections);
124
+ const baseDoc = ensureDocSections("", opts.requiredSections);
97
125
  const withVerifySteps = insertMarkdownSectionBefore({
98
126
  body: baseDoc,
99
127
  section: "Verify Steps",
100
128
  text: verifyStepsTemplate,
101
129
  beforeSection: "Verification",
102
130
  });
103
- return setMarkdownSection(withVerifySteps, "Verification", verificationTemplate);
131
+ const withVerification = setMarkdownSection(withVerifySteps, "Verification", verificationTemplate);
132
+ const withSummary = setMarkdownSection(withVerification, "Summary", buildDefaultSummary({ title: opts.title, description: opts.description }));
133
+ const withScope = setMarkdownSection(withSummary, "Scope", buildDefaultScope({ title: opts.title, description: opts.description }));
134
+ const withPlan = setMarkdownSection(withScope, "Plan", buildDefaultPlan({ title: opts.title }));
135
+ const withRisks = setMarkdownSection(withPlan, "Risks", buildDefaultRisks());
136
+ return setMarkdownSection(withRisks, "Rollback Plan", buildDefaultRollbackPlan());
104
137
  }
105
138
  function buildDefaultVerifyStepsSection(opts) {
106
139
  const checks = opts.verifyCommands.length > 0
@@ -150,7 +183,11 @@ export async function runTaskNewParsed(opts) {
150
183
  doc_updated_at: nowIso(),
151
184
  doc_updated_by: p.owner,
152
185
  id_source: "generated",
153
- doc: defaultTaskDoc(ctx.config.tasks.doc.required_sections),
186
+ doc: defaultTaskDoc({
187
+ requiredSections: ctx.config.tasks.doc.required_sections,
188
+ title: p.title,
189
+ description: p.description,
190
+ }),
154
191
  };
155
192
  const spikeTag = (ctx.config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
156
193
  const primary = resolvePrimaryTag(p.tags, ctx);
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAmDnC,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ElB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAgFlB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAoDnC,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ElB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAsFlB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB"}
@@ -6,7 +6,7 @@ import { backendNotSupportedMessage } from "../../cli/output.js";
6
6
  import { CliError } from "../../shared/errors.js";
7
7
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
8
8
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
9
- import { extractDocSection, isVerifyStepsFilled, nowIso, requiresVerifyStepsByPrimary, toStringArray, } from "./shared.js";
9
+ import { ensureAgentFilledRequiredDocSections, extractDocSection, isVerifyStepsFilled, nowIso, requiresVerifyStepsByPrimary, toStringArray, } from "./shared.js";
10
10
  async function loadPlanTask(opts) {
11
11
  const ctx = opts.ctx ??
12
12
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
@@ -129,6 +129,12 @@ export async function cmdTaskPlanApprove(opts) {
129
129
  message: `${task.id}: cannot approve plan: ## Plan section is missing or empty`,
130
130
  });
131
131
  }
132
+ ensureAgentFilledRequiredDocSections({
133
+ task,
134
+ config,
135
+ doc: baseDoc,
136
+ action: "approve plan",
137
+ });
132
138
  const enforceVerifySteps = config.tasks.verify.enforce_on_plan_approve !== false;
133
139
  if (enforceVerifySteps) {
134
140
  const tags = toStringArray(task.tags);
@@ -8,6 +8,13 @@ export declare function nowIso(): string;
8
8
  export declare const VERIFY_STEPS_PLACEHOLDER = "<!-- TODO: FILL VERIFY STEPS -->";
9
9
  export declare function extractDocSection(doc: string, sectionName: string): string | null;
10
10
  export declare function isVerifyStepsFilled(sectionText: string | null): boolean;
11
+ export declare function isDocSectionFilled(sectionText: string | null): boolean;
12
+ export declare function ensureAgentFilledRequiredDocSections(opts: {
13
+ task: Pick<TaskData, "id">;
14
+ config: AgentplaneConfig;
15
+ doc: string;
16
+ action: string;
17
+ }): void;
11
18
  export declare function normalizeDependsOnInput(value: string): string[];
12
19
  export declare function normalizeTaskStatus(value: string): string;
13
20
  export declare function toStringArray(value: unknown): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,43 @@ export function isVerifyStepsFilled(sectionText) {
57
57
  return false;
58
58
  return true;
59
59
  }
60
+ const DOC_PLACEHOLDER_RE = /<!--\s*TODO\b/i;
61
+ const DOC_SECTIONS_AUTO_MANAGED = new Set(["verification"]);
62
+ const DOC_SECTIONS_CONDITIONAL = new Set(["verify steps", "notes"]);
63
+ export function isDocSectionFilled(sectionText) {
64
+ const normalized = (sectionText ?? "").trim();
65
+ if (!normalized)
66
+ return false;
67
+ if (DOC_PLACEHOLDER_RE.test(normalized))
68
+ return false;
69
+ return true;
70
+ }
71
+ export function ensureAgentFilledRequiredDocSections(opts) {
72
+ const required = dedupeStrings((opts.config.tasks.doc.required_sections ?? [])
73
+ .map((section) => String(section ?? "").trim())
74
+ .filter(Boolean));
75
+ const missing = [];
76
+ for (const section of required) {
77
+ const normalizedSection = section.trim().toLowerCase();
78
+ if (DOC_SECTIONS_AUTO_MANAGED.has(normalizedSection))
79
+ continue;
80
+ if (DOC_SECTIONS_CONDITIONAL.has(normalizedSection))
81
+ continue;
82
+ const sectionText = extractDocSection(opts.doc, section);
83
+ if (!isDocSectionFilled(sectionText)) {
84
+ missing.push(section);
85
+ }
86
+ }
87
+ if (missing.length === 0)
88
+ return;
89
+ const sectionList = missing.map((section) => `## ${section}`).join(", ");
90
+ throw new CliError({
91
+ exitCode: 3,
92
+ code: "E_VALIDATION",
93
+ message: `${opts.task.id}: cannot ${opts.action}: required task doc sections are missing/empty: ${sectionList} ` +
94
+ `(fill via \`agentplane task doc set ${opts.task.id} --section <name> --text "..."\`)`,
95
+ });
96
+ }
60
97
  export function normalizeDependsOnInput(value) {
61
98
  const trimmed = value.trim();
62
99
  if (!trimmed || trimmed === "[]")
@@ -22,7 +22,7 @@ export async function cmdTaskStartReady(opts) {
22
22
  confirmStatusCommit: false,
23
23
  force: opts.force,
24
24
  yes: opts.yes,
25
- quiet: opts.quiet,
25
+ quiet: true,
26
26
  });
27
27
  if (!opts.quiet) {
28
28
  process.stdout.write(`${successMessage("ready", opts.taskId)}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CA0JlD,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,cAAc,CAAC,aAAa,CACsB,CAAC"}
1
+ {"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CA8JlD,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,cAAc,CAAC,aAAa,CACsB,CAAC"}
@@ -4,19 +4,19 @@ export const upgradeSpec = {
4
4
  id: ["upgrade"],
5
5
  group: "Setup",
6
6
  summary: "Upgrade the local agentplane framework bundle in the repo.",
7
- description: "Upgrades the local agentplane framework bundle in the repo using a strict manifest of managed files. By default, upgrade generates an agent-assisted plan from the locally installed agentplane package assets (no network) and does not modify files. Use --auto to apply changes. Use --remote to fetch a GitHub release bundle; network access is gated by config approvals.",
7
+ description: "Upgrades the local agentplane framework bundle in the repo using a strict manifest of managed files. By default, upgrade applies the bundled managed files from the locally installed agentplane package assets (no network) and creates a dedicated upgrade commit. Use --dry-run to preview changes without writing files, or --agent to generate a review plan instead of applying. Use --remote to fetch a GitHub release bundle; network access is gated by config approvals.",
8
8
  options: [
9
9
  {
10
10
  kind: "boolean",
11
11
  name: "agent",
12
12
  default: false,
13
- description: "Generate an agent-assisted upgrade plan (no files are modified). This is the default mode.",
13
+ description: "Generate an agent-assisted upgrade plan instead of applying managed files.",
14
14
  },
15
15
  {
16
16
  kind: "boolean",
17
17
  name: "auto",
18
18
  default: false,
19
- description: "Apply the upgrade automatically (writes managed files).",
19
+ description: "Apply the upgrade automatically (same behavior as the default mode; useful for explicit scripts).",
20
20
  },
21
21
  {
22
22
  kind: "boolean",
@@ -97,11 +97,15 @@ export const upgradeSpec = {
97
97
  examples: [
98
98
  {
99
99
  cmd: "agentplane upgrade",
100
- why: "Generate an agent-assisted plan using locally installed assets (no network).",
100
+ why: "Apply managed files from the installed CLI assets and create an upgrade commit.",
101
101
  },
102
102
  {
103
- cmd: "agentplane upgrade --auto",
104
- why: "Apply the upgrade automatically (writes managed files).",
103
+ cmd: "agentplane upgrade --dry-run",
104
+ why: "Preview managed-file changes without modifying the repo.",
105
+ },
106
+ {
107
+ cmd: "agentplane upgrade --agent",
108
+ why: "Generate an agent-assisted upgrade plan instead of applying files.",
105
109
  },
106
110
  {
107
111
  cmd: "agentplane upgrade --remote --tag v0.1.9 --dry-run",
@@ -115,7 +119,7 @@ export const upgradeSpec = {
115
119
  parse: (raw) => {
116
120
  const noBackup = raw.opts["no-backup"] === true;
117
121
  return {
118
- mode: raw.opts.auto === true ? "auto" : "agent",
122
+ mode: raw.opts.agent === true ? "agent" : "auto",
119
123
  remote: raw.opts.remote === true,
120
124
  allowTarball: raw.opts["allow-tarball"] === true,
121
125
  source: raw.opts.source,
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAmCA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAgGF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GACG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqB1C;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAgBT;AAqQD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiqBlB"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA6GF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GACG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqB1C;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAgBT;AAmRD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAupBlB"}