cool-workflow 0.1.91 → 0.1.92
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 +78 -376
- 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/apps/research-synthesis/workflow.js +1 -1
- package/dist/doctor.js +1 -0
- package/dist/orchestrator/report.js +6 -1
- package/dist/version.js +1 -1
- package/docs/agent-delegation-drive.7.md +2 -0
- package/docs/canonical-workflow-apps.7.md +12 -0
- package/docs/cli-mcp-parity.7.md +2 -0
- package/docs/contract-migration-tooling.7.md +2 -0
- package/docs/control-plane-scheduling.7.md +2 -0
- package/docs/durable-state-and-locking.7.md +2 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
- package/docs/execution-backends.7.md +2 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +2 -0
- package/docs/multi-agent-eval-replay-harness.7.md +2 -0
- package/docs/multi-agent-operator-ux.7.md +2 -0
- package/docs/node-snapshot-diff-replay.7.md +2 -0
- package/docs/observability-cost-accounting.7.md +2 -0
- package/docs/project-index.md +4 -2
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +2 -0
- package/docs/release-tooling.7.md +11 -0
- package/docs/run-registry-control-plane.7.md +2 -0
- package/docs/run-retention-reclamation.7.md +2 -0
- package/docs/state-explosion-management.7.md +2 -0
- package/docs/team-collaboration.7.md +2 -0
- package/docs/web-desktop-workbench.7.md +2 -0
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +3 -1
- package/scripts/agents/agent-adapter-core.js +179 -28
- package/scripts/agents/claude-p-agent.js +24 -7
- package/scripts/agents/codex-agent.js +1 -1
- package/scripts/agents/gemini-agent.js +1 -1
- package/scripts/agents/opencode-agent.js +1 -1
- package/scripts/bump-version.js +4 -1
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/release-check.js +5 -1
- package/scripts/sync-readme.js +123 -0
- package/scripts/version-sync-check.js +5 -1
|
@@ -33,7 +33,7 @@ if (!inputPath || !resultPath) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const prompt = buildPrompt(inputPath);
|
|
36
|
-
const render = createRenderer({ env: process.env, stderr: process.stderr });
|
|
36
|
+
const render = createRenderer({ env: process.env, stderr: process.stderr, label: "gemini" });
|
|
37
37
|
const transcriptPath = path.join(path.dirname(resultPath), "transcript.md");
|
|
38
38
|
const state = { provider: "gemini", buffer: "", model: undefined, usage: undefined, textFragments: [], finalResult: undefined, renderer: render };
|
|
39
39
|
let childStderr = "";
|
|
@@ -38,7 +38,7 @@ if (!inputPath || !resultPath) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const prompt = buildPrompt(inputPath);
|
|
41
|
-
const render = createRenderer({ env: process.env, stderr: process.stderr });
|
|
41
|
+
const render = createRenderer({ env: process.env, stderr: process.stderr, label: "opencode" });
|
|
42
42
|
const transcriptPath = path.join(path.dirname(resultPath), "transcript.md");
|
|
43
43
|
const state = { provider: "opencode", buffer: "", model: undefined, usage: undefined, textFragments: [], finalResult: undefined, renderer: render };
|
|
44
44
|
let childStderr = "";
|
package/scripts/bump-version.js
CHANGED
|
@@ -167,7 +167,10 @@ function contentSurfaceFiles(next) {
|
|
|
167
167
|
// All files the version-sync-check script validates for VERSION or vX.Y.Z.
|
|
168
168
|
// Keep in sync with scripts/version-sync-check.js.
|
|
169
169
|
return [
|
|
170
|
-
|
|
170
|
+
// The npm package README (plugins/cool-workflow/README.md) is GENERATED from the GitHub
|
|
171
|
+
// README.md by scripts/sync-readme.js and shows the version via the live npm/release shields
|
|
172
|
+
// badges, not a hand-maintained literal — so it is NOT a version-bump surface. After a bump,
|
|
173
|
+
// `npm run sync:readme` keeps it byte-identical to the GitHub README (guarded by readme:check).
|
|
171
174
|
{ path: "plugins/cool-workflow/docs/multi-agent-cli-mcp-surface.7.md", needle: next, desc: "multi-agent CLI/MCP surface doc" },
|
|
172
175
|
{ path: "plugins/cool-workflow/docs/multi-agent-operator-ux.7.md", needle: next, desc: "multi-agent operator UX doc" },
|
|
173
176
|
{ path: "plugins/cool-workflow/docs/multi-agent-eval-replay-harness.7.md", needle: next, desc: "multi-agent eval/replay doc" },
|
|
@@ -83,7 +83,7 @@ const canonicalApps = [
|
|
|
83
83
|
"--source",
|
|
84
84
|
"plugins/cool-workflow/docs/workflow-app-framework.7.md",
|
|
85
85
|
"--scope",
|
|
86
|
-
"Cool Workflow v0.1.
|
|
86
|
+
"Cool Workflow v0.1.92",
|
|
87
87
|
"--freshness",
|
|
88
88
|
"as of release preparation"
|
|
89
89
|
]
|
|
@@ -117,14 +117,14 @@ function main() {
|
|
|
117
117
|
assert.ok(summary, `${app.id} must appear in app list`);
|
|
118
118
|
assert.equal(summary.sourceKind, "app-directory");
|
|
119
119
|
assert.equal(summary.legacy, false);
|
|
120
|
-
assert.equal(summary.version, "0.1.
|
|
120
|
+
assert.equal(summary.version, "0.1.92");
|
|
121
121
|
|
|
122
122
|
const validation = runJson(["app", "validate", manifestPath]);
|
|
123
123
|
assert.equal(validation.valid, true, `${app.id} manifest must validate`);
|
|
124
124
|
|
|
125
125
|
const shown = runJson(["app", "show", app.id]);
|
|
126
126
|
assert.equal(shown.app.id, app.id);
|
|
127
|
-
assert.equal(shown.app.version, "0.1.
|
|
127
|
+
assert.equal(shown.app.version, "0.1.92");
|
|
128
128
|
assert.ok(shown.app.metadata.canonical, `${app.id} must be marked canonical`);
|
|
129
129
|
assert.ok(shown.app.sandboxProfiles.length > 0, `${app.id} must declare sandbox profiles`);
|
|
130
130
|
assertTaskIdsUnique(shown);
|
|
@@ -135,7 +135,7 @@ function main() {
|
|
|
135
135
|
const plan = runJson(["plan", app.id, ...app.args(workspace)]);
|
|
136
136
|
const state = JSON.parse(fs.readFileSync(plan.statePath, "utf8"));
|
|
137
137
|
assert.equal(state.workflow.app.id, app.id);
|
|
138
|
-
assert.equal(state.workflow.app.version, "0.1.
|
|
138
|
+
assert.equal(state.workflow.app.version, "0.1.92");
|
|
139
139
|
assert.equal(state.workflow.app.metadata.canonical, true);
|
|
140
140
|
assert.ok(state.tasks.some((task) => task.requiresEvidence), `${app.id} plan must include evidence gates`);
|
|
141
141
|
assert.ok(state.tasks.every((task) => task.sandboxProfileId), `${app.id} plan must include sandbox hints`);
|
|
@@ -6,7 +6,7 @@ const fs = require("node:fs");
|
|
|
6
6
|
const path = require("node:path");
|
|
7
7
|
const { CoolWorkflowRunner } = require("../dist/orchestrator.js");
|
|
8
8
|
|
|
9
|
-
const TARGET_VERSION = "0.1.
|
|
9
|
+
const TARGET_VERSION = "0.1.92";
|
|
10
10
|
const PREVIOUS_VERSION = "0.1.31";
|
|
11
11
|
const pluginRoot = path.resolve(__dirname, "..");
|
|
12
12
|
const repoRoot = path.resolve(pluginRoot, "..", "..");
|
package/scripts/golden-path.js
CHANGED
|
@@ -33,7 +33,7 @@ function main() {
|
|
|
33
33
|
const appValidation = runJson(["app", "validate", "end-to-end-golden-path"], pluginRoot);
|
|
34
34
|
assert.equal(appValidation.valid, true);
|
|
35
35
|
assert.equal(appValidation.summary.id, "end-to-end-golden-path");
|
|
36
|
-
assert.equal(appValidation.summary.version, "0.1.
|
|
36
|
+
assert.equal(appValidation.summary.version, "0.1.92");
|
|
37
37
|
|
|
38
38
|
const plan = runJson(
|
|
39
39
|
[
|
|
@@ -42,7 +42,7 @@ function main() {
|
|
|
42
42
|
"--repo",
|
|
43
43
|
tmp,
|
|
44
44
|
"--question",
|
|
45
|
-
"Prove the deterministic v0.1.
|
|
45
|
+
"Prove the deterministic v0.1.92 end-to-end golden path."
|
|
46
46
|
],
|
|
47
47
|
pluginRoot
|
|
48
48
|
);
|
|
@@ -52,7 +52,7 @@ function main() {
|
|
|
52
52
|
|
|
53
53
|
let state = readJson(plan.statePath);
|
|
54
54
|
assert.equal(state.workflow.app.id, "end-to-end-golden-path");
|
|
55
|
-
assert.equal(state.workflow.app.version, "0.1.
|
|
55
|
+
assert.equal(state.workflow.app.version, "0.1.92");
|
|
56
56
|
assert.equal(state.loopStage, "interpret");
|
|
57
57
|
|
|
58
58
|
const dispatch = runJson(["dispatch", plan.runId, "--limit", "1", "--sandbox", "readonly"], tmp);
|
|
@@ -195,7 +195,7 @@ function main() {
|
|
|
195
195
|
assert.equal(reportPath, plan.reportPath);
|
|
196
196
|
assert.ok(fs.existsSync(reportPath));
|
|
197
197
|
const report = fs.readFileSync(reportPath, "utf8");
|
|
198
|
-
assert.match(report, /Workflow App: end-to-end-golden-path@0\.1\.
|
|
198
|
+
assert.match(report, /Workflow App: end-to-end-golden-path@0\.1\.92/);
|
|
199
199
|
assert.match(report, /## Candidates/);
|
|
200
200
|
assert.match(report, /## Trust Audit/);
|
|
201
201
|
assert.match(report, /## Acceptance Rationale/);
|
package/scripts/release-check.js
CHANGED
|
@@ -74,7 +74,11 @@ const checks = [
|
|
|
74
74
|
// drifted from a fresh source scan. The teeth-on-the-gate live in
|
|
75
75
|
// test/project-index-sync-smoke.js (run by `npm test`); this entry gives the
|
|
76
76
|
// real-doc check its own visible PASS/FAIL line in the release summary.
|
|
77
|
-
{ name: "project index sync", command: ["npm", "run", "index:check"] }
|
|
77
|
+
{ name: "project index sync", command: ["npm", "run", "index:check"] },
|
|
78
|
+
// Fail closed if the npm README (plugins/cool-workflow/README.md) has drifted
|
|
79
|
+
// from the GitHub README.md it is generated from. Keeps the two pages identical
|
|
80
|
+
// by construction; teeth live in test/readme-sync-smoke.js (run by `npm test`).
|
|
81
|
+
{ name: "readme sync", command: ["npm", "run", "readme:check"] }
|
|
78
82
|
];
|
|
79
83
|
|
|
80
84
|
function main() {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// sync-readme — keep the npm package README in lockstep with the GitHub README.
|
|
5
|
+
//
|
|
6
|
+
// The repo-root README.md is the SINGLE SOURCE OF TRUTH. This generates the npm
|
|
7
|
+
// page (plugins/cool-workflow/README.md) from it, changing ONLY what npm needs to
|
|
8
|
+
// render: relative URLs become absolute, because npm cannot resolve a repo's
|
|
9
|
+
// relative `docs/assets/...` image paths or `](LICENSE)` links the way GitHub can.
|
|
10
|
+
//
|
|
11
|
+
// <img src="docs/assets/x.svg"> -> raw.githubusercontent.com/<owner>/<repo>/main/docs/assets/x.svg
|
|
12
|
+
// ](LICENSE) / ](plugins/...) -> github.com/<owner>/<repo>/blob/main/...
|
|
13
|
+
//
|
|
14
|
+
// The text content is otherwise identical, so the two pages can never drift.
|
|
15
|
+
//
|
|
16
|
+
// --check : regenerate in memory, compare to the committed npm README, write
|
|
17
|
+
// nothing, exit non-zero on drift (the release/CI gate). Mirrors
|
|
18
|
+
// sync-project-index.js. Fork-safe: the owner/repo in the absolute URLs
|
|
19
|
+
// is normalized out of the compare, so a fork clone never false-REDs.
|
|
20
|
+
|
|
21
|
+
const fs = require("node:fs");
|
|
22
|
+
const path = require("node:path");
|
|
23
|
+
const { spawnSync } = require("node:child_process");
|
|
24
|
+
|
|
25
|
+
const pluginRoot = path.resolve(__dirname, "..");
|
|
26
|
+
const repoRoot = path.resolve(pluginRoot, "..", "..");
|
|
27
|
+
const sourceReadme = path.join(repoRoot, "README.md");
|
|
28
|
+
// CW_README_PATH overrides the npm README that --check compares against (used by
|
|
29
|
+
// the smoke to point --check at a throwaway drifted fixture). Default: the real one.
|
|
30
|
+
const targetReadme = process.env.CW_README_PATH
|
|
31
|
+
? path.resolve(process.env.CW_README_PATH)
|
|
32
|
+
: path.join(pluginRoot, "README.md");
|
|
33
|
+
|
|
34
|
+
const repoUrl = normalizeGitRemote(git(["config", "--get", "remote.origin.url"]).trim())
|
|
35
|
+
|| "https://github.com/coo1white/cool-workflow";
|
|
36
|
+
const ownerRepo = repoUrl.replace(/^https:\/\/github\.com\//, "");
|
|
37
|
+
const RAW_BASE = `https://raw.githubusercontent.com/${ownerRepo}/main`;
|
|
38
|
+
const BLOB_BASE = `${repoUrl}/blob/main`;
|
|
39
|
+
|
|
40
|
+
const MARKER =
|
|
41
|
+
"<!-- AUTO-GENERATED from /README.md by scripts/sync-readme.js — edit the root README, " +
|
|
42
|
+
"then run `npm run sync:readme`. DO NOT edit this file directly. -->";
|
|
43
|
+
|
|
44
|
+
const CHECK = process.argv.includes("--check");
|
|
45
|
+
|
|
46
|
+
function render() {
|
|
47
|
+
if (!fs.existsSync(sourceReadme)) {
|
|
48
|
+
process.stderr.write(`sync-readme FAILED: source ${path.relative(repoRoot, sourceReadme)} does not exist.\n`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const source = fs.readFileSync(sourceReadme, "utf8");
|
|
52
|
+
// NOTE: a relative path must be free of a literal "(", ")", or '"' — the [^)]+ / [^"]+
|
|
53
|
+
// captures below stop at those. The repo README has none; readme:check catches any drift.
|
|
54
|
+
const absolutized = source
|
|
55
|
+
// HTML image sources: <img src="docs/assets/x.svg"> -> raw URL (skip already-absolute / anchors)
|
|
56
|
+
.replace(/\bsrc="(?!https?:|#|data:)([^"]+)"/g, (_m, rel) => `src="${RAW_BASE}/${rel}"`)
|
|
57
|
+
// Markdown links: ](LICENSE) / ](plugins/...) -> blob URL (skip absolute / in-page anchors / mailto)
|
|
58
|
+
.replace(/\]\((?!https?:|#|mailto:)([^)]+)\)/g, (_m, rel) => `](${BLOB_BASE}/${rel})`);
|
|
59
|
+
return `${MARKER}\n${absolutized}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function normalizeForCompare(text) {
|
|
63
|
+
// Strip the owner/repo from the generated absolute URLs so a fork (whose git
|
|
64
|
+
// remote differs) does not false-RED against the canonical committed README.
|
|
65
|
+
// The CONTENT is what this gate guards; the owner/repo is environment-derived.
|
|
66
|
+
return text
|
|
67
|
+
.replace(/\r\n/g, "\n")
|
|
68
|
+
.replace(/https:\/\/raw\.githubusercontent\.com\/[^/]+\/[^/]+\/main/g, "<RAW>")
|
|
69
|
+
.replace(/https:\/\/github\.com\/[^/]+\/[^/]+\/blob\/main/g, "<BLOB>");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function main() {
|
|
73
|
+
const rendered = render();
|
|
74
|
+
const rel = path.relative(repoRoot, targetReadme);
|
|
75
|
+
|
|
76
|
+
if (CHECK) {
|
|
77
|
+
if (!fs.existsSync(targetReadme)) {
|
|
78
|
+
process.stderr.write(`readme check FAILED: ${rel} does not exist.\nRun: (cd plugins/cool-workflow && npm run sync:readme)\n`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const committed = normalizeForCompare(fs.readFileSync(targetReadme, "utf8"));
|
|
82
|
+
const fresh = normalizeForCompare(rendered);
|
|
83
|
+
if (committed === fresh) {
|
|
84
|
+
process.stdout.write(`${JSON.stringify({ ok: true, check: true, source: "README.md", doc: rel }, null, 2)}\n`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const a = committed.split("\n");
|
|
88
|
+
const b = fresh.split("\n");
|
|
89
|
+
let i = 0;
|
|
90
|
+
while (i < a.length && i < b.length && a[i] === b[i]) i++;
|
|
91
|
+
process.stderr.write(
|
|
92
|
+
`readme check FAILED: ${rel} is stale (does not match the GitHub README.md).\n` +
|
|
93
|
+
`First difference at line ${i + 1}:\n` +
|
|
94
|
+
` committed: ${JSON.stringify(a[i] ?? "<missing>")}\n` +
|
|
95
|
+
` expected: ${JSON.stringify(b[i] ?? "<missing>")}\n` +
|
|
96
|
+
`Regenerate with: (cd plugins/cool-workflow && npm run sync:readme)\n`
|
|
97
|
+
);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fs.writeFileSync(targetReadme, rendered, "utf8");
|
|
102
|
+
process.stdout.write(`${JSON.stringify({
|
|
103
|
+
ok: true,
|
|
104
|
+
source: "README.md",
|
|
105
|
+
output: rel,
|
|
106
|
+
repoUrl
|
|
107
|
+
}, null, 2)}\n`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function git(args) {
|
|
111
|
+
const result = spawnSync("git", args, { cwd: repoRoot, encoding: "utf8" });
|
|
112
|
+
return result.status === 0 ? result.stdout : "";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function normalizeGitRemote(remote) {
|
|
116
|
+
if (!remote) return "";
|
|
117
|
+
if (remote.endsWith(".git")) remote = remote.slice(0, -4);
|
|
118
|
+
const sshMatch = remote.match(/^git@github\.com:(.+)$/);
|
|
119
|
+
if (sshMatch) return `https://github.com/${sshMatch[1]}`;
|
|
120
|
+
return remote;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main();
|
|
@@ -92,7 +92,11 @@ function main() {
|
|
|
92
92
|
checkIncludes("plugins/cool-workflow/dist/mcp-server.js", "CURRENT_COOL_WORKFLOW_VERSION", checks);
|
|
93
93
|
checkIncludes("plugins/cool-workflow/dist/workflow-app-framework.js", "CURRENT_COOL_WORKFLOW_VERSION", checks);
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
// The npm package README (plugins/cool-workflow/README.md) is GENERATED from the GitHub
|
|
96
|
+
// README.md (scripts/sync-readme.js) and conveys the version via the live npm/release shields
|
|
97
|
+
// badges — not a hand-maintained literal — exactly like the GitHub page. It is no longer
|
|
98
|
+
// version-pinned here; readme:check guards that the two pages stay identical, and the surfaces
|
|
99
|
+
// above (version.ts/dist/package.json/manifests/docs) still pin the release.
|
|
96
100
|
checkIncludes("plugins/cool-workflow/docs/index.md", "release and migration", checks);
|
|
97
101
|
checkIncludes("plugins/cool-workflow/docs/multi-agent-topologies.7.md", "Multi-Agent Topologies", checks);
|
|
98
102
|
checkIncludes("plugins/cool-workflow/docs/multi-agent-cli-mcp-surface.7.md", VERSION, checks);
|