cool-workflow 0.1.94 → 0.1.95
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 +4 -0
- 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/pdca-blackboard-loop/app.json +45 -0
- package/apps/pdca-blackboard-loop/workflow.js +59 -0
- 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/cli/command-surface.js +3 -1
- package/dist/orchestrator.js +2 -1
- package/dist/version.js +1 -1
- package/docs/agent-delegation-drive.7.md +2 -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 +10 -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 +7 -4
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +2 -0
- package/docs/release-tooling.7.md +2 -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 +4 -3
- package/scripts/bump-version.js +10 -0
- 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 +7 -1
- package/scripts/release-flow.js +34 -3
- package/scripts/version-sync-check.js +2 -0
|
@@ -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.95",
|
|
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.95",
|
|
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
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
### Get a saved, cited report from your AI agent — not a chat message you lose.
|
|
16
16
|
|
|
17
|
+
<br>
|
|
18
|
+
|
|
19
|
+
<img src="https://raw.githubusercontent.com/coo1white/cool-workflow/main/docs/assets/demo.gif" alt="cw demo tamper — builds a signed ledger, forges it three ways, catches all three" width="100%">
|
|
20
|
+
|
|
17
21
|
</div>
|
|
18
22
|
|
|
19
23
|
Point an AI coding agent at a repo (or any folder of docs) and Cool Workflow turns the run into a
|
|
@@ -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.95",
|
|
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.95",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "pdca-blackboard-loop",
|
|
4
|
+
"title": "PDCA Blackboard Loop",
|
|
5
|
+
"summary": "Three agents use one blackboard to plan, build, check, and choose the next step.",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"author": "COOLWHITE LLC",
|
|
8
|
+
"inputs": [
|
|
9
|
+
{
|
|
10
|
+
"name": "goal",
|
|
11
|
+
"type": "string",
|
|
12
|
+
"required": true,
|
|
13
|
+
"description": "Work goal for the PDCA loop."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "repo",
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Optional repo or folder path."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "acceptance",
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Optional checks that say the work is done."
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"sandboxProfiles": [
|
|
27
|
+
"readonly",
|
|
28
|
+
"workspace-write"
|
|
29
|
+
],
|
|
30
|
+
"compatibility": {
|
|
31
|
+
"minVersion": "0.1.30"
|
|
32
|
+
},
|
|
33
|
+
"metadata": {
|
|
34
|
+
"example": true,
|
|
35
|
+
"domain": "coordination",
|
|
36
|
+
"uses": [
|
|
37
|
+
"blackboard",
|
|
38
|
+
"mcp",
|
|
39
|
+
"pdca"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"workflow": {
|
|
43
|
+
"entrypoint": "workflow.js"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module.exports = ({ workflow, phase, agent, input }) => {
|
|
2
|
+
const inputs = [
|
|
3
|
+
input("goal", {
|
|
4
|
+
type: "string",
|
|
5
|
+
required: true,
|
|
6
|
+
description: "Work goal for the PDCA loop."
|
|
7
|
+
}),
|
|
8
|
+
input("repo", {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Optional repo or folder path."
|
|
11
|
+
}),
|
|
12
|
+
input("acceptance", {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Optional checks that say the work is done."
|
|
15
|
+
})
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
return workflow({
|
|
19
|
+
id: "pdca-blackboard-loop",
|
|
20
|
+
title: "PDCA Blackboard Loop",
|
|
21
|
+
summary: "Three agents use one blackboard to plan, build, check, and choose the next step.",
|
|
22
|
+
limits: {
|
|
23
|
+
maxAgents: 4,
|
|
24
|
+
maxConcurrentAgents: 1
|
|
25
|
+
},
|
|
26
|
+
inputs,
|
|
27
|
+
sandboxProfiles: ["readonly", "workspace-write"],
|
|
28
|
+
phases: [
|
|
29
|
+
phase("Plan", [
|
|
30
|
+
agent(
|
|
31
|
+
"planner:plan",
|
|
32
|
+
"Plan the smallest work loop for {{goal}} in {{repo}}. Include acceptance notes: {{acceptance}}. Write the plan so the builder can use it.",
|
|
33
|
+
{ sandboxProfileId: "readonly" }
|
|
34
|
+
)
|
|
35
|
+
]),
|
|
36
|
+
phase("Do", [
|
|
37
|
+
agent(
|
|
38
|
+
"builder:build",
|
|
39
|
+
"Use the planner output and do the smallest useful work for {{goal}} in {{repo}}. If the plan is missing or unsafe, report blocked instead of success.",
|
|
40
|
+
{ requiresEvidence: true, sandboxProfileId: "workspace-write" }
|
|
41
|
+
)
|
|
42
|
+
]),
|
|
43
|
+
phase("Check", [
|
|
44
|
+
agent(
|
|
45
|
+
"auditor:audit",
|
|
46
|
+
"Check the builder output against {{acceptance}}. Cite the builder evidence. If evidence is missing, report blocked instead of success.",
|
|
47
|
+
{ requiresEvidence: true, sandboxProfileId: "readonly" }
|
|
48
|
+
)
|
|
49
|
+
]),
|
|
50
|
+
phase("Act", [
|
|
51
|
+
agent(
|
|
52
|
+
"planner:next",
|
|
53
|
+
"Read the auditor verdict and record one next action for {{goal}}: accepted, revise, or blocked. Cite the audit evidence.",
|
|
54
|
+
{ requiresEvidence: true, sandboxProfileId: "readonly" }
|
|
55
|
+
)
|
|
56
|
+
])
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
@@ -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.95",
|
|
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.95",
|
|
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.95",
|
|
7
7
|
"author": "COOLWHITE LLC",
|
|
8
8
|
"inputs": [
|
|
9
9
|
{
|
|
@@ -80,11 +80,13 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
// Map vendor shorthand flags (-claude, -codex, -deepseek) to --agent-command.
|
|
83
|
+
// Map vendor shorthand flags (-claude, -codex, -gemini, -deepseek) to --agent-command.
|
|
84
84
|
if (args.options.claude)
|
|
85
85
|
args.options["agent-command"] = "builtin:claude";
|
|
86
86
|
if (args.options.codex)
|
|
87
87
|
args.options["agent-command"] = "builtin:codex";
|
|
88
|
+
if (args.options.gemini)
|
|
89
|
+
args.options["agent-command"] = "builtin:gemini";
|
|
88
90
|
if (args.options.deepseek)
|
|
89
91
|
args.options["agent-command"] = "builtin:deepseek";
|
|
90
92
|
// -dir / --dir / -d : an intuitive alias for --repo — the project folder to review,
|
package/dist/orchestrator.js
CHANGED
|
@@ -812,7 +812,7 @@ function formatHelp() {
|
|
|
812
812
|
return [
|
|
813
813
|
(0, term_1.bold)("Cool Workflow", out),
|
|
814
814
|
"",
|
|
815
|
-
" -q \"question\" [-claude|-codex|-deepseek] Ask a question, get a report",
|
|
815
|
+
" -q \"question\" [-claude|-codex|-gemini|-deepseek] Ask a question, get a report",
|
|
816
816
|
" -q \"question\" --link <url> Review a remote repo by URL",
|
|
817
817
|
" version Show version",
|
|
818
818
|
" update Update to latest release",
|
|
@@ -825,6 +825,7 @@ function formatHelp() {
|
|
|
825
825
|
" -d, --dir PATH Project folder to review (alias for --repo)",
|
|
826
826
|
" -claude Use Claude agent",
|
|
827
827
|
" -codex Use Codex agent",
|
|
828
|
+
" -gemini Use Gemini (via opencode)",
|
|
828
829
|
" -deepseek Use DeepSeek (via opencode)",
|
|
829
830
|
" --verbose Show full agent narration live (default: compact)",
|
|
830
831
|
" --full Verbose, plus the report printed inline at the end",
|
package/dist/version.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION = exports.LEGACY_RUN_STATE_SCHEMA_VERSION = exports.CURRENT_RUN_STATE_SCHEMA_VERSION = exports.WORKFLOW_APP_SCHEMA_VERSION = exports.CURRENT_COOL_WORKFLOW_VERSION = void 0;
|
|
4
|
-
exports.CURRENT_COOL_WORKFLOW_VERSION = "0.1.
|
|
4
|
+
exports.CURRENT_COOL_WORKFLOW_VERSION = "0.1.95";
|
|
5
5
|
exports.WORKFLOW_APP_SCHEMA_VERSION = 1;
|
|
6
6
|
exports.CURRENT_RUN_STATE_SCHEMA_VERSION = 1;
|
|
7
7
|
exports.LEGACY_RUN_STATE_SCHEMA_VERSION = 0;
|
package/docs/cli-mcp-parity.7.md
CHANGED
|
@@ -129,6 +129,14 @@ The host surface fails closed when:
|
|
|
129
129
|
- selection is missing a score or verifier readiness
|
|
130
130
|
- a verifier-gated commit is not ready
|
|
131
131
|
|
|
132
|
+
## PDCA Blackboard Loop
|
|
133
|
+
|
|
134
|
+
`pdca-blackboard-loop` is a small workflow app for three-role work over one
|
|
135
|
+
blackboard: planner, builder, and auditor. The host can plan the app, post each
|
|
136
|
+
role result to one board topic through MCP, snapshot after the check step, and
|
|
137
|
+
snapshot again after the next action. Builder, auditor, and next-action tasks
|
|
138
|
+
require grounded evidence, so a verdict with no builder evidence is refused.
|
|
139
|
+
|
|
132
140
|
## Smoke Coverage
|
|
133
141
|
|
|
134
142
|
`test/multi-agent-cli-mcp-surface-smoke.js` covers the full host loop over the
|
|
@@ -307,3 +315,5 @@ The host-facing surface tracks the CLI golden-path fixes (`cw -q` routing + repo
|
|
|
307
315
|
0.1.93
|
|
308
316
|
|
|
309
317
|
0.1.94
|
|
318
|
+
|
|
319
|
+
0.1.95
|
package/docs/project-index.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Cool Workflow Project Index
|
|
2
2
|
|
|
3
|
-
Generated from the current repository code on 2026-06-
|
|
3
|
+
Generated from the current repository code on 2026-06-27 by `npm run sync:project-index`.
|
|
4
4
|
|
|
5
5
|
## Snapshot
|
|
6
6
|
|
|
7
7
|
- Package: `cool-workflow`
|
|
8
|
-
- Version: `0.1.
|
|
8
|
+
- Version: `0.1.95`
|
|
9
9
|
- Source modules: `68`
|
|
10
|
-
- Workflow apps: `
|
|
10
|
+
- Workflow apps: `8`
|
|
11
11
|
- Docs: `53`
|
|
12
|
-
- Smoke tests: `
|
|
12
|
+
- Smoke tests: `154`
|
|
13
13
|
- Repository: https://github.com/coo1white/cool-workflow
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
@@ -128,6 +128,7 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
128
128
|
| `architecture-review` - Map a repository architecture, assess risks, verify important findings, and synthesize an evidence-backed verdict. | canonical | `repo`, `question`, `invariant`, `focus` | `readonly` | [manifest](../apps/architecture-review/app.json) / [workflow](../apps/architecture-review/workflow.js) |
|
|
129
129
|
| `architecture-review-fast` - Run a shorter architecture review with parallel map and assess phases for faster first results. | canonical | `repo`, `question`, `invariant`, `focus`, `sourceContext`, `sourceContextDigest` | `readonly` | [manifest](../apps/architecture-review-fast/app.json) / [workflow](../apps/architecture-review-fast/workflow.js) |
|
|
130
130
|
| `end-to-end-golden-path` - Deterministic one-worker workflow app for proving the CW integration chain. | userland | `question` | `readonly` | [manifest](../apps/end-to-end-golden-path/app.json) / [workflow](../apps/end-to-end-golden-path/workflow.js) |
|
|
131
|
+
| `pdca-blackboard-loop` - Three agents use one blackboard to plan, build, check, and choose the next step. | example | `goal`, `repo`, `acceptance` | `readonly`, `workspace-write` | [manifest](../apps/pdca-blackboard-loop/app.json) / [workflow](../apps/pdca-blackboard-loop/workflow.js) |
|
|
131
132
|
| `pr-review-fix-ci` - Review a pull request or branch, inspect CI failures, diagnose actionable issues, optionally patch, verify, and summarize with evidence. | canonical | `repo`, `pr`, `branch`, `base`, `ci`, `mode` | `readonly`, `workspace-write` | [manifest](../apps/pr-review-fix-ci/app.json) / [workflow](../apps/pr-review-fix-ci/workflow.js) |
|
|
132
133
|
| `release-cut` - Prepare a release with checklist discipline: version checks, changelog, tests, packaging, release notes, and final verification. | canonical | `repo`, `version`, `previousVersion`, `releaseBranch`, `dryRun` | `readonly`, `workspace-write` | [manifest](../apps/release-cut/app.json) / [workflow](../apps/release-cut/workflow.js) |
|
|
133
134
|
| `research-synthesis` - Split a research question into claims, investigate sources, cross-check evidence, verify claims, and synthesize a concise answer. | canonical | `question`, `source`, `scope`, `freshness` | `readonly`, `locked-down` | [manifest](../apps/research-synthesis/app.json) / [workflow](../apps/research-synthesis/workflow.js) |
|
|
@@ -277,6 +278,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
277
278
|
- [operator-ux-smoke.js](../test/operator-ux-smoke.js)
|
|
278
279
|
- [parallel-onramp-smoke.js](../test/parallel-onramp-smoke.js)
|
|
279
280
|
- [parity-doc-sync-smoke.js](../test/parity-doc-sync-smoke.js)
|
|
281
|
+
- [pdca-blackboard-loop-smoke.js](../test/pdca-blackboard-loop-smoke.js)
|
|
280
282
|
- [pii-redaction-smoke.js](../test/pii-redaction-smoke.js)
|
|
281
283
|
- [pipeline-auto-advance-smoke.js](../test/pipeline-auto-advance-smoke.js)
|
|
282
284
|
- [pipeline-runner-smoke.js](../test/pipeline-runner-smoke.js)
|
|
@@ -291,6 +293,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
291
293
|
- [readme-trust-claim-smoke.js](../test/readme-trust-claim-smoke.js)
|
|
292
294
|
- [real-execution-backends-smoke.js](../test/real-execution-backends-smoke.js)
|
|
293
295
|
- [registry-corrupt-fail-closed-smoke.js](../test/registry-corrupt-fail-closed-smoke.js)
|
|
296
|
+
- [release-check-skip-smoke.js](../test/release-check-skip-smoke.js)
|
|
294
297
|
- [release-flow-smoke.js](../test/release-flow-smoke.js)
|
|
295
298
|
- [release-gate-smoke.js](../test/release-gate-smoke.js)
|
|
296
299
|
- [release-tooling-smoke.js](../test/release-tooling-smoke.js)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"_comment": "SINGLE SOURCE OF TRUTH for every vendor manifest. Edit THIS file, then run `npm run gen:manifests`. Do NOT hand-edit the generated vendor manifests (.claude-plugin/, .codex-plugin/, .agents/, .mcp.json) — `npm run gen:manifests -- --check` (run by release:check) will fail if they drift from this source.",
|
|
3
3
|
"identity": {
|
|
4
4
|
"name": "cool-workflow",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.95",
|
|
6
6
|
"license": "BSD-2-Clause",
|
|
7
7
|
"homepage": "https://github.com/coo1white/cool-workflow",
|
|
8
8
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cool-workflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.95",
|
|
4
4
|
"bin": {
|
|
5
5
|
"cool-workflow": "scripts/cw.js",
|
|
6
6
|
"cw": "scripts/cw.js"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/coo1white/cool-workflow/issues"
|
|
16
16
|
},
|
|
17
|
-
"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
|
|
17
|
+
"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 \u2014 it never runs the models itself.",
|
|
18
18
|
"type": "commonjs",
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=18"
|
|
@@ -85,5 +85,6 @@
|
|
|
85
85
|
"llm-pipeline",
|
|
86
86
|
"claude",
|
|
87
87
|
"delegation"
|
|
88
|
-
]
|
|
88
|
+
],
|
|
89
|
+
"mcpName": "io.github.coo1white/cool-workflow"
|
|
89
90
|
}
|
package/scripts/bump-version.js
CHANGED
|
@@ -79,6 +79,16 @@ function main() {
|
|
|
79
79
|
const lock = path.join(pluginRoot, "package-lock.json");
|
|
80
80
|
if (fs.existsSync(lock) && replaceFirstVersionField(lock, next)) note("package-lock.json");
|
|
81
81
|
|
|
82
|
+
// 2b. Official MCP Registry server metadata (top-level server version + npm package version).
|
|
83
|
+
const serverJson = path.join(pluginRoot, "server.json");
|
|
84
|
+
if (fs.existsSync(serverJson)) {
|
|
85
|
+
const json = JSON.parse(fs.readFileSync(serverJson, "utf8"));
|
|
86
|
+
json.version = next;
|
|
87
|
+
if (json.packages && json.packages[0]) json.packages[0].version = next;
|
|
88
|
+
fs.writeFileSync(serverJson, `${JSON.stringify(json, null, 2)}\n`);
|
|
89
|
+
note("server.json");
|
|
90
|
+
}
|
|
91
|
+
|
|
82
92
|
// 3. src/version.ts runtime constant
|
|
83
93
|
const versionTs = path.join(pluginRoot, "src", "version.ts");
|
|
84
94
|
const vtsText = fs.readFileSync(versionTs, "utf8");
|
|
@@ -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.95",
|
|
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.95");
|
|
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.95");
|
|
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.95");
|
|
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.95";
|
|
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.95");
|
|
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.95 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.95");
|
|
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\.95/);
|
|
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
|
@@ -7,6 +7,7 @@ const path = require("node:path");
|
|
|
7
7
|
|
|
8
8
|
const pluginRoot = path.resolve(__dirname, "..");
|
|
9
9
|
const repoRoot = path.resolve(pluginRoot, "..", "..");
|
|
10
|
+
const skipTests = process.argv.includes("--skip-tests") || process.env.CW_RELEASE_CHECK_SKIP_TESTS === "1";
|
|
10
11
|
const checks = [
|
|
11
12
|
{
|
|
12
13
|
name: "docs presence",
|
|
@@ -87,6 +88,11 @@ function main() {
|
|
|
87
88
|
process.stdout.write(`release:check ${check.name} ... `);
|
|
88
89
|
const started = Date.now();
|
|
89
90
|
try {
|
|
91
|
+
if (skipTests && check.name === "tests") {
|
|
92
|
+
results.push({ name: check.name, ok: true, skipped: true, elapsedMs: 0 });
|
|
93
|
+
process.stdout.write("skipped\n");
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
90
96
|
if (check.run) check.run();
|
|
91
97
|
else runCommand(check.command);
|
|
92
98
|
const elapsedMs = Date.now() - started;
|
|
@@ -103,7 +109,7 @@ function main() {
|
|
|
103
109
|
const failed = results.filter((entry) => !entry.ok);
|
|
104
110
|
process.stdout.write("\nRelease Check Summary\n");
|
|
105
111
|
for (const result of results) {
|
|
106
|
-
process.stdout.write(`- ${result.ok ? "PASS" : "FAIL"} ${result.name}\n`);
|
|
112
|
+
process.stdout.write(`- ${result.skipped ? "SKIP" : result.ok ? "PASS" : "FAIL"} ${result.name}\n`);
|
|
107
113
|
}
|
|
108
114
|
process.stdout.write(`\nDry-run only: no tag, push, publish, or fixture mutation was requested.\n`);
|
|
109
115
|
if (failed.length > 0) {
|
package/scripts/release-flow.js
CHANGED
|
@@ -185,6 +185,11 @@ function buildReviewerInput(resultPath) {
|
|
|
185
185
|
"or:",
|
|
186
186
|
" REJECTED",
|
|
187
187
|
" <numbered gate failures with file:line references>",
|
|
188
|
+
"",
|
|
189
|
+
"If your host wrapper asks for Markdown, JSON, or a fenced result block, still put",
|
|
190
|
+
"the exact APPROVED/REJECTED verdict line above as a standalone line outside any",
|
|
191
|
+
"prose or code fence. The release tool extracts only strict standalone verdict",
|
|
192
|
+
"lines; prose such as 'Verdict: APPROVED' is not trusted.",
|
|
188
193
|
""
|
|
189
194
|
].join("\n");
|
|
190
195
|
}
|
|
@@ -250,14 +255,28 @@ function delegateReview(resultPath, inputPath) {
|
|
|
250
255
|
};
|
|
251
256
|
|
|
252
257
|
if (cfg.command) {
|
|
253
|
-
|
|
254
|
-
|
|
258
|
+
// cfg.command can arrive as a SINGLE unsplit multi-token string. A
|
|
259
|
+
// builtin:<vendor> template (CW_AGENT_COMMAND=builtin:claude) expands to
|
|
260
|
+
// "node /abs/claude-p-agent.js {{input}} {{result}}" with cfg.args undefined,
|
|
261
|
+
// and a durable agent-config.json command field is read verbatim (no split).
|
|
262
|
+
// Split it on whitespace into binary + inline args — the SAME way the
|
|
263
|
+
// orchestrator does (src/execution-backend/agent.ts resolveAgentInvocation) —
|
|
264
|
+
// so we spawn the real binary, never one literally named
|
|
265
|
+
// "node /abs/... {{input}}" (an instant ENOENT the old code mislabeled as a
|
|
266
|
+
// timeout). An explicit cfg.args array still follows the inline args. A plain
|
|
267
|
+
// CW_AGENT_COMMAND="claude -p {{input}}" is already pre-split by
|
|
268
|
+
// resolveAgentConfig, so this leaves it unchanged (no inline args).
|
|
269
|
+
const parts = cfg.command.split(/\s+/).filter(Boolean);
|
|
270
|
+
const bin = parts[0];
|
|
271
|
+
const argTemplate = [...parts.slice(1), ...(cfg.args || [])];
|
|
272
|
+
const args = argTemplate.map((a) => substitute(a, subMap));
|
|
273
|
+
say(`[2/3] reviewer — delegating to: ${bin} ${argTemplate.join(" ")} (model: ${cfg.model || "unreported"})`);
|
|
255
274
|
// RED LINE: argv-style, shell:false. The agent runs the model in its own
|
|
256
275
|
// process and inherits its own credentials; CW holds none.
|
|
257
276
|
// Capture stdout so agents that print verdicts (rather than writing the
|
|
258
277
|
// result file) are supported. Agents that DO write the file still work:
|
|
259
278
|
// the file takes precedence. stderr goes to the terminal for live output.
|
|
260
|
-
const r = spawnSync(
|
|
279
|
+
const r = spawnSync(bin, args, {
|
|
261
280
|
cwd: repoRoot,
|
|
262
281
|
env: { ...process.env },
|
|
263
282
|
encoding: "utf8",
|
|
@@ -266,6 +285,10 @@ function delegateReview(resultPath, inputPath) {
|
|
|
266
285
|
stdio: ["ignore", "pipe", "inherit"],
|
|
267
286
|
maxBuffer: 32 * 1024 * 1024
|
|
268
287
|
});
|
|
288
|
+
// A spawn that never started (ENOENT for a missing binary, ETIMEDOUT on the
|
|
289
|
+
// deadline) sets r.error — surface its real message instead of the old
|
|
290
|
+
// catch-all "(timeout/no-exit)" that hid the builtin: ENOENT for so long.
|
|
291
|
+
if (r.error) die(`reviewer agent could not be spawned (${bin}): ${r.error.message} — no verdict trusted.`);
|
|
269
292
|
if (r.status !== 0) die(`reviewer agent exited ${r.status === null ? "(timeout/no-exit)" : r.status} — no verdict trusted.`);
|
|
270
293
|
// If the agent already wrote the verdict file (backward compat), use it.
|
|
271
294
|
// Otherwise extract the verdict from stdout (headless agent path).
|
|
@@ -316,6 +339,14 @@ function verifyVerdict(resultPath) {
|
|
|
316
339
|
const lines = text.split(/\r?\n/);
|
|
317
340
|
const firstLine = lines[0] || "";
|
|
318
341
|
if (firstLine !== `APPROVED ${HEAD}`) {
|
|
342
|
+
if (firstLine.toUpperCase() !== "REJECTED") {
|
|
343
|
+
const normalized = extractVerdictFromStdout(text, resultPath);
|
|
344
|
+
if (normalized && normalized.split(/\r?\n/)[0] === `APPROVED ${HEAD}`) {
|
|
345
|
+
fs.writeFileSync(resultPath, `${normalized}\n`);
|
|
346
|
+
const normalizedLines = normalized.split(/\r?\n/);
|
|
347
|
+
return (normalizedLines[1] || "").trim();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
319
350
|
die(`verdict first line must be exactly "APPROVED ${HEAD}" — release blocked.`, text.trim());
|
|
320
351
|
}
|
|
321
352
|
const cap = (lines[1] || "").trim();
|
|
@@ -60,6 +60,8 @@ function main() {
|
|
|
60
60
|
// uses `npm install --no-package-lock`), so only validate it when present.
|
|
61
61
|
checkJsonIfPresent("plugins/cool-workflow/package-lock.json", "version", VERSION, checks);
|
|
62
62
|
checkJson("plugins/cool-workflow/.codex-plugin/plugin.json", "version", VERSION, checks);
|
|
63
|
+
checkJson("plugins/cool-workflow/server.json", "version", VERSION, checks);
|
|
64
|
+
checkNestedJson("plugins/cool-workflow/server.json", ["packages", 0, "version"], VERSION, checks);
|
|
63
65
|
checkNestedJson("plugins/cool-workflow/manifest/plugin.manifest.json", ["identity", "version"], VERSION, checks);
|
|
64
66
|
checkJson("plugins/cool-workflow/.claude-plugin/plugin.json", "version", VERSION, checks);
|
|
65
67
|
checkJson("plugins/cool-workflow/.gemini-plugin/plugin.json", "version", VERSION, checks);
|