cool-workflow 0.1.85 → 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 +53 -332
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/architecture-review-fast/workflow.js +2 -0
- 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-core.js +131 -3
- package/dist/capability-registry.js +108 -50
- package/dist/cli/command-surface.js +83 -10
- package/dist/cli.js +2 -1
- package/dist/doctor.js +50 -5
- package/dist/execution-backend.js +8 -0
- package/dist/mcp/tool-call.js +428 -0
- package/dist/mcp/tool-definitions.js +1027 -0
- package/dist/mcp-surface.js +5 -1442
- package/dist/onramp.js +421 -0
- package/dist/operator-ux/format.js +21 -15
- package/dist/operator-ux.js +2 -1
- package/dist/orchestrator.js +190 -87
- package/dist/term.js +93 -0
- package/dist/version.js +1 -1
- package/dist/workbench-host.js +1 -8
- package/docs/agent-delegation-drive.7.md +45 -8
- package/docs/cli-mcp-parity.7.md +41 -6
- package/docs/contract-migration-tooling.7.md +6 -0
- package/docs/control-plane-scheduling.7.md +6 -0
- package/docs/dogfood-one-real-repo.7.md +9 -1
- package/docs/durable-state-and-locking.7.md +6 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +6 -0
- package/docs/execution-backends.7.md +6 -0
- package/docs/getting-started.md +40 -2
- package/docs/index.md +51 -38
- package/docs/multi-agent-cli-mcp-surface.7.md +6 -0
- package/docs/multi-agent-eval-replay-harness.7.md +6 -0
- package/docs/multi-agent-operator-ux.7.md +6 -0
- package/docs/node-snapshot-diff-replay.7.md +6 -0
- package/docs/observability-cost-accounting.7.md +6 -0
- package/docs/project-index.md +24 -7
- package/docs/real-execution-backends.7.md +6 -0
- package/docs/release-and-migration.7.md +7 -1
- package/docs/release-history.md +352 -0
- package/docs/release-tooling.7.md +28 -0
- package/docs/run-registry-control-plane.7.md +6 -0
- package/docs/run-retention-reclamation.7.md +6 -0
- package/docs/state-explosion-management.7.md +6 -0
- package/docs/team-collaboration.7.md +6 -0
- package/docs/web-desktop-workbench.7.md +6 -0
- package/manifest/plugin.manifest.json +1 -1
- package/manifest/source-context-profiles.json +1 -1
- package/package.json +2 -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/architecture-review-fast.js +44 -2
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-release.js +55 -133
- package/scripts/golden-path.js +4 -4
- package/scripts/onramp-check.js +47 -0
- package/scripts/parity-check.js +741 -2
- package/scripts/release-check.js +5 -3
- package/scripts/release-gate.sh +1 -1
- package/scripts/source-context.js +31 -5
- package/scripts/version-sync-check.js +4 -2
package/dist/onramp.js
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.optionEnabled = optionEnabled;
|
|
7
|
+
exports.npmCommand = npmCommand;
|
|
8
|
+
exports.nodeSmokeCommand = nodeSmokeCommand;
|
|
9
|
+
exports.detectSourceCheckout = detectSourceCheckout;
|
|
10
|
+
exports.shellQuote = shellQuote;
|
|
11
|
+
exports.buildDoctorOnramp = buildDoctorOnramp;
|
|
12
|
+
exports.resolveChangedFiles = resolveChangedFiles;
|
|
13
|
+
exports.evaluateOnrampContract = evaluateOnrampContract;
|
|
14
|
+
exports.recommendSmokeTests = recommendSmokeTests;
|
|
15
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
const node_child_process_1 = require("node:child_process");
|
|
18
|
+
const CURATED_SMOKE_MAP = [
|
|
19
|
+
{
|
|
20
|
+
patterns: ["src/doctor.ts", "src/onramp.ts", "scripts/onramp-check.js"],
|
|
21
|
+
smokes: ["doctor-smoke.js", "onramp-check-smoke.js"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
patterns: ["README.md", "docs/getting-started.md", "docs/index.md"],
|
|
25
|
+
smokes: ["quickstart-readme-path-smoke.js", "doctor-smoke.js"]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
patterns: ["src/cli.ts", "src/cli/"],
|
|
29
|
+
smokes: ["cli-command-surface-smoke.js", "cli-jsonmode-parity-smoke.js", "cli-mcp-parity-smoke.js"]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
patterns: ["src/orchestrator.ts"],
|
|
33
|
+
smokes: ["cli-mcp-parity-smoke.js"]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
patterns: ["src/capability-registry.ts", "scripts/parity-check.js"],
|
|
37
|
+
smokes: ["cli-mcp-parity-smoke.js", "cli-jsonmode-parity-smoke.js", "parity-doc-sync-smoke.js"]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
patterns: ["src/mcp-server.ts", "src/mcp-surface.ts"],
|
|
41
|
+
smokes: ["mcp-surface-registry-smoke.js", "mcp-app-surface-smoke.js", "cli-mcp-parity-smoke.js"]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
patterns: ["src/run-export.ts", "src/types/run.ts"],
|
|
45
|
+
smokes: ["run-export-import-smoke.js", "run-export-restore-resume-smoke.js", "run-inspect-archive-smoke.js"]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
patterns: ["src/capability-core.ts", "src/drive.ts", "src/agent-config.ts"],
|
|
49
|
+
smokes: ["quickstart-smoke.js", "quickstart-check-smoke.js", "agent-delegation-drive-smoke.js"]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
patterns: ["src/telemetry", "src/worker-accept/telemetry"],
|
|
53
|
+
smokes: ["telemetry-ledger-smoke.js", "telemetry-attestation-smoke.js", "telemetry-verify-signatures-smoke.js"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
patterns: ["src/workbench", "ui/workbench/"],
|
|
57
|
+
smokes: ["web-desktop-workbench-smoke.js"]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
patterns: ["src/scheduler.ts", "src/scheduling.ts", "src/daemon.ts", "src/triggers.ts"],
|
|
61
|
+
smokes: ["schedule-routine-daemon-smoke.js", "sched-policy-validation-smoke.js"]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
patterns: ["src/multi-agent", "src/topology.ts", "src/coordinator", "src/evidence-reasoning.ts", "src/state-explosion"],
|
|
65
|
+
smokes: [
|
|
66
|
+
"multi-agent-runtime-core-smoke.js",
|
|
67
|
+
"multi-agent-topologies-map-reduce-smoke.js",
|
|
68
|
+
"multi-agent-topologies-debate-smoke.js",
|
|
69
|
+
"multi-agent-topologies-judge-panel-smoke.js",
|
|
70
|
+
"multi-agent-cli-mcp-surface-smoke.js",
|
|
71
|
+
"blackboard-state-explosion-management-smoke.js"
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
function optionEnabled(value) {
|
|
76
|
+
if (value === undefined || value === false)
|
|
77
|
+
return false;
|
|
78
|
+
if (typeof value === "string" && ["", "0", "false", "no"].includes(value.toLowerCase()))
|
|
79
|
+
return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
function npmCommand(cwd, script) {
|
|
83
|
+
const source = detectSourceCheckout(cwd);
|
|
84
|
+
const base = `npm run ${script}`;
|
|
85
|
+
return source ? `${source.chdir}${base}` : base;
|
|
86
|
+
}
|
|
87
|
+
function nodeSmokeCommand(cwd, smoke) {
|
|
88
|
+
const source = detectSourceCheckout(cwd);
|
|
89
|
+
const base = `node test/${smoke}`;
|
|
90
|
+
return source ? `${source.chdir}${base}` : base;
|
|
91
|
+
}
|
|
92
|
+
function detectSourceCheckout(cwd) {
|
|
93
|
+
const resolved = node_path_1.default.resolve(cwd);
|
|
94
|
+
const candidates = [resolved, node_path_1.default.join(resolved, "plugins", "cool-workflow")];
|
|
95
|
+
for (const candidate of candidates) {
|
|
96
|
+
try {
|
|
97
|
+
const pkg = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(candidate, "package.json"), "utf8"));
|
|
98
|
+
if (pkg.name === "cool-workflow") {
|
|
99
|
+
return {
|
|
100
|
+
packageDir: candidate,
|
|
101
|
+
chdir: candidate === resolved ? "" : `cd ${shellQuote(node_path_1.default.relative(resolved, candidate) || ".")} && `
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
/* keep looking */
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
function shellQuote(value) {
|
|
112
|
+
if (/^[A-Za-z0-9_./:-]+$/.test(value))
|
|
113
|
+
return value;
|
|
114
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
115
|
+
}
|
|
116
|
+
function buildDoctorOnramp(options = {}) {
|
|
117
|
+
const cwd = node_path_1.default.resolve(options.cwd || process.cwd());
|
|
118
|
+
const agentCommand = "--agent-command builtin:claude";
|
|
119
|
+
const onramp = {
|
|
120
|
+
schemaVersion: 1,
|
|
121
|
+
summary: "start small, run the short gate while changing code, then run the full gate before release",
|
|
122
|
+
sections: [
|
|
123
|
+
{
|
|
124
|
+
id: "first-run",
|
|
125
|
+
title: "First Run",
|
|
126
|
+
summary: "Prove the tool, check the setup, then make one report.",
|
|
127
|
+
actions: [
|
|
128
|
+
{
|
|
129
|
+
id: "demo",
|
|
130
|
+
title: "Prove tamper checks",
|
|
131
|
+
command: "cw demo tamper",
|
|
132
|
+
reason: "Shows the core trust check without an agent or a repo."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "setup",
|
|
136
|
+
title: "Check setup",
|
|
137
|
+
command: "cw doctor --onramp",
|
|
138
|
+
reason: "Names local setup trouble before a run is made."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: "dry-run",
|
|
142
|
+
title: "Check a real run",
|
|
143
|
+
command: `cw quickstart architecture-review --check --repo /path/to/repo --question "What are the main risks?" ${agentCommand}`,
|
|
144
|
+
reason: "Does no writes and no agent call; it checks inputs first."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: "report",
|
|
148
|
+
title: "Make the report",
|
|
149
|
+
command: `cw quickstart architecture-review --repo /path/to/repo --question "What are the main risks?" ${agentCommand}`,
|
|
150
|
+
reason: "Runs the short user path: ask, run, verify, report."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "bundle",
|
|
154
|
+
title: "Make a bundle",
|
|
155
|
+
command: `cw quickstart architecture-review --repo /path/to/repo --question "What are the main risks?" ${agentCommand} --bundle`,
|
|
156
|
+
reason: "Seals a completed report into a portable file the receiver can check offline."
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "verify-bundle",
|
|
160
|
+
title: "Check the bundle",
|
|
161
|
+
command: "cw report verify-bundle report.cwrun.json",
|
|
162
|
+
reason: "Checks the report bundle without the source repo or a .cw tree."
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "change-loop",
|
|
168
|
+
title: "Change Loop",
|
|
169
|
+
summary: "Use the small checks while changing code; save the slow full gate for the end.",
|
|
170
|
+
actions: [
|
|
171
|
+
{
|
|
172
|
+
id: "build",
|
|
173
|
+
title: "Type check the change",
|
|
174
|
+
command: npmCommand(cwd, "build"),
|
|
175
|
+
reason: "Fast first check for TypeScript errors."
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "target-smoke",
|
|
179
|
+
title: "Run the closest smoke",
|
|
180
|
+
command: nodeSmokeCommand(cwd, "doctor-smoke.js"),
|
|
181
|
+
reason: "Replace this smoke name with the one that covers your changed path."
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "fast-suite",
|
|
185
|
+
title: "Run the parallel suite",
|
|
186
|
+
command: npmCommand(cwd, "test:fast"),
|
|
187
|
+
reason: "Runs all smokes with isolated state and parallel workers."
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "surface-guard",
|
|
193
|
+
title: "Surface Guard",
|
|
194
|
+
summary: "Keep the wide runner, CLI, and MCP faces tied to one source.",
|
|
195
|
+
actions: [
|
|
196
|
+
{
|
|
197
|
+
id: "registry",
|
|
198
|
+
title: "Declare each new verb once",
|
|
199
|
+
command: npmCommand(cwd, "parity:check"),
|
|
200
|
+
reason: "Fails if CLI and MCP drift from the capability registry."
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: "manifest",
|
|
204
|
+
title: "Check generated faces",
|
|
205
|
+
command: npmCommand(cwd, "gen:manifests -- --check"),
|
|
206
|
+
reason: "Fails if plugin manifests drift from source."
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
id: "release-gate",
|
|
212
|
+
title: "Release Gate",
|
|
213
|
+
summary: "Run the full gate only when the batch is ready.",
|
|
214
|
+
actions: [
|
|
215
|
+
{
|
|
216
|
+
id: "release-check",
|
|
217
|
+
title: "Dry-run the release gate",
|
|
218
|
+
command: npmCommand(cwd, "release:check"),
|
|
219
|
+
reason: "Builds, checks docs and generated files, runs the parallel suite, and makes no tag."
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
if (options.changedFrom) {
|
|
226
|
+
const changed = resolveChangedFiles({ cwd, changedFrom: options.changedFrom, env: options.env });
|
|
227
|
+
const contract = evaluateOnrampContract(changed.files, { cwd });
|
|
228
|
+
onramp.changedFiles = changed;
|
|
229
|
+
onramp.contract = contract;
|
|
230
|
+
onramp.recommendedChecks = {
|
|
231
|
+
summary: contract.recommendedSmokeTests.length
|
|
232
|
+
? "run the closest smoke tests first, then the fast suite and release gate"
|
|
233
|
+
: "no changed files were found; use the normal short checks",
|
|
234
|
+
smokeTests: contract.recommendedSmokeTests,
|
|
235
|
+
commands: contract.recommendedCommands
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return onramp;
|
|
239
|
+
}
|
|
240
|
+
function resolveChangedFiles(options = {}) {
|
|
241
|
+
const cwd = node_path_1.default.resolve(options.cwd || process.cwd());
|
|
242
|
+
const root = gitRoot(cwd);
|
|
243
|
+
const baseRef = resolveBaseRef(root, options.changedFrom, options.env || process.env);
|
|
244
|
+
const files = new Set();
|
|
245
|
+
for (const file of gitLines(root, ["diff", "--name-only", baseRef, "--"]))
|
|
246
|
+
files.add(normalizeChangedPath(file));
|
|
247
|
+
for (const file of gitLines(root, ["ls-files", "--others", "--exclude-standard"]))
|
|
248
|
+
files.add(normalizeChangedPath(file));
|
|
249
|
+
return { baseRef, files: [...files].filter(Boolean).sort() };
|
|
250
|
+
}
|
|
251
|
+
function evaluateOnrampContract(files, options = {}) {
|
|
252
|
+
const cwd = node_path_1.default.resolve(options.cwd || process.cwd());
|
|
253
|
+
const normalized = [...new Set(files.map((file) => normalizeChangedPath(file)).filter(Boolean))].sort();
|
|
254
|
+
const issues = [];
|
|
255
|
+
const runtimeFiles = normalized.filter(isRuntimeSource);
|
|
256
|
+
const appFiles = normalized.filter((file) => file.startsWith("plugins/cool-workflow/apps/"));
|
|
257
|
+
const typeFiles = normalized.filter((file) => file.startsWith("plugins/cool-workflow/src/types/") && file.endsWith(".ts"));
|
|
258
|
+
const scriptFiles = normalized.filter((file) => file.startsWith("plugins/cool-workflow/scripts/"));
|
|
259
|
+
const surfaceFiles = normalized.filter(isSurfaceFile);
|
|
260
|
+
const smokeFiles = normalized.filter((file) => /^plugins\/cool-workflow\/test\/.+-smoke\.js$/.test(file));
|
|
261
|
+
const docFiles = normalized.filter(isDocFile);
|
|
262
|
+
const iterationFiles = normalized.filter((file) => file === "ITERATION_LOG.md");
|
|
263
|
+
const sourceAppOrScript = runtimeFiles.length > 0 || typeFiles.length > 0 || appFiles.length > 0 || scriptFiles.length > 0;
|
|
264
|
+
if ((runtimeFiles.length > 0 || appFiles.length > 0) && smokeFiles.length === 0) {
|
|
265
|
+
issues.push({
|
|
266
|
+
code: "runtime-smoke-required",
|
|
267
|
+
detail: "Runtime or app changes must include at least one smoke test change.",
|
|
268
|
+
fix: "Add or update a focused test/*-smoke.js file for the changed behavior.",
|
|
269
|
+
files: [...runtimeFiles, ...appFiles]
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (typeFiles.length > 0 && runtimeFiles.length === 0 && appFiles.length === 0) {
|
|
273
|
+
issues.push({
|
|
274
|
+
code: "types-without-runtime",
|
|
275
|
+
detail: "Type-only source changes are not a valid cycle.",
|
|
276
|
+
fix: "Add the runtime behavior that reads the type, or remove the type-only change.",
|
|
277
|
+
files: typeFiles
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (surfaceFiles.length > 0 && docFiles.length === 0) {
|
|
281
|
+
issues.push({
|
|
282
|
+
code: "surface-docs-required",
|
|
283
|
+
detail: "CLI, MCP, or capability surface changes must update public docs.",
|
|
284
|
+
fix: "Update README.md or plugins/cool-workflow/docs/*.md with the changed surface.",
|
|
285
|
+
files: surfaceFiles
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (sourceAppOrScript && iterationFiles.length === 0) {
|
|
289
|
+
issues.push({
|
|
290
|
+
code: "iteration-log-required",
|
|
291
|
+
detail: "Source, app, or script changes must be recorded in ITERATION_LOG.md.",
|
|
292
|
+
fix: "Append one cycle row with goal, files, tests, gate, and tag decision.",
|
|
293
|
+
files: [...runtimeFiles, ...typeFiles, ...appFiles, ...scriptFiles]
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
const recommendedSmokeTests = recommendSmokeTests(normalized, cwd);
|
|
297
|
+
return {
|
|
298
|
+
ok: issues.length === 0,
|
|
299
|
+
changedFiles: normalized,
|
|
300
|
+
recommendedSmokeTests,
|
|
301
|
+
recommendedCommands: recommendedCommands(normalized, recommendedSmokeTests, cwd),
|
|
302
|
+
issues
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function recommendSmokeTests(files, cwd = process.cwd()) {
|
|
306
|
+
const normalized = files.map((file) => normalizeChangedPath(file));
|
|
307
|
+
const smokes = new Set();
|
|
308
|
+
const curatedFiles = new Set();
|
|
309
|
+
for (const file of normalized) {
|
|
310
|
+
const pluginPath = stripPluginPrefix(file);
|
|
311
|
+
for (const entry of CURATED_SMOKE_MAP) {
|
|
312
|
+
const matched = entry.patterns.some((pattern) => pluginPath === pattern || pluginPath.startsWith(pattern));
|
|
313
|
+
if (matched) {
|
|
314
|
+
curatedFiles.add(file);
|
|
315
|
+
for (const smoke of entry.smokes)
|
|
316
|
+
smokes.add(smoke);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const available = availableSmokeTests(cwd);
|
|
321
|
+
for (const file of normalized) {
|
|
322
|
+
if (curatedFiles.has(file))
|
|
323
|
+
continue;
|
|
324
|
+
const pluginPath = stripPluginPrefix(file);
|
|
325
|
+
if (!pluginPath.startsWith("src/"))
|
|
326
|
+
continue;
|
|
327
|
+
const base = node_path_1.default.basename(pluginPath, ".ts");
|
|
328
|
+
const direct = `${base}-smoke.js`;
|
|
329
|
+
if (available.includes(direct))
|
|
330
|
+
smokes.add(direct);
|
|
331
|
+
const tokens = base.split(/[^a-zA-Z0-9]+/).filter((token) => token.length >= 3);
|
|
332
|
+
for (const smoke of available) {
|
|
333
|
+
if (tokens.some((token) => smoke.includes(token)))
|
|
334
|
+
smokes.add(smoke);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return [...smokes].sort();
|
|
338
|
+
}
|
|
339
|
+
function recommendedCommands(files, smokes, cwd) {
|
|
340
|
+
const commands = new Set();
|
|
341
|
+
commands.add(npmCommand(cwd, "build"));
|
|
342
|
+
for (const smoke of smokes)
|
|
343
|
+
commands.add(nodeSmokeCommand(cwd, smoke));
|
|
344
|
+
commands.add(npmCommand(cwd, "test:fast"));
|
|
345
|
+
if (files.some(isSurfaceFile))
|
|
346
|
+
commands.add(npmCommand(cwd, "parity:check"));
|
|
347
|
+
if (files.some(isSurfaceFile))
|
|
348
|
+
commands.add(npmCommand(cwd, "gen:manifests -- --check"));
|
|
349
|
+
commands.add(npmCommand(cwd, "release:check"));
|
|
350
|
+
return [...commands];
|
|
351
|
+
}
|
|
352
|
+
function resolveBaseRef(root, changedFrom, env) {
|
|
353
|
+
if (changedFrom)
|
|
354
|
+
return verifyRef(root, changedFrom);
|
|
355
|
+
if (env.CW_ONRAMP_BASE)
|
|
356
|
+
return verifyRef(root, env.CW_ONRAMP_BASE);
|
|
357
|
+
const baseBranch = env.GITHUB_BASE_REF ? `origin/${env.GITHUB_BASE_REF}` : "origin/main";
|
|
358
|
+
const mergeBase = gitOne(root, ["merge-base", "HEAD", baseBranch]);
|
|
359
|
+
if (mergeBase)
|
|
360
|
+
return mergeBase;
|
|
361
|
+
return verifyRef(root, "HEAD");
|
|
362
|
+
}
|
|
363
|
+
function verifyRef(root, ref) {
|
|
364
|
+
const resolved = gitOne(root, ["rev-parse", "--verify", `${ref}^{commit}`]);
|
|
365
|
+
if (!resolved)
|
|
366
|
+
throw new Error(`Unknown onramp base ref: ${ref}`);
|
|
367
|
+
return ref;
|
|
368
|
+
}
|
|
369
|
+
function gitRoot(cwd) {
|
|
370
|
+
return gitOne(node_path_1.default.resolve(cwd), ["rev-parse", "--show-toplevel"]) || node_path_1.default.resolve(cwd);
|
|
371
|
+
}
|
|
372
|
+
function gitLines(cwd, args) {
|
|
373
|
+
const result = (0, node_child_process_1.spawnSync)("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
374
|
+
if (result.status !== 0)
|
|
375
|
+
return [];
|
|
376
|
+
return String(result.stdout || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
377
|
+
}
|
|
378
|
+
function gitOne(cwd, args) {
|
|
379
|
+
return gitLines(cwd, args)[0] || "";
|
|
380
|
+
}
|
|
381
|
+
function availableSmokeTests(cwd) {
|
|
382
|
+
const source = detectSourceCheckout(cwd);
|
|
383
|
+
const testDir = source ? node_path_1.default.join(source.packageDir, "test") : node_path_1.default.join(node_path_1.default.resolve(cwd), "test");
|
|
384
|
+
try {
|
|
385
|
+
return node_fs_1.default.readdirSync(testDir).filter((file) => file.endsWith("-smoke.js")).sort();
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return [];
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function normalizeChangedPath(file) {
|
|
392
|
+
const normalized = file.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
393
|
+
if (/^(src|apps|scripts|test|docs|dist|manifest|ui|workflows)\//.test(normalized)) {
|
|
394
|
+
return `plugins/cool-workflow/${normalized}`;
|
|
395
|
+
}
|
|
396
|
+
return normalized;
|
|
397
|
+
}
|
|
398
|
+
function stripPluginPrefix(file) {
|
|
399
|
+
return file.startsWith("plugins/cool-workflow/") ? file.slice("plugins/cool-workflow/".length) : file;
|
|
400
|
+
}
|
|
401
|
+
function isRuntimeSource(file) {
|
|
402
|
+
return file.startsWith("plugins/cool-workflow/src/") && file.endsWith(".ts") && !file.startsWith("plugins/cool-workflow/src/types/");
|
|
403
|
+
}
|
|
404
|
+
function isSurfaceFile(file) {
|
|
405
|
+
const pluginPath = stripPluginPrefix(file);
|
|
406
|
+
return (pluginPath === "src/cli.ts" ||
|
|
407
|
+
pluginPath.startsWith("src/cli/") ||
|
|
408
|
+
pluginPath === "src/capability-registry.ts" ||
|
|
409
|
+
pluginPath === "src/mcp-server.ts" ||
|
|
410
|
+
pluginPath === "src/mcp-surface.ts" ||
|
|
411
|
+
pluginPath === "src/orchestrator.ts" ||
|
|
412
|
+
pluginPath === "scripts/parity-check.js");
|
|
413
|
+
}
|
|
414
|
+
function isDocFile(file) {
|
|
415
|
+
return (file === "README.md" ||
|
|
416
|
+
file === "CHANGELOG.md" ||
|
|
417
|
+
file === "RELEASE.md" ||
|
|
418
|
+
file.startsWith("docs/") ||
|
|
419
|
+
file === "plugins/cool-workflow/README.md" ||
|
|
420
|
+
file.startsWith("plugins/cool-workflow/docs/"));
|
|
421
|
+
}
|
|
@@ -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; } });
|