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.
- package/README.md +85 -182
- package/dist/agents/registry.js +14 -0
- package/dist/config/defaults.d.ts +87 -6
- package/dist/config/defaults.js +82 -51
- package/dist/config/load.d.ts +5 -3
- package/dist/config/load.js +69 -30
- package/dist/config/schema.d.ts +21 -1
- package/dist/config/schema.js +15 -1
- package/dist/configure.d.ts +1 -0
- package/dist/configure.js +24 -14
- package/dist/dashboard/.next/BUILD_ID +1 -1
- package/dist/dashboard/.next/app-build-manifest.json +21 -21
- package/dist/dashboard/.next/app-path-routes-manifest.json +7 -7
- package/dist/dashboard/.next/build-manifest.json +2 -2
- package/dist/dashboard/.next/prerender-manifest.json +10 -10
- package/dist/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/_not-found.html +1 -1
- package/dist/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dist/dashboard/.next/server/app/api/auth/login/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/logout/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/session/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/setup/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/setup/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/overview/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/stream/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/conversation/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/login.html +1 -1
- package/dist/dashboard/.next/server/app/login.rsc +1 -1
- package/dist/dashboard/.next/server/app/page.js +2 -2
- package/dist/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/setup.html +1 -1
- package/dist/dashboard/.next/server/app/setup.rsc +1 -1
- package/dist/dashboard/.next/server/app-paths-manifest.json +7 -7
- package/dist/dashboard/.next/server/chunks/972.js +1 -1
- package/dist/dashboard/.next/server/functions-config-manifest.json +4 -4
- package/dist/dashboard/.next/server/middleware.js +1 -1
- package/dist/dashboard/.next/server/pages/404.html +1 -1
- package/dist/dashboard/.next/server/pages/500.html +1 -1
- package/dist/dashboard/.next/static/chunks/app/page-0314989c31e18b4b.js +1 -0
- package/dist/dashboard/.next/static/css/{94d75aff24d0c077.css → c3a7306cb2ba3f6c.css} +1 -1
- package/dist/dashboard.js +47 -0
- package/dist/doctor.js +28 -5
- package/dist/index.js +170 -170
- package/dist/onboard.d.ts +60 -0
- package/dist/onboard.js +403 -18
- package/dist/orchestration/dispatch.d.ts +1 -0
- package/dist/orchestration/dispatch.js +17 -5
- package/dist/orchestration/evidence.js +18 -5
- package/dist/orchestration/finalize.d.ts +1 -0
- package/dist/orchestration/finalize.js +5 -3
- package/dist/orchestration/report.js +4 -1
- package/dist/orchestration/worker.d.ts +1 -1
- package/dist/orchestration/worker.js +53 -18
- package/dist/state/tasks.d.ts +5 -0
- package/dist/state/tasks.js +7 -0
- package/package.json +23 -2
- package/rules/defaults/README.md +9 -9
- package/rules/defaults/{back-zig.md → backend-agent.md} +4 -4
- package/rules/defaults/{front-zig.md → frontend-agent.md} +4 -4
- package/rules/defaults/orchestrator-agent.md +261 -0
- package/rules/defaults/{qa-zig.md → qa-agent.md} +11 -11
- package/rules/defaults/{sec-zig.md → security-agent.md} +4 -4
- package/rules/defaults/{sys-zig.md → system-agent.md} +8 -9
- package/rules/defaults/worker-common.md +25 -19
- package/skills/zigrix-doctor/SKILL.md +4 -2
- package/skills/zigrix-evidence/SKILL.md +7 -3
- package/skills/zigrix-main-agent-guide/SKILL.md +38 -28
- package/skills/zigrix-shared/SKILL.md +27 -3
- package/skills/zigrix-task-create/SKILL.md +8 -2
- package/skills/zigrix-task-status/SKILL.md +5 -2
- package/skills/zigrix-worker/SKILL.md +12 -4
- package/dist/dashboard/.next/static/chunks/app/page-25f54e54e74fb3af.js +0 -1
- package/rules/defaults/pro-zig.md +0 -238
- /package/dist/dashboard/.next/static/{TlUj0t8APzTccK13DVZZW → PT4hYxzrqxj-Zq4ZjtKNg}/_buildManifest.js +0 -0
- /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
|
|
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
|
|
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
|
|
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(
|
|
58
|
-
const loaded = loadConfig(
|
|
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
|
|
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>', '
|
|
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>', '
|
|
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(
|
|
125
|
-
const loaded = loadRuntime(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
550
|
-
const
|
|
551
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
622
|
-
.option('--auto-report', 'auto-transition to REPORTED
|
|
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(
|
|
647
|
+
const loaded = loadRuntime();
|
|
630
648
|
const result = finalizeTask(loaded.paths, {
|
|
631
649
|
taskId,
|
|
632
|
-
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
791
|
+
const loaded = loadConfig();
|
|
792
792
|
printValue(loadRunRecord(loaded.config, runIdOrPath), true);
|
|
793
793
|
});
|
|
794
794
|
// ─── dashboard ──────────────────────────────────────────────────────────────
|