cool-workflow 0.1.86 → 0.1.87
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +8 -1
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/capability-registry.js +24 -0
- package/dist/cli/command-surface.js +80 -10
- package/dist/cli.js +2 -1
- package/dist/doctor.js +13 -4
- package/dist/execution-backend.js +8 -0
- package/dist/operator-ux/format.js +21 -15
- package/dist/operator-ux.js +2 -1
- package/dist/orchestrator.js +172 -74
- package/dist/term.js +93 -0
- package/dist/version.js +1 -1
- package/docs/agent-delegation-drive.7.md +24 -6
- package/docs/cli-mcp-parity.7.md +12 -2
- package/docs/contract-migration-tooling.7.md +4 -0
- package/docs/control-plane-scheduling.7.md +4 -0
- package/docs/durable-state-and-locking.7.md +4 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
- package/docs/execution-backends.7.md +4 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
- package/docs/multi-agent-eval-replay-harness.7.md +4 -0
- package/docs/multi-agent-operator-ux.7.md +4 -0
- package/docs/node-snapshot-diff-replay.7.md +4 -0
- package/docs/observability-cost-accounting.7.md +4 -0
- package/docs/project-index.md +9 -3
- package/docs/real-execution-backends.7.md +4 -0
- package/docs/release-and-migration.7.md +4 -0
- package/docs/release-history.md +10 -0
- package/docs/release-tooling.7.md +12 -0
- package/docs/run-registry-control-plane.7.md +4 -0
- package/docs/run-retention-reclamation.7.md +4 -0
- package/docs/state-explosion-management.7.md +4 -0
- package/docs/team-collaboration.7.md +4 -0
- package/docs/web-desktop-workbench.7.md +4 -0
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/agents/agent-adapter-core.js +180 -0
- package/scripts/agents/builtin-templates.json +4 -1
- package/scripts/agents/codex-agent.js +134 -0
- package/scripts/agents/gemini-agent.js +115 -0
- package/scripts/agents/opencode-agent.js +119 -0
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/parity-check.js +6 -5
- package/scripts/release-check.js +3 -3
- package/scripts/release-gate.sh +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cool-workflow",
|
|
3
3
|
"description": "A workflow control plane and run-time you are able to check: it sends out jobs in TypeScript, makes certain of work against facts before it goes through, puts state into fixed records, orders jobs by time, runs jobs again and again, gets a group of agents to do their parts together, and talks MCP. It gives the doing of the work to outside agents — it never runs the models itself.",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.87",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "COOLWHITE LLC"
|
|
7
7
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cool-workflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.87",
|
|
4
4
|
"description": "A workflow control plane and run-time you are able to check: it sends out jobs in TypeScript, makes certain of work against facts before it goes through, puts state into fixed records, orders jobs by time, runs jobs again and again, gets a group of agents to do their parts together, and talks MCP. It gives the doing of the work to outside agents — it never runs the models itself.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "COOLWHITE LLC"
|
package/README.md
CHANGED
|
@@ -95,7 +95,10 @@ offline with `cw report verify-bundle report.cwrun.json`.
|
|
|
95
95
|
CW DELEGATES worker execution to your own agent. With no `--agent-command` (or
|
|
96
96
|
`CW_AGENT_COMMAND`) the drive fails closed (status `blocked`) — it never makes up a
|
|
97
97
|
result. `--agent-command builtin:claude` points to a bundled read-only `claude -p`
|
|
98
|
-
wrapper (needs `claude` on your PATH).
|
|
98
|
+
wrapper (needs `claude` on your PATH). `--agent-command builtin:codex` points to
|
|
99
|
+
the bundled read-only Codex wrapper (needs `codex` on your PATH). With
|
|
100
|
+
`CW_AGENT_STREAM=1`, both wrappers can show a live stderr trace while stdout stays
|
|
101
|
+
the kept data channel.
|
|
99
102
|
|
|
100
103
|
**Re-prove a finished run, offline** (`cw` is the installed bin; or `npx cool-workflow <cmd>`):
|
|
101
104
|
|
|
@@ -426,3 +429,7 @@ Verification and synthesis tasks need a structured result block:
|
|
|
426
429
|
````
|
|
427
430
|
|
|
428
431
|
v0.1.86
|
|
432
|
+
|
|
433
|
+
## 0.1.87 (v0.1.87)
|
|
434
|
+
|
|
435
|
+
npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "architecture-review",
|
|
4
4
|
"title": "Architecture Review",
|
|
5
5
|
"summary": "Map a repository architecture, assess risks, verify important findings, and synthesize an evidence-backed verdict.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.87",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "architecture-review-fast",
|
|
4
4
|
"title": "Architecture Review Fast",
|
|
5
5
|
"summary": "Run a shorter architecture review with parallel map and assess phases for faster first results.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.87",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "pr-review-fix-ci",
|
|
4
4
|
"title": "PR Review Fix CI",
|
|
5
5
|
"summary": "Review a pull request or branch, inspect CI failures, diagnose actionable issues, optionally patch, verify, and summarize with evidence.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.87",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "release-cut",
|
|
4
4
|
"title": "Release Cut",
|
|
5
5
|
"summary": "Prepare a release with checklist discipline: version checks, changelog, tests, packaging, release notes, and final verification.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.87",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "research-synthesis",
|
|
4
4
|
"title": "Research Synthesis",
|
|
5
5
|
"summary": "Split a research question into claims, investigate sources, cross-check evidence, verify claims, and synthesize a concise answer.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.87",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -61,6 +61,30 @@ const BUILTIN_CAPABILITIES = [
|
|
|
61
61
|
cli: { path: ["list"], jsonMode: "default" },
|
|
62
62
|
mcp: { tool: "cw_list" }
|
|
63
63
|
},
|
|
64
|
+
{
|
|
65
|
+
capability: "info",
|
|
66
|
+
summary: "Show what a workflow app does: title, description, inputs, sandbox, phases, and a runnable example.",
|
|
67
|
+
entry: "showApp",
|
|
68
|
+
surface: "cli-only",
|
|
69
|
+
cli: { path: ["info"], jsonMode: "flag" },
|
|
70
|
+
reason: "Human-focused workflow discovery tool (like Homebrew's `brew info`). MCP agents discover workflows via cw_list and cw_app_show tools."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
capability: "search",
|
|
74
|
+
summary: "Search workflow apps by keyword (title, description, id).",
|
|
75
|
+
entry: "listApps",
|
|
76
|
+
surface: "cli-only",
|
|
77
|
+
cli: { path: ["search"], jsonMode: "flag" },
|
|
78
|
+
reason: "Human-focused workflow discovery (like Homebrew's `brew search`). MCP agents discover workflows via cw_list tool."
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
capability: "man",
|
|
82
|
+
summary: "Show a man page from docs/ (e.g. cw man release-tooling).",
|
|
83
|
+
entry: "n/a",
|
|
84
|
+
surface: "cli-only",
|
|
85
|
+
cli: { path: ["man"], jsonMode: "human" },
|
|
86
|
+
reason: "Human documentation viewer. MCP agents read docs/ directly via file tools."
|
|
87
|
+
},
|
|
64
88
|
{
|
|
65
89
|
capability: "doctor",
|
|
66
90
|
summary: "Diagnose the host for setup problems (Node version, agent backend, agent binary on PATH, git, writable home/repo state) and print an actionable fix per check.",
|
|
@@ -22,6 +22,8 @@ const multi_agent_eval_1 = require("../multi-agent-eval");
|
|
|
22
22
|
const state_explosion_1 = require("../state-explosion");
|
|
23
23
|
const evidence_reasoning_1 = require("../evidence-reasoning");
|
|
24
24
|
const doctor_1 = require("../doctor");
|
|
25
|
+
const orchestrator_2 = require("../orchestrator");
|
|
26
|
+
const term_1 = require("../term");
|
|
25
27
|
async function runCli(argv = process.argv.slice(2)) {
|
|
26
28
|
const args = (0, orchestrator_1.parseArgv)(argv);
|
|
27
29
|
const runner = new orchestrator_1.CoolWorkflowRunner({
|
|
@@ -37,10 +39,61 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
37
39
|
case "list":
|
|
38
40
|
printJson(runner.listWorkflows());
|
|
39
41
|
return;
|
|
42
|
+
case "search": {
|
|
43
|
+
const keyword = args.positionals.join(" ");
|
|
44
|
+
if (!keyword.trim())
|
|
45
|
+
throw new Error("Missing search keyword.\n Tip: cw search architecture to find workflows about architecture.");
|
|
46
|
+
const apps = runner.listApps();
|
|
47
|
+
const lower = keyword.toLowerCase();
|
|
48
|
+
const results = apps.filter((a) => a.title.toLowerCase().includes(lower) || a.summary.toLowerCase().includes(lower) || a.id.toLowerCase().includes(lower)).map((a) => ({ id: a.id, title: a.title, summary: a.summary }));
|
|
49
|
+
if (wantsJson(args.options))
|
|
50
|
+
printJson(results);
|
|
51
|
+
else
|
|
52
|
+
process.stdout.write(`${(0, orchestrator_2.formatSearchResults)(keyword, results)}\n`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
case "man": {
|
|
56
|
+
const [topic] = args.positionals;
|
|
57
|
+
if (!topic)
|
|
58
|
+
throw new Error("Missing topic.\n Tip: cw man release-tooling for the release tooling manual.");
|
|
59
|
+
const docsDir = node_path_1.default.resolve(runner.pluginRoot, "docs");
|
|
60
|
+
const candidates = [
|
|
61
|
+
node_path_1.default.join(docsDir, `${topic}.7.md`),
|
|
62
|
+
node_path_1.default.join(docsDir, `${topic}.md`),
|
|
63
|
+
node_path_1.default.join(docsDir, `${topic}`)
|
|
64
|
+
];
|
|
65
|
+
let found;
|
|
66
|
+
for (const c of candidates) {
|
|
67
|
+
try {
|
|
68
|
+
if (node_fs_1.default.statSync(c).isFile()) {
|
|
69
|
+
found = c;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch { /* keep looking */ }
|
|
74
|
+
}
|
|
75
|
+
if (!found)
|
|
76
|
+
throw new Error(`Man page not found: ${topic}.\n Tip: cw list for workflow topics, or browse docs/ for manuals.`);
|
|
77
|
+
process.stdout.write(node_fs_1.default.readFileSync(found, "utf8"));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
case "info": {
|
|
81
|
+
const [appId] = args.positionals;
|
|
82
|
+
if (!appId)
|
|
83
|
+
throw new Error("Missing workflow app id.\n Tip: list apps with \"cw list\", then \"cw info <id>\" for details");
|
|
84
|
+
const data = runner.showApp(appId);
|
|
85
|
+
if (wantsJson(args.options))
|
|
86
|
+
printJson(data);
|
|
87
|
+
else
|
|
88
|
+
process.stdout.write(`${(0, orchestrator_2.formatInfo)(appId, data)}\n`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
40
91
|
case "doctor": {
|
|
41
92
|
const report = (0, doctor_1.runDoctor)(args.options, process.env, String(args.options.cwd || process.cwd()));
|
|
42
93
|
if (wantsJson(args.options))
|
|
43
94
|
printJson(report);
|
|
95
|
+
else if (args.options.fix)
|
|
96
|
+
process.stdout.write(`${(0, doctor_1.formatDoctorFixes)(report)}\n`);
|
|
44
97
|
else
|
|
45
98
|
process.stdout.write(`${(0, doctor_1.formatDoctorReport)(report)}\n`);
|
|
46
99
|
if (!report.ok)
|
|
@@ -50,7 +103,7 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
50
103
|
case "init": {
|
|
51
104
|
const [workflowId] = args.positionals;
|
|
52
105
|
if (!workflowId)
|
|
53
|
-
throw new Error("Missing workflow id
|
|
106
|
+
throw new Error("Missing workflow id.\n Tip: create one with \"cw init my-workflow\" or list with \"cw list\"");
|
|
54
107
|
printJson(runner.init(workflowId, args.options));
|
|
55
108
|
return;
|
|
56
109
|
}
|
|
@@ -93,6 +146,15 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
93
146
|
const runId = optionalArg(args.options.run) || optionalArg(args.options.runId);
|
|
94
147
|
const qs = (0, capability_core_1.quickstart)(runner, { ...args.options, ...(appId ? { appId } : {}), ...(runId ? { runId } : {}) });
|
|
95
148
|
printJson(qs);
|
|
149
|
+
const qr = qs;
|
|
150
|
+
if (typeof qr.runId === "string" && typeof qr.reportPath === "string") {
|
|
151
|
+
(0, term_1.printSuccessSummary)({
|
|
152
|
+
runId: qr.runId,
|
|
153
|
+
reportPath: qr.reportPath,
|
|
154
|
+
status: String(qr.status || ""),
|
|
155
|
+
bundle: Boolean(args.options.bundle)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
96
158
|
if (qs.mode === "check" && qs.ok === false) {
|
|
97
159
|
process.exitCode = 1;
|
|
98
160
|
}
|
|
@@ -107,7 +169,7 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
107
169
|
case "plan": {
|
|
108
170
|
const [workflowId] = args.positionals;
|
|
109
171
|
if (!workflowId)
|
|
110
|
-
throw new Error("Missing workflow id
|
|
172
|
+
throw new Error("Missing workflow id.\n Tip: plan an architecture review with \"cw plan architecture-review\"");
|
|
111
173
|
printJson((0, capability_core_1.planSummary)(runner, workflowId, args.options));
|
|
112
174
|
return;
|
|
113
175
|
}
|
|
@@ -121,8 +183,10 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
121
183
|
}
|
|
122
184
|
else if (wantsJson(args.options))
|
|
123
185
|
printJson(runner.status(args.positionals[0]));
|
|
124
|
-
else
|
|
125
|
-
|
|
186
|
+
else {
|
|
187
|
+
const summary = runner.operatorStatus(args.positionals[0]);
|
|
188
|
+
process.stdout.write(`${(args.options.summary || args.options.brief ? (0, operator_ux_1.formatOperatorSummary)(summary) : (0, operator_ux_1.formatOperatorStatus)(summary))}\n`);
|
|
189
|
+
}
|
|
126
190
|
return;
|
|
127
191
|
case "next":
|
|
128
192
|
printJson(runner.next(required(args.positionals[0], "run id"), args.options));
|
|
@@ -204,8 +268,10 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
204
268
|
case "status":
|
|
205
269
|
if (wantsJson(args.options))
|
|
206
270
|
printJson(runner.operatorStatus(required(runId, "run id")));
|
|
207
|
-
else
|
|
208
|
-
|
|
271
|
+
else {
|
|
272
|
+
const summary = runner.operatorStatus(required(runId, "run id"));
|
|
273
|
+
process.stdout.write(`${(args.options.summary || args.options.brief ? (0, operator_ux_1.formatOperatorSummary)(summary) : (0, operator_ux_1.formatOperatorStatus)(summary))}\n`);
|
|
274
|
+
}
|
|
209
275
|
return;
|
|
210
276
|
case "report":
|
|
211
277
|
if (wantsJson(args.options))
|
|
@@ -1050,7 +1116,9 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
1050
1116
|
driveArgs.runId = runId;
|
|
1051
1117
|
else
|
|
1052
1118
|
driveArgs.appId = target;
|
|
1053
|
-
|
|
1119
|
+
const dr = (0, capability_core_1.runDrive)(runner, driveArgs);
|
|
1120
|
+
printJson(dr);
|
|
1121
|
+
(0, term_1.printSuccessSummary)({ runId: dr.runId, reportPath: dr.reportPath, status: dr.status });
|
|
1054
1122
|
return;
|
|
1055
1123
|
}
|
|
1056
1124
|
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
@@ -1062,7 +1130,9 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
1062
1130
|
const driveArgs = { ...args.options };
|
|
1063
1131
|
if (id)
|
|
1064
1132
|
driveArgs.runId = id;
|
|
1065
|
-
|
|
1133
|
+
const dr = (0, capability_core_1.runDrive)(runner, driveArgs);
|
|
1134
|
+
printJson(dr);
|
|
1135
|
+
(0, term_1.printSuccessSummary)({ runId: dr.runId, reportPath: dr.reportPath, status: dr.status });
|
|
1066
1136
|
return;
|
|
1067
1137
|
}
|
|
1068
1138
|
printJson((0, capability_core_1.runDrivePreview)(runner, { ...args.options, runId: required(id, "run id") }));
|
|
@@ -1332,12 +1402,12 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
1332
1402
|
}
|
|
1333
1403
|
}
|
|
1334
1404
|
default:
|
|
1335
|
-
throw new Error(`Unknown command: ${args.command}`);
|
|
1405
|
+
throw new Error(`Unknown command: ${args.command}${((0, orchestrator_1.suggestCommand)(String(args.command || "")) ? `. Did you mean: ${(0, orchestrator_1.suggestCommand)(String(args.command))}?` : "")}`);
|
|
1336
1406
|
}
|
|
1337
1407
|
}
|
|
1338
1408
|
function required(value, label) {
|
|
1339
1409
|
if (!value)
|
|
1340
|
-
throw new Error(`Missing ${label}
|
|
1410
|
+
throw new Error(`Missing ${label}.\n Tip: find run ids with "cw run list" or create one with "cw quickstart"`);
|
|
1341
1411
|
return value;
|
|
1342
1412
|
}
|
|
1343
1413
|
function optionalArg(value) {
|
package/dist/cli.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const command_surface_1 = require("./cli/command-surface");
|
|
5
|
+
const term_1 = require("./term");
|
|
5
6
|
(0, command_surface_1.runCli)(process.argv.slice(2)).catch((error) => {
|
|
6
7
|
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
-
process.stderr.write(
|
|
8
|
+
process.stderr.write(`${(0, term_1.bold)("cw:")} ${(0, term_1.red)(message)}\n`);
|
|
8
9
|
process.exitCode = 1;
|
|
9
10
|
});
|
package/dist/doctor.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.runDoctor = runDoctor;
|
|
7
7
|
exports.formatDoctorReport = formatDoctorReport;
|
|
8
|
+
exports.formatDoctorFixes = formatDoctorFixes;
|
|
8
9
|
// `cw doctor` — environment diagnostics, in the spirit of `brew doctor`.
|
|
9
10
|
//
|
|
10
11
|
// Homebrew's `doctor` turned "something is subtly wrong with your setup" into a
|
|
@@ -26,6 +27,7 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
26
27
|
const node_child_process_1 = require("node:child_process");
|
|
27
28
|
const agent_config_1 = require("./agent-config");
|
|
28
29
|
const onramp_1 = require("./onramp");
|
|
30
|
+
const term_1 = require("./term");
|
|
29
31
|
/** Resolve a bare binary name against $PATH (or accept an explicit path). Returns
|
|
30
32
|
* the resolved path, or undefined when not found. No spawning. */
|
|
31
33
|
function whichBinary(bin, env) {
|
|
@@ -149,15 +151,15 @@ function runDoctor(args = {}, env = process.env, cwd = process.cwd()) {
|
|
|
149
151
|
}
|
|
150
152
|
/** Human rendering (TTY/default). `--json` callers use the report object directly. */
|
|
151
153
|
function formatDoctorReport(report) {
|
|
152
|
-
const
|
|
153
|
-
const lines = ["cw doctor"];
|
|
154
|
+
const lines = [(0, term_1.bold)("cw doctor")];
|
|
154
155
|
for (const check of report.checks) {
|
|
155
|
-
lines.push(` ${
|
|
156
|
+
lines.push(` ${(0, term_1.doctorGlyph)(check.status)} ${check.name}: ${check.detail}`);
|
|
156
157
|
if (check.fix && check.status !== "ok")
|
|
157
158
|
lines.push(` fix: ${check.fix}`);
|
|
158
159
|
}
|
|
159
160
|
lines.push("");
|
|
160
|
-
|
|
161
|
+
const summaryGlyph = report.ok ? (0, term_1.green)("✓") : (0, term_1.red)("✗");
|
|
162
|
+
lines.push(`${summaryGlyph} ${report.summary}`);
|
|
161
163
|
if (report.onramp) {
|
|
162
164
|
lines.push("");
|
|
163
165
|
lines.push("Onramp");
|
|
@@ -187,3 +189,10 @@ function formatDoctorReport(report) {
|
|
|
187
189
|
}
|
|
188
190
|
return lines.join("\n");
|
|
189
191
|
}
|
|
192
|
+
/** `--fix` rendering: consolidates all fix strings into an actionable block. */
|
|
193
|
+
function formatDoctorFixes(report) {
|
|
194
|
+
const fixes = report.checks.filter((c) => c.fix && c.status !== "ok").map((c) => c.fix);
|
|
195
|
+
if (!fixes.length)
|
|
196
|
+
return "No fixes needed.";
|
|
197
|
+
return [(0, term_1.bold)("Fix Commands"), ...fixes.map((f, i) => ` ${i + 1}. ${f}`), ""].join("\n");
|
|
198
|
+
}
|
|
@@ -411,9 +411,17 @@ function executeLocal(descriptor, policy, request, label, attestation) {
|
|
|
411
411
|
// shell backend runs via /bin/sh -c; node/bun run the command directly
|
|
412
412
|
// (bun is Node-compatible by default so evidence stays byte-stable with node).
|
|
413
413
|
// spawnStyle comes from the registered driver, not a hardcoded id check.
|
|
414
|
+
const isTTY = process.stderr.isTTY;
|
|
415
|
+
const shortLabel = command.split("/").pop() || command;
|
|
416
|
+
if (isTTY)
|
|
417
|
+
process.stderr.write(`● Running ${shortLabel}...\n`);
|
|
418
|
+
const startedAt = process.hrtime.bigint();
|
|
414
419
|
const result = getBackendDriver(descriptor.id)?.spawnStyle === "shell"
|
|
415
420
|
? (0, node_child_process_1.spawnSync)([command, ...args].join(" "), { ...options, shell: true })
|
|
416
421
|
: (0, node_child_process_1.spawnSync)(command, args, { ...options, shell: false });
|
|
422
|
+
const elapsedMs = Number((process.hrtime.bigint() - startedAt) / 1000000n);
|
|
423
|
+
if (isTTY)
|
|
424
|
+
process.stderr.write(`✓ Done (${elapsedMs}ms)\n`);
|
|
417
425
|
const exitCode = typeof result.status === "number" ? result.status : null;
|
|
418
426
|
const spawnError = result.error ? (0, util_1.messageOf)(result.error) : undefined;
|
|
419
427
|
const stdout = String(result.stdout || "");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.formatOperatorStatus = formatOperatorStatus;
|
|
4
|
+
exports.formatOperatorSummary = formatOperatorSummary;
|
|
4
5
|
exports.formatOperatorReport = formatOperatorReport;
|
|
5
6
|
exports.formatOperatorGraph = formatOperatorGraph;
|
|
6
7
|
exports.formatWorkerSummary = formatWorkerSummary;
|
|
@@ -11,18 +12,10 @@ exports.formatMultiAgentSummary = formatMultiAgentSummary;
|
|
|
11
12
|
exports.formatTopologySummary = formatTopologySummary;
|
|
12
13
|
exports.formatMultiAgentTrustAudit = formatMultiAgentTrustAudit;
|
|
13
14
|
const multi_agent_operator_ux_1 = require("../multi-agent-operator-ux");
|
|
15
|
+
const term_1 = require("../term");
|
|
14
16
|
function formatOperatorStatus(summary) {
|
|
15
|
-
const operator = summary.multiAgentOperator;
|
|
16
17
|
return [
|
|
17
|
-
|
|
18
|
-
`Workflow: ${summary.workflowId}${summary.appId ? ` (${summary.appId}@${summary.appVersion || "unknown"})` : ""}`,
|
|
19
|
-
`Loop Stage: ${summary.loopStage}`,
|
|
20
|
-
`Active Phase: ${summary.activePhase || "none"}`,
|
|
21
|
-
`Blocked: ${summary.blocked ? summary.blockedReasons.join("; ") : "no"}`,
|
|
22
|
-
`Tasks: ${formatCounts(summary.tasks.byStatus)}; total=${summary.tasks.total}`,
|
|
23
|
-
"",
|
|
24
|
-
"Phases",
|
|
25
|
-
...summary.phases.map((phase) => ` ${phase.name}: ${phase.status} (${phase.tasks.completed}/${phase.tasks.total} completed)`),
|
|
18
|
+
formatOperatorSummary(summary),
|
|
26
19
|
"",
|
|
27
20
|
formatWorkerPanel(summary.workers),
|
|
28
21
|
"",
|
|
@@ -37,9 +30,9 @@ function formatOperatorStatus(summary) {
|
|
|
37
30
|
formatMultiAgentPanel(summary.multiAgent),
|
|
38
31
|
"",
|
|
39
32
|
"Multi-Agent Operator UX",
|
|
40
|
-
` active=${operator.activeMultiAgentRunIds.join(", ") || "none"}; topologies=${operator.topologyRunIds.join(", ") || "none"}; blocked=${operator.blocked ? "yes" : "no"}`,
|
|
41
|
-
` dependencies=${operator.dependencies.length}; failures=${operator.failures.length}; adoptedEvidence=${operator.adoptedEvidence.length}; missingEvidence=${operator.missingEvidence.length}${operator.inspectableEvidence.length ? ` (inspectable=${operator.inspectableEvidence.length})` : ""}`,
|
|
42
|
-
` next=${operator.nextAction}`,
|
|
33
|
+
` active=${operator(summary).activeMultiAgentRunIds.join(", ") || "none"}; topologies=${operator(summary).topologyRunIds.join(", ") || "none"}; blocked=${operator(summary).blocked ? "yes" : "no"}`,
|
|
34
|
+
` dependencies=${operator(summary).dependencies.length}; failures=${operator(summary).failures.length}; adoptedEvidence=${operator(summary).adoptedEvidence.length}; missingEvidence=${operator(summary).missingEvidence.length}${operator(summary).inspectableEvidence.length ? ` (inspectable=${operator(summary).inspectableEvidence.length})` : ""}`,
|
|
35
|
+
` next=${operator(summary).nextAction}`,
|
|
43
36
|
"",
|
|
44
37
|
formatBlackboardPanel(summary.blackboard),
|
|
45
38
|
"",
|
|
@@ -47,10 +40,23 @@ function formatOperatorStatus(summary) {
|
|
|
47
40
|
"",
|
|
48
41
|
formatMultiAgentTrustAudit(summary.multiAgentTrust),
|
|
49
42
|
"",
|
|
50
|
-
`Report: ${summary.reportPath}
|
|
43
|
+
`Report: ${summary.reportPath}`
|
|
44
|
+
].join("\n");
|
|
45
|
+
}
|
|
46
|
+
function operator(summary) { return summary.multiAgentOperator; }
|
|
47
|
+
/** Compact summary — the default `cw status` output. `cw status --verbose` shows the full panel. */
|
|
48
|
+
function formatOperatorSummary(summary) {
|
|
49
|
+
return [
|
|
50
|
+
`Run: ${summary.runId}`,
|
|
51
|
+
`Workflow: ${summary.workflowId}${summary.appId ? ` (${summary.appId}@${summary.appVersion || "unknown"})` : ""}`,
|
|
52
|
+
`Phase: ${summary.activePhase || "none"} | Stage: ${summary.loopStage} | Blocked: ${summary.blocked ? summary.blockedReasons.join("; ") : "no"}`,
|
|
53
|
+
`Tasks: ${formatCounts(summary.tasks.byStatus)}; total=${summary.tasks.total}`,
|
|
54
|
+
...summary.phases.map((phase) => ` ${phase.name}: ${phase.status} (${phase.tasks.completed}/${phase.tasks.total} completed)`),
|
|
51
55
|
"",
|
|
52
56
|
"Next Action",
|
|
53
|
-
...formatRecommendations(summary.nextActions)
|
|
57
|
+
...formatRecommendations(summary.nextActions),
|
|
58
|
+
"",
|
|
59
|
+
(0, term_1.dim)(`(use --verbose for full worker/candidate/feedback/commit/trust panels)`)
|
|
54
60
|
].join("\n");
|
|
55
61
|
}
|
|
56
62
|
function formatOperatorReport(summary) {
|
package/dist/operator-ux.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatMultiAgentTrustAudit = exports.formatTopologySummary = exports.formatMultiAgentSummary = exports.formatCommitSummary = exports.formatFeedbackSummary = exports.formatCandidateSummary = exports.formatWorkerSummary = exports.formatOperatorGraph = exports.formatOperatorReport = exports.formatOperatorStatus = void 0;
|
|
6
|
+
exports.formatMultiAgentTrustAudit = exports.formatTopologySummary = exports.formatMultiAgentSummary = exports.formatCommitSummary = exports.formatFeedbackSummary = exports.formatCandidateSummary = exports.formatWorkerSummary = exports.formatOperatorGraph = exports.formatOperatorReport = exports.formatOperatorSummary = exports.formatOperatorStatus = void 0;
|
|
7
7
|
exports.summarizeOperatorRun = summarizeOperatorRun;
|
|
8
8
|
exports.adviseNoRun = adviseNoRun;
|
|
9
9
|
exports.summarizeOperatorWorkers = summarizeOperatorWorkers;
|
|
@@ -619,6 +619,7 @@ function safeId(value) {
|
|
|
619
619
|
// surface.
|
|
620
620
|
var format_1 = require("./operator-ux/format");
|
|
621
621
|
Object.defineProperty(exports, "formatOperatorStatus", { enumerable: true, get: function () { return format_1.formatOperatorStatus; } });
|
|
622
|
+
Object.defineProperty(exports, "formatOperatorSummary", { enumerable: true, get: function () { return format_1.formatOperatorSummary; } });
|
|
622
623
|
Object.defineProperty(exports, "formatOperatorReport", { enumerable: true, get: function () { return format_1.formatOperatorReport; } });
|
|
623
624
|
Object.defineProperty(exports, "formatOperatorGraph", { enumerable: true, get: function () { return format_1.formatOperatorGraph; } });
|
|
624
625
|
Object.defineProperty(exports, "formatWorkerSummary", { enumerable: true, get: function () { return format_1.formatWorkerSummary; } });
|