agentplane 0.3.2 → 0.3.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.
Files changed (205) hide show
  1. package/assets/AGENTS.md +4 -4
  2. package/assets/agents/CODER.json +14 -10
  3. package/assets/agents/CREATOR.json +8 -6
  4. package/assets/agents/DOCS.json +9 -6
  5. package/assets/agents/INTEGRATOR.json +9 -6
  6. package/assets/agents/ORCHESTRATOR.json +8 -6
  7. package/assets/agents/PLANNER.json +8 -5
  8. package/assets/agents/REDMINE.json +6 -3
  9. package/assets/agents/REVIEWER.json +8 -6
  10. package/assets/agents/TESTER.json +8 -4
  11. package/assets/agents/UPDATER.json +6 -4
  12. package/assets/agents/UPGRADER.json +7 -6
  13. package/assets/policy/dod.code.md +2 -2
  14. package/assets/policy/dod.core.md +16 -2
  15. package/assets/policy/dod.docs.md +2 -2
  16. package/assets/policy/incidents.md +44 -1
  17. package/assets/policy/workflow.direct.md +8 -4
  18. package/bin/agentplane.js +59 -9
  19. package/bin/dist-guard.js +78 -10
  20. package/bin/runtime-context.d.ts +3 -0
  21. package/bin/runtime-context.js +13 -0
  22. package/bin/runtime-watch.d.ts +26 -0
  23. package/bin/runtime-watch.js +116 -0
  24. package/bin/stale-dist-policy.d.ts +6 -0
  25. package/bin/stale-dist-policy.js +44 -0
  26. package/dist/.build-manifest.json +2485 -5
  27. package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
  28. package/dist/backends/task-backend/local-backend.js +9 -12
  29. package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
  30. package/dist/backends/task-backend/redmine-backend.js +23 -18
  31. package/dist/backends/task-backend/shared/constants.d.ts +1 -0
  32. package/dist/backends/task-backend/shared/constants.d.ts.map +1 -1
  33. package/dist/backends/task-backend/shared/constants.js +1 -0
  34. package/dist/backends/task-backend/shared/doc.d.ts +1 -0
  35. package/dist/backends/task-backend/shared/doc.d.ts.map +1 -1
  36. package/dist/backends/task-backend/shared/doc.js +4 -1
  37. package/dist/backends/task-backend/shared/export.js +3 -3
  38. package/dist/cli/bootstrap-guide.d.ts +2 -3
  39. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  40. package/dist/cli/bootstrap-guide.js +16 -35
  41. package/dist/cli/command-guide.d.ts +14 -1
  42. package/dist/cli/command-guide.d.ts.map +1 -1
  43. package/dist/cli/command-guide.js +71 -47
  44. package/dist/cli/run-cli/catalog.d.ts +7 -0
  45. package/dist/cli/run-cli/catalog.d.ts.map +1 -0
  46. package/dist/cli/run-cli/catalog.js +22 -0
  47. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  48. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  49. package/dist/cli/run-cli/command-catalog.js +11 -0
  50. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  51. package/dist/cli/run-cli/commands/core.js +37 -29
  52. package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
  53. package/dist/cli/run-cli/commands/init/write-config.js +2 -0
  54. package/dist/cli/run-cli/commands/init/write-workflow.d.ts.map +1 -1
  55. package/dist/cli/run-cli/commands/init/write-workflow.js +6 -55
  56. package/dist/cli/run-cli/commands/init.js +5 -14
  57. package/dist/cli/run-cli/error-guidance.d.ts +9 -0
  58. package/dist/cli/run-cli/error-guidance.d.ts.map +1 -0
  59. package/dist/cli/run-cli/error-guidance.js +180 -0
  60. package/dist/cli/run-cli/globals.d.ts +22 -0
  61. package/dist/cli/run-cli/globals.d.ts.map +1 -0
  62. package/dist/cli/run-cli/globals.js +197 -0
  63. package/dist/cli/run-cli/update-warning.d.ts +6 -0
  64. package/dist/cli/run-cli/update-warning.d.ts.map +1 -0
  65. package/dist/cli/run-cli/update-warning.js +64 -0
  66. package/dist/cli/run-cli.d.ts.map +1 -1
  67. package/dist/cli/run-cli.js +5 -476
  68. package/dist/cli/spec/docs-render.d.ts.map +1 -1
  69. package/dist/cli/spec/docs-render.js +14 -1
  70. package/dist/commands/doctor/archive.d.ts +4 -0
  71. package/dist/commands/doctor/archive.d.ts.map +1 -0
  72. package/dist/commands/doctor/archive.js +211 -0
  73. package/dist/commands/doctor/fixes.d.ts +9 -0
  74. package/dist/commands/doctor/fixes.d.ts.map +1 -0
  75. package/dist/commands/doctor/fixes.js +40 -0
  76. package/dist/commands/doctor/layering.d.ts +2 -0
  77. package/dist/commands/doctor/layering.d.ts.map +1 -0
  78. package/dist/commands/doctor/layering.js +87 -0
  79. package/dist/commands/doctor/runtime.d.ts +4 -0
  80. package/dist/commands/doctor/runtime.d.ts.map +1 -0
  81. package/dist/commands/doctor/runtime.js +56 -0
  82. package/dist/commands/doctor/workflow.d.ts +6 -0
  83. package/dist/commands/doctor/workflow.d.ts.map +1 -0
  84. package/dist/commands/doctor/workflow.js +62 -0
  85. package/dist/commands/doctor/workspace.d.ts +2 -0
  86. package/dist/commands/doctor/workspace.d.ts.map +1 -0
  87. package/dist/commands/doctor/workspace.js +165 -0
  88. package/dist/commands/doctor.run.d.ts.map +1 -1
  89. package/dist/commands/doctor.run.js +16 -342
  90. package/dist/commands/doctor.spec.d.ts +1 -0
  91. package/dist/commands/doctor.spec.d.ts.map +1 -1
  92. package/dist/commands/doctor.spec.js +15 -1
  93. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  94. package/dist/commands/guard/impl/commands.js +19 -0
  95. package/dist/commands/release/apply.command.d.ts +2 -8
  96. package/dist/commands/release/apply.command.d.ts.map +1 -1
  97. package/dist/commands/release/apply.command.js +158 -387
  98. package/dist/commands/release/apply.mutation.d.ts +7 -0
  99. package/dist/commands/release/apply.mutation.d.ts.map +1 -0
  100. package/dist/commands/release/apply.mutation.js +107 -0
  101. package/dist/commands/release/apply.preflight.d.ts +25 -0
  102. package/dist/commands/release/apply.preflight.d.ts.map +1 -0
  103. package/dist/commands/release/apply.preflight.js +338 -0
  104. package/dist/commands/release/apply.reporting.d.ts +4 -0
  105. package/dist/commands/release/apply.reporting.d.ts.map +1 -0
  106. package/dist/commands/release/apply.reporting.js +24 -0
  107. package/dist/commands/release/apply.types.d.ts +46 -0
  108. package/dist/commands/release/apply.types.d.ts.map +1 -0
  109. package/dist/commands/release/apply.types.js +1 -0
  110. package/dist/commands/runtime.command.d.ts +28 -0
  111. package/dist/commands/runtime.command.d.ts.map +1 -0
  112. package/dist/commands/runtime.command.js +169 -0
  113. package/dist/commands/shared/task-store.d.ts.map +1 -1
  114. package/dist/commands/shared/task-store.js +7 -3
  115. package/dist/commands/task/add.d.ts.map +1 -1
  116. package/dist/commands/task/add.js +3 -33
  117. package/dist/commands/task/block.d.ts.map +1 -1
  118. package/dist/commands/task/block.js +2 -2
  119. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  120. package/dist/commands/task/close-duplicate.js +2 -2
  121. package/dist/commands/task/close-noop.d.ts.map +1 -1
  122. package/dist/commands/task/close-noop.js +2 -2
  123. package/dist/commands/task/comment.js +2 -2
  124. package/dist/commands/task/derive.d.ts.map +1 -1
  125. package/dist/commands/task/derive.js +3 -3
  126. package/dist/commands/task/doc-template.d.ts +10 -0
  127. package/dist/commands/task/doc-template.d.ts.map +1 -0
  128. package/dist/commands/task/doc-template.js +104 -0
  129. package/dist/commands/task/doc.d.ts.map +1 -1
  130. package/dist/commands/task/doc.js +36 -1
  131. package/dist/commands/task/finish.d.ts.map +1 -1
  132. package/dist/commands/task/finish.js +7 -4
  133. package/dist/commands/task/migrate-doc.command.d.ts.map +1 -1
  134. package/dist/commands/task/migrate-doc.command.js +5 -1
  135. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  136. package/dist/commands/task/migrate-doc.js +136 -2
  137. package/dist/commands/task/new.d.ts.map +1 -1
  138. package/dist/commands/task/new.js +4 -110
  139. package/dist/commands/task/new.spec.js +3 -3
  140. package/dist/commands/task/plan.d.ts.map +1 -1
  141. package/dist/commands/task/plan.js +5 -4
  142. package/dist/commands/task/scaffold.d.ts.map +1 -1
  143. package/dist/commands/task/scaffold.js +7 -52
  144. package/dist/commands/task/set-status.d.ts.map +1 -1
  145. package/dist/commands/task/set-status.js +2 -2
  146. package/dist/commands/task/shared/dependencies.d.ts +15 -0
  147. package/dist/commands/task/shared/dependencies.d.ts.map +1 -0
  148. package/dist/commands/task/shared/dependencies.js +143 -0
  149. package/dist/commands/task/shared/docs.d.ts +21 -0
  150. package/dist/commands/task/shared/docs.d.ts.map +1 -0
  151. package/dist/commands/task/shared/docs.js +121 -0
  152. package/dist/commands/task/shared/listing.d.ts +20 -0
  153. package/dist/commands/task/shared/listing.d.ts.map +1 -0
  154. package/dist/commands/task/shared/listing.js +127 -0
  155. package/dist/commands/task/shared/tags.d.ts +24 -0
  156. package/dist/commands/task/shared/tags.d.ts.map +1 -0
  157. package/dist/commands/task/shared/tags.js +177 -0
  158. package/dist/commands/task/shared/transitions.d.ts +42 -0
  159. package/dist/commands/task/shared/transitions.d.ts.map +1 -0
  160. package/dist/commands/task/shared/transitions.js +175 -0
  161. package/dist/commands/task/shared.d.ts +5 -106
  162. package/dist/commands/task/shared.d.ts.map +1 -1
  163. package/dist/commands/task/shared.js +5 -681
  164. package/dist/commands/task/start.d.ts.map +1 -1
  165. package/dist/commands/task/start.js +7 -5
  166. package/dist/commands/task/verify-record.d.ts.map +1 -1
  167. package/dist/commands/task/verify-record.js +9 -25
  168. package/dist/commands/task/verify-show.command.d.ts.map +1 -1
  169. package/dist/commands/task/verify-show.command.js +5 -1
  170. package/dist/commands/upgrade/apply.d.ts +44 -0
  171. package/dist/commands/upgrade/apply.d.ts.map +1 -0
  172. package/dist/commands/upgrade/apply.js +180 -0
  173. package/dist/commands/upgrade/report.d.ts +21 -0
  174. package/dist/commands/upgrade/report.d.ts.map +1 -0
  175. package/dist/commands/upgrade/report.js +81 -0
  176. package/dist/commands/upgrade/source.d.ts +35 -0
  177. package/dist/commands/upgrade/source.d.ts.map +1 -0
  178. package/dist/commands/upgrade/source.js +109 -0
  179. package/dist/commands/upgrade/types.d.ts +31 -0
  180. package/dist/commands/upgrade/types.d.ts.map +1 -0
  181. package/dist/commands/upgrade/types.js +1 -0
  182. package/dist/commands/upgrade.d.ts +1 -35
  183. package/dist/commands/upgrade.d.ts.map +1 -1
  184. package/dist/commands/upgrade.js +68 -332
  185. package/dist/commands/workflow-build.command.d.ts.map +1 -1
  186. package/dist/commands/workflow-build.command.js +9 -15
  187. package/dist/shared/diagnostics.d.ts +23 -0
  188. package/dist/shared/diagnostics.d.ts.map +1 -0
  189. package/dist/shared/diagnostics.js +57 -0
  190. package/dist/shared/errors.d.ts +2 -0
  191. package/dist/shared/errors.d.ts.map +1 -1
  192. package/dist/shared/errors.js +2 -0
  193. package/dist/shared/repo-cli-version.d.ts +13 -0
  194. package/dist/shared/repo-cli-version.d.ts.map +1 -0
  195. package/dist/shared/repo-cli-version.js +63 -0
  196. package/dist/shared/runtime-source.d.ts +33 -0
  197. package/dist/shared/runtime-source.d.ts.map +1 -0
  198. package/dist/shared/runtime-source.js +156 -0
  199. package/dist/shared/version-compare.d.ts +7 -0
  200. package/dist/shared/version-compare.d.ts.map +1 -0
  201. package/dist/shared/version-compare.js +30 -0
  202. package/dist/shared/workflow-artifacts.d.ts +37 -0
  203. package/dist/shared/workflow-artifacts.d.ts.map +1 -0
  204. package/dist/shared/workflow-artifacts.js +97 -0
  205. package/package.json +2 -2
@@ -0,0 +1,169 @@
1
+ import { loadConfig, resolveProject } from "@agentplaneorg/core";
2
+ import { usageError } from "../cli/spec/errors.js";
3
+ import { suggestOne } from "../cli/spec/suggest.js";
4
+ import { evaluateRepoCliVersionExpectation, } from "../shared/repo-cli-version.js";
5
+ import { describeRuntimeMode, resolveRuntimeSourceInfo, } from "../shared/runtime-source.js";
6
+ export const runtimeSpec = {
7
+ id: ["runtime"],
8
+ group: "Diagnostics",
9
+ summary: "Inspect which agentplane runtime/binary/package sources are active.",
10
+ synopsis: ["agentplane runtime <explain> [options]"],
11
+ args: [{ name: "cmd", required: false, variadic: true, valueHint: "<cmd>" }],
12
+ examples: [{ cmd: "agentplane runtime explain", why: "Show active runtime details." }],
13
+ parse: (raw) => ({ cmd: (raw.args.cmd ?? []) }),
14
+ };
15
+ export const runtimeExplainSpec = {
16
+ id: ["runtime", "explain"],
17
+ group: "Diagnostics",
18
+ summary: "Explain the active binary, runtime mode, and resolved package roots.",
19
+ options: [
20
+ {
21
+ kind: "boolean",
22
+ name: "json",
23
+ default: false,
24
+ description: "Emit machine-readable runtime details.",
25
+ },
26
+ ],
27
+ examples: [
28
+ { cmd: "agentplane runtime explain", why: "Show the active runtime as readable text." },
29
+ {
30
+ cmd: "agentplane runtime explain --json",
31
+ why: "Show runtime details for scripts and diagnostics tooling.",
32
+ },
33
+ ],
34
+ parse: (raw) => ({ json: raw.opts.json === true }),
35
+ };
36
+ function renderPath(value) {
37
+ return value ?? "unresolved";
38
+ }
39
+ export function buildFrameworkDevWorkflow(report) {
40
+ const available = report.framework.inFrameworkCheckout;
41
+ const reinstallScript = "scripts/reinstall-global-agentplane.sh";
42
+ const rebuildCommands = [
43
+ "bun run --filter=@agentplaneorg/core build",
44
+ "bun run --filter=agentplane build",
45
+ ];
46
+ const verifyCommand = "agentplane runtime explain";
47
+ const forceGlobalExample = "AGENTPLANE_USE_GLOBAL_IN_FRAMEWORK=1 agentplane <command>";
48
+ if (!available) {
49
+ return {
50
+ available,
51
+ rebuildCommands,
52
+ reinstallScript,
53
+ verifyCommand,
54
+ forceGlobalExample,
55
+ recommendation: null,
56
+ };
57
+ }
58
+ const recommendation = report.mode === "repo-local" || report.mode === "repo-local-handoff"
59
+ ? "Rebuild local packages after source changes; use the reinstall helper only when you need the global PATH command updated from this checkout."
60
+ : report.mode === "global-in-framework"
61
+ ? "Reinstall or update the global agentplane CLI from this checkout so the wrapper can hand off to the repo-local binary."
62
+ : report.mode === "global-forced-in-framework"
63
+ ? "Unset AGENTPLANE_USE_GLOBAL_IN_FRAMEWORK=1 unless you intentionally need the global installed CLI inside the framework checkout."
64
+ : "Use runtime explain after rebuild/reinstall to confirm which binary and package roots are active.";
65
+ return {
66
+ available,
67
+ rebuildCommands,
68
+ reinstallScript,
69
+ verifyCommand,
70
+ forceGlobalExample,
71
+ recommendation,
72
+ };
73
+ }
74
+ function buildRuntimeExplainPayload(report) {
75
+ return {
76
+ ...report,
77
+ frameworkDev: buildFrameworkDevWorkflow(report),
78
+ repoCliExpectation: {
79
+ expectedVersion: null,
80
+ activeVersion: report.agentplane.version,
81
+ state: "unconfigured",
82
+ summary: null,
83
+ recovery: null,
84
+ },
85
+ };
86
+ }
87
+ export function renderRuntimeExplainText(report, repoCliExpectation) {
88
+ const frameworkDev = buildFrameworkDevWorkflow(report);
89
+ const lines = [
90
+ `Mode: ${report.mode} (${describeRuntimeMode(report.mode)})`,
91
+ `Active binary: ${renderPath(report.activeBinaryPath)}`,
92
+ `Current cwd: ${report.cwd}`,
93
+ `Framework checkout: ${report.framework.inFrameworkCheckout ? "yes" : "no"}`,
94
+ `Framework repo root: ${renderPath(report.frameworkSources.repoRoot)}`,
95
+ `Framework agentplane root: ${renderPath(report.frameworkSources.agentplaneRoot)}`,
96
+ `Framework core root: ${renderPath(report.frameworkSources.coreRoot)}`,
97
+ `Resolved agentplane: ${report.agentplane.version ?? "unknown"} @ ${renderPath(report.agentplane.packageRoot)}`,
98
+ `Resolved @agentplaneorg/core: ${report.core.version ?? "unknown"} @ ${renderPath(report.core.packageRoot)}`,
99
+ ];
100
+ if (repoCliExpectation.expectedVersion) {
101
+ lines.push(`Repository expected agentplane CLI: ${repoCliExpectation.expectedVersion}`);
102
+ if (repoCliExpectation.summary) {
103
+ lines.push(`Repository CLI status: ${repoCliExpectation.summary}`);
104
+ }
105
+ if (repoCliExpectation.recovery) {
106
+ lines.push(`Recovery: ${repoCliExpectation.recovery}`);
107
+ }
108
+ }
109
+ if (report.handoffFromBinaryPath) {
110
+ lines.push(`Handoff from: ${report.handoffFromBinaryPath}`);
111
+ }
112
+ if (frameworkDev.available) {
113
+ lines.push("", "Framework dev workflow:", "1. Rebuild local packages after source changes:", ...frameworkDev.rebuildCommands.map((command) => ` - ${command}`), "2. If the global PATH install should resolve this checkout:", ` - ${frameworkDev.reinstallScript}`, "3. Re-verify the active runtime:", ` - ${frameworkDev.verifyCommand}`, "4. Optional: force the global installed CLI inside this checkout:", ` - ${frameworkDev.forceGlobalExample}`);
114
+ if (frameworkDev.recommendation) {
115
+ lines.push(`Recommendation: ${frameworkDev.recommendation}`);
116
+ }
117
+ }
118
+ return lines.join("\n");
119
+ }
120
+ async function resolveRepoCliExpectation(opts) {
121
+ try {
122
+ const resolved = await resolveProject({
123
+ cwd: opts.cwd,
124
+ rootOverride: opts.rootOverride ?? null,
125
+ });
126
+ const loaded = await loadConfig(resolved.agentplaneDir);
127
+ return evaluateRepoCliVersionExpectation(loaded.config, opts.report);
128
+ }
129
+ catch {
130
+ return {
131
+ expectedVersion: null,
132
+ activeVersion: opts.report.agentplane.version,
133
+ state: "unconfigured",
134
+ summary: null,
135
+ recovery: null,
136
+ };
137
+ }
138
+ }
139
+ export const runRuntime = (_ctx, p) => {
140
+ const input = p.cmd.join(" ");
141
+ const suggestion = suggestOne(input, ["explain"]);
142
+ const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
143
+ const msg = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
144
+ return Promise.reject(usageError({
145
+ spec: runtimeSpec,
146
+ command: "runtime",
147
+ message: `${msg}${suffix}`,
148
+ context: { command: "runtime" },
149
+ }));
150
+ };
151
+ export const runRuntimeExplain = (ctx, p) => {
152
+ const report = resolveRuntimeSourceInfo({
153
+ cwd: ctx.cwd,
154
+ entryModuleUrl: import.meta.url,
155
+ });
156
+ return resolveRepoCliExpectation({
157
+ cwd: ctx.cwd,
158
+ rootOverride: ctx.rootOverride ?? null,
159
+ report,
160
+ }).then((repoCliExpectation) => {
161
+ const payload = { ...buildRuntimeExplainPayload(report), repoCliExpectation };
162
+ if (p.json) {
163
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
164
+ return 0;
165
+ }
166
+ process.stdout.write(`${renderRuntimeExplainText(report, repoCliExpectation)}\n`);
167
+ return 0;
168
+ });
169
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/task-store.ts"],"names":[],"mappings":"AAYA,OAAO,EAAgB,KAAK,QAAQ,EAAoB,MAAM,gCAAgC,CAAC;AAI/F,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA0DpG,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,KAAK,CAA0C;gBAE3C,GAAG,EAAE,cAAc;IAIzB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAK9B,SAAS;IAsBjB,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAC3D,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;CAwEjD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,CAI3D;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAEtE"}
1
+ {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/task-store.ts"],"names":[],"mappings":"AAYA,OAAO,EAAgB,KAAK,QAAQ,EAAoB,MAAM,gCAAgC,CAAC;AAI/F,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA8DpG,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,KAAK,CAA0C;gBAE3C,GAAG,EAAE,cAAc;IAIzB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAK9B,SAAS;IAsBjB,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAC3D,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;CA6EjD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,CAI3D;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAEtE"}
@@ -9,6 +9,9 @@ import { resolveDocUpdatedBy, taskDataToFrontmatter } from "./task-backend.js";
9
9
  function taskReadmePath(ctx, taskId) {
10
10
  return path.join(ctx.resolvedProject.gitRoot, ctx.config.paths.workflow_dir, taskId, "README.md");
11
11
  }
12
+ function normalizeTaskDocVersion(value, fallback = 2) {
13
+ return value === 3 ? 3 : value === 2 ? 2 : fallback;
14
+ }
12
15
  async function readTaskReadmeCached(opts) {
13
16
  const readmePath = taskReadmePath(opts.ctx, opts.taskId);
14
17
  let text;
@@ -89,17 +92,18 @@ export class TaskStore {
89
92
  let body = entry.parsed.body ?? "";
90
93
  const existingDoc = extractTaskDoc(body);
91
94
  const now = new Date().toISOString();
95
+ const currentDocVersion = normalizeTaskDocVersion(entry.parsed.frontmatter.doc_version);
96
+ const requestedDocVersion = normalizeTaskDocVersion(next.doc_version, currentDocVersion);
92
97
  if (next.doc !== undefined) {
93
98
  const nextDoc = String(next.doc ?? "");
94
99
  body = mergeTaskDoc(body, nextDoc);
95
100
  if (docChanged(existingDoc, nextDoc) || !frontmatter.doc_updated_at) {
96
- frontmatter.doc_version = 2;
101
+ frontmatter.doc_version = requestedDocVersion;
97
102
  frontmatter.doc_updated_at = now;
98
103
  frontmatter.doc_updated_by = resolveDocUpdatedBy(next);
99
104
  }
100
105
  }
101
- if (frontmatter.doc_version !== 2)
102
- frontmatter.doc_version = 2;
106
+ frontmatter.doc_version = normalizeTaskDocVersion(frontmatter.doc_version, requestedDocVersion);
103
107
  if (typeof frontmatter.doc_updated_at !== "string" ||
104
108
  frontmatter.doc_updated_at.trim() === "") {
105
109
  frontmatter.doc_updated_at = now;
@@ -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;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"}
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;AAIpF,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,CAyDlB"}
@@ -2,33 +2,7 @@ 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
+ import { defaultTaskDocV3, TASK_DOC_VERSION_V3 } from "./doc-template.js";
32
6
  export async function cmdTaskAdd(opts) {
33
7
  try {
34
8
  const ctx = opts.ctx ??
@@ -62,15 +36,11 @@ export async function cmdTaskAdd(opts) {
62
36
  comments: opts.commentAuthor && opts.commentBody
63
37
  ? [{ author: opts.commentAuthor, body: opts.commentBody }]
64
38
  : [],
65
- doc_version: 2,
39
+ doc_version: TASK_DOC_VERSION_V3,
66
40
  doc_updated_at: nowIso(),
67
41
  doc_updated_by: docUpdatedBy,
68
42
  id_source: "explicit",
69
- doc: defaultTaskDoc({
70
- requiredSections: ctx.config.tasks.doc.required_sections,
71
- title: opts.title,
72
- description: opts.description,
73
- }),
43
+ doc: defaultTaskDocV3({ title: opts.title, description: opts.description }),
74
44
  }));
75
45
  if (ctx.taskBackend.writeTasks) {
76
46
  await ctx.taskBackend.writeTasks(tasks);
@@ -1 +1 @@
1
- {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/task/block.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgBnC,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,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,IAAI,EAAE,MAAM,CAAC;IACb,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,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+HlB"}
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/task/block.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAiBnC,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,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,IAAI,EAAE,MAAM,CAAC;IACb,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,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+HlB"}
@@ -7,7 +7,7 @@ import { ensureActionApproved } from "../shared/approval-requirements.js";
7
7
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
8
8
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
9
9
  import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
10
- import { appendTaskEvent, defaultCommitEmojiForAgentId, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, nowIso, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
10
+ import { appendTaskEvent, defaultCommitEmojiForAgentId, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, normalizeTaskDocVersion, nowIso, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
11
11
  export async function cmdBlock(opts) {
12
12
  try {
13
13
  const ctx = opts.ctx ??
@@ -63,7 +63,7 @@ export async function cmdBlock(opts) {
63
63
  to: "BLOCKED",
64
64
  note: commentBody,
65
65
  }),
66
- doc_version: 2,
66
+ doc_version: normalizeTaskDocVersion(task.doc_version),
67
67
  doc_updated_at: at,
68
68
  doc_updated_by: opts.author,
69
69
  };
@@ -1 +1 @@
1
- {"version":3,"file":"close-duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-duplicate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIrF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuFlB"}
1
+ {"version":3,"file":"close-duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-duplicate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AASrF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuFlB"}
@@ -3,7 +3,7 @@ import { CliError } from "../../shared/errors.js";
3
3
  import { ensureActionApproved } from "../shared/approval-requirements.js";
4
4
  import { loadTaskFromContext } from "../shared/task-backend.js";
5
5
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
6
- import { appendTaskEvent, nowIso, requireStructuredComment } from "./shared.js";
6
+ import { appendTaskEvent, normalizeTaskDocVersion, nowIso, requireStructuredComment, } from "./shared.js";
7
7
  export async function cmdTaskCloseDuplicate(opts) {
8
8
  try {
9
9
  const sourceId = opts.taskId.trim();
@@ -69,7 +69,7 @@ export async function cmdTaskCloseDuplicate(opts) {
69
69
  result_summary: `Closed as duplicate of ${duplicateOf}.`,
70
70
  risk_level: "low",
71
71
  breaking: false,
72
- doc_version: 2,
72
+ doc_version: normalizeTaskDocVersion(task.doc_version),
73
73
  doc_updated_at: at,
74
74
  doc_updated_by: opts.author,
75
75
  };
@@ -1 +1 @@
1
- {"version":3,"file":"close-noop.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-noop.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGpF,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,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsElB"}
1
+ {"version":3,"file":"close-noop.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-noop.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQpF,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,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsElB"}
@@ -3,7 +3,7 @@ import { CliError } from "../../shared/errors.js";
3
3
  import { ensureActionApproved } from "../shared/approval-requirements.js";
4
4
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
5
5
  import { loadCommandContext } from "../shared/task-backend.js";
6
- import { appendTaskEvent, nowIso, requireStructuredComment } from "./shared.js";
6
+ import { appendTaskEvent, normalizeTaskDocVersion, nowIso, requireStructuredComment, } from "./shared.js";
7
7
  export async function cmdTaskCloseNoop(opts) {
8
8
  try {
9
9
  const ctx = opts.ctx ??
@@ -59,7 +59,7 @@ export async function cmdTaskCloseNoop(opts) {
59
59
  result_summary: "No-op closure recorded.",
60
60
  risk_level: "low",
61
61
  breaking: false,
62
- doc_version: 2,
62
+ doc_version: normalizeTaskDocVersion(task.doc_version),
63
63
  doc_updated_at: at,
64
64
  doc_updated_by: opts.author,
65
65
  };
@@ -2,7 +2,7 @@ import { mapBackendError } from "../../cli/error-map.js";
2
2
  import { successMessage } from "../../cli/output.js";
3
3
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
4
4
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
5
- import { appendTaskEvent, nowIso } from "./shared.js";
5
+ import { appendTaskEvent, normalizeTaskDocVersion, nowIso } from "./shared.js";
6
6
  export async function cmdTaskComment(opts) {
7
7
  try {
8
8
  const ctx = opts.ctx ??
@@ -25,7 +25,7 @@ export async function cmdTaskComment(opts) {
25
25
  author: opts.author,
26
26
  body: opts.body,
27
27
  }),
28
- doc_version: 2,
28
+ doc_version: normalizeTaskDocVersion(task.doc_version),
29
29
  doc_updated_at: at,
30
30
  doc_updated_by: opts.author,
31
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../../src/commands/task/derive.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAUpF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,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;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgElB"}
1
+ {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../../src/commands/task/derive.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAepF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,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;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiElB"}
@@ -2,7 +2,7 @@ import { mapBackendError } from "../../cli/error-map.js";
2
2
  import { unknownEntityMessage } from "../../cli/output.js";
3
3
  import { CliError } from "../../shared/errors.js";
4
4
  import { loadCommandContext } from "../shared/task-backend.js";
5
- import { extractDocSection, nowIso, toStringArray } from "./shared.js";
5
+ import { extractTaskObservationSection, normalizeTaskDocVersion, nowIso, toStringArray, } from "./shared.js";
6
6
  function normalizeOneLine(text, maxChars) {
7
7
  const normalized = text.trim().replaceAll(/\s+/g, " ");
8
8
  if (normalized.length <= maxChars)
@@ -37,8 +37,8 @@ export async function cmdTaskDerive(opts) {
37
37
  });
38
38
  }
39
39
  const spikeDoc = typeof spike.doc === "string" ? spike.doc : "";
40
- const notes = extractDocSection(spikeDoc, "Notes") ?? "";
41
- const excerpt = notes.trim() ? normalizeOneLine(notes, 180) : "";
40
+ const observation = extractTaskObservationSection(spikeDoc, normalizeTaskDocVersion(spike.doc_version)) ?? "";
41
+ const excerpt = observation.trim() ? normalizeOneLine(observation, 180) : "";
42
42
  const suffixLength = ctx.config.tasks.id_suffix_length_default;
43
43
  const taskId = await ctx.taskBackend.generateTaskId({ length: suffixLength, attempts: 1000 });
44
44
  let description = opts.description.trim();
@@ -0,0 +1,10 @@
1
+ export declare const TASK_DOC_VERSION_V3 = 3;
2
+ export declare function defaultTaskDocV3(opts: {
3
+ title: string;
4
+ description: string;
5
+ }): string;
6
+ export declare function buildDefaultVerifyStepsSection(opts: {
7
+ primary: string;
8
+ verifyCommands: string[];
9
+ }): string;
10
+ //# sourceMappingURL=doc-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-template.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAkErC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAkCrF;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,MAAM,CA2BT"}
@@ -0,0 +1,104 @@
1
+ import { setMarkdownSection } from "@agentplaneorg/core";
2
+ export const TASK_DOC_VERSION_V3 = 3;
3
+ function normalizeTaskHumanText(text) {
4
+ let next = text.replaceAll("\r\n", "\n");
5
+ const escapedDoubleNewline = next.includes(String.raw `\n\n`) || next.includes(String.raw `\r\n\r\n`);
6
+ const escapedNewlineMatches = next.match(/\\n/g) ?? [];
7
+ if (escapedDoubleNewline || escapedNewlineMatches.length >= 2) {
8
+ next = next.replaceAll(String.raw `\r\n`, "\n").replaceAll(String.raw `\n`, "\n");
9
+ }
10
+ return next.trim();
11
+ }
12
+ function normalizeTaskHumanInlineText(text) {
13
+ return normalizeTaskHumanText(text)
14
+ .split("\n")
15
+ .map((line) => line.trim())
16
+ .filter(Boolean)
17
+ .join(" ");
18
+ }
19
+ function ensureTrailingSentence(text) {
20
+ return /[.!?]$/.test(text) ? text : `${text}.`;
21
+ }
22
+ function buildDefaultSummary(opts) {
23
+ return `${opts.title}\n\n${normalizeTaskHumanText(opts.description)}`;
24
+ }
25
+ function buildDefaultScope(opts) {
26
+ const summary = ensureTrailingSentence(normalizeTaskHumanInlineText(opts.description));
27
+ return [
28
+ `- In scope: ${summary}`,
29
+ `- Out of scope: unrelated refactors not required for "${opts.title}".`,
30
+ ].join("\n");
31
+ }
32
+ function buildDefaultPlan(opts) {
33
+ return [
34
+ `1. Implement the change for "${opts.title}".`,
35
+ "2. Run required checks and capture verification evidence.",
36
+ "3. Finalize task findings and finish with traceable commit metadata.",
37
+ ].join("\n");
38
+ }
39
+ function buildDefaultVerifyStepsTemplate() {
40
+ return [
41
+ "<!-- TODO: REPLACE WITH TASK-SPECIFIC ACCEPTANCE STEPS -->",
42
+ "",
43
+ "1. <Action>. Expected: <observable result>.",
44
+ "2. <Action>. Expected: <observable result>.",
45
+ "3. <Action>. Expected: <observable result>.",
46
+ ].join("\n");
47
+ }
48
+ function buildDefaultVerificationTemplate() {
49
+ return ["<!-- BEGIN VERIFICATION RESULTS -->", "<!-- END VERIFICATION RESULTS -->"].join("\n");
50
+ }
51
+ function buildDefaultRollbackPlan() {
52
+ return [
53
+ "- Revert task-related commit(s).",
54
+ "- Re-run required checks to confirm rollback safety.",
55
+ ].join("\n");
56
+ }
57
+ export function defaultTaskDocV3(opts) {
58
+ let body = [
59
+ "## Summary",
60
+ "",
61
+ "## Scope",
62
+ "",
63
+ "## Plan",
64
+ "",
65
+ "## Verify Steps",
66
+ "",
67
+ "## Verification",
68
+ "",
69
+ "## Rollback Plan",
70
+ "",
71
+ "## Findings",
72
+ "",
73
+ ].join("\n");
74
+ body = setMarkdownSection(body, "Summary", buildDefaultSummary({ title: opts.title, description: opts.description }));
75
+ body = setMarkdownSection(body, "Scope", buildDefaultScope({ title: opts.title, description: opts.description }));
76
+ body = setMarkdownSection(body, "Plan", buildDefaultPlan({ title: opts.title }));
77
+ body = setMarkdownSection(body, "Verify Steps", buildDefaultVerifyStepsTemplate());
78
+ body = setMarkdownSection(body, "Verification", buildDefaultVerificationTemplate());
79
+ body = setMarkdownSection(body, "Rollback Plan", buildDefaultRollbackPlan());
80
+ body = setMarkdownSection(body, "Findings", "");
81
+ return body;
82
+ }
83
+ export function buildDefaultVerifyStepsSection(opts) {
84
+ const commandSteps = opts.verifyCommands.length > 0
85
+ ? opts.verifyCommands.map((command, index) => `${index + 1}. Run \`${command}\`. Expected: it succeeds and confirms the requested outcome for this task.`)
86
+ : [];
87
+ const genericSteps = [
88
+ `Review the changed artifact or behavior for the \`${opts.primary}\` task. Expected: the requested outcome is visible and matches the approved scope.`,
89
+ "Compare the final result against the task summary and touched scope. Expected: remaining follow-up is either resolved or explicit in ## Findings.",
90
+ ];
91
+ if (commandSteps.length === 0) {
92
+ return [
93
+ "<!-- TODO: REPLACE WITH TASK-SPECIFIC ACCEPTANCE STEPS -->",
94
+ "",
95
+ "1. Review the changed artifact or behavior. Expected: the requested outcome is visible and matches the approved scope.",
96
+ "2. Run the most relevant validation step for this task. Expected: it succeeds without unexpected regressions in touched scope.",
97
+ "3. Compare the final result against the task summary and scope. Expected: any remaining follow-up is explicit in ## Findings.",
98
+ ].join("\n");
99
+ }
100
+ return [
101
+ ...commandSteps,
102
+ ...genericSteps.map((step, index) => `${commandSteps.length + index + 1}. ${step}`),
103
+ ].join("\n");
104
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.ts"],"names":[],"mappings":"AAaA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGpF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6GlB;AAED,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB"}
1
+ {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAmBpF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2IlB;AAED,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB"}
@@ -2,10 +2,24 @@ import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { ensureDocSections, normalizeDocSectionName, parseDocSections, setMarkdownSection, } from "@agentplaneorg/core";
4
4
  import { mapBackendError, mapCoreError } from "../../cli/error-map.js";
5
- import { infoMessage, unknownEntityMessage, backendNotSupportedMessage } from "../../cli/output.js";
5
+ import { infoMessage, unknownEntityMessage, backendNotSupportedMessage, warnMessage, } from "../../cli/output.js";
6
6
  import { CliError } from "../../shared/errors.js";
7
7
  import { loadCommandContext } from "../shared/task-backend.js";
8
8
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
9
+ function normalizeOutcomeText(value) {
10
+ return value
11
+ .replaceAll("\r\n", "\n")
12
+ .split("\n")
13
+ .map((line) => line.trimEnd())
14
+ .join("\n")
15
+ .trim();
16
+ }
17
+ function readSectionContent(doc, section) {
18
+ const sectionKey = normalizeDocSectionName(section);
19
+ const { sections } = parseDocSections(doc);
20
+ const lines = sections.get(sectionKey)?.lines ?? [];
21
+ return normalizeOutcomeText(lines.join("\n"));
22
+ }
9
23
  export async function cmdTaskDocSet(opts) {
10
24
  let updatedBy;
11
25
  if (opts.updatedBy !== undefined) {
@@ -76,6 +90,10 @@ export async function cmdTaskDocSet(opts) {
76
90
  ? String(storeTask.doc ?? "")
77
91
  : ((await backend.getTaskDoc(opts.taskId)) ?? "");
78
92
  const baseDoc = ensureDocSections(baseDocRaw, config.tasks.doc.required_sections);
93
+ const baseSection = readSectionContent(baseDoc, opts.section);
94
+ const requestMode = headingKeys.size > 0 && (headingKeys.size > 1 || !headingKeys.has(targetKey))
95
+ ? "full-doc"
96
+ : "section";
79
97
  if (headingKeys.size > 0 && (headingKeys.size > 1 || !headingKeys.has(targetKey))) {
80
98
  const fullDoc = ensureDocSections(text, config.tasks.doc.required_sections);
81
99
  await (useStore
@@ -110,8 +128,25 @@ export async function cmdTaskDocSet(opts) {
110
128
  }))
111
129
  : backend.setTaskDoc(opts.taskId, normalized, updatedBy));
112
130
  }
131
+ const updatedTask = useStore ? await store.get(opts.taskId) : null;
132
+ const updatedDocRaw = useStore
133
+ ? String(updatedTask?.doc ?? "")
134
+ : ((await backend.getTaskDoc(opts.taskId)) ?? "");
135
+ const updatedDoc = ensureDocSections(updatedDocRaw, config.tasks.doc.required_sections);
136
+ const updatedSection = readSectionContent(updatedDoc, opts.section);
137
+ const docChanged = normalizeOutcomeText(baseDoc) !== normalizeOutcomeText(updatedDoc);
138
+ const sectionChanged = baseSection !== updatedSection;
113
139
  const tasksDir = path.join(resolved.gitRoot, config.paths.workflow_dir);
114
140
  process.stdout.write(`${path.join(tasksDir, opts.taskId, "README.md")}\n`);
141
+ if (!docChanged) {
142
+ process.stderr.write(`${warnMessage(`task doc set wrote no effective README change for section ${opts.section}`)}\n`);
143
+ }
144
+ else if (requestMode === "full-doc") {
145
+ process.stderr.write(`${infoMessage(`task doc set applied a full-doc update; target section ${opts.section} ${sectionChanged ? "changed" : "did not change"}`)}\n`);
146
+ }
147
+ else {
148
+ process.stderr.write(`${infoMessage(`task doc set updated section ${opts.section}${sectionChanged ? "" : " (effective section content unchanged)"}`)}\n`);
149
+ }
115
150
  return 0;
116
151
  }
117
152
  catch (err) {
@@ -1 +1 @@
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
+ {"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAqCnC,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,CA2XlB"}
@@ -1,6 +1,6 @@
1
1
  import { ensureDocSections } from "@agentplaneorg/core";
2
2
  import { mapBackendError } from "../../cli/error-map.js";
3
- import { invalidValueMessage, successMessage } from "../../cli/output.js";
3
+ import { infoMessage, invalidValueMessage, successMessage } from "../../cli/output.js";
4
4
  import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
5
5
  import { CliError } from "../../shared/errors.js";
6
6
  import { readFile, rm } from "node:fs/promises";
@@ -11,7 +11,7 @@ import { ensureReconciledBeforeMutation } from "../shared/reconcile-check.js";
11
11
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
12
12
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
13
13
  import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
14
- import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureAgentFilledRequiredDocSections, ensureVerificationSatisfiedIfRequired, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
14
+ import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureAgentFilledRequiredDocSections, ensureVerificationSatisfiedIfRequired, normalizeTaskDocVersion, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
15
15
  async function clearDirectWorkLockIfMatches(opts) {
16
16
  const lockPath = path.join(opts.agentplaneDir, "cache", "direct-work.json");
17
17
  try {
@@ -201,7 +201,7 @@ export async function cmdFinish(opts) {
201
201
  result_summary: taskId === metaTaskId && resultSummary ? resultSummary : task.result_summary,
202
202
  risk_level: taskId === metaTaskId && riskLevel ? riskLevel : task.risk_level,
203
203
  breaking: taskId === metaTaskId && breaking ? true : task.breaking,
204
- doc_version: 2,
204
+ doc_version: normalizeTaskDocVersion(task.doc_version),
205
205
  doc_updated_at: at,
206
206
  doc_updated_by: opts.author,
207
207
  };
@@ -268,7 +268,7 @@ export async function cmdFinish(opts) {
268
268
  const updatedAfterCommit = {
269
269
  ...taskAfterCommit,
270
270
  commit: { hash: committed.hash, message: committed.message },
271
- doc_version: 2,
271
+ doc_version: normalizeTaskDocVersion(taskAfterCommit.doc_version),
272
272
  doc_updated_at: nowIso(),
273
273
  doc_updated_by: opts.author,
274
274
  };
@@ -322,6 +322,9 @@ export async function cmdFinish(opts) {
322
322
  });
323
323
  }
324
324
  if (shouldCloseCommit && primaryTaskId) {
325
+ if (!opts.quiet) {
326
+ process.stdout.write(`${infoMessage("task marked DONE; creating deterministic close commit")}\n`);
327
+ }
325
328
  await cmdCommit({
326
329
  ctx,
327
330
  cwd: opts.cwd,
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAa,MAAM,wBAAwB,CAAC;AAKjF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAUF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CA6ChE,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQjG"}
1
+ {"version":3,"file":"migrate-doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAa,MAAM,wBAAwB,CAAC;AAKjF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAUF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAiDhE,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQjG"}