cool-workflow 0.1.98 → 0.2.1

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 (315) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +18 -7
  4. package/apps/architecture-review/app.json +2 -2
  5. package/apps/architecture-review/workflow.js +12 -12
  6. package/apps/architecture-review-fast/app.json +1 -1
  7. package/apps/end-to-end-golden-path/app.json +1 -1
  8. package/apps/pr-review-fix-ci/app.json +1 -1
  9. package/apps/release-cut/app.json +1 -1
  10. package/apps/research-synthesis/app.json +1 -1
  11. package/dist/cli/dispatch.js +236 -0
  12. package/dist/cli/entry.js +120 -0
  13. package/dist/cli/io.js +21 -4
  14. package/dist/cli/parseargv.js +157 -0
  15. package/dist/cli.js +6 -33
  16. package/dist/core/capability-table.js +3518 -0
  17. package/dist/core/format/help.js +314 -0
  18. package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
  19. package/dist/core/hash.js +137 -0
  20. package/dist/core/multi-agent/candidate-scoring.js +219 -0
  21. package/dist/core/multi-agent/collaboration.js +481 -0
  22. package/dist/core/multi-agent/coordinator.js +515 -0
  23. package/dist/core/multi-agent/eval-replay.js +306 -0
  24. package/dist/core/multi-agent/runtime.js +929 -0
  25. package/dist/core/multi-agent/topology.js +298 -0
  26. package/dist/core/multi-agent/trust-policy.js +197 -0
  27. package/dist/core/pipeline/commit-gate.js +320 -0
  28. package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
  29. package/dist/core/pipeline/dispatch.js +103 -0
  30. package/dist/core/pipeline/drive-decide.js +227 -0
  31. package/dist/core/pipeline/error-feedback.js +161 -0
  32. package/dist/core/pipeline/loop-expansion.js +124 -0
  33. package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
  34. package/dist/core/pipeline/runner.js +230 -0
  35. package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
  36. package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
  37. package/dist/core/state/node-projection.js +95 -0
  38. package/dist/core/state/node-snapshot.js +230 -0
  39. package/dist/core/state/run-paths.js +93 -0
  40. package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
  41. package/dist/core/state/schema.js +50 -0
  42. package/dist/core/state/state-explosion/digest.js +243 -0
  43. package/dist/core/state/state-explosion/graph.js +527 -0
  44. package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
  45. package/dist/core/state/state-explosion/report.js +187 -0
  46. package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
  47. package/dist/{state-node.js → core/state/state-node.js} +90 -113
  48. package/dist/core/state/types.js +19 -0
  49. package/dist/{validation.js → core/state/validation.js} +64 -131
  50. package/dist/core/trust/evidence-grounding.js +134 -0
  51. package/dist/core/trust/ledger.js +199 -0
  52. package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
  53. package/dist/core/trust/telemetry-ledger.js +127 -0
  54. package/dist/core/types.js +20 -0
  55. package/dist/core/version.js +16 -0
  56. package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
  57. package/dist/mcp/dispatch.js +104 -0
  58. package/dist/mcp/server.js +144 -0
  59. package/dist/mcp-server.js +6 -84
  60. package/dist/{agent-config.js → shell/agent-config.js} +118 -71
  61. package/dist/shell/app-run-cli.js +88 -0
  62. package/dist/shell/audit-cli.js +259 -0
  63. package/dist/shell/audit-provenance.js +83 -0
  64. package/dist/shell/candidate-scoring-io.js +459 -0
  65. package/dist/shell/collaboration-io.js +264 -0
  66. package/dist/shell/commit-summary.js +104 -0
  67. package/dist/shell/commit.js +290 -0
  68. package/dist/shell/coordinator-io.js +476 -0
  69. package/dist/shell/demo-cli.js +19 -0
  70. package/dist/shell/dispatch.js +162 -0
  71. package/dist/shell/doctor.js +292 -0
  72. package/dist/shell/drive.js +885 -0
  73. package/dist/shell/error-feedback-io.js +305 -0
  74. package/dist/shell/eval-io.js +473 -0
  75. package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
  76. package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
  77. package/dist/shell/exec-backend-cli.js +88 -0
  78. package/dist/shell/execution-backend/agent.js +507 -0
  79. package/dist/shell/execution-backend/ci.js +15 -0
  80. package/dist/shell/execution-backend/container.js +69 -0
  81. package/dist/shell/execution-backend/envelopes.js +55 -0
  82. package/dist/shell/execution-backend/local.js +113 -0
  83. package/dist/shell/execution-backend/probes.js +175 -0
  84. package/dist/shell/execution-backend/registry.js +402 -0
  85. package/dist/shell/execution-backend/remote.js +128 -0
  86. package/dist/shell/execution-backend/types.js +11 -0
  87. package/dist/shell/feedback-cli.js +81 -0
  88. package/dist/shell/feedback-operations.js +48 -0
  89. package/dist/shell/fs-atomic.js +276 -0
  90. package/dist/shell/harness.js +98 -0
  91. package/dist/shell/ledger-cli.js +212 -0
  92. package/dist/shell/ledger-io.js +169 -0
  93. package/dist/shell/man-cli.js +89 -0
  94. package/dist/shell/metrics-cli.js +100 -0
  95. package/dist/shell/multi-agent-cli.js +1002 -0
  96. package/dist/shell/multi-agent-host.js +563 -0
  97. package/dist/shell/multi-agent-io.js +387 -0
  98. package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
  99. package/dist/shell/node-store.js +124 -0
  100. package/dist/{observability/format.js → shell/observability-format.js} +7 -1
  101. package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
  102. package/dist/{observability.js → shell/observability.js} +159 -332
  103. package/dist/{onramp.js → shell/onramp.js} +11 -0
  104. package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
  105. package/dist/shell/operator-ux.js +431 -0
  106. package/dist/shell/orchestrator.js +231 -0
  107. package/dist/shell/pipeline-cli.js +667 -0
  108. package/dist/shell/pipeline.js +217 -0
  109. package/dist/shell/reclamation-io.js +1366 -0
  110. package/dist/shell/registry-cli.js +344 -0
  111. package/dist/{remote-source.js → shell/remote-source.js} +2 -2
  112. package/dist/shell/report-cli.js +101 -0
  113. package/dist/shell/report-view-cli.js +117 -0
  114. package/dist/{orchestrator → shell}/report.js +289 -282
  115. package/dist/shell/reporter.js +62 -0
  116. package/dist/shell/run-export-cli.js +106 -0
  117. package/dist/shell/run-export.js +680 -0
  118. package/dist/shell/run-registry-io.js +1014 -0
  119. package/dist/shell/run-store.js +164 -0
  120. package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
  121. package/dist/{scheduler.js → shell/scheduler-io.js} +257 -48
  122. package/dist/shell/scheduling-io.js +321 -0
  123. package/dist/shell/state-cli.js +181 -0
  124. package/dist/shell/state-explosion-cli.js +197 -0
  125. package/dist/shell/telemetry-cli.js +85 -0
  126. package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
  127. package/dist/shell/telemetry-ledger-io.js +132 -0
  128. package/dist/{term.js → shell/term.js} +36 -46
  129. package/dist/shell/topology-io.js +361 -0
  130. package/dist/shell/trust-audit.js +472 -0
  131. package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
  132. package/dist/shell/verifier.js +48 -0
  133. package/dist/shell/workbench-host.js +258 -0
  134. package/dist/shell/workbench-text.js +18 -0
  135. package/dist/shell/workbench.js +170 -0
  136. package/dist/shell/worker-cli.js +124 -0
  137. package/dist/shell/worker-isolation.js +852 -0
  138. package/dist/shell/workflow-app-loader.js +650 -0
  139. package/docs/agent-delegation-drive.7.md +4 -0
  140. package/docs/cli-mcp-parity.7.md +282 -219
  141. package/docs/contract-migration-tooling.7.md +4 -0
  142. package/docs/control-plane-scheduling.7.md +4 -0
  143. package/docs/durable-state-and-locking.7.md +4 -0
  144. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  145. package/docs/execution-backends.7.md +4 -0
  146. package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
  147. package/docs/multi-agent-eval-replay-harness.7.md +4 -0
  148. package/docs/multi-agent-operator-ux.7.md +4 -0
  149. package/docs/node-snapshot-diff-replay.7.md +4 -0
  150. package/docs/observability-cost-accounting.7.md +6 -1
  151. package/docs/project-index.md +137 -71
  152. package/docs/real-execution-backends.7.md +4 -0
  153. package/docs/release-and-migration.7.md +4 -0
  154. package/docs/release-tooling.7.md +4 -0
  155. package/docs/remote-source-review.7.md +4 -4
  156. package/docs/report-verifiable-bundle.7.md +1 -1
  157. package/docs/run-registry-control-plane.7.md +4 -0
  158. package/docs/run-retention-reclamation.7.md +25 -0
  159. package/docs/security-trust-hardening.7.md +3 -1
  160. package/docs/state-explosion-management.7.md +4 -0
  161. package/docs/team-collaboration.7.md +4 -0
  162. package/docs/web-desktop-workbench.7.md +15 -1
  163. package/manifest/plugin.manifest.json +1 -1
  164. package/manifest/source-context-profiles.json +9 -13
  165. package/package.json +1 -1
  166. package/scripts/agents/agent-adapter-core.js +22 -2
  167. package/scripts/agents/claude-p-agent.js +8 -3
  168. package/scripts/agents/cw-attest-wrap.js +2 -2
  169. package/scripts/agents/gemini-agent.js +5 -1
  170. package/scripts/agents/opencode-agent.js +5 -1
  171. package/scripts/bump-version.js +4 -3
  172. package/scripts/canonical-apps.js +4 -4
  173. package/scripts/dogfood-architecture-review.js +2 -3
  174. package/scripts/dogfood-release.js +3 -3
  175. package/scripts/gen-parity-doc.js +15 -2
  176. package/scripts/golden-path.js +4 -4
  177. package/scripts/onramp-check.js +1 -1
  178. package/scripts/parity-check.js +38 -21
  179. package/scripts/release-flow.js +2 -2
  180. package/scripts/sync-project-index.js +51 -27
  181. package/scripts/validate-run-state-schema.js +2 -2
  182. package/scripts/version-sync-check.js +30 -30
  183. package/dist/candidate-scoring.js +0 -729
  184. package/dist/capability-core.js +0 -1189
  185. package/dist/capability-registry.js +0 -885
  186. package/dist/cli/command-surface.js +0 -494
  187. package/dist/cli/format.js +0 -56
  188. package/dist/cli/handlers/audit.js +0 -82
  189. package/dist/cli/handlers/blackboard.js +0 -81
  190. package/dist/cli/handlers/candidate.js +0 -40
  191. package/dist/cli/handlers/clones.js +0 -34
  192. package/dist/cli/handlers/collaboration.js +0 -61
  193. package/dist/cli/handlers/eval.js +0 -40
  194. package/dist/cli/handlers/ledger.js +0 -169
  195. package/dist/cli/handlers/maintenance.js +0 -107
  196. package/dist/cli/handlers/multi-agent.js +0 -165
  197. package/dist/cli/handlers/node.js +0 -41
  198. package/dist/cli/handlers/operational.js +0 -155
  199. package/dist/cli/handlers/operator.js +0 -146
  200. package/dist/cli/handlers/registry.js +0 -68
  201. package/dist/cli/handlers/run.js +0 -153
  202. package/dist/cli/handlers/scheduling.js +0 -132
  203. package/dist/cli/handlers/workbench.js +0 -41
  204. package/dist/cli/handlers/worker.js +0 -45
  205. package/dist/cli/run-summary.js +0 -45
  206. package/dist/clones.js +0 -162
  207. package/dist/collaboration.js +0 -726
  208. package/dist/commit.js +0 -592
  209. package/dist/compare.js +0 -18
  210. package/dist/coordinator/classify.js +0 -45
  211. package/dist/coordinator/paths.js +0 -42
  212. package/dist/coordinator/util.js +0 -126
  213. package/dist/coordinator.js +0 -990
  214. package/dist/daemon.js +0 -44
  215. package/dist/dispatch.js +0 -250
  216. package/dist/doctor.js +0 -212
  217. package/dist/drive.js +0 -864
  218. package/dist/error-feedback.js +0 -419
  219. package/dist/evidence-grounding.js +0 -184
  220. package/dist/execution-backend/agent.js +0 -354
  221. package/dist/execution-backend/probes.js +0 -112
  222. package/dist/execution-backend/util.js +0 -47
  223. package/dist/execution-backend.js +0 -961
  224. package/dist/gates.js +0 -48
  225. package/dist/harness.js +0 -61
  226. package/dist/ledger.js +0 -313
  227. package/dist/loop-expansion.js +0 -60
  228. package/dist/mcp/tool-call.js +0 -470
  229. package/dist/mcp/tool-definitions.js +0 -1066
  230. package/dist/mcp-surface.js +0 -30
  231. package/dist/multi-agent/graph.js +0 -84
  232. package/dist/multi-agent/helpers.js +0 -141
  233. package/dist/multi-agent/ids.js +0 -20
  234. package/dist/multi-agent/paths.js +0 -22
  235. package/dist/multi-agent-eval/normalize.js +0 -51
  236. package/dist/multi-agent-eval.js +0 -678
  237. package/dist/multi-agent-host.js +0 -777
  238. package/dist/multi-agent.js +0 -984
  239. package/dist/node-projection.js +0 -59
  240. package/dist/node-snapshot.js +0 -260
  241. package/dist/operator-ux.js +0 -631
  242. package/dist/orchestrator/app-operations.js +0 -211
  243. package/dist/orchestrator/audit-operations.js +0 -182
  244. package/dist/orchestrator/candidate-operations.js +0 -117
  245. package/dist/orchestrator/cli-options.js +0 -294
  246. package/dist/orchestrator/collaboration-operations.js +0 -86
  247. package/dist/orchestrator/feedback-operations.js +0 -81
  248. package/dist/orchestrator/host-operations.js +0 -78
  249. package/dist/orchestrator/lifecycle-operations.js +0 -650
  250. package/dist/orchestrator/migration-operations.js +0 -44
  251. package/dist/orchestrator/multi-agent-operations.js +0 -362
  252. package/dist/orchestrator/topology-operations.js +0 -84
  253. package/dist/orchestrator.js +0 -925
  254. package/dist/pipeline-runner.js +0 -285
  255. package/dist/reclamation/hash.js +0 -72
  256. package/dist/reclamation.js +0 -812
  257. package/dist/reporter.js +0 -67
  258. package/dist/run-export.js +0 -815
  259. package/dist/run-registry/derive.js +0 -175
  260. package/dist/run-registry/format.js +0 -124
  261. package/dist/run-registry/gc.js +0 -251
  262. package/dist/run-registry/policy.js +0 -16
  263. package/dist/run-registry/queue.js +0 -115
  264. package/dist/run-registry.js +0 -850
  265. package/dist/run-state-schema.js +0 -68
  266. package/dist/scheduling.js +0 -184
  267. package/dist/state-explosion.js +0 -1014
  268. package/dist/state.js +0 -367
  269. package/dist/telemetry-ledger.js +0 -196
  270. package/dist/topology.js +0 -565
  271. package/dist/triggers.js +0 -184
  272. package/dist/trust-audit.js +0 -644
  273. package/dist/types/blackboard.js +0 -2
  274. package/dist/types/candidate.js +0 -2
  275. package/dist/types/collaboration.js +0 -2
  276. package/dist/types/core.js +0 -2
  277. package/dist/types/drive.js +0 -10
  278. package/dist/types/error-feedback.js +0 -2
  279. package/dist/types/evidence-reasoning.js +0 -2
  280. package/dist/types/execution-backend.js +0 -2
  281. package/dist/types/multi-agent.js +0 -2
  282. package/dist/types/observability.js +0 -2
  283. package/dist/types/pipeline.js +0 -2
  284. package/dist/types/reclamation.js +0 -8
  285. package/dist/types/report-bundle.js +0 -6
  286. package/dist/types/result.js +0 -2
  287. package/dist/types/run-registry.js +0 -2
  288. package/dist/types/run.js +0 -2
  289. package/dist/types/sandbox.js +0 -2
  290. package/dist/types/schedule.js +0 -2
  291. package/dist/types/state-node.js +0 -2
  292. package/dist/types/topology.js +0 -2
  293. package/dist/types/trust.js +0 -2
  294. package/dist/types/workbench.js +0 -2
  295. package/dist/types/worker.js +0 -2
  296. package/dist/types/workflow-app.js +0 -2
  297. package/dist/types.js +0 -44
  298. package/dist/util/fingerprint.js +0 -19
  299. package/dist/util/fingerprint.test.js +0 -27
  300. package/dist/verifier.js +0 -78
  301. package/dist/version.js +0 -8
  302. package/dist/workbench-host.js +0 -192
  303. package/dist/workbench.js +0 -192
  304. package/dist/worker-accept/acceptance.js +0 -114
  305. package/dist/worker-accept/blackboard-fanout.js +0 -80
  306. package/dist/worker-accept/blackboard-linkage.js +0 -19
  307. package/dist/worker-accept/context.js +0 -2
  308. package/dist/worker-accept/telemetry-ledger.js +0 -126
  309. package/dist/worker-accept/validation.js +0 -77
  310. package/dist/worker-accept/verifier-completion.js +0 -73
  311. package/dist/worker-isolation/helpers.js +0 -51
  312. package/dist/worker-isolation/paths.js +0 -46
  313. package/dist/worker-isolation.js +0 -656
  314. package/dist/workflow-api.js +0 -131
  315. /package/dist/{types → core/types}/boundary.js +0 -0
@@ -1,494 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.runCli = runCli;
40
- const node_fs_1 = __importDefault(require("node:fs"));
41
- const node_path_1 = __importDefault(require("node:path"));
42
- const node_child_process_1 = require("node:child_process");
43
- const readline = __importStar(require("node:readline"));
44
- const orchestrator_1 = require("../orchestrator");
45
- const capability_core_1 = require("../capability-core");
46
- const scheduler_1 = require("../scheduler");
47
- const triggers_1 = require("../triggers");
48
- const io_1 = require("./io");
49
- const run_summary_1 = require("./run-summary");
50
- const audit_1 = require("./handlers/audit");
51
- const candidate_1 = require("./handlers/candidate");
52
- const operator_1 = require("./handlers/operator");
53
- const registry_1 = require("./handlers/registry");
54
- const multi_agent_1 = require("./handlers/multi-agent");
55
- const run_1 = require("./handlers/run");
56
- const collaboration_1 = require("./handlers/collaboration");
57
- const ledger_1 = require("./handlers/ledger");
58
- const blackboard_1 = require("./handlers/blackboard");
59
- const eval_1 = require("./handlers/eval");
60
- const node_1 = require("./handlers/node");
61
- const maintenance_1 = require("./handlers/maintenance");
62
- const operational_1 = require("./handlers/operational");
63
- const scheduling_1 = require("./handlers/scheduling");
64
- const worker_1 = require("./handlers/worker");
65
- const clones_1 = require("./handlers/clones");
66
- const workbench_1 = require("./handlers/workbench");
67
- const operator_ux_1 = require("../operator-ux");
68
- const doctor_1 = require("../doctor");
69
- const orchestrator_2 = require("../orchestrator");
70
- const version_1 = require("../version");
71
- async function runCli(argv = process.argv.slice(2)) {
72
- const args = (0, orchestrator_1.parseArgv)(argv);
73
- // Top-level flags: accept --version / -v / --help / -h before command lookup.
74
- if (args.command?.startsWith("-") || !args.command) {
75
- if (args.command === "--version" || args.command === "-v" || args.options.v || args.options.version) {
76
- process.stdout.write(`${version_1.CURRENT_COOL_WORKFLOW_VERSION}\n`);
77
- return;
78
- }
79
- if (!args.command || args.command === "--help" || args.command === "-h" || args.options.h || args.options.help) {
80
- process.stdout.write((0, orchestrator_1.formatHelp)() + "\n");
81
- return;
82
- }
83
- }
84
- // Map vendor shorthand flags (-claude, -codex, -gemini, -deepseek) to --agent-command.
85
- if (args.options.claude)
86
- args.options["agent-command"] = "builtin:claude";
87
- if (args.options.codex)
88
- args.options["agent-command"] = "builtin:codex";
89
- if (args.options.gemini)
90
- args.options["agent-command"] = "builtin:gemini";
91
- if (args.options.deepseek)
92
- args.options["agent-command"] = "builtin:deepseek";
93
- // -dir / --dir / -d : an intuitive alias for --repo — the project folder to review,
94
- // so `cw -q "…" -dir /path` works from any directory (no cd). Explicit --repo wins.
95
- if (!args.options.repo && args.options.dir)
96
- args.options.repo = args.options.dir;
97
- // Presentation flags — set BEFORE any drive spawn so the out-of-process agent wrapper
98
- // inherits them via process.env (presentation-only; stdout/the cw:result fence are untouched):
99
- // --verbose full agent narration inline (default is compact: current action + summary)
100
- // --no-color disable ANSI everywhere (CW_NO_COLOR is honored by term.colorEnabled AND the
101
- // wrapper); complements NO_COLOR/FORCE_COLOR
102
- // --full also stream full narration AND print the report inline at run end
103
- if (args.options.verbose)
104
- process.env.CW_VERBOSE = "1";
105
- if (args.options["no-color"])
106
- process.env.CW_NO_COLOR = "1";
107
- if (args.options.full)
108
- process.env.CW_OUTPUT = "full";
109
- // `cw <verb> --help` / `-h` -> per-command help (the verb's subcommands +
110
- // one-line summaries), derived from the capability registry. Additive: the
111
- // bare `cw` / `cw --help` top-level help is handled above.
112
- if ((args.options.help || args.options.h) && args.command && !args.command.startsWith("-")) {
113
- process.stdout.write((0, orchestrator_1.formatCommandHelp)(args.command) + "\n");
114
- return;
115
- }
116
- // Bare -q / --question -> redirect to quickstart (auto-detect repo/agent/app).
117
- // CONSUME the positional (shift) so the question never survives as positionals[0]
118
- // — otherwise the quickstart handler reads it as the app id ("Workflow app not found").
119
- if (args.command === "-q" || args.command === "--question") {
120
- if (!args.options.question && args.positionals[0])
121
- args.options.question = args.positionals.shift();
122
- args.command = "quickstart";
123
- }
124
- else if (!args.command && typeof args.options.question === "string") {
125
- args.command = "quickstart";
126
- }
127
- const runner = new orchestrator_1.CoolWorkflowRunner({
128
- pluginRoot: node_path_1.default.resolve(__dirname, "../..")
129
- });
130
- const scheduler = new scheduler_1.Scheduler(String(args.options.cwd || process.cwd()));
131
- const triggers = new triggers_1.RoutineTriggerBridge(String(args.options.cwd || process.cwd()));
132
- switch (args.command) {
133
- case "help": {
134
- const [topic] = args.positionals;
135
- process.stdout.write((topic ? (0, orchestrator_1.formatCommandHelp)(topic) : (0, orchestrator_1.formatHelp)()) + "\n");
136
- return;
137
- }
138
- case undefined:
139
- process.stdout.write((0, orchestrator_1.formatHelp)() + "\n");
140
- return;
141
- case "version":
142
- process.stdout.write(`${version_1.CURRENT_COOL_WORKFLOW_VERSION}\n`);
143
- return;
144
- case "update": {
145
- process.stderr.write("Updating cool-workflow...\n");
146
- const npm = (0, node_child_process_1.spawnSync)("npm", ["update", "-g", "cool-workflow"], { encoding: "utf8", stdio: "inherit" });
147
- if (npm.status !== 0) {
148
- process.stderr.write("Update failed, trying install...\n");
149
- const install = (0, node_child_process_1.spawnSync)("npm", ["install", "-g", "cool-workflow@latest"], { encoding: "utf8", stdio: "inherit" });
150
- if (install.status !== 0) {
151
- process.stderr.write("Install failed. Check npm and try again.\n");
152
- process.exitCode = 1;
153
- }
154
- }
155
- return;
156
- }
157
- case "fix": {
158
- const report = (0, doctor_1.runDoctor)(args.options, process.env, String(args.options.cwd || process.cwd()));
159
- process.stdout.write(`${(0, doctor_1.formatDoctorFixes)(report)}\n`);
160
- if (!report.ok)
161
- process.exitCode = 1;
162
- return;
163
- }
164
- case "list":
165
- (0, io_1.printJson)(runner.listWorkflows());
166
- return;
167
- case "search": {
168
- const keyword = args.positionals.join(" ");
169
- if (!keyword.trim())
170
- throw new Error("Missing search keyword.\n Tip: cw search architecture to find workflows about architecture.");
171
- const apps = runner.listApps();
172
- const lower = keyword.toLowerCase();
173
- const results = apps.filter((a) => a.title.toLowerCase().includes(lower) || a.summary.toLowerCase().includes(lower) || a.id.toLowerCase().includes(lower)).map((a) => ({ id: a.id, title: a.title, summary: a.summary }));
174
- if ((0, io_1.wantsJson)(args.options))
175
- (0, io_1.printJson)(results);
176
- else
177
- process.stdout.write(`${(0, orchestrator_2.formatSearchResults)(keyword, results)}\n`);
178
- return;
179
- }
180
- case "man": {
181
- const [topic] = args.positionals;
182
- if (!topic)
183
- throw new Error("Missing topic.\n Tip: cw man release-tooling for the release tooling manual.");
184
- const docsDir = node_path_1.default.resolve(runner.pluginRoot, "docs");
185
- const candidates = [
186
- node_path_1.default.join(docsDir, `${topic}.7.md`),
187
- node_path_1.default.join(docsDir, `${topic}.md`),
188
- node_path_1.default.join(docsDir, `${topic}`)
189
- ];
190
- let found;
191
- for (const c of candidates) {
192
- try {
193
- if (node_fs_1.default.statSync(c).isFile()) {
194
- found = c;
195
- break;
196
- }
197
- }
198
- catch { /* keep looking */ }
199
- }
200
- if (!found)
201
- throw new Error(`Man page not found: ${topic}.\n Tip: cw list for workflow topics, or browse docs/ for manuals.`);
202
- process.stdout.write(node_fs_1.default.readFileSync(found, "utf8"));
203
- return;
204
- }
205
- case "info": {
206
- const [appId] = args.positionals;
207
- if (!appId)
208
- throw new Error("Missing workflow app id.\n Tip: list apps with \"cw list\", then \"cw info <id>\" for details");
209
- const data = runner.showApp(appId);
210
- if ((0, io_1.wantsJson)(args.options))
211
- (0, io_1.printJson)(data);
212
- else
213
- process.stdout.write(`${(0, orchestrator_2.formatInfo)(appId, data)}\n`);
214
- return;
215
- }
216
- case "doctor": {
217
- const report = (0, doctor_1.runDoctor)(args.options, process.env, String(args.options.cwd || process.cwd()));
218
- if ((0, io_1.wantsJson)(args.options))
219
- (0, io_1.printJson)(report);
220
- else if (args.options.fix)
221
- process.stdout.write(`${(0, doctor_1.formatDoctorFixes)(report)}\n`);
222
- else
223
- process.stdout.write(`${(0, doctor_1.formatDoctorReport)(report)}\n`);
224
- if (!report.ok)
225
- process.exitCode = 1;
226
- return;
227
- }
228
- case "init": {
229
- const [workflowId] = args.positionals;
230
- if (!workflowId)
231
- throw new Error("Missing workflow id.\n Tip: create one with \"cw init my-workflow\" or list with \"cw list\"");
232
- (0, io_1.printJson)(runner.init(workflowId, args.options));
233
- return;
234
- }
235
- case "app": {
236
- const [subcommand, appIdOrPath] = args.positionals;
237
- switch (subcommand) {
238
- case "list":
239
- (0, io_1.printJson)(runner.listApps());
240
- return;
241
- case "show":
242
- (0, io_1.printJson)(runner.showApp((0, io_1.required)(appIdOrPath, "app id")));
243
- return;
244
- case "validate": {
245
- const result = runner.validateApp((0, io_1.required)(appIdOrPath, "app path or id"));
246
- (0, io_1.printJson)(result);
247
- if (!result.valid)
248
- process.exitCode = 1;
249
- return;
250
- }
251
- case "init":
252
- (0, io_1.printJson)(runner.initApp((0, io_1.required)(appIdOrPath, "app id"), args.options));
253
- return;
254
- case "package":
255
- (0, io_1.printJson)(runner.packageApp((0, io_1.required)(appIdOrPath, "app id"), args.options));
256
- return;
257
- case "run":
258
- (0, io_1.printJson)((0, capability_core_1.appRun)(runner, { ...args.options, appId: (0, io_1.required)(appIdOrPath, "app id") }));
259
- return;
260
- default:
261
- throw new Error("Usage: cw.js app list|show|validate|init|package|run [app-id|path]");
262
- }
263
- }
264
- case "quickstart":
265
- case "audit-run": {
266
- // ONE-COMMAND first value (v0.1.38+): plan(app) -> run --drive -> report in a
267
- // single invocation. A thin UX wrapper over the EXISTING drive() pipeline — it
268
- // DELEGATES worker execution to the operator's configured agent backend and
269
- // fails closed (status=blocked) when none is set. No new executor/scheduler.
270
- const [appId] = args.positionals;
271
- const runId = (0, io_1.optionalArg)(args.options.run) || (0, io_1.optionalArg)(args.options.runId);
272
- await promptQuestion(args.options);
273
- const qs = (0, capability_core_1.quickstart)(runner, { ...args.options, ...(appId ? { appId } : {}), ...(runId ? { runId } : {}) });
274
- (0, io_1.printJson)(qs);
275
- const qr = qs;
276
- // Clean human summary on stderr (TTY-gated, inside the reporter). Suppressed under --json so
277
- // machine mode emits ONLY the stdout payload — no stderr chrome to parse around. The type
278
- // guard also skips --check/--preview results (no reportPath of their own). The summary is the
279
- // COMPACT findings table (re-parsed from each completed worker's cw:result), the report path,
280
- // and where the per-worker transcripts live — NOT the full prose (that's report.md/--full).
281
- if (!(0, io_1.wantsJson)(args.options) && typeof qr.runId === "string" && typeof qr.reportPath === "string") {
282
- (0, run_summary_1.emitRunSummary)(runner, args.options, {
283
- runId: qr.runId,
284
- reportPath: qr.reportPath,
285
- status: String(qr.status || ""),
286
- statePath: typeof qr.statePath === "string" ? qr.statePath : undefined,
287
- completedWorkers: typeof qr.completedWorkers === "number" ? qr.completedWorkers : undefined,
288
- plannedWorkers: typeof qr.plannedWorkers === "number" ? qr.plannedWorkers : undefined,
289
- agentConfigured: typeof qr.agentConfigured === "boolean" ? qr.agentConfigured : undefined
290
- });
291
- }
292
- if (qs.mode === "check" && qs.ok === false) {
293
- process.exitCode = 1;
294
- }
295
- // Fail closed: if --bundle produced an artifact that does not self-verify, exit
296
- // non-zero so `cw quickstart ... --bundle && send-to-client` cannot ship a report
297
- // whose bundle a client could not verify. Mirrors `report bundle`.
298
- if (qs.bundle && qs.bundle.ok === false) {
299
- process.exitCode = 1;
300
- }
301
- return;
302
- }
303
- case "plan": {
304
- const [workflowId] = args.positionals;
305
- if (!workflowId)
306
- throw new Error("Missing workflow id.\n Tip: plan an architecture review with \"cw plan architecture-review\"");
307
- (0, io_1.printJson)((0, capability_core_1.planSummary)(runner, workflowId, args.options));
308
- return;
309
- }
310
- case "status":
311
- if (!args.positionals[0]) {
312
- const nextActions = (0, operator_ux_1.adviseNoRun)();
313
- if ((0, io_1.wantsJson)(args.options))
314
- (0, io_1.printJson)({ runId: null, nextActions });
315
- else
316
- process.stdout.write(`No run selected\n\nNext Action\n${nextActions.map((action) => ` ${action.command}\n reason: ${action.reason}`).join("\n")}\n`);
317
- }
318
- else if ((0, io_1.wantsJson)(args.options))
319
- (0, io_1.printJson)(runner.status(args.positionals[0]));
320
- else {
321
- const summary = runner.operatorStatus(args.positionals[0]);
322
- process.stdout.write(`${(args.options.summary || args.options.brief ? (0, operator_ux_1.formatOperatorSummary)(summary) : (0, operator_ux_1.formatOperatorStatus)(summary))}\n`);
323
- }
324
- return;
325
- case "next":
326
- (0, io_1.printJson)(runner.next((0, io_1.required)(args.positionals[0], "run id"), args.options));
327
- return;
328
- case "dispatch":
329
- (0, io_1.printJson)(runner.dispatch((0, io_1.required)(args.positionals[0], "run id"), args.options));
330
- return;
331
- case "result": {
332
- const [runId, taskId, resultPath] = args.positionals;
333
- (0, io_1.printJson)(runner.recordResult((0, io_1.required)(runId, "run id"), (0, io_1.required)(taskId, "task id"), (0, io_1.required)(resultPath, "result file"), args.options));
334
- return;
335
- }
336
- case "state": {
337
- const [subcommand, runId] = args.positionals;
338
- switch (subcommand) {
339
- case "check": {
340
- const report = runner.checkState((0, io_1.required)(runId, "run id"), args.options);
341
- (0, io_1.printJson)(report);
342
- if (report.status === "unsupported")
343
- process.exitCode = 1;
344
- return;
345
- }
346
- default:
347
- throw new Error("Usage: cw.js state check <run-id> [--state PATH] [--write]");
348
- }
349
- }
350
- case "commit":
351
- if (args.positionals[0] === "summary") {
352
- const summary = runner.summarizeCommitRecords((0, io_1.required)(args.positionals[1], "run id"));
353
- if ((0, io_1.wantsJson)(args.options))
354
- (0, io_1.printJson)(summary);
355
- else
356
- process.stdout.write(`${(0, operator_ux_1.formatCommitSummary)(summary)}\n`);
357
- return;
358
- }
359
- (0, io_1.printJson)(runner.commit((0, io_1.required)(args.positionals[0], "run id"), args.options));
360
- return;
361
- case "report":
362
- (0, operator_1.handleReport)(args, runner);
363
- return;
364
- case "operator":
365
- (0, operator_1.handleOperator)(args, runner);
366
- return;
367
- case "graph":
368
- (0, operator_1.handleGraph)(args, runner);
369
- return;
370
- case "topology":
371
- (0, operator_1.handleTopology)(args, runner);
372
- return;
373
- case "summary":
374
- (0, operator_1.handleSummary)(args, runner);
375
- return;
376
- case "multi-agent":
377
- (0, multi_agent_1.handleMultiAgent)(args, runner);
378
- return;
379
- case "eval":
380
- (0, eval_1.handleEval)(args, runner);
381
- return;
382
- case "blackboard":
383
- (0, blackboard_1.handleBlackboard)(args, runner);
384
- return;
385
- case "coordinator":
386
- (0, blackboard_1.handleCoordinator)(args, runner);
387
- return;
388
- case "sandbox":
389
- (0, operational_1.handleSandbox)(args, runner);
390
- return;
391
- case "backend":
392
- (0, operational_1.handleBackend)(args, runner);
393
- return;
394
- case "contract":
395
- (0, operational_1.handleContract)(args, runner);
396
- return;
397
- case "node":
398
- (0, node_1.handleNode)(args, runner);
399
- return;
400
- case "migration":
401
- (0, operational_1.handleMigration)(args, runner);
402
- return;
403
- case "feedback":
404
- (0, operational_1.handleFeedback)(args, runner);
405
- return;
406
- case "worker":
407
- (0, worker_1.handleWorker)(args, runner);
408
- return;
409
- case "audit":
410
- (0, audit_1.handleAudit)(args, runner);
411
- return;
412
- case "candidate":
413
- (0, candidate_1.handleCandidate)(args, runner);
414
- return;
415
- // ---- Team Collaboration (v0.1.32) ------------------------------------
416
- case "approve":
417
- (0, collaboration_1.handleApprove)(args, runner);
418
- return;
419
- case "reject":
420
- (0, collaboration_1.handleReject)(args, runner);
421
- return;
422
- case "comment":
423
- (0, collaboration_1.handleComment)(args, runner);
424
- return;
425
- case "handoff":
426
- (0, collaboration_1.handleHandoff)(args, runner);
427
- return;
428
- case "review":
429
- (0, collaboration_1.handleReview)(args, runner);
430
- return;
431
- case "ledger":
432
- (0, ledger_1.handleLedger)(args, runner);
433
- return;
434
- case "loop": {
435
- (0, io_1.printJson)(scheduler.create({ ...args.options, kind: "loop" }));
436
- return;
437
- }
438
- case "schedule":
439
- await (0, scheduling_1.handleSchedule)(args, scheduler);
440
- return;
441
- case "routine":
442
- (0, scheduling_1.handleRoutine)(args, triggers);
443
- return;
444
- case "registry":
445
- (0, registry_1.handleRegistry)(args, runner);
446
- return;
447
- case "metrics":
448
- (0, operational_1.handleMetrics)(args, runner);
449
- return;
450
- case "run":
451
- (0, run_1.handleRun)(args, runner);
452
- return;
453
- case "queue":
454
- (0, registry_1.handleQueue)(args, runner);
455
- return;
456
- case "sched":
457
- (0, scheduling_1.handleSched)(args, runner);
458
- return;
459
- case "clones":
460
- (0, clones_1.handleClones)(args);
461
- return;
462
- case "gc":
463
- (0, maintenance_1.handleGc)(args, runner);
464
- return;
465
- case "history":
466
- (0, registry_1.handleHistory)(args, runner);
467
- return;
468
- case "telemetry":
469
- (0, maintenance_1.handleTelemetry)(args, runner);
470
- return;
471
- case "demo":
472
- (0, maintenance_1.handleDemo)(args, runner);
473
- return;
474
- case "workbench":
475
- await (0, workbench_1.handleWorkbench)(args, runner);
476
- return;
477
- default:
478
- throw new Error(`Unknown command: ${args.command}${((0, orchestrator_1.suggestCommand)(String(args.command || "")) ? `. Did you mean: ${(0, orchestrator_1.suggestCommand)(String(args.command))}?` : "")}`);
479
- }
480
- }
481
- /** Prompt the user for a question interactively when --question is missing on a TTY. */
482
- async function promptQuestion(options) {
483
- if (options.question || !process.stdin.isTTY)
484
- return;
485
- const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
486
- return new Promise((resolve) => {
487
- rl.question("Question: ", (answer) => {
488
- rl.close();
489
- if (answer.trim())
490
- options.question = answer.trim();
491
- resolve();
492
- });
493
- });
494
- }
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.humanBytes = humanBytes;
4
- exports.formatClonesList = formatClonesList;
5
- exports.formatClonesGc = formatClonesGc;
6
- exports.formatWorkbenchView = formatWorkbenchView;
7
- function humanBytes(n) {
8
- if (n < 1024)
9
- return `${n}B`;
10
- const units = ["KiB", "MiB", "GiB"];
11
- let v = n / 1024;
12
- let i = 0;
13
- while (v >= 1024 && i < units.length - 1) {
14
- v /= 1024;
15
- i += 1;
16
- }
17
- return `${v.toFixed(1)}${units[i]}`;
18
- }
19
- function formatClonesList(result) {
20
- if (result.count === 0)
21
- return `No cached remote checkouts in ${result.clonesDir}.`;
22
- const rows = result.entries.map((e) => {
23
- const when = e.fetchedAt ? e.fetchedAt.replace("T", " ").replace(/\..*$/, "Z") : "unknown";
24
- return ` ${e.kind.padEnd(7)} ${humanBytes(e.bytes).padStart(8)} ${when} ${e.url}${e.ref ? `@${e.ref}` : ""}`;
25
- });
26
- return [
27
- `${result.count} cached checkout${result.count === 1 ? "" : "s"} — ${humanBytes(result.totalBytes)} in ${result.clonesDir}`,
28
- " KIND SIZE FETCHED SOURCE",
29
- ...rows,
30
- `\nReclaim with: cw clones gc --older-than-days 30 (or --all)`
31
- ].join("\n");
32
- }
33
- function formatClonesGc(result) {
34
- const scope = result.all ? "all entries" : `entries older than ${result.olderThanDays} day(s)`;
35
- if (result.removed.length === 0)
36
- return `Nothing to reclaim (${scope}); ${result.keptCount} kept in ${result.clonesDir}.`;
37
- const rows = result.removed.map((r) => ` ${humanBytes(r.bytes).padStart(8)} ${r.url}`);
38
- return [
39
- `Reclaimed ${result.removed.length} checkout${result.removed.length === 1 ? "" : "s"} (${scope}) — freed ${humanBytes(result.freedBytes)}; ${result.keptCount} kept`,
40
- ...rows
41
- ].join("\n");
42
- }
43
- function formatWorkbenchView(view) {
44
- const lines = [
45
- `Workbench view ${view.runId} (${view.resolved ? "resolved" : "UNRESOLVED"})`,
46
- view.error ? ` error: ${view.error}` : ""
47
- ].filter(Boolean);
48
- for (const [group, panels] of Object.entries(view.panels)) {
49
- lines.push(` ${group}:`);
50
- for (const [name, panel] of Object.entries(panels)) {
51
- const note = panel.status === "present" ? panel.capability : `absent (${panel.error || "unreadable"})`;
52
- lines.push(` ${name}: ${panel.status} — ${note}`);
53
- }
54
- }
55
- return lines.join("\n");
56
- }
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleAudit = handleAudit;
4
- const capability_core_1 = require("../../capability-core");
5
- const operator_ux_1 = require("../../operator-ux");
6
- const io_1 = require("../io");
7
- /** `cw audit summary|verify|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]`. */
8
- function handleAudit(args, runner) {
9
- const [subcommand, runId, id] = args.positionals;
10
- switch (subcommand) {
11
- case "summary":
12
- (0, io_1.printJson)(runner.auditSummary((0, io_1.required)(runId, "run id")));
13
- return;
14
- case "verify": {
15
- const result = (0, capability_core_1.auditVerify)(runner, { ...args.options, runId: (0, io_1.required)(runId, "run id") });
16
- (0, io_1.printJson)(result);
17
- // Fail-closed: any unverified chain exits non-zero so `cw audit verify
18
- // <run> && deploy` stops — mirrors the telemetry-verify guard. verifyTrustAudit
19
- // returns verified:true for a truly absent/empty chain (nothing to prove),
20
- // so this stays exit 0 there; a FULLY-corrupt log reports present:false but
21
- // verified:false (corruptLines>0) and must NOT be conflated with absent — the
22
- // earlier `present && ...` guard let that severe tamper escape (exit 0).
23
- if (!result.verified)
24
- process.exitCode = 1;
25
- return;
26
- }
27
- case "worker":
28
- (0, io_1.printJson)(runner.workerAudit((0, io_1.required)(runId, "run id"), (0, io_1.required)(id, "worker id")));
29
- return;
30
- case "provenance":
31
- (0, io_1.printJson)(runner.evidenceProvenance((0, io_1.required)(runId, "run id"), args.options));
32
- return;
33
- case "multi-agent": {
34
- const view = runner.auditMultiAgent((0, io_1.required)(runId, "run id"));
35
- if ((0, io_1.wantsJson)(args.options))
36
- (0, io_1.printJson)(view);
37
- else
38
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
39
- return;
40
- }
41
- case "policy": {
42
- const view = runner.auditPolicy((0, io_1.required)(runId, "run id"));
43
- if ((0, io_1.wantsJson)(args.options))
44
- (0, io_1.printJson)(view);
45
- else
46
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
47
- return;
48
- }
49
- case "role": {
50
- const view = runner.auditRole((0, io_1.required)(runId, "run id"), (0, io_1.required)(id, "role id"));
51
- if ((0, io_1.wantsJson)(args.options))
52
- (0, io_1.printJson)(view);
53
- else
54
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
55
- return;
56
- }
57
- case "blackboard": {
58
- const view = runner.auditBlackboard((0, io_1.required)(runId, "run id"));
59
- if ((0, io_1.wantsJson)(args.options))
60
- (0, io_1.printJson)(view);
61
- else
62
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
63
- return;
64
- }
65
- case "judge": {
66
- const view = runner.auditJudge((0, io_1.required)(runId, "run id"));
67
- if ((0, io_1.wantsJson)(args.options))
68
- (0, io_1.printJson)(view);
69
- else
70
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
71
- return;
72
- }
73
- case "attest":
74
- (0, io_1.printJson)(runner.recordAuditAttestation((0, io_1.required)(runId, "run id"), args.options));
75
- return;
76
- case "decision":
77
- (0, io_1.printJson)(runner.recordAuditDecision((0, io_1.required)(runId, "run id"), (0, io_1.required)(id, "worker id"), args.options));
78
- return;
79
- default:
80
- throw new Error("Usage: cw.js audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]");
81
- }
82
- }