agentplane 0.3.5 → 0.3.6

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 (187) hide show
  1. package/README.md +103 -75
  2. package/assets/AGENTS.md +4 -2
  3. package/bin/dist-guard.js +13 -3
  4. package/bin/runtime-watch.d.ts +1 -0
  5. package/bin/runtime-watch.js +22 -5
  6. package/bin/stale-dist-policy.js +9 -2
  7. package/dist/.build-manifest.json +196 -776
  8. package/dist/backends/task-backend.test-helpers.d.ts +4 -0
  9. package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
  10. package/dist/backends/task-backend.test-helpers.js +33 -0
  11. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  12. package/dist/cli/bootstrap-guide.js +1 -0
  13. package/dist/cli/command-guide.d.ts.map +1 -1
  14. package/dist/cli/command-guide.js +3 -2
  15. package/dist/cli/reason-codes.d.ts.map +1 -1
  16. package/dist/cli/reason-codes.js +30 -0
  17. package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
  18. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
  19. package/dist/cli/run-cli/command-catalog/core.js +137 -0
  20. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
  21. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
  22. package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
  23. package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
  24. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
  25. package/dist/cli/run-cli/command-catalog/project.js +78 -0
  26. package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
  27. package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
  28. package/dist/cli/run-cli/command-catalog/shared.js +9 -0
  29. package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
  30. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
  31. package/dist/cli/run-cli/command-catalog/task.js +85 -0
  32. package/dist/cli/run-cli/command-catalog.d.ts +3 -18
  33. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  34. package/dist/cli/run-cli/command-catalog.js +8 -337
  35. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  36. package/dist/cli/run-cli/commands/ide.js +64 -2
  37. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
  38. package/dist/cli/run-cli/commands/init/ui.js +33 -13
  39. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
  40. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
  41. package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
  42. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
  43. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
  44. package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
  45. package/dist/cli/run-cli.test-helpers.d.ts +3 -0
  46. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  47. package/dist/cli/run-cli.test-helpers.js +138 -6
  48. package/dist/commands/commit.spec.d.ts.map +1 -1
  49. package/dist/commands/commit.spec.js +2 -2
  50. package/dist/commands/doctor/runtime.d.ts.map +1 -1
  51. package/dist/commands/doctor/runtime.js +3 -6
  52. package/dist/commands/guard/commit.command.js +1 -1
  53. package/dist/commands/guard/impl/allow.d.ts +5 -0
  54. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  55. package/dist/commands/guard/impl/allow.js +15 -10
  56. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  57. package/dist/commands/guard/impl/commands.js +137 -18
  58. package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
  59. package/dist/commands/guard/impl/comment-commit.js +2 -0
  60. package/dist/commands/hooks/index.d.ts.map +1 -1
  61. package/dist/commands/hooks/index.js +8 -35
  62. package/dist/commands/recipes/impl/apply.d.ts +4 -0
  63. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  64. package/dist/commands/recipes/impl/apply.js +34 -0
  65. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  66. package/dist/commands/recipes/impl/commands/explain.js +70 -11
  67. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  68. package/dist/commands/recipes/impl/commands/info.js +24 -12
  69. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  70. package/dist/commands/recipes/impl/commands/install.js +32 -36
  71. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  72. package/dist/commands/recipes/impl/commands/list.js +7 -4
  73. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  74. package/dist/commands/recipes/impl/commands/remove.js +9 -11
  75. package/dist/commands/recipes/impl/constants.d.ts +2 -0
  76. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  77. package/dist/commands/recipes/impl/constants.js +2 -0
  78. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  79. package/dist/commands/recipes/impl/manifest.js +219 -23
  80. package/dist/commands/recipes/impl/normalize.d.ts +3 -0
  81. package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
  82. package/dist/commands/recipes/impl/normalize.js +28 -24
  83. package/dist/commands/recipes/impl/paths.d.ts +9 -0
  84. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  85. package/dist/commands/recipes/impl/paths.js +10 -1
  86. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
  87. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
  88. package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
  89. package/dist/commands/recipes/impl/resolver.d.ts +20 -0
  90. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
  91. package/dist/commands/recipes/impl/resolver.js +220 -0
  92. package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
  93. package/dist/commands/recipes/impl/scenario.js +40 -11
  94. package/dist/commands/recipes/impl/types.d.ts +145 -16
  95. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  96. package/dist/commands/recipes/install.spec.d.ts.map +1 -1
  97. package/dist/commands/recipes/install.spec.js +3 -2
  98. package/dist/commands/recipes.d.ts +6 -4
  99. package/dist/commands/recipes.d.ts.map +1 -1
  100. package/dist/commands/recipes.js +5 -3
  101. package/dist/commands/recipes.test-helpers.d.ts +185 -0
  102. package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
  103. package/dist/commands/recipes.test-helpers.js +339 -0
  104. package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
  105. package/dist/commands/scenario/impl/commands.js +192 -336
  106. package/dist/commands/scenario/info.command.d.ts.map +1 -1
  107. package/dist/commands/scenario/info.command.js +7 -2
  108. package/dist/commands/scenario/list.command.js +2 -2
  109. package/dist/commands/scenario/run.command.d.ts.map +1 -1
  110. package/dist/commands/scenario/run.command.js +7 -2
  111. package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
  112. package/dist/commands/shared/reconcile-check.js +77 -2
  113. package/dist/commands/shared/task-store.d.ts +32 -1
  114. package/dist/commands/shared/task-store.d.ts.map +1 -1
  115. package/dist/commands/shared/task-store.js +166 -42
  116. package/dist/commands/task/block.d.ts.map +1 -1
  117. package/dist/commands/task/block.js +46 -29
  118. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  119. package/dist/commands/task/close-duplicate.js +12 -37
  120. package/dist/commands/task/close-noop.d.ts.map +1 -1
  121. package/dist/commands/task/close-noop.js +12 -30
  122. package/dist/commands/task/close-shared.d.ts +14 -0
  123. package/dist/commands/task/close-shared.d.ts.map +1 -0
  124. package/dist/commands/task/close-shared.js +76 -0
  125. package/dist/commands/task/comment.d.ts.map +1 -1
  126. package/dist/commands/task/comment.js +35 -17
  127. package/dist/commands/task/doc-set.command.d.ts +2 -1
  128. package/dist/commands/task/doc-set.command.d.ts.map +1 -1
  129. package/dist/commands/task/doc-set.command.js +36 -4
  130. package/dist/commands/task/doc-template.d.ts.map +1 -1
  131. package/dist/commands/task/doc-template.js +2 -7
  132. package/dist/commands/task/doc.command.js +1 -1
  133. package/dist/commands/task/doc.d.ts +2 -1
  134. package/dist/commands/task/doc.d.ts.map +1 -1
  135. package/dist/commands/task/doc.js +123 -71
  136. package/dist/commands/task/finish.d.ts.map +1 -1
  137. package/dist/commands/task/finish.js +138 -76
  138. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  139. package/dist/commands/task/migrate-doc.js +2 -8
  140. package/dist/commands/task/plan-set.command.js +1 -1
  141. package/dist/commands/task/plan.command.d.ts +8 -0
  142. package/dist/commands/task/plan.command.d.ts.map +1 -0
  143. package/dist/commands/task/plan.command.js +37 -0
  144. package/dist/commands/task/plan.d.ts.map +1 -1
  145. package/dist/commands/task/plan.js +190 -93
  146. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  147. package/dist/commands/task/set-status.command.js +1 -1
  148. package/dist/commands/task/set-status.d.ts.map +1 -1
  149. package/dist/commands/task/set-status.js +40 -3
  150. package/dist/commands/task/shared/docs.d.ts +1 -0
  151. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  152. package/dist/commands/task/shared/docs.js +7 -0
  153. package/dist/commands/task/shared/transitions.d.ts +0 -2
  154. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  155. package/dist/commands/task/shared/transitions.js +0 -6
  156. package/dist/commands/task/shared.d.ts +2 -2
  157. package/dist/commands/task/shared.d.ts.map +1 -1
  158. package/dist/commands/task/shared.js +2 -2
  159. package/dist/commands/task/start.d.ts.map +1 -1
  160. package/dist/commands/task/start.js +88 -63
  161. package/dist/commands/task/task.command.d.ts +8 -0
  162. package/dist/commands/task/task.command.d.ts.map +1 -0
  163. package/dist/commands/task/task.command.js +71 -0
  164. package/dist/commands/task/verify-command-shared.d.ts +16 -0
  165. package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
  166. package/dist/commands/task/verify-command-shared.js +53 -0
  167. package/dist/commands/task/verify-ok.command.d.ts +2 -6
  168. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  169. package/dist/commands/task/verify-ok.command.js +8 -50
  170. package/dist/commands/task/verify-record.d.ts.map +1 -1
  171. package/dist/commands/task/verify-record.js +119 -140
  172. package/dist/commands/task/verify-rework.command.d.ts +2 -6
  173. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  174. package/dist/commands/task/verify-rework.command.js +8 -50
  175. package/dist/commands/verify.spec.d.ts.map +1 -1
  176. package/dist/commands/verify.spec.js +3 -12
  177. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  178. package/dist/policy/rules/allowlist.js +13 -4
  179. package/dist/policy/rules/protected-paths.d.ts.map +1 -1
  180. package/dist/policy/rules/protected-paths.js +6 -1
  181. package/dist/shared/agent-emoji.d.ts.map +1 -1
  182. package/dist/shared/protected-paths.d.ts +7 -0
  183. package/dist/shared/protected-paths.d.ts.map +1 -1
  184. package/dist/shared/protected-paths.js +26 -10
  185. package/dist/shared/repo-cli-version.d.ts.map +1 -1
  186. package/dist/shared/repo-cli-version.js +9 -3
  187. package/package.json +2 -2
@@ -3,7 +3,7 @@ import { readFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { ensureDocSections, setMarkdownSection } from "@agentplaneorg/core";
5
5
  import { mapBackendError, mapCoreError } from "../../cli/error-map.js";
6
- import { backendNotSupportedMessage } from "../../cli/output.js";
6
+ import { backendNotSupportedMessage, successMessage } from "../../cli/output.js";
7
7
  import { CliError } from "../../shared/errors.js";
8
8
  import { ensureReconciledBeforeMutation } from "../shared/reconcile-check.js";
9
9
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
@@ -68,59 +68,113 @@ async function recordVerificationResult(opts) {
68
68
  const task = useStore
69
69
  ? await store.get(opts.taskId)
70
70
  : await loadTaskFromContext({ ctx, taskId: opts.taskId });
71
- const existingDoc = useStore
72
- ? String(task.doc ?? "")
73
- : (typeof task.doc === "string" ? task.doc : "") || (await backend.getTaskDoc(task.id));
74
- const baseDoc = ensureDocSections(existingDoc ?? "", config.tasks.doc.required_sections);
75
- const verificationSection = extractDocSection(baseDoc, "Verification") ?? "";
76
- const verifySteps = extractDocSection(baseDoc, "Verify Steps");
77
- const verifyStepsHash = verifySteps
78
- ? sha256Hex(verifySteps.replaceAll("\r\n", "\n").trim())
79
- : null;
80
- const docVersion = normalizeTaskDocVersion(task.doc_version);
81
- const verifyStepsRef = [
82
- `doc_version=${String(docVersion)}`,
83
- `doc_updated_at=${String(task.doc_updated_at ?? "missing")}`,
84
- `excerpt_hash=sha256:${verifyStepsHash ?? "missing"}`,
85
- ].join(", ");
86
71
  const at = nowIso();
87
- const entry = renderVerificationEntry({
88
- at,
89
- state: opts.state,
90
- by: opts.by,
91
- note: opts.note,
92
- details: opts.details ?? null,
93
- verifyStepsRef,
94
- });
95
- const nextVerification = appendBetweenMarkers(verificationSection, entry, docVersion);
96
- const nextDoc = ensureDocSections(setMarkdownSection(baseDoc, "Verification", nextVerification), config.tasks.doc.required_sections);
97
- const nextTask = {
98
- ...task,
99
- status: opts.state === "needs_rework" ? "DOING" : task.status,
100
- commit: opts.state === "needs_rework" ? null : (task.commit ?? null),
101
- doc: nextDoc,
102
- doc_updated_by: opts.by,
103
- events: appendTaskEvent(task, {
104
- type: "verify",
72
+ if (useStore) {
73
+ await store.patch(opts.taskId, (current) => {
74
+ const existingDoc = String(current.doc ?? "");
75
+ const baseDoc = ensureDocSections(existingDoc, config.tasks.doc.required_sections);
76
+ const verificationSection = extractDocSection(baseDoc, "Verification") ?? "";
77
+ const verifySteps = extractDocSection(baseDoc, "Verify Steps");
78
+ const verifyStepsHash = verifySteps
79
+ ? sha256Hex(verifySteps.replaceAll("\r\n", "\n").trim())
80
+ : null;
81
+ const docVersion = normalizeTaskDocVersion(current.doc_version);
82
+ const verifyStepsRef = [
83
+ `doc_version=${String(docVersion)}`,
84
+ `doc_updated_at=${String(current.doc_updated_at ?? "missing")}`,
85
+ `excerpt_hash=sha256:${verifyStepsHash ?? "missing"}`,
86
+ ].join(", ");
87
+ const entry = renderVerificationEntry({
88
+ at,
89
+ state: opts.state,
90
+ by: opts.by,
91
+ note: opts.note,
92
+ details: opts.details ?? null,
93
+ verifyStepsRef,
94
+ });
95
+ const nextVerification = appendBetweenMarkers(verificationSection, entry, docVersion);
96
+ return {
97
+ task: {
98
+ status: opts.state === "needs_rework" ? "DOING" : current.status,
99
+ commit: opts.state === "needs_rework" ? null : (current.commit ?? null),
100
+ verification: {
101
+ state: opts.state,
102
+ updated_at: at,
103
+ updated_by: opts.by,
104
+ note: opts.note,
105
+ },
106
+ },
107
+ doc: {
108
+ kind: "set-section",
109
+ section: "Verification",
110
+ text: nextVerification,
111
+ requiredSections: config.tasks.doc.required_sections,
112
+ },
113
+ appendEvents: [
114
+ {
115
+ type: "verify",
116
+ at,
117
+ author: opts.by,
118
+ state: opts.state,
119
+ note: opts.note,
120
+ },
121
+ ],
122
+ docMeta: { updatedBy: opts.by },
123
+ };
124
+ });
125
+ }
126
+ else {
127
+ const existingDoc = (typeof task.doc === "string" ? task.doc : "") || (await backend.getTaskDoc(task.id));
128
+ const baseDoc = ensureDocSections(existingDoc ?? "", config.tasks.doc.required_sections);
129
+ const verificationSection = extractDocSection(baseDoc, "Verification") ?? "";
130
+ const verifySteps = extractDocSection(baseDoc, "Verify Steps");
131
+ const verifyStepsHash = verifySteps
132
+ ? sha256Hex(verifySteps.replaceAll("\r\n", "\n").trim())
133
+ : null;
134
+ const docVersion = normalizeTaskDocVersion(task.doc_version);
135
+ const verifyStepsRef = [
136
+ `doc_version=${String(docVersion)}`,
137
+ `doc_updated_at=${String(task.doc_updated_at ?? "missing")}`,
138
+ `excerpt_hash=sha256:${verifyStepsHash ?? "missing"}`,
139
+ ].join(", ");
140
+ const entry = renderVerificationEntry({
105
141
  at,
106
- author: opts.by,
107
142
  state: opts.state,
143
+ by: opts.by,
108
144
  note: opts.note,
109
- }),
110
- verification: {
111
- state: opts.state,
112
- updated_at: at,
113
- updated_by: opts.by,
114
- note: opts.note,
115
- },
116
- };
117
- await (useStore ? store.update(opts.taskId, () => nextTask) : backend.writeTask(nextTask));
145
+ details: opts.details ?? null,
146
+ verifyStepsRef,
147
+ });
148
+ const nextVerification = appendBetweenMarkers(verificationSection, entry, docVersion);
149
+ const nextDoc = ensureDocSections(setMarkdownSection(baseDoc, "Verification", nextVerification), config.tasks.doc.required_sections);
150
+ await backend.writeTask({
151
+ ...task,
152
+ status: opts.state === "needs_rework" ? "DOING" : task.status,
153
+ commit: opts.state === "needs_rework" ? null : (task.commit ?? null),
154
+ doc: nextDoc,
155
+ doc_updated_by: opts.by,
156
+ events: appendTaskEvent(task, {
157
+ type: "verify",
158
+ at,
159
+ author: opts.by,
160
+ state: opts.state,
161
+ note: opts.note,
162
+ }),
163
+ verification: {
164
+ state: opts.state,
165
+ updated_at: at,
166
+ updated_by: opts.by,
167
+ note: opts.note,
168
+ },
169
+ });
170
+ }
118
171
  if (!opts.quiet) {
119
172
  const readmePath = path.join(resolved.gitRoot, config.paths.workflow_dir, task.id, "README.md");
120
- process.stdout.write(`${readmePath}\n`);
173
+ const relReadmePath = path.relative(resolved.gitRoot, readmePath);
174
+ process.stdout.write(`${successMessage("verified", task.id, `state=${opts.state} readme=${relReadmePath}`)}\n`);
121
175
  }
122
176
  }
123
- export async function cmdTaskVerifyOk(opts) {
177
+ async function resolveVerifyRecordInput(opts) {
124
178
  const by = String(opts.by ?? "").trim();
125
179
  const note = String(opts.note ?? "").trim();
126
180
  if (!by || !note) {
@@ -143,19 +197,23 @@ export async function cmdTaskVerifyOk(opts) {
143
197
  details = await readFile(path.resolve(opts.cwd, opts.file), "utf8");
144
198
  }
145
199
  catch (err) {
146
- throw mapCoreError(err, { command: "task verify ok", filePath: opts.file });
200
+ throw mapCoreError(err, { command: opts.command, filePath: opts.file });
147
201
  }
148
202
  }
203
+ return { by, note, details };
204
+ }
205
+ async function executeVerifyRecordCommand(opts) {
206
+ const input = await resolveVerifyRecordInput(opts);
149
207
  try {
150
208
  await recordVerificationResult({
151
209
  ctx: opts.ctx,
152
210
  cwd: opts.cwd,
153
211
  rootOverride: opts.rootOverride,
154
212
  taskId: opts.taskId,
155
- state: "ok",
156
- by,
157
- note,
158
- details,
213
+ state: opts.state,
214
+ by: input.by,
215
+ note: input.note,
216
+ details: input.details,
159
217
  quiet: opts.quiet,
160
218
  });
161
219
  return 0;
@@ -163,98 +221,19 @@ export async function cmdTaskVerifyOk(opts) {
163
221
  catch (err) {
164
222
  if (err instanceof CliError)
165
223
  throw err;
166
- throw mapBackendError(err, { command: "task verify ok", root: opts.rootOverride ?? null });
224
+ throw mapBackendError(err, { command: opts.command, root: opts.rootOverride ?? null });
167
225
  }
168
226
  }
227
+ export async function cmdTaskVerifyOk(opts) {
228
+ return await executeVerifyRecordCommand({ ...opts, state: "ok", command: "task verify ok" });
229
+ }
169
230
  export async function cmdTaskVerifyRework(opts) {
170
- const by = String(opts.by ?? "").trim();
171
- const note = String(opts.note ?? "").trim();
172
- if (!by || !note) {
173
- throw new CliError({
174
- exitCode: 2,
175
- code: "E_USAGE",
176
- message: "Missing required inputs: --by and --note.",
177
- });
178
- }
179
- if (typeof opts.details === "string" && typeof opts.file === "string") {
180
- throw new CliError({
181
- exitCode: 2,
182
- code: "E_USAGE",
183
- message: "Options --details and --file are mutually exclusive.",
184
- });
185
- }
186
- let details = typeof opts.details === "string" ? opts.details : null;
187
- if (typeof opts.file === "string") {
188
- try {
189
- details = await readFile(path.resolve(opts.cwd, opts.file), "utf8");
190
- }
191
- catch (err) {
192
- throw mapCoreError(err, { command: "task verify rework", filePath: opts.file });
193
- }
194
- }
195
- try {
196
- await recordVerificationResult({
197
- ctx: opts.ctx,
198
- cwd: opts.cwd,
199
- rootOverride: opts.rootOverride,
200
- taskId: opts.taskId,
201
- state: "needs_rework",
202
- by,
203
- note,
204
- details,
205
- quiet: opts.quiet,
206
- });
207
- return 0;
208
- }
209
- catch (err) {
210
- if (err instanceof CliError)
211
- throw err;
212
- throw mapBackendError(err, { command: "task verify rework", root: opts.rootOverride ?? null });
213
- }
231
+ return await executeVerifyRecordCommand({
232
+ ...opts,
233
+ state: "needs_rework",
234
+ command: "task verify rework",
235
+ });
214
236
  }
215
237
  export async function cmdVerifyParsed(opts) {
216
- const by = String(opts.by ?? "").trim();
217
- const note = String(opts.note ?? "").trim();
218
- if (!by || !note) {
219
- throw new CliError({
220
- exitCode: 2,
221
- code: "E_USAGE",
222
- message: "Missing required inputs: --by and --note.",
223
- });
224
- }
225
- if (typeof opts.details === "string" && typeof opts.file === "string") {
226
- throw new CliError({
227
- exitCode: 2,
228
- code: "E_USAGE",
229
- message: "Options --details and --file are mutually exclusive.",
230
- });
231
- }
232
- let details = typeof opts.details === "string" ? opts.details : null;
233
- if (typeof opts.file === "string") {
234
- try {
235
- details = await readFile(path.resolve(opts.cwd, opts.file), "utf8");
236
- }
237
- catch (err) {
238
- throw mapCoreError(err, { command: "verify", filePath: opts.file });
239
- }
240
- }
241
- try {
242
- await recordVerificationResult({
243
- ctx: opts.ctx,
244
- cwd: opts.cwd,
245
- rootOverride: opts.rootOverride,
246
- taskId: opts.taskId,
247
- state: opts.state,
248
- by,
249
- note,
250
- details,
251
- quiet: opts.quiet,
252
- });
253
- return 0;
254
- }
255
- catch (err) {
256
- if (err instanceof CliError)
257
- throw err;
258
- throw mapBackendError(err, { command: "verify", root: opts.rootOverride ?? null });
259
- }
238
+ return await executeVerifyRecordCommand({ ...opts, command: "verify" });
260
239
  }
@@ -1,12 +1,8 @@
1
1
  import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
2
2
  import type { CommandContext } from "../shared/task-backend.js";
3
- export type TaskVerifyReworkParsed = {
3
+ import { type VerifyCommonParsed } from "./verify-command-shared.js";
4
+ export type TaskVerifyReworkParsed = VerifyCommonParsed & {
4
5
  taskId: string;
5
- by: string;
6
- note: string;
7
- details?: string;
8
- file?: string;
9
- quiet: boolean;
10
6
  };
11
7
  export declare const taskVerifyReworkSpec: CommandSpec<TaskVerifyReworkParsed>;
12
8
  export declare function makeRunTaskVerifyReworkHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskVerifyReworkParsed) => Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"verify-rework.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-rework.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,sBAAsB,CAkEpE,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC/E,KAAK,UAAU,EAAE,GAAG,sBAAsB,KAAG,OAAO,CAAC,MAAM,CAAC,CAa3E"}
1
+ {"version":3,"file":"verify-rework.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-rework.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,sBAAsB,CAwBpE,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC/E,KAAK,UAAU,EAAE,GAAG,sBAAsB,KAAG,OAAO,CAAC,MAAM,CAAC,CAa3E"}
@@ -1,38 +1,11 @@
1
- import { usageError } from "../../cli/spec/errors.js";
2
1
  import { cmdTaskVerifyRework } from "./verify-record.js";
2
+ import { parseVerifyCommonOptions, validateVerifyDetailsFileExclusive, validateVerifyNonEmptyInput, verifyCommonOptions, } from "./verify-command-shared.js";
3
3
  export const taskVerifyReworkSpec = {
4
4
  id: ["task", "verify", "rework"],
5
5
  group: "Task",
6
6
  summary: "Record verification as needs rework (resets commit, sets status to DOING, updates Verification).",
7
7
  args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
8
- options: [
9
- { kind: "string", name: "by", valueHint: "<id>", required: true, description: "Verifier id." },
10
- {
11
- kind: "string",
12
- name: "note",
13
- valueHint: "<text>",
14
- required: true,
15
- description: "Short verification note.",
16
- },
17
- {
18
- kind: "string",
19
- name: "details",
20
- valueHint: "<text>",
21
- description: "Optional details text (mutually exclusive with --file).",
22
- },
23
- {
24
- kind: "string",
25
- name: "file",
26
- valueHint: "<path>",
27
- description: "Optional details file path (mutually exclusive with --details).",
28
- },
29
- {
30
- kind: "boolean",
31
- name: "quiet",
32
- default: false,
33
- description: "Suppress normal output (still prints errors).",
34
- },
35
- ],
8
+ options: verifyCommonOptions,
36
9
  examples: [
37
10
  {
38
11
  cmd: 'agentplane task verify rework 202602030608-F1Q8AB --by REVIEWER --note "Needs changes"',
@@ -40,30 +13,15 @@ export const taskVerifyReworkSpec = {
40
13
  },
41
14
  ],
42
15
  validateRaw: (raw) => {
43
- const details = raw.opts.details;
44
- const file = raw.opts.file;
45
- if (typeof details === "string" && typeof file === "string") {
46
- throw usageError({
47
- spec: taskVerifyReworkSpec,
48
- message: "Provide at most one of --details or --file.",
49
- });
50
- }
51
- const by = raw.opts.by;
52
- if (typeof by === "string" && by.trim().length === 0) {
53
- throw usageError({ spec: taskVerifyReworkSpec, message: "Invalid value for --by: empty." });
54
- }
55
- const note = raw.opts.note;
56
- if (typeof note === "string" && note.trim().length === 0) {
57
- throw usageError({ spec: taskVerifyReworkSpec, message: "Invalid value for --note: empty." });
58
- }
16
+ validateVerifyDetailsFileExclusive(raw, taskVerifyReworkSpec, {
17
+ message: "Provide at most one of --details or --file.",
18
+ });
19
+ validateVerifyNonEmptyInput(raw, taskVerifyReworkSpec, "by");
20
+ validateVerifyNonEmptyInput(raw, taskVerifyReworkSpec, "note");
59
21
  },
60
22
  parse: (raw) => ({
61
23
  taskId: String(raw.args["task-id"]),
62
- by: String(raw.opts.by),
63
- note: String(raw.opts.note),
64
- details: typeof raw.opts.details === "string" ? raw.opts.details : undefined,
65
- file: typeof raw.opts.file === "string" ? raw.opts.file : undefined,
66
- quiet: raw.opts.quiet === true,
24
+ ...parseVerifyCommonOptions(raw),
67
25
  }),
68
26
  };
69
27
  export function makeRunTaskVerifyReworkHandler(getCtx) {
@@ -1 +1 @@
1
- {"version":3,"file":"verify.spec.d.ts","sourceRoot":"","sources":["../../src/commands/verify.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CA8FhD,CAAC"}
1
+ {"version":3,"file":"verify.spec.d.ts","sourceRoot":"","sources":["../../src/commands/verify.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAoFhD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { usageError } from "../cli/spec/errors.js";
2
+ import { parseVerifyCommonOptions, validateVerifyDetailsFileExclusive, } from "./task/verify-command-shared.js";
2
3
  export const verifySpec = {
3
4
  id: ["verify"],
4
5
  group: "Lifecycle",
@@ -72,13 +73,7 @@ export const verifySpec = {
72
73
  message: "Exactly one of --ok or --rework must be provided.",
73
74
  });
74
75
  }
75
- if (typeof raw.opts.details === "string" && typeof raw.opts.file === "string") {
76
- throw usageError({
77
- spec: verifySpec,
78
- command: "verify",
79
- message: "Options --details and --file are mutually exclusive.",
80
- });
81
- }
76
+ validateVerifyDetailsFileExclusive(raw, verifySpec, { command: "verify" });
82
77
  },
83
78
  parse: (raw) => {
84
79
  const ok = raw.opts.ok === true;
@@ -86,11 +81,7 @@ export const verifySpec = {
86
81
  return {
87
82
  taskId: typeof raw.args["task-id"] === "string" ? raw.args["task-id"] : "",
88
83
  state,
89
- by: raw.opts.by,
90
- note: raw.opts.note,
91
- details: raw.opts.details,
92
- file: raw.opts.file,
93
- quiet: raw.opts.quiet === true,
84
+ ...parseVerifyCommonOptions(raw),
94
85
  };
95
86
  },
96
87
  };
@@ -1 +1 @@
1
- {"version":3,"file":"allowlist.d.ts","sourceRoot":"","sources":["../../../src/policy/rules/allowlist.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CA0C9D"}
1
+ {"version":3,"file":"allowlist.d.ts","sourceRoot":"","sources":["../../../src/policy/rules/allowlist.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAmD9D"}
@@ -1,12 +1,22 @@
1
1
  import { gitPathIsUnderPrefix, normalizeGitPathPrefix } from "../../shared/git-path.js";
2
+ import { taskArtifactPrefixes } from "../../shared/protected-paths.js";
2
3
  import { gitError, okResult } from "../result.js";
3
4
  export function allowlistRule(ctx) {
4
5
  const allowRaw = ctx.allow?.prefixes ?? [];
5
6
  const staged = ctx.git.stagedPaths ?? [];
7
+ const allow = allowRaw.map((p) => normalizeGitPathPrefix(p));
8
+ const taskAllow = ctx.allow?.allowTasks === true
9
+ ? taskArtifactPrefixes({
10
+ tasksPath: ctx.config.paths.tasks_path,
11
+ workflowDir: ctx.config.paths.workflow_dir,
12
+ taskId: ctx.taskId,
13
+ })
14
+ : [];
15
+ const effectiveAllow = [...new Set([...allow, ...taskAllow])];
6
16
  if (staged.length === 0) {
7
17
  return { ok: false, errors: [gitError("No staged files (git index empty)")], warnings: [] };
8
18
  }
9
- if (allowRaw.length === 0) {
19
+ if (effectiveAllow.length === 0) {
10
20
  const message = ctx.action === "guard_commit" || ctx.action === "commit"
11
21
  ? "Provide at least one --allow <path> prefix"
12
22
  : "Provide at least one allowlist prefix";
@@ -16,8 +26,7 @@ export function allowlistRule(ctx) {
16
26
  warnings: [],
17
27
  };
18
28
  }
19
- const allow = allowRaw.map((p) => normalizeGitPathPrefix(p));
20
- if (allow.includes(".")) {
29
+ if (effectiveAllow.includes(".")) {
21
30
  return {
22
31
  ok: false,
23
32
  errors: [
@@ -28,7 +37,7 @@ export function allowlistRule(ctx) {
28
37
  }
29
38
  const errors = [];
30
39
  for (const filePath of staged) {
31
- if (!allow.some((prefix) => gitPathIsUnderPrefix(filePath, prefix))) {
40
+ if (!effectiveAllow.some((prefix) => gitPathIsUnderPrefix(filePath, prefix))) {
32
41
  errors.push(`Staged file is outside allowlist: ${filePath}`);
33
42
  }
34
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"protected-paths.d.ts","sourceRoot":"","sources":["../../../src/policy/rules/protected-paths.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc7E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAgDnE"}
1
+ {"version":3,"file":"protected-paths.d.ts","sourceRoot":"","sources":["../../../src/policy/rules/protected-paths.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc7E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAqDnE"}
@@ -18,7 +18,12 @@ export function protectedPathsRule(ctx) {
18
18
  const allowCI = ctx.allow?.allowCI === true;
19
19
  const errors = [];
20
20
  for (const filePath of staged) {
21
- const kind = protectedPathKindForFile({ filePath, tasksPath });
21
+ const kind = protectedPathKindForFile({
22
+ filePath,
23
+ tasksPath,
24
+ workflowDir: ctx.config.paths.workflow_dir,
25
+ taskId: ctx.taskId,
26
+ });
22
27
  if (!kind)
23
28
  continue;
24
29
  if (kind === "tasks" && !allowTasks) {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-emoji.d.ts","sourceRoot":"","sources":["../../src/shared/agent-emoji.ts"],"names":[],"mappings":"AAmCA,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlB"}
1
+ {"version":3,"file":"agent-emoji.d.ts","sourceRoot":"","sources":["../../src/shared/agent-emoji.ts"],"names":[],"mappings":"AAkCA,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlB"}
@@ -4,9 +4,16 @@ export type ProtectedPathOverride = {
4
4
  cliFlag: string;
5
5
  envVar: string;
6
6
  };
7
+ export declare function taskArtifactPrefixes(opts: {
8
+ tasksPath: string;
9
+ workflowDir?: string;
10
+ taskId?: string;
11
+ }): string[];
7
12
  export declare function getProtectedPathOverride(kind: ProtectedPathKind): ProtectedPathOverride;
8
13
  export declare function protectedPathKindForFile(opts: {
9
14
  filePath: string;
10
15
  tasksPath: string;
16
+ workflowDir?: string;
17
+ taskId?: string;
11
18
  }): ProtectedPathKind | null;
12
19
  //# sourceMappingURL=protected-paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protected-paths.d.ts","sourceRoot":"","sources":["../../src/shared/protected-paths.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/E,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAQF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,GAAG,qBAAqB,CAkBvF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,iBAAiB,GAAG,IAAI,CA8B3B"}
1
+ {"version":3,"file":"protected-paths.d.ts","sourceRoot":"","sources":["../../src/shared/protected-paths.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/E,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAYF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,EAAE,CAOX;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,GAAG,qBAAqB,CAkBvF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,iBAAiB,GAAG,IAAI,CAsC3B"}
@@ -1,9 +1,20 @@
1
- function pathIsUnder(candidate, prefix) {
2
- if (prefix === "." || prefix === "")
3
- return true;
4
- if (candidate === prefix)
5
- return true;
6
- return candidate.startsWith(`${prefix}/`);
1
+ import { gitPathIsUnderPrefix, normalizeGitPathPrefix } from "./git-path.js";
2
+ function taskWorkflowPrefix(workflowDir, taskId) {
3
+ const dir = normalizeGitPathPrefix(workflowDir ?? "");
4
+ const id = (taskId ?? "").trim();
5
+ if (!dir || !id)
6
+ return null;
7
+ return normalizeGitPathPrefix(`${dir}/${id}`);
8
+ }
9
+ export function taskArtifactPrefixes(opts) {
10
+ const out = new Set();
11
+ const tasksPath = normalizeGitPathPrefix(opts.tasksPath);
12
+ if (tasksPath)
13
+ out.add(tasksPath);
14
+ const workflowPrefix = taskWorkflowPrefix(opts.workflowDir, opts.taskId);
15
+ if (workflowPrefix)
16
+ out.add(workflowPrefix);
17
+ return [...out].toSorted((a, b) => a.localeCompare(b));
7
18
  }
8
19
  export function getProtectedPathOverride(kind) {
9
20
  switch (kind) {
@@ -28,24 +39,29 @@ export function protectedPathKindForFile(opts) {
28
39
  const p = opts.filePath;
29
40
  if (!p)
30
41
  return null;
31
- if (p === opts.tasksPath)
42
+ if (taskArtifactPrefixes({
43
+ tasksPath: opts.tasksPath,
44
+ workflowDir: opts.workflowDir,
45
+ taskId: opts.taskId,
46
+ }).some((prefix) => gitPathIsUnderPrefix(p, prefix))) {
32
47
  return "tasks";
48
+ }
33
49
  // "Rules of the game": authoring/agent policies and registry.
34
50
  if (p === "AGENTS.md" ||
35
51
  p === "CLAUDE.md" ||
36
52
  p === "packages/agentplane/assets/AGENTS.md" ||
37
- pathIsUnder(p, ".agentplane/agents")) {
53
+ gitPathIsUnderPrefix(p, ".agentplane/agents")) {
38
54
  return "policy";
39
55
  }
40
56
  // Framework config and task backend config determine enforcement behavior.
41
- if (p === ".agentplane/config.json" || pathIsUnder(p, ".agentplane/backends")) {
57
+ if (p === ".agentplane/config.json" || gitPathIsUnderPrefix(p, ".agentplane/backends")) {
42
58
  return "config";
43
59
  }
44
60
  // Local hook orchestrator is a quality gate for commits.
45
61
  if (p === "lefthook.yml")
46
62
  return "hooks";
47
63
  // CI workflows are "remote hooks" for quality gates.
48
- if (pathIsUnder(p, ".github/workflows") || pathIsUnder(p, ".github/actions")) {
64
+ if (gitPathIsUnderPrefix(p, ".github/workflows") || gitPathIsUnderPrefix(p, ".github/actions")) {
49
65
  return "ci";
50
66
  }
51
67
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"repo-cli-version.d.ts","sourceRoot":"","sources":["../../src/shared/repo-cli-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,MAAM,MAAM,mBAAmB,GAC3B,cAAc,GACd,WAAW,GACX,qBAAqB,GACrB,2BAA2B,CAAC;AAEhC,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAKjF;AAqBD,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,iBAAiB,GACzB,yBAAyB,CAuC3B"}
1
+ {"version":3,"file":"repo-cli-version.d.ts","sourceRoot":"","sources":["../../src/shared/repo-cli-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,MAAM,MAAM,mBAAmB,GAC3B,cAAc,GACd,WAAW,GACX,qBAAqB,GACrB,2BAA2B,CAAC;AAEhC,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAKjF;AA8BD,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,iBAAiB,GACzB,yBAAyB,CAuC3B"}
@@ -9,16 +9,22 @@ export function getRepoExpectedCliVersion(config) {
9
9
  function buildRecovery(runtime, expectedVersion) {
10
10
  switch (runtime.mode) {
11
11
  case "global-installed": {
12
- return `Run: npm i -g agentplane@${expectedVersion}`;
12
+ return `Run: npm i -g agentplane@${expectedVersion}. Then verify: agentplane runtime explain`;
13
13
  }
14
14
  case "global-in-framework":
15
15
  case "global-forced-in-framework": {
16
- return "Run: scripts/reinstall-global-agentplane.sh";
16
+ const prefix = runtime.mode === "global-forced-in-framework"
17
+ ? "Unset AGENTPLANE_USE_GLOBAL_IN_FRAMEWORK=1 if forced global mode is not intentional. "
18
+ : "";
19
+ return (`${prefix}Run: scripts/reinstall-global-agentplane.sh. ` +
20
+ "Fallback: node packages/agentplane/bin/agentplane.js runtime explain. " +
21
+ "Then verify: agentplane runtime explain");
17
22
  }
18
23
  case "repo-local":
19
24
  case "repo-local-handoff": {
20
25
  return (`Sync this framework checkout to agentplane ${expectedVersion} or lower ` +
21
- "framework.cli.expected_version if the repository intentionally targets an older CLI.");
26
+ "framework.cli.expected_version if the repository intentionally targets an older CLI. " +
27
+ "Then verify: agentplane runtime explain");
22
28
  }
23
29
  }
24
30
  }