zigrix 0.1.0-alpha.9 → 0.1.0

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 (82) hide show
  1. package/README.md +85 -182
  2. package/dist/agents/registry.js +14 -0
  3. package/dist/config/defaults.d.ts +87 -6
  4. package/dist/config/defaults.js +82 -51
  5. package/dist/config/load.d.ts +5 -3
  6. package/dist/config/load.js +69 -30
  7. package/dist/config/schema.d.ts +21 -1
  8. package/dist/config/schema.js +15 -1
  9. package/dist/configure.d.ts +1 -0
  10. package/dist/configure.js +24 -14
  11. package/dist/dashboard/.next/BUILD_ID +1 -1
  12. package/dist/dashboard/.next/app-build-manifest.json +21 -21
  13. package/dist/dashboard/.next/app-path-routes-manifest.json +7 -7
  14. package/dist/dashboard/.next/build-manifest.json +2 -2
  15. package/dist/dashboard/.next/prerender-manifest.json +10 -10
  16. package/dist/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/dist/dashboard/.next/server/app/_not-found.html +1 -1
  18. package/dist/dashboard/.next/server/app/_not-found.rsc +1 -1
  19. package/dist/dashboard/.next/server/app/api/auth/login/route.js +1 -1
  20. package/dist/dashboard/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  21. package/dist/dashboard/.next/server/app/api/auth/logout/route.js +1 -1
  22. package/dist/dashboard/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  23. package/dist/dashboard/.next/server/app/api/auth/session/route.js +1 -1
  24. package/dist/dashboard/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
  25. package/dist/dashboard/.next/server/app/api/auth/setup/route.js +1 -1
  26. package/dist/dashboard/.next/server/app/api/auth/setup/route_client-reference-manifest.js +1 -1
  27. package/dist/dashboard/.next/server/app/api/overview/route_client-reference-manifest.js +1 -1
  28. package/dist/dashboard/.next/server/app/api/stream/route_client-reference-manifest.js +1 -1
  29. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  30. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/conversation/route_client-reference-manifest.js +1 -1
  31. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  32. package/dist/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
  33. package/dist/dashboard/.next/server/app/login.html +1 -1
  34. package/dist/dashboard/.next/server/app/login.rsc +1 -1
  35. package/dist/dashboard/.next/server/app/page.js +2 -2
  36. package/dist/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  37. package/dist/dashboard/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  38. package/dist/dashboard/.next/server/app/setup.html +1 -1
  39. package/dist/dashboard/.next/server/app/setup.rsc +1 -1
  40. package/dist/dashboard/.next/server/app-paths-manifest.json +7 -7
  41. package/dist/dashboard/.next/server/chunks/972.js +1 -1
  42. package/dist/dashboard/.next/server/functions-config-manifest.json +4 -4
  43. package/dist/dashboard/.next/server/middleware.js +1 -1
  44. package/dist/dashboard/.next/server/pages/404.html +1 -1
  45. package/dist/dashboard/.next/server/pages/500.html +1 -1
  46. package/dist/dashboard/.next/static/chunks/app/page-0314989c31e18b4b.js +1 -0
  47. package/dist/dashboard/.next/static/css/{94d75aff24d0c077.css → c3a7306cb2ba3f6c.css} +1 -1
  48. package/dist/dashboard.js +47 -0
  49. package/dist/doctor.js +28 -5
  50. package/dist/index.js +170 -170
  51. package/dist/onboard.d.ts +60 -0
  52. package/dist/onboard.js +403 -18
  53. package/dist/orchestration/dispatch.d.ts +1 -0
  54. package/dist/orchestration/dispatch.js +17 -5
  55. package/dist/orchestration/evidence.js +18 -5
  56. package/dist/orchestration/finalize.d.ts +1 -0
  57. package/dist/orchestration/finalize.js +5 -3
  58. package/dist/orchestration/report.js +4 -1
  59. package/dist/orchestration/worker.d.ts +1 -1
  60. package/dist/orchestration/worker.js +53 -18
  61. package/dist/state/tasks.d.ts +5 -0
  62. package/dist/state/tasks.js +7 -0
  63. package/package.json +23 -2
  64. package/rules/defaults/README.md +9 -9
  65. package/rules/defaults/{back-zig.md → backend-agent.md} +4 -4
  66. package/rules/defaults/{front-zig.md → frontend-agent.md} +4 -4
  67. package/rules/defaults/orchestrator-agent.md +261 -0
  68. package/rules/defaults/{qa-zig.md → qa-agent.md} +11 -11
  69. package/rules/defaults/{sec-zig.md → security-agent.md} +4 -4
  70. package/rules/defaults/{sys-zig.md → system-agent.md} +8 -9
  71. package/rules/defaults/worker-common.md +25 -19
  72. package/skills/zigrix-doctor/SKILL.md +4 -2
  73. package/skills/zigrix-evidence/SKILL.md +7 -3
  74. package/skills/zigrix-main-agent-guide/SKILL.md +38 -28
  75. package/skills/zigrix-shared/SKILL.md +27 -3
  76. package/skills/zigrix-task-create/SKILL.md +8 -2
  77. package/skills/zigrix-task-status/SKILL.md +5 -2
  78. package/skills/zigrix-worker/SKILL.md +12 -4
  79. package/dist/dashboard/.next/static/chunks/app/page-25f54e54e74fb3af.js +0 -1
  80. package/rules/defaults/pro-zig.md +0 -238
  81. /package/dist/dashboard/.next/static/{TlUj0t8APzTccK13DVZZW → PT4hYxzrqxj-Zq4ZjtKNg}/_buildManifest.js +0 -0
  82. /package/dist/dashboard/.next/static/{TlUj0t8APzTccK13DVZZW → PT4hYxzrqxj-Zq4ZjtKNg}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import { Command } from 'commander';
4
4
  import { addAgent, excludeAgent, includeAgent, listAgents, removeAgent, setAgentEnabled, setAgentRole, } from './agents/registry.js';
5
5
  import { runConfigure } from './configure.js';
6
6
  import { diffValues, getValueAtPath, parseConfigInput, resetValueAtPath, setValueAtPath } from './config/mutate.js';
7
- import { defaultConfig } from './config/defaults.js';
7
+ import { defaultConfig, resolveAbsolutePath } from './config/defaults.js';
8
8
  import { getConfigValue, loadConfig, writeConfigFile, writeDefaultConfig } from './config/load.js';
9
9
  import { zigrixConfigJsonSchema } from './config/schema.js';
10
10
  import { gatherDoctor, renderDoctorText } from './doctor.js';
11
11
  import { runOnboard } from './onboard.js';
12
- import { dispatchTask } from './orchestration/dispatch.js';
12
+ import { dispatchTask, resolveConfiguredProjectDir } from './orchestration/dispatch.js';
13
13
  import { collectEvidence, mergeEvidence } from './orchestration/evidence.js';
14
14
  import { finalizeTask } from './orchestration/finalize.js';
15
15
  import { runPipeline } from './orchestration/pipeline.js';
@@ -19,7 +19,7 @@ import { listRules, renderTemplate, validateRules } from './rules/templates.js';
19
19
  import { runWorkflow, summarizeRun } from './runner/run.js';
20
20
  import { loadRunRecord } from './runner/store.js';
21
21
  import { ensureBaseState, resolvePaths } from './state/paths.js';
22
- import { applyStalePolicy, createTask, findStaleTasks, listTaskEvents, listTasks, loadTask, rebuildIndex, recordTaskProgress, updateTaskStatus, } from './state/tasks.js';
22
+ import { applyStalePolicy, createTask, findStaleTasks, listTaskEvents, listTasks, loadTask, rebuildIndex, recordTaskProgress, resolveTaskPaths, updateTaskStatus, } from './state/tasks.js';
23
23
  import { verifyState } from './state/verify.js';
24
24
  import { runDashboard, DASHBOARD_DEFAULT_PORT } from './dashboard.js';
25
25
  const STATUS_MAP = {
@@ -33,19 +33,16 @@ function printValue(value, json = false) {
33
33
  }
34
34
  console.log(value);
35
35
  }
36
- function requireConfigPath(configPath, baseDir) {
37
- if (!configPath) {
38
- throw new Error(`zigrix config not found under ${baseDir}; run 'zigrix onboard' first`);
39
- }
36
+ function requireConfigPath(configPath) {
40
37
  return configPath;
41
38
  }
42
39
  function persistAndPrintMutation(params) {
43
- const targetPath = requireConfigPath(params.configPath, params.baseDir);
40
+ const targetPath = requireConfigPath(params.configPath);
44
41
  writeConfigFile(targetPath, params.nextConfig);
45
42
  printValue({ ok: true, action: params.action, agentId: params.agentId, configPath: targetPath }, params.json);
46
43
  }
47
44
  function persistConfigMutation(params) {
48
- const targetPath = requireConfigPath(params.configPath, params.baseDir);
45
+ const targetPath = requireConfigPath(params.configPath);
49
46
  writeConfigFile(targetPath, params.nextConfig);
50
47
  printValue({ ok: true, action: params.action, path: params.path ?? null, configPath: targetPath }, params.json);
51
48
  }
@@ -54,10 +51,59 @@ function requireYes(yes, action = 'perform this action') {
54
51
  throw new Error(`refusing to ${action} without --yes`);
55
52
  }
56
53
  }
57
- function loadRuntime(options) {
58
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
54
+ function loadRuntime() {
55
+ const loaded = loadConfig();
59
56
  return { ...loaded, paths: resolvePaths(loaded.config) };
60
57
  }
58
+ function listRuntimePathValues(loaded) {
59
+ return {
60
+ configPath: loaded.configPath,
61
+ 'paths.baseDir': loaded.paths.baseDir,
62
+ 'paths.tasksDir': loaded.paths.tasksDir,
63
+ 'paths.evidenceDir': loaded.paths.evidenceDir,
64
+ 'paths.promptsDir': loaded.paths.promptsDir,
65
+ 'paths.eventsFile': loaded.paths.eventsFile,
66
+ 'paths.indexFile': loaded.paths.indexFile,
67
+ 'paths.runsDir': loaded.paths.runsDir,
68
+ 'paths.rulesDir': loaded.paths.rulesDir,
69
+ 'workspace.projectsBaseDir': loaded.config.workspace.projectsBaseDir,
70
+ };
71
+ }
72
+ function resolveRuntimePathValue(loaded, requestedKey) {
73
+ const normalized = requestedKey.trim();
74
+ const aliases = {
75
+ configPath: 'configPath',
76
+ baseDir: 'paths.baseDir',
77
+ tasksDir: 'paths.tasksDir',
78
+ evidenceDir: 'paths.evidenceDir',
79
+ promptsDir: 'paths.promptsDir',
80
+ eventsFile: 'paths.eventsFile',
81
+ indexFile: 'paths.indexFile',
82
+ runsDir: 'paths.runsDir',
83
+ rulesDir: 'paths.rulesDir',
84
+ projectsBaseDir: 'workspace.projectsBaseDir',
85
+ workspaceBaseDir: 'workspace.projectsBaseDir',
86
+ 'paths.baseDir': 'paths.baseDir',
87
+ 'paths.tasksDir': 'paths.tasksDir',
88
+ 'paths.evidenceDir': 'paths.evidenceDir',
89
+ 'paths.promptsDir': 'paths.promptsDir',
90
+ 'paths.eventsFile': 'paths.eventsFile',
91
+ 'paths.indexFile': 'paths.indexFile',
92
+ 'paths.runsDir': 'paths.runsDir',
93
+ 'paths.rulesDir': 'paths.rulesDir',
94
+ 'workspace.projectsBaseDir': 'workspace.projectsBaseDir',
95
+ };
96
+ const canonicalKey = aliases[normalized];
97
+ if (!canonicalKey) {
98
+ throw new Error(`unknown path key: ${requestedKey}`);
99
+ }
100
+ const values = listRuntimePathValues(loaded);
101
+ return {
102
+ requestedKey,
103
+ canonicalKey,
104
+ value: values[canonicalKey] ?? null,
105
+ };
106
+ }
61
107
  const { version: pkgVersion } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
62
108
  const program = new Command();
63
109
  program
@@ -65,6 +111,7 @@ program
65
111
  .description('Zigrix — multi-project parallel task orchestration CLI')
66
112
  .version(pkgVersion);
67
113
  const config = program.command('config').description('Inspect Zigrix config');
114
+ const pathCmd = program.command('path').description('Resolve runtime paths from Zigrix config');
68
115
  const agent = program.command('agent').description('Manage Zigrix agent registry and orchestration membership');
69
116
  const rule = program.command('rule').description('Inspect and validate rule assets');
70
117
  const template = program.command('template').description('Inspect and modify prompt templates');
@@ -78,16 +125,20 @@ const pipeline = program.command('pipeline').description('High-level orchestrati
78
125
  // ─── onboard ────────────────────────────────────────────────────────────────
79
126
  program
80
127
  .command('onboard')
81
- .description('Set up Zigrix for first use (creates ~/.zigrix, seeds rules, registers agents)')
128
+ .description('Set up Zigrix for first use (creates config.paths.baseDir state, seeds rules, registers agents, and captures workspace defaults)')
82
129
  .option('--yes', 'non-interactive confirmation')
83
130
  .option('--json', 'JSON output')
84
- .option('--project-dir <path>', 'path to project directory containing orchestration/rules/')
131
+ .option('--project-dir <path>', 'optional directory to import rule templates from (`rules/defaults` or `rules`); otherwise bundled defaults are used')
132
+ .option('--projects-base-dir <path>', 'workspace base directory to persist in zigrix.config.json')
85
133
  .option('--orchestrator-id <agentId>', 'set orchestration orchestrator agent id')
134
+ .option('--gateway-url <url>', 'OpenClaw gateway URL (auto-detected from openclaw.json when available)')
86
135
  .action(async (options) => {
87
136
  const result = await runOnboard({
88
137
  yes: Boolean(options.yes),
89
138
  projectDir: options.projectDir,
139
+ projectsBaseDir: options.projectsBaseDir,
90
140
  orchestratorId: options.orchestratorId,
141
+ gatewayUrl: options.gatewayUrl,
91
142
  silent: Boolean(options.json),
92
143
  });
93
144
  printValue(result, options.json ?? true);
@@ -98,7 +149,7 @@ program
98
149
  .description('Reconfigure agents, rules, PATH, skills, or workspace settings')
99
150
  .option('--section <section>', 'reconfigure specific section (agents|rules|workspace|path|skills), repeatable', (value, prev = []) => [...prev, value], [])
100
151
  .option('--projects-base-dir <path>', 'set projects base directory')
101
- .option('--project-dir <path>', 'path to project directory containing orchestration/rules/')
152
+ .option('--project-dir <path>', 'optional directory to import rule templates from (`rules/defaults` or `rules`); otherwise bundled defaults are used')
102
153
  .option('--orchestrator-id <agentId>', 'set orchestration orchestrator agent id')
103
154
  .option('--yes', 'non-interactive confirmation')
104
155
  .option('--json', 'JSON output')
@@ -121,8 +172,8 @@ program
121
172
  .option('--json', 'JSON output')
122
173
  .action((options) => {
123
174
  console.error('⚠️ "zigrix init" is deprecated. Use "zigrix onboard" instead.');
124
- const configPath = writeDefaultConfig(undefined, Boolean(options.yes));
125
- const loaded = loadRuntime({ config: configPath });
175
+ const configPath = writeDefaultConfig(Boolean(options.yes));
176
+ const loaded = loadRuntime();
126
177
  ensureBaseState(loaded.paths);
127
178
  rebuildIndex(loaded.paths);
128
179
  printValue({ ok: true, path: configPath, deprecated: true, useInstead: 'zigrix onboard' }, options.json);
@@ -131,11 +182,9 @@ program
131
182
  program
132
183
  .command('doctor')
133
184
  .description('Inspect environment, config, and runtime readiness')
134
- .option('--config <path>')
135
- .option('--base-dir <path>')
136
185
  .option('--json')
137
186
  .action((options) => {
138
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
187
+ const loaded = loadRuntime();
139
188
  const payload = gatherDoctor(loaded, loaded.paths);
140
189
  if (options.json) {
141
190
  printValue(payload, true);
@@ -143,23 +192,48 @@ program
143
192
  }
144
193
  console.log(renderDoctorText(payload));
145
194
  });
195
+ // ─── path ───────────────────────────────────────────────────────────────────
196
+ pathCmd
197
+ .command('get <key>')
198
+ .description('Resolve one runtime path by key or alias (for example: tasksDir, paths.tasksDir, workspace.projectsBaseDir)')
199
+ .option('--json', 'JSON output')
200
+ .action((key, options) => {
201
+ const loaded = loadRuntime();
202
+ const resolved = resolveRuntimePathValue(loaded, key);
203
+ if (options.json) {
204
+ printValue({ ok: true, ...resolved }, true);
205
+ return;
206
+ }
207
+ printValue(resolved.value, false);
208
+ });
209
+ pathCmd
210
+ .command('list')
211
+ .description('List resolved runtime paths')
212
+ .option('--json', 'JSON output')
213
+ .action((options) => {
214
+ const loaded = loadRuntime();
215
+ const values = listRuntimePathValues(loaded);
216
+ if (options.json) {
217
+ printValue({ ok: true, values }, true);
218
+ return;
219
+ }
220
+ for (const [key, value] of Object.entries(values)) {
221
+ console.log(`${key}=${value ?? ''}`);
222
+ }
223
+ });
146
224
  // ─── config ─────────────────────────────────────────────────────────────────
147
225
  config
148
226
  .command('validate')
149
- .option('--config <path>', 'explicit config path')
150
- .option('--base-dir <path>', 'Zigrix base directory override')
151
227
  .option('--json', 'JSON output')
152
228
  .action((options) => {
153
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
229
+ const loaded = loadConfig();
154
230
  printValue({ ok: true, configPath: loaded.configPath, baseDir: loaded.baseDir }, options.json);
155
231
  });
156
232
  config
157
233
  .command('get [path]')
158
- .option('--config <path>', 'explicit config path')
159
- .option('--base-dir <path>', 'Zigrix base directory override')
160
234
  .option('--json', 'JSON output')
161
235
  .action((dottedPath, options) => {
162
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
236
+ const loaded = loadConfig();
163
237
  printValue(getConfigValue(loaded.config, dottedPath) ?? null, true);
164
238
  });
165
239
  config
@@ -179,11 +253,9 @@ config
179
253
  config
180
254
  .command('set <path>')
181
255
  .requiredOption('--value <jsonOrString>')
182
- .option('--config <path>', 'explicit config path')
183
- .option('--base-dir <path>', 'Zigrix base directory override')
184
256
  .option('--json', 'JSON output')
185
257
  .action((dottedPath, options) => {
186
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
258
+ const loaded = loadConfig();
187
259
  const nextConfig = setValueAtPath(loaded.config, dottedPath, parseConfigInput(options.value));
188
260
  persistConfigMutation({
189
261
  configPath: loaded.configPath,
@@ -196,23 +268,19 @@ config
196
268
  });
197
269
  config
198
270
  .command('diff <path>')
199
- .option('--config <path>', 'explicit config path')
200
- .option('--base-dir <path>', 'Zigrix base directory override')
201
271
  .option('--json', 'JSON output')
202
272
  .action((dottedPath, options) => {
203
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
273
+ const loaded = loadConfig();
204
274
  printValue(diffValues(getValueAtPath(loaded.config, dottedPath), getValueAtPath(defaultConfig, dottedPath)), true);
205
275
  });
206
276
  config
207
277
  .command('reset')
208
278
  .option('--path <path>', 'dotted config path to restore from defaults', 'all')
209
- .option('--config <path>', 'explicit config path')
210
- .option('--base-dir <path>', 'Zigrix base directory override')
211
279
  .option('--yes', 'confirm destructive reset')
212
280
  .option('--json', 'JSON output')
213
281
  .action((options) => {
214
282
  requireYes(options.yes, 'reset config');
215
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
283
+ const loaded = loadConfig();
216
284
  const nextConfig = resetValueAtPath(loaded.config, options.path);
217
285
  persistConfigMutation({
218
286
  configPath: loaded.configPath,
@@ -226,10 +294,8 @@ config
226
294
  // ─── agent ──────────────────────────────────────────────────────────────────
227
295
  agent
228
296
  .command('list')
229
- .option('--config <path>')
230
- .option('--base-dir <path>')
231
297
  .option('--json')
232
- .action((options) => printValue(listAgents(loadConfig({ baseDir: options.baseDir, configPath: options.config }).config), true));
298
+ .action((options) => printValue(listAgents(loadConfig().config), true));
233
299
  agent
234
300
  .command('add')
235
301
  .requiredOption('--id <agentId>')
@@ -238,102 +304,80 @@ agent
238
304
  .option('--label <label>')
239
305
  .option('--include')
240
306
  .option('--disabled')
241
- .option('--config <path>')
242
- .option('--base-dir <path>')
243
307
  .option('--json')
244
308
  .action((options) => {
245
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
309
+ const loaded = loadConfig();
246
310
  const result = addAgent(loaded.config, { id: options.id, role: options.role, runtime: options.runtime, label: options.label, enabled: !options.disabled, include: Boolean(options.include) });
247
311
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.add', agentId: result.agentId });
248
312
  });
249
313
  agent
250
314
  .command('remove <agentId>')
251
- .option('--config <path>')
252
- .option('--base-dir <path>')
253
315
  .option('--json')
254
316
  .action((agentId, options) => {
255
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
317
+ const loaded = loadConfig();
256
318
  const result = removeAgent(loaded.config, agentId);
257
319
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.remove', agentId: result.agentId });
258
320
  });
259
321
  agent
260
322
  .command('include <agentId>')
261
- .option('--config <path>')
262
- .option('--base-dir <path>')
263
323
  .option('--json')
264
324
  .action((agentId, options) => {
265
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
325
+ const loaded = loadConfig();
266
326
  const result = includeAgent(loaded.config, agentId);
267
327
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.include', agentId: result.agentId });
268
328
  });
269
329
  agent
270
330
  .command('exclude <agentId>')
271
- .option('--config <path>')
272
- .option('--base-dir <path>')
273
331
  .option('--json')
274
332
  .action((agentId, options) => {
275
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
333
+ const loaded = loadConfig();
276
334
  const result = excludeAgent(loaded.config, agentId);
277
335
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.exclude', agentId: result.agentId });
278
336
  });
279
337
  agent
280
338
  .command('enable <agentId>')
281
- .option('--config <path>')
282
- .option('--base-dir <path>')
283
339
  .option('--json')
284
340
  .action((agentId, options) => {
285
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
341
+ const loaded = loadConfig();
286
342
  const result = setAgentEnabled(loaded.config, agentId, true);
287
343
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.enable', agentId: result.agentId });
288
344
  });
289
345
  agent
290
346
  .command('disable <agentId>')
291
- .option('--config <path>')
292
- .option('--base-dir <path>')
293
347
  .option('--json')
294
348
  .action((agentId, options) => {
295
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
349
+ const loaded = loadConfig();
296
350
  const result = setAgentEnabled(loaded.config, agentId, false);
297
351
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.disable', agentId: result.agentId });
298
352
  });
299
353
  agent
300
354
  .command('set-role <agentId>')
301
355
  .requiredOption('--role <role>')
302
- .option('--config <path>')
303
- .option('--base-dir <path>')
304
356
  .option('--json')
305
357
  .action((agentId, options) => {
306
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
358
+ const loaded = loadConfig();
307
359
  const result = setAgentRole(loaded.config, agentId, options.role);
308
360
  persistAndPrintMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig: result.config, json: options.json, action: 'agent.set-role', agentId: result.agentId });
309
361
  });
310
362
  // ─── rule ───────────────────────────────────────────────────────────────────
311
363
  rule
312
364
  .command('list')
313
- .option('--config <path>')
314
- .option('--base-dir <path>')
315
365
  .option('--json')
316
- .action((options) => printValue(listRules(loadConfig({ baseDir: options.baseDir, configPath: options.config }).config), true));
366
+ .action((options) => printValue(listRules(loadConfig().config), true));
317
367
  rule
318
368
  .command('get <path>')
319
- .option('--config <path>')
320
- .option('--base-dir <path>')
321
369
  .option('--json')
322
- .action((dottedPath, options) => printValue(getConfigValue(loadConfig({ baseDir: options.baseDir, configPath: options.config }).config, dottedPath) ?? null, true));
370
+ .action((dottedPath, options) => printValue(getConfigValue(loadConfig().config, dottedPath) ?? null, true));
323
371
  rule
324
372
  .command('validate')
325
- .option('--config <path>')
326
- .option('--base-dir <path>')
327
373
  .option('--json')
328
- .action((options) => printValue(validateRules(loadConfig({ baseDir: options.baseDir, configPath: options.config }).config), true));
374
+ .action((options) => printValue(validateRules(loadConfig().config), true));
329
375
  rule
330
376
  .command('render <templateKind>')
331
377
  .requiredOption('--context <json>')
332
- .option('--config <path>')
333
- .option('--base-dir <path>')
334
378
  .option('--json')
335
379
  .action((templateKind, options) => {
336
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
380
+ const loaded = loadConfig();
337
381
  const tpl = getConfigValue(loaded.config, `templates.${templateKind}`);
338
382
  if (!tpl?.body)
339
383
  throw new Error(`template not found: ${templateKind}`);
@@ -343,59 +387,49 @@ rule
343
387
  rule
344
388
  .command('set <path>')
345
389
  .requiredOption('--value <jsonOrString>')
346
- .option('--config <path>')
347
- .option('--base-dir <path>')
348
390
  .option('--json')
349
391
  .action((dottedPath, options) => {
350
392
  if (!dottedPath.startsWith('rules.'))
351
393
  throw new Error('rule path must start with rules.');
352
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
394
+ const loaded = loadConfig();
353
395
  const nextConfig = setValueAtPath(loaded.config, dottedPath, parseConfigInput(options.value));
354
396
  persistConfigMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig, json: options.json, action: 'rule.set', path: dottedPath });
355
397
  });
356
398
  rule
357
399
  .command('diff <path>')
358
- .option('--config <path>')
359
- .option('--base-dir <path>')
360
400
  .option('--json')
361
401
  .action((dottedPath, options) => {
362
402
  if (!dottedPath.startsWith('rules.'))
363
403
  throw new Error('rule path must start with rules.');
364
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
404
+ const loaded = loadConfig();
365
405
  printValue(diffValues(getValueAtPath(loaded.config, dottedPath), getValueAtPath(defaultConfig, dottedPath)), true);
366
406
  });
367
407
  rule
368
408
  .command('reset')
369
409
  .requiredOption('--path <path>')
370
- .option('--config <path>')
371
- .option('--base-dir <path>')
372
410
  .option('--yes')
373
411
  .option('--json')
374
412
  .action((options) => {
375
413
  if (!options.path.startsWith('rules.'))
376
414
  throw new Error('rule path must start with rules.');
377
415
  requireYes(options.yes, 'reset rule config');
378
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
416
+ const loaded = loadConfig();
379
417
  const nextConfig = resetValueAtPath(loaded.config, options.path);
380
418
  persistConfigMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig, json: options.json, action: 'rule.reset', path: options.path });
381
419
  });
382
420
  // ─── template ───────────────────────────────────────────────────────────────
383
421
  template
384
422
  .command('list')
385
- .option('--config <path>')
386
- .option('--base-dir <path>')
387
423
  .option('--json')
388
424
  .action((options) => {
389
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
425
+ const loaded = loadConfig();
390
426
  printValue(Object.keys(loaded.config.templates).map((name) => ({ name, path: `templates.${name}` })), true);
391
427
  });
392
428
  template
393
429
  .command('get <name>')
394
- .option('--config <path>')
395
- .option('--base-dir <path>')
396
430
  .option('--json')
397
431
  .action((name, options) => {
398
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
432
+ const loaded = loadConfig();
399
433
  printValue(getValueAtPath(loaded.config, `templates.${name}`) ?? null, true);
400
434
  });
401
435
  template
@@ -404,11 +438,9 @@ template
404
438
  .option('--format <format>', 'markdown|text')
405
439
  .option('--version <version>')
406
440
  .option('--placeholders <jsonArray>')
407
- .option('--config <path>')
408
- .option('--base-dir <path>')
409
441
  .option('--json')
410
442
  .action((name, options) => {
411
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
443
+ const loaded = loadConfig();
412
444
  const current = getValueAtPath(loaded.config, `templates.${name}`);
413
445
  if (!current)
414
446
  throw new Error(`template not found: ${name}`);
@@ -424,33 +456,27 @@ template
424
456
  });
425
457
  template
426
458
  .command('diff <name>')
427
- .option('--config <path>')
428
- .option('--base-dir <path>')
429
459
  .option('--json')
430
460
  .action((name, options) => {
431
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
461
+ const loaded = loadConfig();
432
462
  printValue(diffValues(getValueAtPath(loaded.config, `templates.${name}`), getValueAtPath(defaultConfig, `templates.${name}`)), true);
433
463
  });
434
464
  template
435
465
  .command('reset <name>')
436
- .option('--config <path>')
437
- .option('--base-dir <path>')
438
466
  .option('--yes')
439
467
  .option('--json')
440
468
  .action((name, options) => {
441
469
  requireYes(options.yes, 'reset template config');
442
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
470
+ const loaded = loadConfig();
443
471
  const nextConfig = resetValueAtPath(loaded.config, `templates.${name}`);
444
472
  persistConfigMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig, json: options.json, action: 'template.reset', path: `templates.${name}` });
445
473
  });
446
474
  template
447
475
  .command('render <name>')
448
476
  .requiredOption('--context <json>')
449
- .option('--config <path>')
450
- .option('--base-dir <path>')
451
477
  .option('--json')
452
478
  .action((name, options) => {
453
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
479
+ const loaded = loadConfig();
454
480
  const item = getValueAtPath(loaded.config, `templates.${name}`);
455
481
  if (!item?.body)
456
482
  throw new Error(`template not found: ${name}`);
@@ -460,25 +486,21 @@ template
460
486
  reset
461
487
  .command('config')
462
488
  .option('--path <path>', 'dotted config path to restore from defaults', 'all')
463
- .option('--config <path>')
464
- .option('--base-dir <path>')
465
489
  .option('--yes')
466
490
  .option('--json')
467
491
  .action((options) => {
468
492
  requireYes(options.yes, 'reset config');
469
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
493
+ const loaded = loadConfig();
470
494
  const nextConfig = resetValueAtPath(loaded.config, options.path);
471
495
  persistConfigMutation({ configPath: loaded.configPath, baseDir: loaded.baseDir, nextConfig, json: options.json, action: 'reset.config', path: options.path });
472
496
  });
473
497
  reset
474
498
  .command('state')
475
- .option('--base-dir <path>')
476
- .option('--config <path>')
477
499
  .option('--yes')
478
500
  .option('--json')
479
501
  .action((options) => {
480
502
  requireYes(options.yes, 'reset runtime state');
481
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
503
+ const loaded = loadRuntime();
482
504
  // Remove task data but preserve config and rules
483
505
  for (const dir of [loaded.paths.tasksDir, loaded.paths.evidenceDir, loaded.paths.promptsDir, loaded.paths.runsDir]) {
484
506
  fs.rmSync(dir, { recursive: true, force: true });
@@ -492,37 +514,31 @@ reset
492
514
  // ─── state ──────────────────────────────────────────────────────────────────
493
515
  state
494
516
  .command('check')
495
- .option('--base-dir <path>')
496
- .option('--config <path>')
497
517
  .option('--json')
498
518
  .action((options) => {
499
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
519
+ const loaded = loadRuntime();
500
520
  printValue(verifyState(loaded.paths), true);
501
521
  });
502
522
  program
503
523
  .command('index-rebuild')
504
- .option('--config <path>')
505
- .option('--base-dir <path>')
506
524
  .option('--json')
507
525
  .action((options) => {
508
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
526
+ const loaded = loadRuntime();
509
527
  printValue(rebuildIndex(loaded.paths), true);
510
528
  });
511
529
  // ─── task ───────────────────────────────────────────────────────────────────
512
530
  task
513
531
  .command('dispatch')
514
- .description('Create a task with full orchestration metadata and boot prompt (replaces dev_dispatch.py)')
532
+ .description('Create a task with full orchestration metadata and boot prompt')
515
533
  .requiredOption('--title <title>')
516
534
  .requiredOption('--description <description>')
517
535
  .requiredOption('--scale <scale>', 'simple|normal|risky|large')
518
536
  .option('--project-dir <path>', 'target project directory')
519
537
  .option('--requested-by <name>', 'who requested this task')
520
538
  .option('--constraints <constraints>', 'task constraints')
521
- .option('--config <path>')
522
- .option('--base-dir <path>')
523
539
  .option('--json')
524
540
  .action((options) => {
525
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
541
+ const loaded = loadRuntime();
526
542
  const result = dispatchTask(loaded.paths, loaded.config, {
527
543
  title: options.title,
528
544
  description: options.description,
@@ -542,37 +558,47 @@ task
542
558
  .option('--project-dir <path>', 'target project directory for this task')
543
559
  .option('--requested-by <name>', 'who requested this task')
544
560
  .option('--prefix <prefix>', 'task ID prefix (DEV|TEST)', 'DEV')
545
- .option('--config <path>')
546
- .option('--base-dir <path>')
547
561
  .option('--json')
548
562
  .action((options) => {
549
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
550
- const created = createTask(loaded.paths, { title: options.title, description: options.description, scale: options.scale, requiredAgents: options.requiredAgent, projectDir: options.projectDir, requestedBy: options.requestedBy, prefix: options.prefix });
551
- printValue(created, true);
563
+ const loaded = loadRuntime();
564
+ const projectDir = options.projectDir
565
+ ? resolveAbsolutePath(options.projectDir)
566
+ : resolveConfiguredProjectDir(loaded.config);
567
+ const created = createTask(loaded.paths, {
568
+ title: options.title,
569
+ description: options.description,
570
+ scale: options.scale,
571
+ requiredAgents: options.requiredAgent,
572
+ projectDir,
573
+ requestedBy: options.requestedBy,
574
+ prefix: options.prefix,
575
+ });
576
+ printValue({
577
+ ...created,
578
+ ...resolveTaskPaths(loaded.paths, created.taskId),
579
+ }, true);
552
580
  });
553
581
  task
554
582
  .command('list')
555
- .option('--config <path>')
556
- .option('--base-dir <path>')
557
583
  .option('--json')
558
- .action((options) => printValue(listTasks(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths), true));
584
+ .action((options) => printValue(listTasks(loadRuntime().paths), true));
559
585
  task
560
586
  .command('status <taskId>')
561
- .option('--config <path>')
562
- .option('--base-dir <path>')
563
587
  .option('--json')
564
588
  .action((taskId, options) => {
565
- const payload = loadTask(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, taskId);
589
+ const loaded = loadRuntime();
590
+ const payload = loadTask(loaded.paths, taskId);
566
591
  if (!payload)
567
592
  throw new Error(`task not found: ${taskId}`);
568
- printValue(payload, true);
593
+ printValue({
594
+ ...payload,
595
+ ...resolveTaskPaths(loaded.paths, taskId),
596
+ }, true);
569
597
  });
570
598
  task
571
599
  .command('events [taskId]')
572
- .option('--config <path>')
573
- .option('--base-dir <path>')
574
600
  .option('--json')
575
- .action((taskId, options) => printValue(listTaskEvents(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, taskId), true));
601
+ .action((taskId, options) => printValue(listTaskEvents(loadRuntime().paths, taskId), true));
576
602
  task
577
603
  .command('progress')
578
604
  .requiredOption('--task-id <taskId>')
@@ -580,11 +606,9 @@ task
580
606
  .requiredOption('--message <message>')
581
607
  .option('--unit-id <unitId>')
582
608
  .option('--work-package <workPackage>')
583
- .option('--config <path>')
584
- .option('--base-dir <path>')
585
609
  .option('--json')
586
610
  .action((options) => {
587
- const payload = recordTaskProgress(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, actor: options.actor, message: options.message, unitId: options.unitId, workPackage: options.workPackage });
611
+ const payload = recordTaskProgress(loadRuntime().paths, { taskId: options.taskId, actor: options.actor, message: options.message, unitId: options.unitId, workPackage: options.workPackage });
588
612
  if (!payload)
589
613
  throw new Error(`task not found: ${options.taskId}`);
590
614
  printValue(payload, true);
@@ -594,11 +618,9 @@ task
594
618
  .option('--hours <hours>', 'stale threshold hours', '24')
595
619
  .option('--apply')
596
620
  .option('--reason <reason>', 'block reason', 'stale_timeout')
597
- .option('--config <path>')
598
- .option('--base-dir <path>')
599
621
  .option('--json')
600
622
  .action((options) => {
601
- const paths = loadRuntime({ baseDir: options.baseDir, config: options.config }).paths;
623
+ const paths = loadRuntime().paths;
602
624
  const hours = Number(options.hours);
603
625
  const payload = options.apply ? applyStalePolicy(paths, hours, options.reason) : { ok: true, hours, count: findStaleTasks(paths, hours).length, tasks: findStaleTasks(paths, hours) };
604
626
  printValue(payload, true);
@@ -606,11 +628,9 @@ task
606
628
  for (const [name, status] of Object.entries(STATUS_MAP)) {
607
629
  task
608
630
  .command(`${name} <taskId>`)
609
- .option('--config <path>')
610
- .option('--base-dir <path>')
611
631
  .option('--json')
612
632
  .action((taskId, options) => {
613
- const payload = updateTaskStatus(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, taskId, status);
633
+ const payload = updateTaskStatus(loadRuntime().paths, taskId, status);
614
634
  if (!payload)
615
635
  throw new Error(`task not found: ${taskId}`);
616
636
  printValue(payload, true);
@@ -618,18 +638,16 @@ for (const [name, status] of Object.entries(STATUS_MAP)) {
618
638
  }
619
639
  task
620
640
  .command('finalize <taskId>')
621
- .description('Finalize a task: merge evidence, check units, optionally auto-report (replaces dev_finalize.py)')
622
- .option('--auto-report', 'auto-transition to REPORTED if complete')
641
+ .description('Finalize a task: merge evidence, check units, and auto-report by default')
642
+ .option('--no-auto-report', 'skip auto-transition to REPORTED (default: auto-report enabled)')
623
643
  .option('--sec-issues', 'flag security issues (blocks auto-report)')
624
644
  .option('--qa-issues', 'flag QA issues (blocks auto-report)')
625
- .option('--config <path>')
626
- .option('--base-dir <path>')
627
645
  .option('--json')
628
646
  .action((taskId, options) => {
629
- const loaded = loadRuntime({ baseDir: options.baseDir, config: options.config });
647
+ const loaded = loadRuntime();
630
648
  const result = finalizeTask(loaded.paths, {
631
649
  taskId,
632
- autoReport: Boolean(options.autoReport),
650
+ autoReport: options.autoReport !== false,
633
651
  secIssues: Boolean(options.secIssues),
634
652
  qaIssues: Boolean(options.qaIssues),
635
653
  });
@@ -648,11 +666,9 @@ worker
648
666
  .option('--work-package <workPackage>')
649
667
  .option('--dod <dod>')
650
668
  .option('--project-dir <path>', 'working directory for this worker')
651
- .option('--config <path>')
652
- .option('--base-dir <path>')
653
669
  .option('--json')
654
670
  .action((options) => {
655
- const payload = prepareWorker(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, agentId: options.agentId, description: options.description, constraints: options.constraints, unitId: options.unitId, workPackage: options.workPackage, dod: options.dod, projectDir: options.projectDir });
671
+ const payload = prepareWorker(loadRuntime().paths, { taskId: options.taskId, agentId: options.agentId, description: options.description, constraints: options.constraints, unitId: options.unitId, workPackage: options.workPackage, dod: options.dod, projectDir: options.projectDir });
656
672
  if (!payload)
657
673
  throw new Error(`task not found: ${options.taskId}`);
658
674
  printValue(payload, true);
@@ -667,11 +683,9 @@ worker
667
683
  .option('--unit-id <unitId>')
668
684
  .option('--work-package <workPackage>')
669
685
  .option('--reason <reason>')
670
- .option('--config <path>')
671
- .option('--base-dir <path>')
672
686
  .option('--json')
673
687
  .action((options) => {
674
- const payload = registerWorker(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, agentId: options.agentId, sessionKey: options.sessionKey, runId: options.runId, sessionId: options.sessionId, unitId: options.unitId, workPackage: options.workPackage, reason: options.reason });
688
+ const payload = registerWorker(loadRuntime().paths, { taskId: options.taskId, agentId: options.agentId, sessionKey: options.sessionKey, runId: options.runId, sessionId: options.sessionId, unitId: options.unitId, workPackage: options.workPackage, reason: options.reason });
675
689
  if (!payload)
676
690
  throw new Error(`task not found: ${options.taskId}`);
677
691
  printValue(payload, true);
@@ -686,11 +700,9 @@ worker
686
700
  .option('--result <result>', 'done|blocked|skipped', 'done')
687
701
  .option('--unit-id <unitId>')
688
702
  .option('--work-package <workPackage>')
689
- .option('--config <path>')
690
- .option('--base-dir <path>')
691
703
  .option('--json')
692
704
  .action((options) => {
693
- const payload = completeWorker(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, agentId: options.agentId, sessionKey: options.sessionKey, runId: options.runId, sessionId: options.sessionId, result: options.result, unitId: options.unitId, workPackage: options.workPackage });
705
+ const payload = completeWorker(loadRuntime().paths, { taskId: options.taskId, agentId: options.agentId, sessionKey: options.sessionKey, runId: options.runId, sessionId: options.sessionId, result: options.result, unitId: options.unitId, workPackage: options.workPackage });
694
706
  if (!payload)
695
707
  throw new Error(`task not found: ${options.taskId}`);
696
708
  printValue(payload, true);
@@ -709,11 +721,9 @@ evidence
709
721
  .option('--tool-result <toolResult>', 'repeatable', (value, prev = []) => [...prev, value], [])
710
722
  .option('--notes <notes>')
711
723
  .option('--limit <limit>', 'transcript line limit', '40')
712
- .option('--config <path>')
713
- .option('--base-dir <path>')
714
724
  .option('--json')
715
725
  .action((options) => {
716
- const payload = collectEvidence(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, agentId: options.agentId, runId: options.runId, unitId: options.unitId, sessionKey: options.sessionKey, sessionId: options.sessionId, transcript: options.transcript, summary: options.summary, toolResults: options.toolResult, notes: options.notes, limit: Number(options.limit) });
726
+ const payload = collectEvidence(loadRuntime().paths, { taskId: options.taskId, agentId: options.agentId, runId: options.runId, unitId: options.unitId, sessionKey: options.sessionKey, sessionId: options.sessionId, transcript: options.transcript, summary: options.summary, toolResults: options.toolResult, notes: options.notes, limit: Number(options.limit) });
717
727
  if (!payload)
718
728
  throw new Error(`task not found: ${options.taskId}`);
719
729
  printValue(payload, true);
@@ -723,11 +733,9 @@ evidence
723
733
  .requiredOption('--task-id <taskId>')
724
734
  .option('--required-agent <agent>', 'repeatable', (value, prev = []) => [...prev, value], [])
725
735
  .option('--require-qa')
726
- .option('--config <path>')
727
- .option('--base-dir <path>')
728
736
  .option('--json')
729
737
  .action((options) => {
730
- const payload = mergeEvidence(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, requiredAgents: options.requiredAgent, requireQa: Boolean(options.requireQa) });
738
+ const payload = mergeEvidence(loadRuntime().paths, { taskId: options.taskId, requiredAgents: options.requiredAgent, requireQa: Boolean(options.requireQa) });
731
739
  if (!payload)
732
740
  throw new Error(`task not found: ${options.taskId}`);
733
741
  printValue(payload, true);
@@ -737,11 +745,9 @@ report
737
745
  .command('render')
738
746
  .requiredOption('--task-id <taskId>')
739
747
  .option('--record-events')
740
- .option('--config <path>')
741
- .option('--base-dir <path>')
742
748
  .option('--json')
743
749
  .action((options) => {
744
- const payload = renderReport(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { taskId: options.taskId, recordEvents: Boolean(options.recordEvents) });
750
+ const payload = renderReport(loadRuntime().paths, { taskId: options.taskId, recordEvents: Boolean(options.recordEvents) });
745
751
  if (!payload)
746
752
  throw new Error(`task not found: ${options.taskId}`);
747
753
  printValue(payload, true);
@@ -757,22 +763,18 @@ pipeline
757
763
  .option('--require-qa')
758
764
  .option('--auto-report')
759
765
  .option('--record-feedback')
760
- .option('--config <path>')
761
- .option('--base-dir <path>')
762
766
  .option('--json')
763
767
  .action((options) => {
764
- const payload = runPipeline(loadRuntime({ baseDir: options.baseDir, config: options.config }).paths, { title: options.title, description: options.description, scale: options.scale, requiredAgents: options.requiredAgent, evidenceSummaries: options.evidenceSummary, requireQa: Boolean(options.requireQa), autoReport: Boolean(options.autoReport), recordFeedback: Boolean(options.recordFeedback) });
768
+ const payload = runPipeline(loadRuntime().paths, { title: options.title, description: options.description, scale: options.scale, requiredAgents: options.requiredAgent, evidenceSummaries: options.evidenceSummary, requireQa: Boolean(options.requireQa), autoReport: Boolean(options.autoReport), recordFeedback: Boolean(options.recordFeedback) });
765
769
  printValue(payload, true);
766
770
  });
767
771
  // ─── run / inspect ──────────────────────────────────────────────────────────
768
772
  program
769
773
  .command('run <workflowPath>')
770
774
  .description('Run a minimal sequential workflow file')
771
- .option('--config <path>')
772
- .option('--base-dir <path>')
773
775
  .option('--json')
774
776
  .action(async (workflowPath, options) => {
775
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
777
+ const loaded = loadConfig();
776
778
  const result = await runWorkflow({ config: loaded.config, workflowPath });
777
779
  if (options.json) {
778
780
  printValue({ ...result.record, savedPath: result.savedPath }, true);
@@ -784,11 +786,9 @@ program
784
786
  program
785
787
  .command('inspect <runIdOrPath>')
786
788
  .description('Inspect a saved run record')
787
- .option('--config <path>')
788
- .option('--base-dir <path>')
789
789
  .option('--json')
790
790
  .action((runIdOrPath, options) => {
791
- const loaded = loadConfig({ baseDir: options.baseDir, configPath: options.config });
791
+ const loaded = loadConfig();
792
792
  printValue(loadRunRecord(loaded.config, runIdOrPath), true);
793
793
  });
794
794
  // ─── dashboard ──────────────────────────────────────────────────────────────