cool-workflow 0.1.98 → 0.2.0

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 (306) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +11 -2
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +1 -1
  6. package/apps/end-to-end-golden-path/app.json +1 -1
  7. package/apps/pr-review-fix-ci/app.json +1 -1
  8. package/apps/release-cut/app.json +1 -1
  9. package/apps/research-synthesis/app.json +1 -1
  10. package/dist/cli/dispatch.js +236 -0
  11. package/dist/cli/entry.js +120 -0
  12. package/dist/cli/io.js +21 -4
  13. package/dist/cli/parseargv.js +157 -0
  14. package/dist/cli.js +6 -33
  15. package/dist/core/capability-table.js +3534 -0
  16. package/dist/core/format/help.js +314 -0
  17. package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
  18. package/dist/core/hash.js +137 -0
  19. package/dist/core/multi-agent/candidate-scoring.js +219 -0
  20. package/dist/core/multi-agent/collaboration.js +481 -0
  21. package/dist/core/multi-agent/coordinator.js +515 -0
  22. package/dist/core/multi-agent/eval-replay.js +306 -0
  23. package/dist/core/multi-agent/runtime.js +929 -0
  24. package/dist/core/multi-agent/topology.js +298 -0
  25. package/dist/core/multi-agent/trust-policy.js +197 -0
  26. package/dist/core/pipeline/commit-gate.js +320 -0
  27. package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
  28. package/dist/core/pipeline/dispatch.js +103 -0
  29. package/dist/core/pipeline/drive-decide.js +227 -0
  30. package/dist/core/pipeline/error-feedback.js +161 -0
  31. package/dist/core/pipeline/loop-expansion.js +124 -0
  32. package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
  33. package/dist/core/pipeline/runner.js +230 -0
  34. package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
  35. package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
  36. package/dist/core/state/node-projection.js +95 -0
  37. package/dist/core/state/node-snapshot.js +230 -0
  38. package/dist/core/state/run-paths.js +93 -0
  39. package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
  40. package/dist/core/state/schema.js +50 -0
  41. package/dist/core/state/state-explosion/digest.js +243 -0
  42. package/dist/core/state/state-explosion/graph.js +527 -0
  43. package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
  44. package/dist/core/state/state-explosion/report.js +187 -0
  45. package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
  46. package/dist/{state-node.js → core/state/state-node.js} +90 -113
  47. package/dist/core/state/types.js +19 -0
  48. package/dist/{validation.js → core/state/validation.js} +64 -131
  49. package/dist/core/trust/evidence-grounding.js +134 -0
  50. package/dist/core/trust/ledger.js +199 -0
  51. package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
  52. package/dist/core/trust/telemetry-ledger.js +127 -0
  53. package/dist/core/types.js +20 -0
  54. package/dist/core/version.js +16 -0
  55. package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
  56. package/dist/mcp/dispatch.js +104 -0
  57. package/dist/mcp/server.js +144 -0
  58. package/dist/mcp-server.js +6 -84
  59. package/dist/{agent-config.js → shell/agent-config.js} +118 -71
  60. package/dist/shell/app-run-cli.js +88 -0
  61. package/dist/shell/audit-cli.js +259 -0
  62. package/dist/shell/audit-provenance.js +83 -0
  63. package/dist/shell/candidate-scoring-io.js +459 -0
  64. package/dist/shell/collaboration-io.js +264 -0
  65. package/dist/shell/commit-summary.js +104 -0
  66. package/dist/shell/commit.js +290 -0
  67. package/dist/shell/coordinator-io.js +476 -0
  68. package/dist/shell/demo-cli.js +19 -0
  69. package/dist/shell/dispatch.js +162 -0
  70. package/dist/{doctor.js → shell/doctor.js} +123 -56
  71. package/dist/shell/drive.js +873 -0
  72. package/dist/shell/error-feedback-io.js +305 -0
  73. package/dist/shell/eval-io.js +473 -0
  74. package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
  75. package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
  76. package/dist/shell/exec-backend-cli.js +88 -0
  77. package/dist/shell/execution-backend/agent.js +475 -0
  78. package/dist/shell/execution-backend/ci.js +15 -0
  79. package/dist/shell/execution-backend/container.js +69 -0
  80. package/dist/shell/execution-backend/envelopes.js +55 -0
  81. package/dist/shell/execution-backend/local.js +113 -0
  82. package/dist/shell/execution-backend/probes.js +175 -0
  83. package/dist/shell/execution-backend/registry.js +402 -0
  84. package/dist/shell/execution-backend/remote.js +128 -0
  85. package/dist/shell/execution-backend/types.js +11 -0
  86. package/dist/shell/feedback-cli.js +81 -0
  87. package/dist/shell/feedback-operations.js +48 -0
  88. package/dist/shell/fs-atomic.js +276 -0
  89. package/dist/shell/harness.js +98 -0
  90. package/dist/shell/ledger-cli.js +212 -0
  91. package/dist/shell/ledger-io.js +169 -0
  92. package/dist/shell/man-cli.js +89 -0
  93. package/dist/shell/metrics-cli.js +98 -0
  94. package/dist/shell/multi-agent-cli.js +1002 -0
  95. package/dist/shell/multi-agent-host.js +563 -0
  96. package/dist/shell/multi-agent-io.js +387 -0
  97. package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
  98. package/dist/shell/node-store.js +124 -0
  99. package/dist/{observability/format.js → shell/observability-format.js} +7 -1
  100. package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
  101. package/dist/{observability.js → shell/observability.js} +159 -332
  102. package/dist/{onramp.js → shell/onramp.js} +11 -0
  103. package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
  104. package/dist/shell/operator-ux.js +431 -0
  105. package/dist/shell/orchestrator.js +231 -0
  106. package/dist/shell/pipeline-cli.js +667 -0
  107. package/dist/shell/pipeline.js +217 -0
  108. package/dist/shell/reclamation-io.js +1366 -0
  109. package/dist/shell/registry-cli.js +329 -0
  110. package/dist/{remote-source.js → shell/remote-source.js} +2 -2
  111. package/dist/shell/report-cli.js +101 -0
  112. package/dist/shell/report-view-cli.js +117 -0
  113. package/dist/{orchestrator → shell}/report.js +289 -282
  114. package/dist/shell/reporter.js +62 -0
  115. package/dist/shell/run-export-cli.js +106 -0
  116. package/dist/shell/run-export.js +680 -0
  117. package/dist/shell/run-registry-io.js +1014 -0
  118. package/dist/shell/run-store.js +164 -0
  119. package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
  120. package/dist/{scheduler.js → shell/scheduler-io.js} +248 -48
  121. package/dist/shell/scheduling-io.js +311 -0
  122. package/dist/shell/state-cli.js +181 -0
  123. package/dist/shell/state-explosion-cli.js +197 -0
  124. package/dist/shell/telemetry-cli.js +85 -0
  125. package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
  126. package/dist/shell/telemetry-ledger-io.js +132 -0
  127. package/dist/{term.js → shell/term.js} +36 -46
  128. package/dist/shell/topology-io.js +361 -0
  129. package/dist/shell/trust-audit.js +471 -0
  130. package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
  131. package/dist/shell/verifier.js +48 -0
  132. package/dist/shell/workbench-host.js +250 -0
  133. package/dist/shell/workbench-text.js +18 -0
  134. package/dist/shell/workbench.js +175 -0
  135. package/dist/shell/worker-cli.js +124 -0
  136. package/dist/shell/worker-isolation.js +852 -0
  137. package/dist/shell/workflow-app-loader.js +650 -0
  138. package/docs/agent-delegation-drive.7.md +2 -0
  139. package/docs/cli-mcp-parity.7.md +280 -219
  140. package/docs/contract-migration-tooling.7.md +2 -0
  141. package/docs/control-plane-scheduling.7.md +2 -0
  142. package/docs/durable-state-and-locking.7.md +2 -0
  143. package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
  144. package/docs/execution-backends.7.md +2 -0
  145. package/docs/multi-agent-cli-mcp-surface.7.md +2 -0
  146. package/docs/multi-agent-eval-replay-harness.7.md +2 -0
  147. package/docs/multi-agent-operator-ux.7.md +2 -0
  148. package/docs/node-snapshot-diff-replay.7.md +2 -0
  149. package/docs/observability-cost-accounting.7.md +2 -0
  150. package/docs/project-index.md +132 -71
  151. package/docs/real-execution-backends.7.md +2 -0
  152. package/docs/release-and-migration.7.md +2 -0
  153. package/docs/release-tooling.7.md +2 -0
  154. package/docs/run-registry-control-plane.7.md +2 -0
  155. package/docs/run-retention-reclamation.7.md +23 -0
  156. package/docs/state-explosion-management.7.md +2 -0
  157. package/docs/team-collaboration.7.md +2 -0
  158. package/docs/web-desktop-workbench.7.md +2 -0
  159. package/manifest/plugin.manifest.json +1 -1
  160. package/manifest/source-context-profiles.json +9 -13
  161. package/package.json +1 -1
  162. package/scripts/agents/cw-attest-wrap.js +2 -2
  163. package/scripts/bump-version.js +4 -3
  164. package/scripts/canonical-apps.js +4 -4
  165. package/scripts/dogfood-architecture-review.js +2 -3
  166. package/scripts/dogfood-release.js +3 -3
  167. package/scripts/gen-parity-doc.js +15 -2
  168. package/scripts/golden-path.js +4 -4
  169. package/scripts/onramp-check.js +1 -1
  170. package/scripts/parity-check.js +38 -21
  171. package/scripts/release-flow.js +2 -2
  172. package/scripts/sync-project-index.js +51 -27
  173. package/scripts/validate-run-state-schema.js +2 -2
  174. package/scripts/version-sync-check.js +30 -30
  175. package/dist/candidate-scoring.js +0 -729
  176. package/dist/capability-core.js +0 -1189
  177. package/dist/capability-registry.js +0 -885
  178. package/dist/cli/command-surface.js +0 -494
  179. package/dist/cli/format.js +0 -56
  180. package/dist/cli/handlers/audit.js +0 -82
  181. package/dist/cli/handlers/blackboard.js +0 -81
  182. package/dist/cli/handlers/candidate.js +0 -40
  183. package/dist/cli/handlers/clones.js +0 -34
  184. package/dist/cli/handlers/collaboration.js +0 -61
  185. package/dist/cli/handlers/eval.js +0 -40
  186. package/dist/cli/handlers/ledger.js +0 -169
  187. package/dist/cli/handlers/maintenance.js +0 -107
  188. package/dist/cli/handlers/multi-agent.js +0 -165
  189. package/dist/cli/handlers/node.js +0 -41
  190. package/dist/cli/handlers/operational.js +0 -155
  191. package/dist/cli/handlers/operator.js +0 -146
  192. package/dist/cli/handlers/registry.js +0 -68
  193. package/dist/cli/handlers/run.js +0 -153
  194. package/dist/cli/handlers/scheduling.js +0 -132
  195. package/dist/cli/handlers/workbench.js +0 -41
  196. package/dist/cli/handlers/worker.js +0 -45
  197. package/dist/cli/run-summary.js +0 -45
  198. package/dist/clones.js +0 -162
  199. package/dist/collaboration.js +0 -726
  200. package/dist/commit.js +0 -592
  201. package/dist/compare.js +0 -18
  202. package/dist/coordinator/classify.js +0 -45
  203. package/dist/coordinator/paths.js +0 -42
  204. package/dist/coordinator/util.js +0 -126
  205. package/dist/coordinator.js +0 -990
  206. package/dist/daemon.js +0 -44
  207. package/dist/dispatch.js +0 -250
  208. package/dist/drive.js +0 -864
  209. package/dist/error-feedback.js +0 -419
  210. package/dist/evidence-grounding.js +0 -184
  211. package/dist/execution-backend/agent.js +0 -354
  212. package/dist/execution-backend/probes.js +0 -112
  213. package/dist/execution-backend/util.js +0 -47
  214. package/dist/execution-backend.js +0 -961
  215. package/dist/gates.js +0 -48
  216. package/dist/harness.js +0 -61
  217. package/dist/ledger.js +0 -313
  218. package/dist/loop-expansion.js +0 -60
  219. package/dist/mcp/tool-call.js +0 -470
  220. package/dist/mcp/tool-definitions.js +0 -1066
  221. package/dist/mcp-surface.js +0 -30
  222. package/dist/multi-agent/graph.js +0 -84
  223. package/dist/multi-agent/helpers.js +0 -141
  224. package/dist/multi-agent/ids.js +0 -20
  225. package/dist/multi-agent/paths.js +0 -22
  226. package/dist/multi-agent-eval/normalize.js +0 -51
  227. package/dist/multi-agent-eval.js +0 -678
  228. package/dist/multi-agent-host.js +0 -777
  229. package/dist/multi-agent.js +0 -984
  230. package/dist/node-projection.js +0 -59
  231. package/dist/node-snapshot.js +0 -260
  232. package/dist/operator-ux.js +0 -631
  233. package/dist/orchestrator/app-operations.js +0 -211
  234. package/dist/orchestrator/audit-operations.js +0 -182
  235. package/dist/orchestrator/candidate-operations.js +0 -117
  236. package/dist/orchestrator/cli-options.js +0 -294
  237. package/dist/orchestrator/collaboration-operations.js +0 -86
  238. package/dist/orchestrator/feedback-operations.js +0 -81
  239. package/dist/orchestrator/host-operations.js +0 -78
  240. package/dist/orchestrator/lifecycle-operations.js +0 -650
  241. package/dist/orchestrator/migration-operations.js +0 -44
  242. package/dist/orchestrator/multi-agent-operations.js +0 -362
  243. package/dist/orchestrator/topology-operations.js +0 -84
  244. package/dist/orchestrator.js +0 -925
  245. package/dist/pipeline-runner.js +0 -285
  246. package/dist/reclamation/hash.js +0 -72
  247. package/dist/reclamation.js +0 -812
  248. package/dist/reporter.js +0 -67
  249. package/dist/run-export.js +0 -815
  250. package/dist/run-registry/derive.js +0 -175
  251. package/dist/run-registry/format.js +0 -124
  252. package/dist/run-registry/gc.js +0 -251
  253. package/dist/run-registry/policy.js +0 -16
  254. package/dist/run-registry/queue.js +0 -115
  255. package/dist/run-registry.js +0 -850
  256. package/dist/run-state-schema.js +0 -68
  257. package/dist/scheduling.js +0 -184
  258. package/dist/state-explosion.js +0 -1014
  259. package/dist/state.js +0 -367
  260. package/dist/telemetry-ledger.js +0 -196
  261. package/dist/topology.js +0 -565
  262. package/dist/triggers.js +0 -184
  263. package/dist/trust-audit.js +0 -644
  264. package/dist/types/blackboard.js +0 -2
  265. package/dist/types/candidate.js +0 -2
  266. package/dist/types/collaboration.js +0 -2
  267. package/dist/types/core.js +0 -2
  268. package/dist/types/drive.js +0 -10
  269. package/dist/types/error-feedback.js +0 -2
  270. package/dist/types/evidence-reasoning.js +0 -2
  271. package/dist/types/execution-backend.js +0 -2
  272. package/dist/types/multi-agent.js +0 -2
  273. package/dist/types/observability.js +0 -2
  274. package/dist/types/pipeline.js +0 -2
  275. package/dist/types/reclamation.js +0 -8
  276. package/dist/types/report-bundle.js +0 -6
  277. package/dist/types/result.js +0 -2
  278. package/dist/types/run-registry.js +0 -2
  279. package/dist/types/run.js +0 -2
  280. package/dist/types/sandbox.js +0 -2
  281. package/dist/types/schedule.js +0 -2
  282. package/dist/types/state-node.js +0 -2
  283. package/dist/types/topology.js +0 -2
  284. package/dist/types/trust.js +0 -2
  285. package/dist/types/workbench.js +0 -2
  286. package/dist/types/worker.js +0 -2
  287. package/dist/types/workflow-app.js +0 -2
  288. package/dist/types.js +0 -44
  289. package/dist/util/fingerprint.js +0 -19
  290. package/dist/util/fingerprint.test.js +0 -27
  291. package/dist/verifier.js +0 -78
  292. package/dist/version.js +0 -8
  293. package/dist/workbench-host.js +0 -192
  294. package/dist/workbench.js +0 -192
  295. package/dist/worker-accept/acceptance.js +0 -114
  296. package/dist/worker-accept/blackboard-fanout.js +0 -80
  297. package/dist/worker-accept/blackboard-linkage.js +0 -19
  298. package/dist/worker-accept/context.js +0 -2
  299. package/dist/worker-accept/telemetry-ledger.js +0 -126
  300. package/dist/worker-accept/validation.js +0 -77
  301. package/dist/worker-accept/verifier-completion.js +0 -73
  302. package/dist/worker-isolation/helpers.js +0 -51
  303. package/dist/worker-isolation/paths.js +0 -46
  304. package/dist/worker-isolation.js +0 -656
  305. package/dist/workflow-api.js +0 -131
  306. /package/dist/{types → core/types}/boundary.js +0 -0
package/dist/topology.js DELETED
@@ -1,565 +0,0 @@
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.OFFICIAL_TOPOLOGIES = exports.TOPOLOGY_SCHEMA_VERSION = void 0;
7
- exports.ensureTopologyState = ensureTopologyState;
8
- exports.persistTopologyState = persistTopologyState;
9
- exports.registerTopology = registerTopology;
10
- exports.listTopologyDefinitions = listTopologyDefinitions;
11
- exports.getTopologyDefinition = getTopologyDefinition;
12
- exports.validateTopologyDefinition = validateTopologyDefinition;
13
- exports.applyTopology = applyTopology;
14
- exports.summarizeTopologies = summarizeTopologies;
15
- exports.buildTopologyGraph = buildTopologyGraph;
16
- exports.showTopologyRun = showTopologyRun;
17
- const node_fs_1 = __importDefault(require("node:fs"));
18
- const node_path_1 = __importDefault(require("node:path"));
19
- const state_1 = require("./state");
20
- const execution_backend_1 = require("./execution-backend");
21
- const telemetry_attestation_1 = require("./telemetry-attestation");
22
- const pipeline_contract_1 = require("./pipeline-contract");
23
- const state_node_1 = require("./state-node");
24
- const trust_audit_1 = require("./trust-audit");
25
- const multi_agent_1 = require("./multi-agent");
26
- const coordinator_1 = require("./coordinator");
27
- exports.TOPOLOGY_SCHEMA_VERSION = 1;
28
- exports.OFFICIAL_TOPOLOGIES = [
29
- {
30
- schemaVersion: 1,
31
- id: "map-reduce",
32
- title: "Map-Reduce",
33
- summary: "Fan out mapper roles, index mapper evidence on the blackboard, then reduce only after required evidence is present.",
34
- roles: [
35
- roleSpec("mapper", "Mapper", ["Produce an independent shard result and cite evidence."], ["mapper output artifact"], ["indexed mapper artifact"], 2),
36
- roleSpec("reducer", "Reducer", ["Synthesize mapper outputs only after fanin is verifier-ready."], ["reducer synthesis"], ["all mapper evidence"])
37
- ],
38
- groups: [{ id: "map-reduce", title: "Map-Reduce Group", roleIds: ["mapper", "reducer"] }],
39
- blackboardTopics: [
40
- topicSpec("mapper-outputs", "Mapper Outputs", "Indexed mapper result artifacts and evidence."),
41
- topicSpec("reducer-synthesis", "Reducer Synthesis", "Reducer fanin readiness and synthesis provenance.")
42
- ],
43
- phases: [
44
- phaseSpec("map", "Map", ["mapper"], true, false, ["mapper output artifact"], ["artifact-index"]),
45
- phaseSpec("reduce", "Reduce", ["reducer"], false, true, ["all mapper evidence"], ["fanin-readiness", "candidate-synthesis"])
46
- ],
47
- fanoutStrategy: "one membership per mapper role over selected run tasks",
48
- faninStrategy: "required mapper roles must report result evidence and indexed blackboard artifacts",
49
- requiredEvidence: ["mapper output artifact", "blackboard artifact ref", "reducer synthesis"],
50
- coordinatorDecisions: ["artifact-index", "fanin-readiness", "candidate-synthesis"],
51
- candidateExpectations: ["Reducer result becomes a candidate only with mapper provenance."],
52
- verifierGates: ["Reducer fanin must be ready before completion or commit."]
53
- },
54
- {
55
- schemaVersion: 1,
56
- id: "debate",
57
- title: "Debate",
58
- summary: "Record opposing claims, rebuttal rounds, conflict context, coordinator decisions, and final synthesis on shared topics.",
59
- roles: [
60
- roleSpec("position-a", "Position A", ["Argue one supported position with evidence."], ["claim message"], ["round messages"]),
61
- roleSpec("position-b", "Position B", ["Argue a contrasting position with evidence."], ["counterclaim message"], ["round messages"]),
62
- roleSpec("synthesizer", "Synthesis", ["Resolve or preserve conflicts with citations."], ["debate synthesis"], ["coordinator decisions"])
63
- ],
64
- groups: [{ id: "debate", title: "Debate Group", roleIds: ["position-a", "position-b", "synthesizer"] }],
65
- blackboardTopics: [
66
- topicSpec("debate-rounds", "Debate Rounds", "Claim and rebuttal messages by round."),
67
- topicSpec("debate-conflicts", "Conflict Context", "Conflicting or unresolved claims."),
68
- topicSpec("debate-synthesis", "Final Synthesis", "Accepted, rejected, conflicting, and unresolved claims.")
69
- ],
70
- phases: [
71
- phaseSpec("opening", "Opening Claims", ["position-a", "position-b"], true, false, ["claim evidence"], ["message-moderation"]),
72
- phaseSpec("rebuttal", "Rebuttal Rounds", ["position-a", "position-b"], true, false, ["response evidence"], ["conflict-resolution"]),
73
- phaseSpec("synthesis", "Synthesis", ["synthesizer"], false, true, ["debate messages", "coordinator decisions"], ["candidate-synthesis"])
74
- ],
75
- fanoutStrategy: "opposing roles write blackboard messages for each round",
76
- faninStrategy: "synthesis requires debate messages and coordinator claim decisions",
77
- requiredEvidence: ["debate message", "conflict context", "coordinator decision", "final synthesis"],
78
- coordinatorDecisions: ["message-moderation", "conflict-resolution", "candidate-synthesis"],
79
- candidateExpectations: ["Final synthesis cites debate messages and decisions."],
80
- verifierGates: ["Required debate rounds and synthesis evidence must be present."]
81
- },
82
- {
83
- schemaVersion: 1,
84
- id: "judge-panel",
85
- title: "Judge Panel",
86
- summary: "Collect independent judge outputs, aggregate scores, and select a panel decision with linked evidence.",
87
- roles: [
88
- roleSpec("judge", "Judge", ["Score candidates independently and cite evidence."], ["judge score artifact"], ["judge verdict"], 3),
89
- roleSpec("panel-chair", "Panel Chair", ["Aggregate scores and write a panel decision."], ["panel decision"], ["judge evidence"])
90
- ],
91
- groups: [{ id: "judge-panel", title: "Judge Panel Group", roleIds: ["judge", "panel-chair"] }],
92
- blackboardTopics: [
93
- topicSpec("judge-verdicts", "Judge Verdicts", "Independent judge outputs and score evidence."),
94
- topicSpec("panel-decision", "Panel Decision", "Aggregated verdict and candidate selection rationale.")
95
- ],
96
- phases: [
97
- phaseSpec("judge", "Judge", ["judge"], true, false, ["judge score artifact"], ["artifact-index"]),
98
- phaseSpec("panel", "Panel", ["panel-chair"], false, true, ["judge evidence", "score records"], ["candidate-synthesis"])
99
- ],
100
- fanoutStrategy: "one membership per independent judge role",
101
- faninStrategy: "panel decision requires fanin over judge evidence and score records",
102
- requiredEvidence: ["judge output", "score record", "panel decision", "candidate selection rationale"],
103
- coordinatorDecisions: ["artifact-index", "candidate-synthesis"],
104
- candidateExpectations: ["No single judge is authoritative without aggregated fanin and score evidence."],
105
- verifierGates: ["Panel decision requires multiple judge outputs unless explicitly configured otherwise."]
106
- }
107
- ];
108
- function ensureTopologyState(run) {
109
- run.paths.topologiesDir = topologyRoot(run);
110
- node_fs_1.default.mkdirSync(run.paths.topologiesDir, { recursive: true });
111
- node_fs_1.default.mkdirSync(node_path_1.default.join(run.paths.topologiesDir, "runs"), { recursive: true });
112
- if (!run.topologies)
113
- run.topologies = { schemaVersion: exports.TOPOLOGY_SCHEMA_VERSION, runs: [] };
114
- run.topologies.schemaVersion = exports.TOPOLOGY_SCHEMA_VERSION;
115
- run.topologies.runs = run.topologies.runs || [];
116
- return run.topologies;
117
- }
118
- function persistTopologyState(run) {
119
- const state = ensureTopologyState(run);
120
- (0, state_1.writeJson)(node_path_1.default.join(topologyRoot(run), "index.json"), {
121
- schemaVersion: exports.TOPOLOGY_SCHEMA_VERSION,
122
- runId: run.id,
123
- counts: { runs: state.runs.length },
124
- runs: state.runs.map((record) => ({
125
- id: record.id,
126
- topologyId: record.topologyId,
127
- status: record.status,
128
- updatedAt: record.updatedAt
129
- }))
130
- });
131
- for (const record of state.runs)
132
- (0, state_1.writeJson)(topologyRunPath(run, record.id), record);
133
- }
134
- // ---- Topology registry (v0.1.53) — MECHANISM, not policy ------------------
135
- // SEPARATE MECHANISM FROM POLICY. The Map is mechanism; OFFICIAL_TOPOLOGIES and
136
- // any registerTopology() calls are policy. listTopologyDefinitions() composes
137
- // them — consumers see one merged set, never two.
138
- const _topologyRegistry = new Map();
139
- /** Register a topology definition. Later registrations with the same id
140
- * overwrite earlier ones (last-write-wins dedup). */
141
- function registerTopology(definition) {
142
- _topologyRegistry.set(definition.id, clone(definition));
143
- }
144
- function listTopologyDefinitions() {
145
- const merged = exports.OFFICIAL_TOPOLOGIES.map((definition) => clone(definition));
146
- for (const registered of _topologyRegistry.values()) {
147
- const idx = merged.findIndex((d) => d.id === registered.id);
148
- if (idx >= 0)
149
- merged[idx] = clone(registered);
150
- else
151
- merged.push(clone(registered));
152
- }
153
- return merged;
154
- }
155
- function getTopologyDefinition(topologyId) {
156
- const registered = _topologyRegistry.get(topologyId);
157
- if (registered)
158
- return clone(registered);
159
- return exports.OFFICIAL_TOPOLOGIES.find((definition) => definition.id === topologyId);
160
- }
161
- function validateTopologyDefinition(topologyId) {
162
- const definition = getTopologyDefinition(topologyId);
163
- if (!definition)
164
- return { valid: false, topologyId, issues: [{ code: "unknown-topology", message: `Unknown topology id: ${topologyId}` }] };
165
- const issues = [];
166
- if (!definition.roles.length)
167
- issues.push(issue("missing-roles", "Topology must declare at least one role.", "roles"));
168
- if (!definition.groups.length)
169
- issues.push(issue("missing-groups", "Topology must declare at least one group.", "groups"));
170
- if (!definition.blackboardTopics.length)
171
- issues.push(issue("missing-topics", "Topology must declare blackboard topics.", "blackboardTopics"));
172
- if (!definition.requiredEvidence.length)
173
- issues.push(issue("missing-evidence", "Topology must declare required evidence.", "requiredEvidence"));
174
- const roleIds = new Set(definition.roles.map((role) => role.id));
175
- for (const phase of definition.phases) {
176
- for (const roleId of phase.roleIds) {
177
- if (!roleIds.has(roleId))
178
- issues.push(issue("unknown-phase-role", `Phase ${phase.id} references unknown role ${roleId}.`, `phases.${phase.id}`));
179
- }
180
- }
181
- return { valid: issues.length === 0, topologyId, issues, definition };
182
- }
183
- function applyTopology(run, topologyId, input = {}) {
184
- const validation = validateTopologyDefinition(topologyId);
185
- if (!validation.valid || !validation.definition) {
186
- throw new Error(`Invalid topology ${topologyId}: ${validation.issues.map((entry) => entry.message).join("; ")}`);
187
- }
188
- const definition = validation.definition;
189
- const state = ensureTopologyState(run);
190
- (0, multi_agent_1.ensureMultiAgentState)(run);
191
- const taskIds = selectedTaskIds(run, input.taskIds);
192
- // Default id is a DETERMINISTIC content-hash (replay determinism): two `topology
193
- // apply` invocations WITHOUT --id over the same definition/tasks/run produce a
194
- // byte-identical id. Same sha256/stableStringify the kernel uses for node ids
195
- // (state-node/createNodeId) and ledger record ids. `state.runs.length` is the
196
- // stable sequence so repeated applies on the same run get distinct ids without a
197
- // wall-clock stamp. input.id stays an explicit override.
198
- const id = input.id || topologyRunId(definition, taskIds, run.id, state.runs.length);
199
- if (state.runs.some((record) => record.id === id))
200
- throw new Error(`Duplicate MultiAgentTopologyRun id: ${id}`);
201
- const board = (0, coordinator_1.resolveBlackboard)(run, {
202
- id: input.blackboardId || `${id}-blackboard`,
203
- title: `${definition.title} Blackboard`,
204
- tags: ["topology", definition.id]
205
- });
206
- const topics = definition.blackboardTopics.map((topic) => (0, coordinator_1.createBlackboardTopic)(run, {
207
- id: `${id}-${topic.id}`,
208
- title: topic.title,
209
- description: topic.description,
210
- blackboardId: board.id,
211
- tags: ["topology", definition.id]
212
- }));
213
- const multiAgentRun = (0, multi_agent_1.createMultiAgentRun)(run, {
214
- id: input.multiAgentRunId || `${id}-ma`,
215
- title: input.title || definition.title,
216
- objective: definition.summary,
217
- blackboardId: board.id,
218
- topicIds: topics.map((topic) => topic.id),
219
- metadata: { topologyId: definition.id, topologyRunId: id }
220
- });
221
- const roleIds = [];
222
- for (const role of materializedRoles(definition, withLegacyRoleCounts(input))) {
223
- const record = (0, multi_agent_1.createAgentRole)(run, {
224
- id: `${id}-${role.id}`,
225
- multiAgentRunId: multiAgentRun.id,
226
- title: role.title,
227
- responsibilities: role.responsibilities,
228
- requiredEvidence: role.requiredEvidence,
229
- expectedArtifacts: role.expectedArtifacts,
230
- faninObligations: role.faninObligations,
231
- blackboardId: board.id,
232
- topicIds: topics.map((topic) => topic.id),
233
- metadata: { topologyId: definition.id, topologyRunId: id, topologyRoleId: role.id }
234
- });
235
- roleIds.push(record.id);
236
- }
237
- const group = (0, multi_agent_1.createAgentGroup)(run, {
238
- id: `${id}-group`,
239
- multiAgentRunId: multiAgentRun.id,
240
- title: `${definition.title} Group`,
241
- phase: definition.title,
242
- taskIds,
243
- blackboardId: board.id,
244
- topicIds: topics.map((topic) => topic.id),
245
- metadata: { topologyId: definition.id, topologyRunId: id }
246
- });
247
- const fanoutRoleIds = roleIds.filter((roleId) => !roleId.endsWith("-reducer") && !roleId.endsWith("-synthesizer") && !roleId.endsWith("-panel-chair"));
248
- const fanout = (0, multi_agent_1.createAgentFanout)(run, {
249
- id: `${id}-fanout`,
250
- multiAgentRunId: multiAgentRun.id,
251
- groupId: group.id,
252
- reason: `${definition.id} topology fanout`,
253
- roleIds: fanoutRoleIds.length ? fanoutRoleIds : roleIds,
254
- taskIds,
255
- concurrencyLimit: fanoutRoleIds.length || roleIds.length,
256
- expectedReturnShape: `${definition.title} worker output must include cw:result evidence and blackboard-indexable artifacts/messages.`,
257
- blackboardId: board.id,
258
- topicIds: topics.map((topic) => topic.id),
259
- metadata: { topologyId: definition.id, topologyRunId: id, fanoutStrategy: definition.fanoutStrategy }
260
- });
261
- const message = (0, coordinator_1.postBlackboardMessage)(run, {
262
- topicId: topics[0].id,
263
- blackboardId: board.id,
264
- body: `${definition.title} topology applied. Roles=${roleIds.join(", ")} fanout=${fanout.id}.`,
265
- tags: ["topology", definition.id],
266
- metadata: { topologyRunId: id }
267
- });
268
- const decision = (0, coordinator_1.recordCoordinatorDecision)(run, {
269
- blackboardId: board.id,
270
- topicId: topics[0].id,
271
- kind: "context-update",
272
- outcome: "accepted",
273
- reason: `${definition.title} topology materialized on multi-agent runtime and blackboard.`,
274
- subjectIds: [multiAgentRun.id, group.id, fanout.id],
275
- messageIds: [message.id],
276
- tags: ["topology", definition.id],
277
- metadata: { topologyRunId: id }
278
- });
279
- const fanin = input.collectInitialFanin ? (0, multi_agent_1.collectAgentFanin)(run, {
280
- id: `${id}-fanin-initial`,
281
- multiAgentRunId: multiAgentRun.id,
282
- groupId: group.id,
283
- fanoutId: fanout.id,
284
- requiredRoleIds: fanout.roleIds,
285
- strategy: definition.faninStrategy,
286
- blackboardId: board.id,
287
- topicIds: topics.map((topic) => topic.id),
288
- metadata: { topologyId: definition.id, topologyRunId: id }
289
- }) : undefined;
290
- const audit = (0, trust_audit_1.recordTrustAuditEvent)(run, {
291
- kind: "topology.create",
292
- decision: "recorded",
293
- source: "runtime-derived",
294
- topologyId: definition.id,
295
- topologyRunId: id,
296
- multiAgentRunId: multiAgentRun.id,
297
- agentGroupId: group.id,
298
- agentFanoutId: fanout.id,
299
- blackboardId: board.id,
300
- blackboardMessageId: message.id,
301
- coordinatorDecisionId: decision.id,
302
- metadata: { fanoutStrategy: definition.fanoutStrategy, faninStrategy: definition.faninStrategy }
303
- });
304
- const now = new Date().toISOString();
305
- const record = {
306
- schemaVersion: exports.TOPOLOGY_SCHEMA_VERSION,
307
- id,
308
- runId: run.id,
309
- topologyId: definition.id,
310
- createdAt: now,
311
- updatedAt: now,
312
- status: fanin?.status === "blocked" ? "blocked" : "planned",
313
- title: input.title || definition.title,
314
- multiAgentRunId: multiAgentRun.id,
315
- blackboardId: board.id,
316
- topicIds: topics.map((topic) => topic.id),
317
- roleIds,
318
- groupIds: [group.id],
319
- fanoutIds: [fanout.id],
320
- faninIds: fanin ? [fanin.id] : [],
321
- messageIds: [message.id],
322
- artifactRefIds: [],
323
- coordinatorDecisionIds: [decision.id],
324
- candidateIds: [],
325
- selectionIds: [],
326
- commitIds: [],
327
- missingEvidence: fanin?.blockedReasons || definition.requiredEvidence,
328
- conflicts: [],
329
- nextActions: nextActionsFor(definition.id, run.id, id, fanout.id),
330
- links: {
331
- workflowRunId: run.id,
332
- multiAgentRunId: multiAgentRun.id,
333
- blackboardId: board.id,
334
- blackboardTopicIds: topics.map((topic) => topic.id),
335
- agentRoleIds: roleIds,
336
- agentGroupIds: [group.id],
337
- agentFanoutIds: [fanout.id],
338
- agentFaninIds: fanin ? [fanin.id] : [],
339
- coordinatorDecisionIds: [decision.id],
340
- candidateIds: [],
341
- selectionIds: [],
342
- commitIds: [],
343
- auditEventIds: [audit.id]
344
- },
345
- metadata: compact({ ...input.metadata, topology: definition })
346
- };
347
- state.runs.push(record);
348
- appendTopologyNode(run, record, statusToNodeStatus(record.status));
349
- (0, trust_audit_1.recordTrustAuditEvent)(run, {
350
- kind: "topology.verdict",
351
- decision: record.status === "blocked" ? "failed" : "recorded",
352
- source: "cw-validated",
353
- topologyId: definition.id,
354
- topologyRunId: id,
355
- multiAgentRunId: multiAgentRun.id,
356
- agentFanoutId: fanout.id,
357
- agentFaninId: fanin?.id,
358
- blackboardId: board.id,
359
- coordinatorDecisionId: decision.id,
360
- metadata: { status: record.status, missingEvidence: record.missingEvidence }
361
- });
362
- persistTopologyState(run);
363
- return record;
364
- }
365
- function summarizeTopologies(run) {
366
- const state = ensureTopologyState(run);
367
- const multi = (0, multi_agent_1.ensureMultiAgentState)(run);
368
- const active = state.runs.map((record) => {
369
- const inferredFanins = multi.fanins.filter((fanin) => record.groupIds.includes(fanin.groupId) || record.fanoutIds.includes(fanin.fanoutId || ""));
370
- const allFaninIds = unique([...record.faninIds, ...inferredFanins.map((fanin) => fanin.id)]);
371
- const blocked = inferredFanins.filter((fanin) => fanin.status === "blocked" || !fanin.verifierReady);
372
- const ready = inferredFanins.some((fanin) => fanin.verifierReady);
373
- const missingEvidence = unique([
374
- ...record.missingEvidence,
375
- ...blocked.flatMap((fanin) => fanin.blockedReasons)
376
- ]);
377
- return {
378
- id: record.id,
379
- topologyId: record.topologyId,
380
- status: ready ? "ready" : blocked.length ? "blocked" : record.status,
381
- multiAgentRunId: record.multiAgentRunId,
382
- blackboardId: record.blackboardId,
383
- roles: record.roleIds,
384
- groups: record.groupIds,
385
- topics: record.topicIds,
386
- fanouts: record.fanoutIds,
387
- fanins: allFaninIds,
388
- missingEvidence,
389
- conflicts: record.conflicts,
390
- readiness: ready ? "fanin ready" : missingEvidence.length ? "missing evidence" : "awaiting worker output",
391
- nextActions: ready ? [`node scripts/cw.js candidate register ${run.id} --result-node <reducer-or-panel-result>`] : record.nextActions
392
- };
393
- });
394
- return {
395
- runId: run.id,
396
- totalRuns: state.runs.length,
397
- runsByStatus: countBy(active, (record) => record.status),
398
- officialTopologies: listTopologyDefinitions().map((definition) => definition.id),
399
- active,
400
- nextAction: active.find((record) => record.nextActions.length)?.nextActions[0] || `node scripts/cw.js topology apply ${run.id} map-reduce --task <task-id>`
401
- };
402
- }
403
- function buildTopologyGraph(run) {
404
- const state = ensureTopologyState(run);
405
- const nodes = [];
406
- const edges = [];
407
- for (const record of state.runs) {
408
- nodes.push({ id: `${run.id}:topology:${record.id}`, kind: "topology-run", status: record.status, label: `${record.topologyId}:${record.id}`, path: topologyRunPath(run, record.id) });
409
- edges.push({ from: `${run.id}:run`, to: `${run.id}:topology:${record.id}` });
410
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:multi-agent:${record.multiAgentRunId}`, label: "multi-agent" });
411
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
412
- for (const topicId of record.topicIds)
413
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:blackboard:topic:${topicId}`, label: "topic" });
414
- for (const roleId of record.roleIds)
415
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:multi-agent:role:${roleId}`, label: "role" });
416
- for (const groupId of record.groupIds)
417
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:multi-agent:group:${groupId}`, label: "group" });
418
- for (const fanoutId of record.fanoutIds)
419
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:multi-agent:fanout:${fanoutId}`, label: "fanout" });
420
- for (const faninId of record.faninIds)
421
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:multi-agent:fanin:${faninId}`, label: "fanin" });
422
- for (const decisionId of record.coordinatorDecisionIds)
423
- edges.push({ from: `${run.id}:topology:${record.id}`, to: `${run.id}:blackboard:decision:${decisionId}`, label: "decision" });
424
- }
425
- return { nodes, edges: uniqueEdges(edges) };
426
- }
427
- function showTopologyRun(run, topologyRunId) {
428
- const record = ensureTopologyState(run).runs.find((entry) => entry.id === topologyRunId);
429
- if (!record)
430
- throw new Error(`Unknown topology run id: ${topologyRunId}`);
431
- return record;
432
- }
433
- /** Boundary adapter: fold the legacy id-keyed mapperCount/judgeCount flags into
434
- * the uniform roleCounts map so materializedRoles can stay purely data-driven.
435
- * An explicit roleCounts entry always wins; the judge floor (>= 2) preserves the
436
- * prior clamp so a panel never collapses to a single judge. */
437
- function withLegacyRoleCounts(input) {
438
- const legacy = {
439
- mapper: input.mapperCount === undefined ? undefined : Math.max(1, input.mapperCount),
440
- judge: input.judgeCount === undefined ? undefined : Math.max(2, input.judgeCount)
441
- };
442
- const roleCounts = { ...input.roleCounts };
443
- for (const [roleId, value] of Object.entries(legacy)) {
444
- if (value !== undefined && roleCounts[roleId] === undefined)
445
- roleCounts[roleId] = value;
446
- }
447
- return Object.keys(roleCounts).length ? { ...input, roleCounts } : input;
448
- }
449
- function materializedRoles(definition, input) {
450
- const roles = [];
451
- for (const role of definition.roles) {
452
- // Width is data-driven: a uniform per-role override, else the role's
453
- // declared count, else a single instance. No topology-id/role-id branching.
454
- const roleCount = Math.max(1, input.roleCounts?.[role.id] ?? role.count ?? 1);
455
- if (roleCount > 1) {
456
- for (let index = 1; index <= roleCount; index += 1)
457
- roles.push(expandRole(role, `${role.id}-${index}`, `${role.title} ${index}`));
458
- }
459
- else {
460
- roles.push(expandRole(role, role.id, role.title));
461
- }
462
- }
463
- return roles;
464
- }
465
- function selectedTaskIds(run, taskIds) {
466
- const ids = taskIds?.length ? taskIds : [run.tasks.find((task) => task.status === "pending")?.id || run.tasks[0]?.id].filter(Boolean);
467
- for (const id of ids) {
468
- if (!run.tasks.some((task) => task.id === id))
469
- throw new Error(`Unknown task id for topology: ${id}`);
470
- }
471
- return ids;
472
- }
473
- function appendTopologyNode(run, record, status) {
474
- (0, state_node_1.appendRunNode)(run, (0, state_node_1.createStateNode)({
475
- id: `${run.id}:topology:${record.id}`,
476
- kind: "topology-run",
477
- status,
478
- loopStage: run.loopStage,
479
- outputs: { topologyId: record.topologyId, status: record.status },
480
- artifacts: [{ id: "topology-run", kind: "json", path: topologyRunPath(run, record.id) }],
481
- parents: [`${run.id}:multi-agent:${record.multiAgentRunId}`, `${run.id}:blackboard:${record.blackboardId}`],
482
- contractId: pipeline_contract_1.DEFAULT_PIPELINE_CONTRACT_ID,
483
- metadata: { topologyId: record.topologyId, topologyRunId: record.id }
484
- }));
485
- }
486
- function roleSpec(id, title, responsibilities, expectedArtifacts, faninObligations, count) {
487
- return { id, title, responsibilities, requiredEvidence: expectedArtifacts, expectedArtifacts, faninObligations, ...(count !== undefined ? { count } : {}) };
488
- }
489
- function topicSpec(id, title, description) {
490
- return { id, title, description };
491
- }
492
- function phaseSpec(id, title, roleIds, fanout, fanin, requiredEvidence, coordinatorDecisionKinds) {
493
- return { id, title, roleIds, fanout, fanin, requiredEvidence, coordinatorDecisionKinds };
494
- }
495
- function expandRole(role, id, title) {
496
- return { ...role, id, title };
497
- }
498
- function topologyRoot(run) {
499
- return run.paths.topologiesDir || node_path_1.default.join(run.paths.runDir, "topologies");
500
- }
501
- function topologyRunPath(run, id) {
502
- return node_path_1.default.join(topologyRoot(run), "runs", `${(0, state_1.safeFileName)(id)}.json`);
503
- }
504
- function nextActionsFor(topologyId, runId, topologyRunId, fanoutId) {
505
- return [
506
- `node scripts/cw.js dispatch ${runId} --multi-agent-fanout ${fanoutId}`,
507
- `node scripts/cw.js multi-agent fanin ${runId} ${topologyRunId}-fanin --fanout ${fanoutId}`,
508
- `node scripts/cw.js topology summary ${runId}`
509
- ];
510
- }
511
- function statusToNodeStatus(status) {
512
- if (status === "completed" || status === "ready")
513
- return "completed";
514
- if (status === "blocked")
515
- return "blocked";
516
- if (status === "failed")
517
- return "failed";
518
- if (status === "running")
519
- return "running";
520
- return "pending";
521
- }
522
- function issue(code, message, path) {
523
- return { code, message, path };
524
- }
525
- // Deterministic default topology-run id (F2, replay determinism): no wall-clock.
526
- // Bound to a short sha256 of canonical content — definition id, the SORTED role and
527
- // selected-task ids, the workflow run id, and a stable sequence (the count of
528
- // topology runs already on this run). Same sha256/stableStringify the kernel uses
529
- // for node ids and ledger record hashes, so two replays without --id reach a
530
- // byte-identical fingerprint, while distinct applies on one run stay distinct.
531
- function topologyRunId(definition, taskIds, runId, sequence) {
532
- const digest = (0, execution_backend_1.sha256)((0, telemetry_attestation_1.stableStringify)({
533
- definitionId: definition.id,
534
- roleIds: [...definition.roles.map((role) => role.id)].sort(),
535
- taskIds: [...taskIds].sort(),
536
- runId,
537
- sequence
538
- }));
539
- return `${definition.id}-${digest.replace("sha256:", "").slice(0, 16)}`;
540
- }
541
- function countBy(items, pick) {
542
- const counts = {};
543
- for (const item of items)
544
- counts[pick(item)] = (counts[pick(item)] || 0) + 1;
545
- return counts;
546
- }
547
- function unique(items) {
548
- return [...new Set(items.filter((item) => item !== undefined && item !== null))];
549
- }
550
- function uniqueEdges(edges) {
551
- const seen = new Set();
552
- return edges.filter((edge) => {
553
- const key = `${edge.from}->${edge.to}:${edge.label || ""}`;
554
- if (seen.has(key))
555
- return false;
556
- seen.add(key);
557
- return true;
558
- });
559
- }
560
- function compact(value) {
561
- return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
562
- }
563
- function clone(value) {
564
- return JSON.parse(JSON.stringify(value));
565
- }