agentplane 0.3.5 → 0.3.7

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 (256) 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 +251 -821
  8. package/dist/adapters/task-backend/task-backend-adapter.d.ts +2 -2
  9. package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
  10. package/dist/adapters/task-backend/task-backend-adapter.js +2 -2
  11. package/dist/backends/task-backend/local-backend.d.ts +7 -5
  12. package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
  13. package/dist/backends/task-backend/local-backend.js +79 -7
  14. package/dist/backends/task-backend/redmine/env.d.ts +1 -1
  15. package/dist/backends/task-backend/redmine/env.d.ts.map +1 -1
  16. package/dist/backends/task-backend/redmine/env.js +3 -0
  17. package/dist/backends/task-backend/redmine/inspect.d.ts +11 -0
  18. package/dist/backends/task-backend/redmine/inspect.d.ts.map +1 -0
  19. package/dist/backends/task-backend/redmine/inspect.js +75 -0
  20. package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
  21. package/dist/backends/task-backend/redmine/mapping.js +21 -2
  22. package/dist/backends/task-backend/redmine/state.d.ts +17 -0
  23. package/dist/backends/task-backend/redmine/state.d.ts.map +1 -0
  24. package/dist/backends/task-backend/redmine/state.js +95 -0
  25. package/dist/backends/task-backend/redmine-backend.d.ts +10 -16
  26. package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
  27. package/dist/backends/task-backend/redmine-backend.js +205 -15
  28. package/dist/backends/task-backend/shared/constants.d.ts +1 -1
  29. package/dist/backends/task-backend/shared/constants.js +1 -1
  30. package/dist/backends/task-backend/shared/record.d.ts.map +1 -1
  31. package/dist/backends/task-backend/shared/record.js +20 -1
  32. package/dist/backends/task-backend/shared/types.d.ts +42 -4
  33. package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
  34. package/dist/backends/task-backend/shared.d.ts +1 -1
  35. package/dist/backends/task-backend/shared.d.ts.map +1 -1
  36. package/dist/backends/task-backend.d.ts +1 -1
  37. package/dist/backends/task-backend.d.ts.map +1 -1
  38. package/dist/backends/task-backend.test-helpers.d.ts +4 -0
  39. package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
  40. package/dist/backends/task-backend.test-helpers.js +33 -0
  41. package/dist/backends/task-index.d.ts.map +1 -1
  42. package/dist/backends/task-index.js +1 -0
  43. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  44. package/dist/cli/bootstrap-guide.js +1 -0
  45. package/dist/cli/command-guide.d.ts.map +1 -1
  46. package/dist/cli/command-guide.js +3 -2
  47. package/dist/cli/reason-codes.d.ts.map +1 -1
  48. package/dist/cli/reason-codes.js +30 -0
  49. package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
  50. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
  51. package/dist/cli/run-cli/command-catalog/core.js +137 -0
  52. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
  53. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
  54. package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
  55. package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
  56. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
  57. package/dist/cli/run-cli/command-catalog/project.js +80 -0
  58. package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
  59. package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
  60. package/dist/cli/run-cli/command-catalog/shared.js +9 -0
  61. package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
  62. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
  63. package/dist/cli/run-cli/command-catalog/task.js +85 -0
  64. package/dist/cli/run-cli/command-catalog.d.ts +3 -18
  65. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  66. package/dist/cli/run-cli/command-catalog.js +8 -337
  67. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  68. package/dist/cli/run-cli/commands/ide.js +64 -2
  69. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
  70. package/dist/cli/run-cli/commands/init/ui.js +33 -13
  71. package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -1
  72. package/dist/cli/run-cli/commands/init/write-env.js +12 -0
  73. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
  74. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
  75. package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
  76. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
  77. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
  78. package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
  79. package/dist/cli/run-cli.test-helpers.d.ts +3 -0
  80. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  81. package/dist/cli/run-cli.test-helpers.js +140 -6
  82. package/dist/commands/backend/sync.command.d.ts +5 -1
  83. package/dist/commands/backend/sync.command.d.ts.map +1 -1
  84. package/dist/commands/backend/sync.command.js +67 -3
  85. package/dist/commands/backend.d.ts +22 -0
  86. package/dist/commands/backend.d.ts.map +1 -1
  87. package/dist/commands/backend.js +110 -1
  88. package/dist/commands/commit.spec.d.ts.map +1 -1
  89. package/dist/commands/commit.spec.js +31 -7
  90. package/dist/commands/doctor/runtime.d.ts.map +1 -1
  91. package/dist/commands/doctor/runtime.js +3 -6
  92. package/dist/commands/doctor/workspace.d.ts +8 -0
  93. package/dist/commands/doctor/workspace.d.ts.map +1 -1
  94. package/dist/commands/doctor/workspace.js +127 -3
  95. package/dist/commands/guard/commit.command.d.ts.map +1 -1
  96. package/dist/commands/guard/commit.command.js +30 -6
  97. package/dist/commands/guard/impl/allow.d.ts +9 -0
  98. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  99. package/dist/commands/guard/impl/allow.js +26 -10
  100. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  101. package/dist/commands/guard/impl/commands.js +146 -18
  102. package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
  103. package/dist/commands/guard/impl/comment-commit.js +2 -0
  104. package/dist/commands/hooks/index.d.ts.map +1 -1
  105. package/dist/commands/hooks/index.js +8 -35
  106. package/dist/commands/recipes/impl/apply.d.ts +4 -0
  107. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  108. package/dist/commands/recipes/impl/apply.js +34 -0
  109. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  110. package/dist/commands/recipes/impl/commands/explain.js +70 -11
  111. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  112. package/dist/commands/recipes/impl/commands/info.js +24 -12
  113. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  114. package/dist/commands/recipes/impl/commands/install.js +32 -36
  115. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  116. package/dist/commands/recipes/impl/commands/list.js +7 -4
  117. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  118. package/dist/commands/recipes/impl/commands/remove.js +9 -11
  119. package/dist/commands/recipes/impl/constants.d.ts +2 -0
  120. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  121. package/dist/commands/recipes/impl/constants.js +2 -0
  122. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  123. package/dist/commands/recipes/impl/manifest.js +219 -23
  124. package/dist/commands/recipes/impl/normalize.d.ts +3 -0
  125. package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
  126. package/dist/commands/recipes/impl/normalize.js +28 -24
  127. package/dist/commands/recipes/impl/paths.d.ts +9 -0
  128. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  129. package/dist/commands/recipes/impl/paths.js +10 -1
  130. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
  131. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
  132. package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
  133. package/dist/commands/recipes/impl/resolver.d.ts +20 -0
  134. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
  135. package/dist/commands/recipes/impl/resolver.js +220 -0
  136. package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
  137. package/dist/commands/recipes/impl/scenario.js +40 -11
  138. package/dist/commands/recipes/impl/types.d.ts +145 -16
  139. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  140. package/dist/commands/recipes/install.spec.d.ts.map +1 -1
  141. package/dist/commands/recipes/install.spec.js +3 -2
  142. package/dist/commands/recipes.d.ts +6 -4
  143. package/dist/commands/recipes.d.ts.map +1 -1
  144. package/dist/commands/recipes.js +5 -3
  145. package/dist/commands/recipes.test-helpers.d.ts +185 -0
  146. package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
  147. package/dist/commands/recipes.test-helpers.js +339 -0
  148. package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
  149. package/dist/commands/scenario/impl/commands.js +192 -336
  150. package/dist/commands/scenario/info.command.d.ts.map +1 -1
  151. package/dist/commands/scenario/info.command.js +7 -2
  152. package/dist/commands/scenario/list.command.js +2 -2
  153. package/dist/commands/scenario/run.command.d.ts.map +1 -1
  154. package/dist/commands/scenario/run.command.js +7 -2
  155. package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
  156. package/dist/commands/shared/reconcile-check.js +77 -2
  157. package/dist/commands/shared/task-backend.d.ts +1 -1
  158. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  159. package/dist/commands/shared/task-backend.js +9 -0
  160. package/dist/commands/shared/task-store.d.ts +92 -2
  161. package/dist/commands/shared/task-store.d.ts.map +1 -1
  162. package/dist/commands/shared/task-store.js +405 -43
  163. package/dist/commands/task/block.d.ts.map +1 -1
  164. package/dist/commands/task/block.js +84 -46
  165. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  166. package/dist/commands/task/close-duplicate.js +12 -37
  167. package/dist/commands/task/close-noop.d.ts.map +1 -1
  168. package/dist/commands/task/close-noop.js +12 -30
  169. package/dist/commands/task/close-shared.d.ts +14 -0
  170. package/dist/commands/task/close-shared.d.ts.map +1 -0
  171. package/dist/commands/task/close-shared.js +73 -0
  172. package/dist/commands/task/comment.d.ts.map +1 -1
  173. package/dist/commands/task/comment.js +34 -21
  174. package/dist/commands/task/derive.command.d.ts +1 -0
  175. package/dist/commands/task/derive.command.d.ts.map +1 -1
  176. package/dist/commands/task/derive.command.js +15 -2
  177. package/dist/commands/task/derive.d.ts +1 -0
  178. package/dist/commands/task/derive.d.ts.map +1 -1
  179. package/dist/commands/task/derive.js +27 -4
  180. package/dist/commands/task/doc-set.command.d.ts +2 -1
  181. package/dist/commands/task/doc-set.command.d.ts.map +1 -1
  182. package/dist/commands/task/doc-set.command.js +36 -4
  183. package/dist/commands/task/doc-template.d.ts.map +1 -1
  184. package/dist/commands/task/doc-template.js +2 -7
  185. package/dist/commands/task/doc.command.js +1 -1
  186. package/dist/commands/task/doc.d.ts +2 -1
  187. package/dist/commands/task/doc.d.ts.map +1 -1
  188. package/dist/commands/task/doc.js +139 -76
  189. package/dist/commands/task/finish.d.ts.map +1 -1
  190. package/dist/commands/task/finish.js +142 -80
  191. package/dist/commands/task/migrate-doc.d.ts +15 -0
  192. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  193. package/dist/commands/task/migrate-doc.js +128 -43
  194. package/dist/commands/task/new.d.ts.map +1 -1
  195. package/dist/commands/task/new.js +3 -1
  196. package/dist/commands/task/plan-set.command.js +1 -1
  197. package/dist/commands/task/plan.command.d.ts +8 -0
  198. package/dist/commands/task/plan.command.d.ts.map +1 -0
  199. package/dist/commands/task/plan.command.js +37 -0
  200. package/dist/commands/task/plan.d.ts.map +1 -1
  201. package/dist/commands/task/plan.js +198 -101
  202. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  203. package/dist/commands/task/set-status.command.js +1 -1
  204. package/dist/commands/task/set-status.d.ts.map +1 -1
  205. package/dist/commands/task/set-status.js +115 -35
  206. package/dist/commands/task/shared/dependencies.d.ts +1 -0
  207. package/dist/commands/task/shared/dependencies.d.ts.map +1 -1
  208. package/dist/commands/task/shared/dependencies.js +10 -0
  209. package/dist/commands/task/shared/docs.d.ts +1 -0
  210. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  211. package/dist/commands/task/shared/docs.js +8 -1
  212. package/dist/commands/task/shared/transitions.d.ts +17 -2
  213. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  214. package/dist/commands/task/shared/transitions.js +20 -13
  215. package/dist/commands/task/shared.d.ts +3 -3
  216. package/dist/commands/task/shared.d.ts.map +1 -1
  217. package/dist/commands/task/shared.js +3 -3
  218. package/dist/commands/task/start.d.ts.map +1 -1
  219. package/dist/commands/task/start.js +101 -71
  220. package/dist/commands/task/task.command.d.ts +8 -0
  221. package/dist/commands/task/task.command.d.ts.map +1 -0
  222. package/dist/commands/task/task.command.js +71 -0
  223. package/dist/commands/task/verify-command-shared.d.ts +16 -0
  224. package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
  225. package/dist/commands/task/verify-command-shared.js +53 -0
  226. package/dist/commands/task/verify-ok.command.d.ts +2 -6
  227. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  228. package/dist/commands/task/verify-ok.command.js +8 -50
  229. package/dist/commands/task/verify-record.d.ts.map +1 -1
  230. package/dist/commands/task/verify-record.js +124 -145
  231. package/dist/commands/task/verify-rework.command.d.ts +2 -6
  232. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  233. package/dist/commands/task/verify-rework.command.js +8 -50
  234. package/dist/commands/upgrade/apply.d.ts +2 -0
  235. package/dist/commands/upgrade/apply.d.ts.map +1 -1
  236. package/dist/commands/upgrade/apply.js +33 -1
  237. package/dist/commands/upgrade.command.d.ts.map +1 -1
  238. package/dist/commands/upgrade.command.js +25 -0
  239. package/dist/commands/upgrade.d.ts +1 -0
  240. package/dist/commands/upgrade.d.ts.map +1 -1
  241. package/dist/commands/upgrade.js +34 -0
  242. package/dist/commands/verify.spec.d.ts.map +1 -1
  243. package/dist/commands/verify.spec.js +3 -12
  244. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  245. package/dist/policy/rules/allowlist.js +16 -4
  246. package/dist/policy/rules/protected-paths.d.ts.map +1 -1
  247. package/dist/policy/rules/protected-paths.js +6 -1
  248. package/dist/ports/task-backend-port.d.ts +2 -2
  249. package/dist/ports/task-backend-port.d.ts.map +1 -1
  250. package/dist/shared/agent-emoji.d.ts.map +1 -1
  251. package/dist/shared/protected-paths.d.ts +17 -0
  252. package/dist/shared/protected-paths.d.ts.map +1 -1
  253. package/dist/shared/protected-paths.js +59 -10
  254. package/dist/shared/repo-cli-version.d.ts.map +1 -1
  255. package/dist/shared/repo-cli-version.js +9 -3
  256. package/package.json +2 -2
@@ -1,16 +1,149 @@
1
1
  import { execFile } from "node:child_process";
2
- import { mkdir, readdir } from "node:fs/promises";
3
2
  import path from "node:path";
4
3
  import { promisify } from "node:util";
5
- import { atomicWriteFile, resolveProject } from "@agentplaneorg/core";
4
+ import { resolveProject } from "@agentplaneorg/core";
6
5
  import { mapCoreError } from "../../../cli/error-map.js";
7
6
  import { exitCodeForError } from "../../../cli/exit-codes.js";
8
- import { fileExists, getPathKind } from "../../../cli/fs-utils.js";
7
+ import { fileExists } from "../../../cli/fs-utils.js";
9
8
  import { emptyStateMessage } from "../../../cli/output.js";
10
9
  import { CliError } from "../../../shared/errors.js";
11
- import { RECIPES_DIR_NAME, RECIPES_SCENARIOS_DIR_NAME, RECIPES_SCENARIOS_INDEX_NAME, normalizeScenarioToolStep, readInstalledRecipesFile, readRecipeManifest, readScenarioDefinition, readScenarioIndex, resolveInstalledRecipeDir, resolveInstalledRecipesPath, resolveProjectRecipesCacheDir, } from "../../recipes.js";
12
- import { collectScenarioEnvKeys, getGitDiffSummary, redactArgs, writeScenarioReport, } from "./report.js";
10
+ import { formatJsonBlock } from "../../recipes/impl/format.js";
11
+ import { listResolvedRecipeScenarios, readProjectInstalledRecipes, readScenarioDefinition, resolveRecipeScenarioSelection, } from "../../recipes.js";
13
12
  const execFileAsync = promisify(execFile);
13
+ function printJsonSection(label, value) {
14
+ const payload = formatJsonBlock(value, " ");
15
+ if (!payload)
16
+ return;
17
+ process.stdout.write(`${label}:\n${payload}\n`);
18
+ }
19
+ function buildScenarioNotFoundError(recipeId, scenarioId) {
20
+ return new CliError({
21
+ exitCode: exitCodeForError("E_IO"),
22
+ code: "E_IO",
23
+ message: `Scenario not found: ${recipeId}:${scenarioId}`,
24
+ });
25
+ }
26
+ async function resolveScenarioForCli(opts) {
27
+ const installed = await readProjectInstalledRecipes(opts.project);
28
+ const entry = installed.recipes.find((recipe) => recipe.id === opts.recipeId);
29
+ if (!entry) {
30
+ throw new CliError({
31
+ exitCode: exitCodeForError("E_IO"),
32
+ code: "E_IO",
33
+ message: `Recipe not installed: ${opts.recipeId}`,
34
+ });
35
+ }
36
+ try {
37
+ const selection = await resolveRecipeScenarioSelection({
38
+ project: opts.project,
39
+ flags: {
40
+ recipeId: opts.recipeId,
41
+ scenarioId: opts.scenarioId,
42
+ includeIncompatible: true,
43
+ },
44
+ });
45
+ return { entry, selection };
46
+ }
47
+ catch (error) {
48
+ const message = error instanceof Error ? error.message : String(error);
49
+ if (message.startsWith("No recipe scenario matches")) {
50
+ throw buildScenarioNotFoundError(opts.recipeId, opts.scenarioId);
51
+ }
52
+ if (message.startsWith("Scenario selection is ambiguous")) {
53
+ throw new CliError({
54
+ exitCode: exitCodeForError("E_VALIDATION"),
55
+ code: "E_VALIDATION",
56
+ message,
57
+ });
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ async function readValidatedScenarioDefinition(opts) {
63
+ if (!(await fileExists(opts.selection.scenario_file))) {
64
+ throw new CliError({
65
+ exitCode: exitCodeForError("E_IO"),
66
+ code: "E_IO",
67
+ message: `Scenario definition not found: ${opts.selection.scenario_file}`,
68
+ });
69
+ }
70
+ try {
71
+ const scenario = await readScenarioDefinition(opts.selection.scenario_file);
72
+ if (scenario.id !== opts.selection.scenario_id) {
73
+ throw new CliError({
74
+ exitCode: exitCodeForError("E_VALIDATION"),
75
+ code: "E_VALIDATION",
76
+ message: `Scenario definition id mismatch: manifest expects ${opts.selection.scenario_id}, ` +
77
+ `file defines ${scenario.id}`,
78
+ });
79
+ }
80
+ return scenario;
81
+ }
82
+ catch (error) {
83
+ if (error instanceof CliError)
84
+ throw error;
85
+ throw new CliError({
86
+ exitCode: exitCodeForError("E_VALIDATION"),
87
+ code: "E_VALIDATION",
88
+ message: error instanceof Error ? error.message : String(error),
89
+ });
90
+ }
91
+ }
92
+ async function validateScenarioRecipeFiles(opts) {
93
+ const checks = [];
94
+ const agents = opts.entry.manifest.agents ?? [];
95
+ const skills = opts.entry.manifest.skills ?? [];
96
+ const tools = opts.entry.manifest.tools ?? [];
97
+ const selectedAgents = agents.filter((agent) => opts.selection.run_profile.agents_involved.includes(agent.id));
98
+ const selectedSkills = skills.filter((skill) => opts.selection.run_profile.skills_used.includes(skill.id));
99
+ const selectedTools = tools.filter((tool) => opts.selection.run_profile.tools_used.includes(tool.id));
100
+ for (const agent of selectedAgents) {
101
+ const agentFile = path.join(opts.selection.recipe_dir, agent.file);
102
+ if (!(await fileExists(agentFile))) {
103
+ throw new CliError({
104
+ exitCode: exitCodeForError("E_IO"),
105
+ code: "E_IO",
106
+ message: `Recipe agent file not found: ${agent.file}`,
107
+ });
108
+ }
109
+ }
110
+ checks.push(`agent files ok: ${selectedAgents.length}`);
111
+ for (const skill of selectedSkills) {
112
+ const skillFile = path.join(opts.selection.recipe_dir, skill.file);
113
+ if (!(await fileExists(skillFile))) {
114
+ throw new CliError({
115
+ exitCode: exitCodeForError("E_IO"),
116
+ code: "E_IO",
117
+ message: `Recipe skill file not found: ${skill.file}`,
118
+ });
119
+ }
120
+ }
121
+ checks.push(`skill files ok: ${selectedSkills.length}`);
122
+ for (const tool of selectedTools) {
123
+ const toolEntrypoint = path.join(opts.selection.recipe_dir, tool.entrypoint);
124
+ if (!(await fileExists(toolEntrypoint))) {
125
+ throw new CliError({
126
+ exitCode: exitCodeForError("E_IO"),
127
+ code: "E_IO",
128
+ message: `Tool entrypoint not found: ${tool.entrypoint}`,
129
+ });
130
+ }
131
+ }
132
+ checks.push(`tool entrypoints ok: ${selectedTools.length}`);
133
+ return checks;
134
+ }
135
+ function assertScenarioCompatibility(selection) {
136
+ if (selection.compatibility.ok)
137
+ return;
138
+ const reasons = selection.compatibility.failures
139
+ .map((failure) => `- ${failure.reason}`)
140
+ .join("\n");
141
+ throw new CliError({
142
+ exitCode: exitCodeForError("E_VALIDATION"),
143
+ code: "E_VALIDATION",
144
+ message: `Scenario is not compatible with the current runtime:\n${reasons}`,
145
+ });
146
+ }
14
147
  export function resolveRecipeToolInvocation(runtime, entrypoint, args) {
15
148
  if (runtime === "node") {
16
149
  return { command: "node", args: [entrypoint, ...args] };
@@ -22,44 +155,22 @@ export function resolveRecipeToolInvocation(runtime, entrypoint, args) {
22
155
  }
23
156
  export async function cmdScenarioListParsed(opts) {
24
157
  try {
25
- const installed = await readInstalledRecipesFile(resolveInstalledRecipesPath());
26
- const entries = [];
27
- for (const recipe of installed.recipes) {
28
- const recipeDir = resolveInstalledRecipeDir(recipe);
29
- const scenariosDir = path.join(recipeDir, RECIPES_SCENARIOS_DIR_NAME);
30
- if ((await getPathKind(scenariosDir)) === "dir") {
31
- const files = await readdir(scenariosDir);
32
- const jsonFiles = files.filter((entry) => entry.toLowerCase().endsWith(".json")).toSorted();
33
- for (const file of jsonFiles) {
34
- const scenario = await readScenarioDefinition(path.join(scenariosDir, file));
35
- entries.push({ recipeId: recipe.id, scenarioId: scenario.id, summary: scenario.summary });
36
- }
37
- continue;
38
- }
39
- const scenariosIndexPath = path.join(recipeDir, RECIPES_SCENARIOS_INDEX_NAME);
40
- if (await fileExists(scenariosIndexPath)) {
41
- const index = await readScenarioIndex(scenariosIndexPath);
42
- for (const scenario of index.scenarios) {
43
- entries.push({
44
- recipeId: recipe.id,
45
- scenarioId: scenario.id,
46
- summary: scenario.summary,
47
- });
48
- }
49
- }
50
- }
158
+ const project = await resolveProject({
159
+ cwd: opts.cwd,
160
+ rootOverride: opts.rootOverride ?? null,
161
+ });
162
+ const entries = await listResolvedRecipeScenarios({
163
+ project,
164
+ includeIncompatible: true,
165
+ });
51
166
  if (entries.length === 0) {
52
167
  process.stdout.write(`${emptyStateMessage("scenarios", "Install a recipe to add scenarios.")}\n`);
53
168
  return 0;
54
169
  }
55
- const sorted = entries.toSorted((a, b) => {
56
- const byRecipe = a.recipeId.localeCompare(b.recipeId);
57
- if (byRecipe !== 0)
58
- return byRecipe;
59
- return a.scenarioId.localeCompare(b.scenarioId);
60
- });
61
- for (const entry of sorted) {
62
- process.stdout.write(`${entry.recipeId}:${entry.scenarioId} - ${entry.summary ?? "No summary"}\n`);
170
+ for (const entry of entries) {
171
+ const compatibilityLabel = entry.compatibility.ok ? "compatible" : "incompatible";
172
+ process.stdout.write(`${entry.recipe_id}:${entry.scenario_id} - ${entry.scenario_summary} ` +
173
+ `[mode=${entry.run_profile.mode}] [${compatibilityLabel}]\n`);
63
174
  }
64
175
  return 0;
65
176
  }
@@ -70,72 +181,33 @@ export async function cmdScenarioListParsed(opts) {
70
181
  }
71
182
  }
72
183
  export async function cmdScenarioInfoParsed(opts) {
73
- const { recipeId, scenarioId } = opts;
74
184
  try {
75
- const installed = await readInstalledRecipesFile(resolveInstalledRecipesPath());
76
- const entry = installed.recipes.find((recipe) => recipe.id === recipeId);
77
- if (!entry) {
78
- throw new CliError({
79
- exitCode: exitCodeForError("E_IO"),
80
- code: "E_IO",
81
- message: `Recipe not installed: ${recipeId}`,
82
- });
83
- }
84
- const recipeDir = resolveInstalledRecipeDir(entry);
85
- const scenariosDir = path.join(recipeDir, RECIPES_SCENARIOS_DIR_NAME);
86
- let scenario = null;
87
- if ((await getPathKind(scenariosDir)) === "dir") {
88
- const files = await readdir(scenariosDir);
89
- const jsonFiles = files.filter((file) => file.toLowerCase().endsWith(".json")).toSorted();
90
- for (const file of jsonFiles) {
91
- const candidate = await readScenarioDefinition(path.join(scenariosDir, file));
92
- if (candidate.id === scenarioId) {
93
- scenario = candidate;
94
- break;
95
- }
96
- }
97
- }
98
- let summary;
99
- if (!scenario) {
100
- const scenariosIndexPath = path.join(recipeDir, RECIPES_SCENARIOS_INDEX_NAME);
101
- if (await fileExists(scenariosIndexPath)) {
102
- const index = await readScenarioIndex(scenariosIndexPath);
103
- const entrySummary = index.scenarios.find((item) => item.id === scenarioId);
104
- summary = entrySummary?.summary;
105
- }
106
- }
107
- if (!scenario && !summary) {
108
- throw new CliError({
109
- exitCode: exitCodeForError("E_IO"),
110
- code: "E_IO",
111
- message: `Scenario not found: ${recipeId}:${scenarioId}`,
112
- });
113
- }
114
- process.stdout.write(`Scenario: ${recipeId}:${scenarioId}\n`);
115
- if (summary)
116
- process.stdout.write(`Summary: ${summary}\n`);
117
- if (!scenario) {
118
- process.stdout.write("Details: Scenario definition not found in recipe.\n");
119
- return 0;
185
+ const project = await resolveProject({
186
+ cwd: opts.cwd,
187
+ rootOverride: opts.rootOverride ?? null,
188
+ });
189
+ const { selection } = await resolveScenarioForCli({
190
+ project,
191
+ recipeId: opts.recipeId,
192
+ scenarioId: opts.scenarioId,
193
+ });
194
+ process.stdout.write(`Scenario: ${selection.recipe_id}:${selection.scenario_id}\n`);
195
+ process.stdout.write(`Recipe: ${selection.recipe_name} (${selection.recipe_id}@${selection.recipe_version})\n`);
196
+ process.stdout.write(`Summary: ${selection.scenario_summary}\n`);
197
+ if (selection.scenario_description) {
198
+ process.stdout.write(`Description: ${selection.scenario_description}\n`);
120
199
  }
121
- if (scenario.summary)
122
- process.stdout.write(`Summary: ${scenario.summary}\n`);
123
- if (scenario.description)
124
- process.stdout.write(`Description: ${scenario.description}\n`);
125
- process.stdout.write(`Goal: ${scenario.goal}\n`);
126
- process.stdout.write(`Inputs: ${JSON.stringify(scenario.inputs, null, 2)}\n`);
127
- process.stdout.write(`Outputs: ${JSON.stringify(scenario.outputs, null, 2)}\n`);
128
- if (scenario.evidence?.required) {
129
- process.stdout.write(`Evidence: required (${normalizeExpectedEvidenceFiles(scenario.evidence.files).join(", ")})\n`);
200
+ printJsonSection("Use when", selection.use_when);
201
+ if (selection.avoid_when.length > 0) {
202
+ printJsonSection("Avoid when", selection.avoid_when);
130
203
  }
131
- else if (scenario.evidence?.files && scenario.evidence.files.length > 0) {
132
- process.stdout.write(`Evidence: optional (${scenario.evidence.files.join(", ")})\n`);
204
+ printJsonSection("Run profile", selection.run_profile);
205
+ process.stdout.write(`Scenario file: ${path.relative(project.gitRoot, selection.scenario_file)}\n`);
206
+ if (selection.compatibility.ok) {
207
+ process.stdout.write("Compatibility: satisfied\n");
133
208
  }
134
- process.stdout.write("Steps:\n");
135
- let stepIndex = 1;
136
- for (const step of scenario.steps) {
137
- process.stdout.write(` ${stepIndex}. ${JSON.stringify(step)}\n`);
138
- stepIndex += 1;
209
+ else {
210
+ printJsonSection("Compatibility failures", selection.compatibility.failures);
139
211
  }
140
212
  return 0;
141
213
  }
@@ -188,248 +260,32 @@ export async function executeRecipeTool(opts) {
188
260
  };
189
261
  }
190
262
  }
191
- function sanitizeRunId(value) {
192
- return value.replaceAll(/[^a-zA-Z0-9._-]/g, "_");
193
- }
194
- function normalizeExpectedEvidenceFiles(raw) {
195
- if (!raw || raw.length === 0)
196
- return ["evidence.json"];
197
- const unique = [];
198
- for (const value of raw) {
199
- const file = value.trim();
200
- if (!file)
201
- continue;
202
- if (unique.includes(file))
203
- continue;
204
- unique.push(file);
205
- }
206
- return unique.length > 0 ? unique : ["evidence.json"];
207
- }
208
- async function collectStepEvidenceFiles(stepDir, expectedFiles) {
209
- const present = [];
210
- const missing = [];
211
- for (const file of expectedFiles) {
212
- if (await fileExists(path.join(stepDir, file))) {
213
- present.push(file);
214
- }
215
- else {
216
- missing.push(file);
217
- }
218
- }
219
- return { present, missing };
220
- }
221
263
  export async function cmdScenarioRunParsed(opts) {
222
- const resolved = opts.resolved ??
264
+ const project = opts.resolved ??
223
265
  (await resolveProject({
224
266
  cwd: opts.cwd,
225
267
  rootOverride: opts.rootOverride ?? null,
226
268
  }));
227
- const { recipeId, scenarioId } = opts;
228
269
  try {
229
- const installed = await readInstalledRecipesFile(resolveInstalledRecipesPath());
230
- const entry = installed.recipes.find((recipe) => recipe.id === recipeId);
231
- if (!entry) {
232
- throw new CliError({
233
- exitCode: exitCodeForError("E_IO"),
234
- code: "E_IO",
235
- message: `Recipe not installed: ${recipeId}`,
236
- });
237
- }
238
- const recipeDir = resolveInstalledRecipeDir(entry);
239
- const manifestPath = path.join(recipeDir, "manifest.json");
240
- const manifest = await readRecipeManifest(manifestPath);
241
- const scenariosDir = path.join(recipeDir, RECIPES_SCENARIOS_DIR_NAME);
242
- if ((await getPathKind(scenariosDir)) !== "dir") {
243
- throw new CliError({
244
- exitCode: exitCodeForError("E_IO"),
245
- code: "E_IO",
246
- message: `Scenario definitions not found for recipe: ${recipeId}`,
247
- });
248
- }
249
- let scenario = null;
250
- const files = await readdir(scenariosDir);
251
- const jsonFiles = files.filter((file) => file.toLowerCase().endsWith(".json")).toSorted();
252
- for (const file of jsonFiles) {
253
- const candidate = await readScenarioDefinition(path.join(scenariosDir, file));
254
- if (candidate.id === scenarioId) {
255
- scenario = candidate;
256
- break;
257
- }
258
- }
259
- if (!scenario) {
260
- throw new CliError({
261
- exitCode: exitCodeForError("E_IO"),
262
- code: "E_IO",
263
- message: `Scenario not found: ${recipeId}:${scenarioId}`,
264
- });
265
- }
266
- const runsRoot = path.join(resolved.agentplaneDir, RECIPES_DIR_NAME, recipeId, "runs");
267
- await mkdir(runsRoot, { recursive: true });
268
- const recipesCacheDir = resolveProjectRecipesCacheDir(resolved);
269
- await mkdir(recipesCacheDir, { recursive: true });
270
- const runStartedAt = new Date().toISOString();
271
- const runId = `${new Date()
272
- .toISOString()
273
- .replaceAll(":", "-")
274
- .replaceAll(".", "-")}-${sanitizeRunId(scenarioId)}`;
275
- const runDir = path.join(runsRoot, runId);
276
- await mkdir(runDir, { recursive: true });
277
- const evidenceRequired = scenario.evidence?.required === true;
278
- const expectedEvidenceFiles = evidenceRequired
279
- ? normalizeExpectedEvidenceFiles(scenario.evidence?.files)
280
- : normalizeExpectedEvidenceFiles(scenario.evidence?.files && scenario.evidence.files.length > 0
281
- ? scenario.evidence.files
282
- : undefined);
283
- const missingEvidenceSteps = [];
284
- const stepsMeta = [];
285
- const stepsReport = [];
286
- for (let index = 0; index < scenario.steps.length; index++) {
287
- const step = normalizeScenarioToolStep(scenario.steps[index], `${recipeId}:${scenarioId}`);
288
- const toolEntry = manifest.tools?.find((tool) => tool?.id === step.tool);
289
- if (!toolEntry) {
290
- throw new CliError({
291
- exitCode: exitCodeForError("E_IO"),
292
- code: "E_IO",
293
- message: `Tool not found in recipe manifest: ${step.tool}`,
294
- });
295
- }
296
- const runtime = toolEntry.runtime === "node" || toolEntry.runtime === "bash"
297
- ? toolEntry.runtime
298
- : "";
299
- const entrypoint = typeof toolEntry.entrypoint === "string" ? toolEntry.entrypoint : "";
300
- if (!runtime || !entrypoint) {
301
- throw new CliError({
302
- exitCode: 3,
303
- code: "E_VALIDATION",
304
- message: `Tool entry is missing runtime/entrypoint: ${step.tool}`,
305
- });
306
- }
307
- if (Array.isArray(toolEntry.permissions) && toolEntry.permissions.length > 0) {
308
- process.stdout.write(`Warning: tool ${toolEntry.id} declares permissions: ${toolEntry.permissions.join(", ")}\n`);
309
- }
310
- const entrypointPath = path.join(recipeDir, entrypoint);
311
- if (!(await fileExists(entrypointPath))) {
312
- throw new CliError({
313
- exitCode: exitCodeForError("E_IO"),
314
- code: "E_IO",
315
- message: `Tool entrypoint not found: ${entrypoint}`,
316
- });
317
- }
318
- const stepDir = path.join(runDir, `step-${index + 1}-${sanitizeRunId(step.tool)}`);
319
- await mkdir(stepDir, { recursive: true });
320
- const stepEnvKeys = collectScenarioEnvKeys(step.env);
321
- const env = {
322
- ...process.env,
323
- ...step.env,
324
- AGENTPLANE_RUN_DIR: runDir,
325
- AGENTPLANE_STEP_DIR: stepDir,
326
- AGENTPLANE_RECIPES_CACHE_DIR: recipesCacheDir,
327
- AGENTPLANE_RECIPE_ID: recipeId,
328
- AGENTPLANE_SCENARIO_ID: scenarioId,
329
- AGENTPLANE_TOOL_ID: step.tool,
330
- };
331
- const startedAt = Date.now();
332
- const result = await executeRecipeTool({
333
- runtime,
334
- entrypoint: entrypointPath,
335
- args: step.args,
336
- cwd: recipeDir,
337
- env,
338
- });
339
- const durationMs = Date.now() - startedAt;
340
- await atomicWriteFile(path.join(stepDir, "stdout.log"), result.stdout, "utf8");
341
- await atomicWriteFile(path.join(stepDir, "stderr.log"), result.stderr, "utf8");
342
- const stepEvidence = await collectStepEvidenceFiles(stepDir, expectedEvidenceFiles);
343
- const missingRequiredEvidence = evidenceRequired ? stepEvidence.missing : [];
344
- if (missingRequiredEvidence.length > 0) {
345
- missingEvidenceSteps.push(index + 1);
346
- }
347
- stepsMeta.push({
348
- tool: step.tool,
349
- runtime,
350
- entrypoint,
351
- exitCode: result.exitCode,
352
- duration_ms: durationMs,
353
- });
354
- stepsReport.push({
355
- step: index + 1,
356
- tool: step.tool,
357
- runtime,
358
- entrypoint,
359
- args: redactArgs(step.args),
360
- env_keys: stepEnvKeys,
361
- evidence_files: stepEvidence.present,
362
- missing_evidence_files: missingRequiredEvidence.length > 0 ? missingRequiredEvidence : undefined,
363
- exit_code: result.exitCode,
364
- duration_ms: durationMs,
365
- });
366
- if (result.exitCode !== 0 || missingRequiredEvidence.length > 0) {
367
- const gitSummary = await getGitDiffSummary(resolved.gitRoot);
368
- await writeScenarioReport({
369
- runDir,
370
- recipeId,
371
- scenarioId,
372
- runId,
373
- startedAt: runStartedAt,
374
- status: "failed",
375
- steps: stepsReport,
376
- evidence: {
377
- required: evidenceRequired,
378
- expected_files: expectedEvidenceFiles,
379
- missing_steps: missingEvidenceSteps,
380
- },
381
- gitSummary,
382
- });
383
- await atomicWriteFile(path.join(runDir, "meta.json"), `${JSON.stringify({
384
- recipe: recipeId,
385
- scenario: scenarioId,
386
- run_id: runId,
387
- evidence: {
388
- required: evidenceRequired,
389
- expected_files: expectedEvidenceFiles,
390
- missing_steps: missingEvidenceSteps,
391
- },
392
- steps: stepsMeta,
393
- }, null, 2)}\n`, "utf8");
394
- const reason = missingRequiredEvidence.length > 0
395
- ? `Scenario step missing required evidence: ${step.tool} (${missingRequiredEvidence.join(", ")})`
396
- : `Scenario step failed: ${step.tool}`;
397
- const stepExitCode = result.exitCode === 0 ? 1 : result.exitCode;
398
- throw new CliError({
399
- exitCode: stepExitCode,
400
- code: "E_INTERNAL",
401
- message: reason,
402
- });
403
- }
404
- }
405
- const gitSummary = await getGitDiffSummary(resolved.gitRoot);
406
- await writeScenarioReport({
407
- runDir,
408
- recipeId,
409
- scenarioId,
410
- runId,
411
- startedAt: runStartedAt,
412
- status: "success",
413
- steps: stepsReport,
414
- evidence: {
415
- required: evidenceRequired,
416
- expected_files: expectedEvidenceFiles,
417
- missing_steps: missingEvidenceSteps,
418
- },
419
- gitSummary,
270
+ const { entry, selection } = await resolveScenarioForCli({
271
+ project,
272
+ recipeId: opts.recipeId,
273
+ scenarioId: opts.scenarioId,
420
274
  });
421
- await atomicWriteFile(path.join(runDir, "meta.json"), `${JSON.stringify({
422
- recipe: recipeId,
423
- scenario: scenarioId,
424
- run_id: runId,
425
- evidence: {
426
- required: evidenceRequired,
427
- expected_files: expectedEvidenceFiles,
428
- missing_steps: missingEvidenceSteps,
429
- },
430
- steps: stepsMeta,
431
- }, null, 2)}\n`, "utf8");
432
- process.stdout.write(`Run artifacts: ${path.relative(resolved.gitRoot, runDir)}\n`);
275
+ assertScenarioCompatibility(selection);
276
+ const scenarioDefinition = await readValidatedScenarioDefinition({ selection });
277
+ const validationChecks = await validateScenarioRecipeFiles({ entry, selection });
278
+ process.stdout.write(`Prepared run plan: ${selection.recipe_id}:${selection.scenario_id}\n`);
279
+ process.stdout.write(`Recipe: ${selection.recipe_name} (${selection.recipe_id}@${selection.recipe_version})\n`);
280
+ process.stdout.write(`Goal: ${scenarioDefinition.goal}\n`);
281
+ process.stdout.write(`Scenario file: ${path.relative(project.gitRoot, selection.scenario_file)}\n`);
282
+ printJsonSection("Run profile", selection.run_profile);
283
+ printJsonSection("Selection reasons", selection.selection_reasons);
284
+ printJsonSection("Validation", [
285
+ `scenario definition ok: ${path.relative(project.gitRoot, selection.scenario_file)}`,
286
+ ...validationChecks,
287
+ ]);
288
+ process.stdout.write("Status: scenario orchestration runtime is not implemented yet.\n");
433
289
  return 0;
434
290
  }
435
291
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"info.command.d.ts","sourceRoot":"","sources":["../../../src/commands/scenario/info.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAkB5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAM3D,CAAC"}
1
+ {"version":3,"file":"info.command.d.ts","sourceRoot":"","sources":["../../../src/commands/scenario/info.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAuB5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAM3D,CAAC"}
@@ -3,9 +3,14 @@ import { cmdScenarioInfoParsed } from "../scenario.js";
3
3
  export const scenarioInfoSpec = {
4
4
  id: ["scenario", "info"],
5
5
  group: "Scenario",
6
- summary: "Show scenario details (goal/inputs/outputs/steps).",
6
+ summary: "Show manifest-backed scenario details and normalized run profile.",
7
7
  args: [{ name: "id", required: true, valueHint: "<recipe:scenario>" }],
8
- examples: [{ cmd: "agentplane scenario info viewer:demo", why: "Show scenario details." }],
8
+ examples: [
9
+ {
10
+ cmd: "agentplane scenario info viewer:demo",
11
+ why: "Inspect resolver-backed scenario metadata before execution.",
12
+ },
13
+ ],
9
14
  parse: (raw) => {
10
15
  const id = String(raw.args.id ?? "");
11
16
  const [recipeId, scenarioId] = id.split(":", 2);
@@ -2,8 +2,8 @@ import { cmdScenarioListParsed } from "../scenario.js";
2
2
  export const scenarioListSpec = {
3
3
  id: ["scenario", "list"],
4
4
  group: "Scenario",
5
- summary: "List scenarios available from installed recipes.",
5
+ summary: "List resolver-backed scenario descriptors from installed recipes.",
6
6
  parse: () => ({}),
7
- examples: [{ cmd: "agentplane scenario list", why: "List scenarios." }],
7
+ examples: [{ cmd: "agentplane scenario list", why: "List available recipe scenarios." }],
8
8
  };
9
9
  export const runScenarioList = (ctx) => cmdScenarioListParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride });
@@ -1 +1 @@
1
- {"version":3,"file":"run.command.d.ts","sourceRoot":"","sources":["../../../src/commands/scenario/run.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAkB1D,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,iBAAiB,CAMzD,CAAC"}
1
+ {"version":3,"file":"run.command.d.ts","sourceRoot":"","sources":["../../../src/commands/scenario/run.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAuB1D,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,iBAAiB,CAMzD,CAAC"}
@@ -3,9 +3,14 @@ import { cmdScenarioRunParsed } from "../scenario.js";
3
3
  export const scenarioRunSpec = {
4
4
  id: ["scenario", "run"],
5
5
  group: "Scenario",
6
- summary: "Run a scenario toolchain from an installed recipe.",
6
+ summary: "Validate a scenario and print a prepared run plan (no execution).",
7
7
  args: [{ name: "id", required: true, valueHint: "<recipe:scenario>" }],
8
- examples: [{ cmd: "agentplane scenario run viewer:demo", why: "Run a scenario." }],
8
+ examples: [
9
+ {
10
+ cmd: "agentplane scenario run viewer:demo",
11
+ why: "Validate a scenario and inspect the prepared run plan.",
12
+ },
13
+ ],
9
14
  parse: (raw) => {
10
15
  const id = String(raw.args.id ?? "");
11
16
  const [recipeId, scenarioId] = id.split(":", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-check.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/reconcile-check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgBvE,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4ChB"}
1
+ {"version":3,"file":"reconcile-check.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/reconcile-check.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAuGvE,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ChB"}