cool-workflow 0.2.3 → 0.2.5

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.
Files changed (143) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/.gemini-plugin/mcp.json +10 -0
  4. package/.gemini-plugin/plugin.json +40 -0
  5. package/.opencode-plugin/mcp.json +10 -0
  6. package/.opencode-plugin/plugin.json +40 -0
  7. package/README.md +202 -48
  8. package/apps/architecture-review/app.json +1 -1
  9. package/apps/architecture-review-fast/app.json +1 -1
  10. package/apps/end-to-end-golden-path/app.json +1 -1
  11. package/apps/pr-review-fix-ci/app.json +1 -1
  12. package/apps/release-cut/app.json +1 -1
  13. package/apps/research-synthesis/app.json +1 -1
  14. package/dist/cli/dispatch.js +33 -4
  15. package/dist/cli/entry.js +11 -19
  16. package/dist/cli/global-flags.js +113 -0
  17. package/dist/cli/io.js +6 -20
  18. package/dist/cli/parseargv.js +7 -1
  19. package/dist/core/capability-data.js +339 -10
  20. package/dist/core/format/help.js +80 -4
  21. package/dist/core/format/recovery-hint.js +32 -0
  22. package/dist/core/multi-agent/collaboration.js +35 -6
  23. package/dist/core/multi-agent/runtime.js +7 -0
  24. package/dist/core/multi-agent/trust-policy.js +7 -1
  25. package/dist/core/pipeline/contract.js +7 -0
  26. package/dist/core/pipeline/error-feedback.js +2 -2
  27. package/dist/core/trust/evidence-grounding.js +13 -1
  28. package/dist/core/util/cli-args.js +55 -0
  29. package/dist/core/version.js +1 -1
  30. package/dist/mcp/dispatch.js +22 -2
  31. package/dist/mcp/server.js +124 -13
  32. package/dist/mcp-server.js +20 -0
  33. package/dist/shell/commit.js +8 -2
  34. package/dist/shell/coordinator-io.js +73 -1
  35. package/dist/shell/drive.js +129 -64
  36. package/dist/shell/error-feedback-io.js +6 -0
  37. package/dist/shell/execution-backend/agent.js +205 -24
  38. package/dist/shell/execution-backend/container.js +44 -10
  39. package/dist/shell/execution-backend/local.js +47 -10
  40. package/dist/shell/fs-atomic.js +93 -12
  41. package/dist/shell/ledger-cli.js +9 -2
  42. package/dist/shell/multi-agent-cli.js +5 -1
  43. package/dist/shell/onramp.js +48 -5
  44. package/dist/shell/pipeline-cli.js +20 -2
  45. package/dist/shell/pipeline.js +2 -1
  46. package/dist/shell/reclamation-io.js +76 -7
  47. package/dist/shell/registry-cli.js +4 -0
  48. package/dist/shell/run-export.js +52 -4
  49. package/dist/shell/run-registry-io.js +1 -0
  50. package/dist/shell/run-store.js +156 -0
  51. package/dist/shell/scheduler-io.js +101 -10
  52. package/dist/shell/telemetry-ledger-io.js +36 -24
  53. package/dist/shell/trust-audit.js +104 -10
  54. package/dist/shell/workbench-host.js +121 -10
  55. package/dist/shell/workbench.js +79 -5
  56. package/dist/shell/worker-isolation.js +1 -1
  57. package/dist/shell/workflow-app-loader.js +67 -1
  58. package/dist/wiring/capability-table/basics.js +7 -2
  59. package/dist/wiring/capability-table/exec-backend.js +42 -24
  60. package/dist/wiring/capability-table/multi-agent.js +69 -69
  61. package/dist/wiring/capability-table/pipeline.js +60 -28
  62. package/dist/wiring/capability-table/registry-core.js +29 -6
  63. package/dist/wiring/capability-table/reporting.js +45 -39
  64. package/dist/wiring/capability-table/scheduling-registry.js +66 -60
  65. package/dist/wiring/capability-table/state.js +34 -34
  66. package/dist/wiring/capability-table/trust-ledger.js +66 -24
  67. package/dist/wiring/capability-table/workflow-apps.js +15 -15
  68. package/docs/agent-delegation-drive.7.md +17 -0
  69. package/docs/cli-mcp-parity.7.md +43 -13
  70. package/docs/contract-migration-tooling.7.md +4 -0
  71. package/docs/control-plane-scheduling.7.md +38 -0
  72. package/docs/cross-agent-ledger.7.md +20 -8
  73. package/docs/durable-state-and-locking.7.md +4 -0
  74. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  75. package/docs/execution-backends.7.md +4 -0
  76. package/docs/fix.7.md +4 -4
  77. package/docs/getting-started.md +40 -32
  78. package/docs/index.md +17 -0
  79. package/docs/launch/demo.tape +4 -3
  80. package/docs/mcp-app-surface.7.md +6 -0
  81. package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
  82. package/docs/multi-agent-eval-replay-harness.7.md +4 -0
  83. package/docs/multi-agent-operator-ux.7.md +4 -0
  84. package/docs/node-snapshot-diff-replay.7.md +4 -0
  85. package/docs/observability-cost-accounting.7.md +4 -0
  86. package/docs/project-index.md +43 -9
  87. package/docs/real-execution-backends.7.md +4 -0
  88. package/docs/release-and-migration.7.md +4 -0
  89. package/docs/release-tooling.7.md +22 -0
  90. package/docs/routine.7.md +22 -0
  91. package/docs/run-registry-control-plane.7.md +4 -0
  92. package/docs/run-retention-reclamation.7.md +28 -3
  93. package/docs/state-explosion-management.7.md +4 -0
  94. package/docs/team-collaboration.7.md +4 -0
  95. package/docs/trust-audit-anchor.7.md +4 -0
  96. package/docs/web-desktop-workbench.7.md +26 -2
  97. package/docs/workflow-app-framework.7.md +31 -0
  98. package/manifest/plugin.manifest.json +1 -1
  99. package/manifest/source-context-profiles.json +4 -3
  100. package/package.json +5 -2
  101. package/scripts/agents/agent-adapter-core.js +26 -0
  102. package/scripts/agents/claude-p-agent.js +4 -1
  103. package/scripts/agents/codex-agent.js +4 -0
  104. package/scripts/agents/cw-attest-wrap.js +1 -1
  105. package/scripts/agents/gemini-agent.js +4 -0
  106. package/scripts/agents/opencode-agent.js +5 -0
  107. package/scripts/block-unapproved-tag.js +160 -0
  108. package/scripts/bump-version.js +27 -10
  109. package/scripts/canonical-apps.js +4 -4
  110. package/scripts/children/batch-delegate-child.js +72 -4
  111. package/scripts/children/http-batch-delegate-child.js +132 -0
  112. package/scripts/children/http-delegate-child.js +8 -0
  113. package/scripts/dogfood-release.js +2 -2
  114. package/scripts/fake-date-for-reproduction.js +1 -1
  115. package/scripts/golden-path.js +4 -4
  116. package/scripts/lang-policy-check.js +82 -0
  117. package/scripts/purity-baseline.json +0 -30
  118. package/scripts/purity-gate.js +16 -3
  119. package/scripts/release-check.js +2 -1
  120. package/scripts/release-flow.js +264 -41
  121. package/scripts/release-gate.js +184 -0
  122. package/scripts/release-oneclick.js +438 -0
  123. package/scripts/release-tags.js +47 -0
  124. package/scripts/verdict-keygen.js +2 -2
  125. package/scripts/verify-bump-reproduction.js +193 -0
  126. package/scripts/verify-verdict-signature.js +1 -1
  127. package/scripts/version-sync-check.js +39 -22
  128. package/ui/workbench/app.css +41 -9
  129. package/ui/workbench/app.js +160 -27
  130. package/ui/workbench/index.html +2 -2
  131. package/docs/agent-framework.md +0 -177
  132. package/docs/designs/handoff-ledger.md +0 -145
  133. package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +0 -40
  134. package/docs/launch/launch-kit.md +0 -195
  135. package/docs/launch/pre-launch-checklist.md +0 -53
  136. package/docs/readme-v0.1.87-full.md +0 -301
  137. package/docs/routines.md +0 -101
  138. package/docs/scheduled-tasks.md +0 -80
  139. package/scripts/agents/claude-p-agent.sh +0 -9
  140. package/scripts/block-unapproved-tag.sh +0 -60
  141. package/scripts/release-gate.sh +0 -94
  142. package/scripts/verify-bump-reproduction.sh +0 -148
  143. package/scripts/verify-container-selfref.js +0 -64
package/dist/cli/entry.js CHANGED
@@ -15,7 +15,7 @@
15
15
  // so byte content there is unaffected; cli-color-env.case.js exercises
16
16
  // the FORCE_COLOR/NO_COLOR/CW_NO_COLOR branches explicitly.
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.recoveryHint = recoveryHint;
18
+ exports.recoveryHint = void 0;
19
19
  exports.runCli = runCli;
20
20
  exports.main = main;
21
21
  const parseargv_1 = require("./parseargv");
@@ -25,6 +25,13 @@ const parseargv_2 = require("./parseargv");
25
25
  const capability_table_1 = require("../core/capability-table");
26
26
  const term_1 = require("../shell/term");
27
27
  const io_1 = require("./io");
28
+ const recovery_hint_1 = require("../core/format/recovery-hint");
29
+ // recoveryHint now lives in core/format/recovery-hint.ts (a core/-layer
30
+ // file, so mcp/server.ts can use it too without crossing the mcp/-may-
31
+ // never-import-cli/ layer rule). Re-exported here so every existing
32
+ // importer of `recoveryHint` from this file keeps working unchanged.
33
+ var recovery_hint_2 = require("../core/format/recovery-hint");
34
+ Object.defineProperty(exports, "recoveryHint", { enumerable: true, get: function () { return recovery_hint_2.recoveryHint; } });
28
35
  /** MILESTONE 2: `version` is now a pure projection of the capability
29
36
  * table's `version` row — there is exactly one place its print text
30
37
  * lives (core/capability-table.ts's cli handler), not a second
@@ -39,23 +46,6 @@ function printVersion() {
39
46
  const result = row?.cli?.handler({ positionals: [], options: {} });
40
47
  process.stdout.write(result?.text ?? "");
41
48
  }
42
- /** src/cli.ts:18-29 — map a top-level error message to ONE copy-pasteable
43
- * recovery command. Content-based so it stays correct regardless of which
44
- * call site threw; returns undefined rather than a wrong guess. */
45
- function recoveryHint(message) {
46
- const m = message.toLowerCase();
47
- if (m.startsWith("unknown command"))
48
- return "cw help";
49
- if (m.includes("not configured") || m.includes("agent backend"))
50
- return "cw doctor";
51
- if (m.includes("missing") && m.includes("repo"))
52
- return 'cw -q "<question>" -dir <project-folder>';
53
- if (m.includes("app") && (m.includes("not found") || m.includes("not available")))
54
- return "cw app list";
55
- if (m.includes("run id") || m.includes("run not found"))
56
- return "cw run list";
57
- return undefined;
58
- }
59
49
  async function runCli(argv = process.argv.slice(2)) {
60
50
  const args = (0, parseargv_1.parseArgv)(argv);
61
51
  // Top-level flags: accept --version / -v / --help / -h before command lookup.
@@ -77,6 +67,8 @@ async function runCli(argv = process.argv.slice(2)) {
77
67
  args.options["agent-command"] = "builtin:codex";
78
68
  if (args.options.gemini)
79
69
  args.options["agent-command"] = "builtin:gemini";
70
+ if (args.options.opencode)
71
+ args.options["agent-command"] = "builtin:opencode";
80
72
  if (args.options.deepseek)
81
73
  args.options["agent-command"] = "builtin:deepseek";
82
74
  // -dir / --dir / -d is a second name for --repo; an explicit --repo wins
@@ -152,7 +144,7 @@ function main(argv = process.argv.slice(2)) {
152
144
  return;
153
145
  const message = error instanceof Error ? error.message : String(error);
154
146
  process.stderr.write(`${(0, term_1.bold)("cw:", process.stderr)} ${(0, term_1.red)(message, process.stderr)}\n`);
155
- const hint = recoveryHint(message);
147
+ const hint = (0, recovery_hint_1.recoveryHint)(message);
156
148
  if (hint)
157
149
  process.stderr.write(` ${(0, term_1.dim)("Try:", process.stderr)} ${hint}\n`);
158
150
  process.exitCode = 1;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ // cli/global-flags.ts — the shared global CLI flag set, plus the TTY-gated
3
+ // unknown-flag warning for capability rows that declare `flagsComplete`
4
+ // (core/capability-data.ts's CliBinding).
5
+ //
6
+ // WHY: an unknown flag used to be dropped without a sound — `cw doctor
7
+ // --jsno` ran fine, printed the human report, and exited 0, so a typo of
8
+ // `--json` was easy to miss. A full allowlist check for EVERY command is
9
+ // not safe (a missed name means a FALSE warning, and many scripted and
10
+ // conformance callers assert stderr === ""), so the design here is
11
+ // incremental and fail-open:
12
+ // - only a row that declares `flagsComplete: true` is ever checked, and
13
+ // a row earns that mark only after its handler's option reads have
14
+ // been checked against source, one by one;
15
+ // - the warning is ONE line to stderr, printed ONLY when stderr is a
16
+ // real interactive terminal (same injectable-stream gate as
17
+ // shell/workbench-host.ts's printServeHint) — a piped, scripted, or
18
+ // conformance run can never see it;
19
+ // - stdout bytes and the exit code never change.
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.GLOBAL_CLI_FLAGS = void 0;
22
+ exports.unknownFlagKeys = unknownFlagKeys;
23
+ exports.warnUnknownFlags = warnUnknownFlags;
24
+ /** Every option key the shared CLI front door reads for ANY command, so a
25
+ * `flagsComplete` row's check never flags them. Built by reading the
26
+ * actual consumers:
27
+ * - cli/entry.ts: `version`/`v`, `help`/`h`, the vendor shorthands
28
+ * `claude`/`codex`/`gemini`/`deepseek` (each sets `agent-command`),
29
+ * `repo`/`dir` (`--dir`/`-d` is a global alias for `--repo`),
30
+ * `verbose`, `no-color`, `full`, `quiet`, `question` (`-q`), and the
31
+ * `--resume --run <id>` continuation pair;
32
+ * - cli/dispatch.ts + core/util/cli-args.ts's wantsJson: `json`,
33
+ * `format`;
34
+ * - cli/parseargv.ts's short-alias table: `link` (`-l`),
35
+ * `agent-command` (`-a`) — the short spellings map to these long
36
+ * names before any handler sees them;
37
+ * - the doctor/fix handlers' shared working-dir override: `cwd`.
38
+ * Keys are the POST-parse spellings (what lands in `args.options`). */
39
+ exports.GLOBAL_CLI_FLAGS = [
40
+ "agent-command",
41
+ "claude",
42
+ "codex",
43
+ "cwd",
44
+ "deepseek",
45
+ "dir",
46
+ "format",
47
+ "full",
48
+ "gemini",
49
+ "h",
50
+ "help",
51
+ "json",
52
+ "link",
53
+ "no-color",
54
+ "question",
55
+ "quiet",
56
+ "repo",
57
+ "resume",
58
+ "run",
59
+ "v",
60
+ "verbose",
61
+ "version",
62
+ ];
63
+ /** "changed-from" -> "changedFrom". A name with no dash comes back as-is. */
64
+ function kebabToCamel(name) {
65
+ return name.replace(/-([a-z0-9])/g, (_, ch) => ch.toUpperCase());
66
+ }
67
+ /** "changedFrom" -> "changed-from". A name with no capitals comes back as-is. */
68
+ function camelToKebab(name) {
69
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
70
+ }
71
+ /** The option key a declared flag help entry documents: the first token
72
+ * of its display name, without the leading dashes ("--changed-from REF"
73
+ * -> "changed-from"). */
74
+ function flagNameToKey(name) {
75
+ return name.trim().split(/\s+/)[0].replace(/^-+/, "");
76
+ }
77
+ /** The full accepted-key set for one row: the row's declared flags plus
78
+ * the global set, each in BOTH its kebab-case and camelCase spelling. */
79
+ function knownKeysFor(cli) {
80
+ const known = new Set();
81
+ const add = (key) => {
82
+ known.add(key);
83
+ known.add(kebabToCamel(key));
84
+ known.add(camelToKebab(key));
85
+ };
86
+ for (const name of exports.GLOBAL_CLI_FLAGS)
87
+ add(name);
88
+ for (const flag of cli.flags ?? [])
89
+ add(flagNameToKey(flag.name));
90
+ return known;
91
+ }
92
+ /** The option keys this row does not know about (pure; exported for unit
93
+ * tests). Empty unless the row declares `flagsComplete`. */
94
+ function unknownFlagKeys(cli, options) {
95
+ if (!cli.flagsComplete)
96
+ return [];
97
+ const known = knownKeysFor(cli);
98
+ return Object.keys(options).filter((key) => !known.has(key));
99
+ }
100
+ /** Write ONE warning line to `stream` when a `flagsComplete` row got an
101
+ * option it does not read — and only when the stream is a real TTY, so
102
+ * no piped caller, script, or conformance case can ever see it. stdout
103
+ * and the exit code are untouched either way. */
104
+ function warnUnknownFlags(cli, options, stream = process.stderr) {
105
+ if (!stream.isTTY)
106
+ return;
107
+ const unknown = unknownFlagKeys(cli, options);
108
+ if (unknown.length === 0)
109
+ return;
110
+ const label = unknown.length === 1 ? "flag" : "flags";
111
+ const list = unknown.map((key) => `--${key}`).join(", ");
112
+ stream.write(`cw: warning: unknown ${label} ${list} (see: cw help ${cli.path[0]})\n`);
113
+ }
package/dist/cli/io.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  // cli/io.ts — shared CLI input/output helpers.
3
3
  //
4
- // Byte-exact port of src/cli/io.ts in the old build. Pure + zero-dep: arg
5
- // coercion + JSON stdout. See SPEC/cli-surface.md "Shared io helpers".
4
+ // Byte-exact port of src/cli/io.ts in the old build. Pure + zero-dep JSON
5
+ // stdout, plus one impure TTY-aware help formatter. See SPEC/cli-surface.md
6
+ // "Shared io helpers". Arg-coercion helpers (`required`/`optionalArg`/
7
+ // `wantsJson`) moved to core/util/cli-args.ts (architecture-review P2) —
8
+ // wiring/capability-table/*.ts needed them directly, and a cli/-layer file
9
+ // may not be imported by wiring/ (scripts/purity-gate.js's layer rule).
6
10
  //
7
11
  // MILESTONE 11 (reporting/observability) adds `styledHelp` — the one
8
12
  // place `formatHelp()`'s plain text gets its "Cool Workflow" header
@@ -11,10 +15,7 @@
11
15
  // shell/term.ts's env/TTY read.
12
16
  Object.defineProperty(exports, "__esModule", { value: true });
13
17
  exports.styledHelp = styledHelp;
14
- exports.required = required;
15
- exports.optionalArg = optionalArg;
16
18
  exports.printJson = printJson;
17
- exports.wantsJson = wantsJson;
18
19
  const help_1 = require("../core/format/help");
19
20
  const safe_json_1 = require("../core/format/safe-json");
20
21
  const term_1 = require("../shell/term");
@@ -24,17 +25,6 @@ function styledHelp() {
24
25
  const text = (0, help_1.formatHelp)();
25
26
  return text.replace(/^Cool Workflow\n/, `${(0, term_1.bold)("Cool Workflow")}\n`);
26
27
  }
27
- /** Require a positional/option value or fail with a copy-pasteable recovery tip. */
28
- function required(value, label) {
29
- if (!value) {
30
- throw new Error(`Missing ${label}.\n Tip: find run ids with "cw run list" or create one with "cw quickstart"`);
31
- }
32
- return value;
33
- }
34
- /** Normalize an optional CLI arg to a trimmed non-empty string, else undefined. */
35
- function optionalArg(value) {
36
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
37
- }
38
28
  /** Machine payload to stdout (stdout = data; never colored, never chrome).
39
29
  * Byte-capped via safeJsonStringify — an aggregate result too large to be
40
30
  * useful (or large enough to blow V8's string limit) prints a small
@@ -42,7 +32,3 @@ function optionalArg(value) {
42
32
  function printJson(value) {
43
33
  process.stdout.write(`${(0, safe_json_1.safeJsonStringify)(value)}\n`);
44
34
  }
45
- /** True when the caller asked for JSON output (`--json` or `--format json`). */
46
- function wantsJson(options) {
47
- return Boolean(options.json || options.format === "json");
48
- }
@@ -140,13 +140,19 @@ function levenshtein(a, b) {
140
140
  }
141
141
  /** src/orchestrator.ts:875-887 — nearest known command by edit distance.
142
142
  * Gives `undefined` when the input is under 2 chars, or when the best
143
- * distance is over 3 or over half the input length. */
143
+ * distance is over 3 or over half the input length. Never gives back the
144
+ * input itself: a caller only asks for a suggestion when the input did
145
+ * NOT resolve, so a distance-0 self-match (an alias token like
146
+ * `audit-run` that IS in KNOWN_COMMANDS but has no help rows of its own)
147
+ * was a hint that pointed at the very thing the user just typed. */
144
148
  function suggestCommand(input) {
145
149
  if (!input || input.length < 2)
146
150
  return undefined;
147
151
  let best;
148
152
  let bestDistance = Infinity;
149
153
  for (const candidate of exports.KNOWN_COMMANDS) {
154
+ if (candidate === input)
155
+ continue;
150
156
  const distance = levenshtein(input, candidate);
151
157
  if (distance < bestDistance) {
152
158
  bestDistance = distance;