@the-open-engine/zeroshot 6.38.1 → 6.39.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 (383) hide show
  1. package/README.md +6 -0
  2. package/cli/event-copy.js +8 -7
  3. package/cli/event-copy.ts +12 -0
  4. package/cli/index.js +67 -48
  5. package/cli/json-export.js +61 -64
  6. package/cli/json-export.ts +112 -0
  7. package/cli/message-formatter-utils.js +68 -56
  8. package/cli/message-formatter-utils.ts +121 -0
  9. package/cli/message-formatters-normal.js +124 -259
  10. package/cli/message-formatters-normal.ts +250 -0
  11. package/cli/message-formatters-watch.js +81 -84
  12. package/cli/message-formatters-watch.ts +189 -0
  13. package/lib/cluster/generated/protocol-schema.cjs +1 -1
  14. package/lib/cluster/generated/protocol-schema.mjs +1 -1
  15. package/lib/cluster/generated/protocol.d.cts +8 -0
  16. package/lib/cluster/generated/protocol.d.mts +8 -0
  17. package/lib/cluster/generated/protocol.d.ts +8 -0
  18. package/lib/clusters-registry.d.ts +23 -0
  19. package/lib/clusters-registry.js +17 -29
  20. package/lib/completion.d.ts +12 -0
  21. package/lib/completion.js +84 -94
  22. package/lib/compose-utils.d.ts +32 -0
  23. package/lib/compose-utils.js +57 -72
  24. package/lib/detached-startup.d.ts +84 -0
  25. package/lib/detached-startup.js +232 -302
  26. package/lib/docker-config.d.ts +43 -0
  27. package/lib/docker-config.js +150 -325
  28. package/lib/docker-env-auth.d.ts +17 -0
  29. package/lib/docker-env-auth.js +75 -0
  30. package/lib/git-remote-utils.d.ts +48 -0
  31. package/lib/git-remote-utils.js +147 -213
  32. package/lib/id-detector.d.ts +15 -0
  33. package/lib/id-detector.js +37 -41
  34. package/lib/path-check.d.ts +30 -0
  35. package/lib/path-check.js +42 -45
  36. package/lib/process-liveness.d.ts +16 -0
  37. package/lib/process-liveness.js +19 -12
  38. package/lib/provider-credential-path.d.ts +16 -0
  39. package/lib/provider-credential-path.js +31 -29
  40. package/lib/provider-defaults.d.ts +30 -0
  41. package/lib/provider-defaults.js +47 -42
  42. package/lib/provider-detection.d.ts +11 -0
  43. package/lib/provider-detection.js +91 -54
  44. package/lib/provider-names.d.ts +38 -0
  45. package/lib/provider-names.js +56 -64
  46. package/lib/repo-settings.d.ts +28 -0
  47. package/lib/repo-settings.js +83 -59
  48. package/lib/run-mode.d.ts +21 -0
  49. package/lib/run-mode.js +21 -20
  50. package/lib/run-plan.d.ts +28 -0
  51. package/lib/run-plan.js +17 -16
  52. package/lib/settings/claude-auth.d.ts +35 -0
  53. package/lib/settings/claude-auth.js +30 -47
  54. package/lib/settings-defaults.d.ts +20 -0
  55. package/lib/settings-defaults.js +149 -0
  56. package/lib/settings-error.d.ts +7 -0
  57. package/lib/settings-error.js +8 -0
  58. package/lib/settings-issue-providers.d.ts +10 -0
  59. package/lib/settings-issue-providers.js +12 -0
  60. package/lib/settings-models.d.ts +22 -0
  61. package/lib/settings-models.js +93 -0
  62. package/lib/settings-storage.d.ts +23 -0
  63. package/lib/settings-storage.js +205 -0
  64. package/lib/settings-validation.d.ts +7 -0
  65. package/lib/settings-validation.js +182 -0
  66. package/lib/settings.d.ts +29 -0
  67. package/lib/settings.js +41 -736
  68. package/lib/setup-apply-types.d.ts +66 -0
  69. package/lib/setup-apply-types.js +2 -0
  70. package/lib/setup-apply.d.ts +39 -0
  71. package/lib/setup-apply.js +267 -264
  72. package/lib/setup-journal.d.ts +41 -0
  73. package/lib/setup-journal.js +119 -76
  74. package/lib/setup-plan-types.d.ts +102 -0
  75. package/lib/setup-plan-types.js +2 -0
  76. package/lib/setup-plan.d.ts +30 -0
  77. package/lib/setup-plan.js +300 -324
  78. package/lib/setup-undo.d.ts +44 -0
  79. package/lib/setup-undo.js +61 -74
  80. package/lib/start-cluster-config.d.ts +26 -0
  81. package/lib/start-cluster-config.js +56 -0
  82. package/lib/start-cluster-environment.d.ts +41 -0
  83. package/lib/start-cluster-environment.js +134 -0
  84. package/lib/start-cluster-run-options.d.ts +54 -0
  85. package/lib/start-cluster-run-options.js +148 -0
  86. package/lib/start-cluster.d.ts +64 -0
  87. package/lib/start-cluster.js +98 -454
  88. package/lib/stream-json-parser.d.ts +17 -0
  89. package/lib/stream-json-parser.js +51 -52
  90. package/npm-shrinkwrap.json +6 -8
  91. package/package.json +14 -8
  92. package/scripts/postinstall.js +27 -0
  93. package/scripts/rust-distribution.js +36 -45
  94. package/src/agent/agent-command-proofs-context.js +35 -45
  95. package/src/agent/agent-command-proofs-context.ts +87 -0
  96. package/src/agent/agent-config-settings.js +19 -0
  97. package/src/agent/agent-config-settings.ts +41 -0
  98. package/src/agent/agent-config.js +122 -231
  99. package/src/agent/agent-config.ts +285 -0
  100. package/src/agent/agent-context-builder.js +38 -273
  101. package/src/agent/agent-context-builder.ts +51 -0
  102. package/src/agent/agent-context-environment-sections.js +105 -0
  103. package/src/agent/agent-context-environment-sections.ts +134 -0
  104. package/src/agent/agent-context-packs.js +165 -0
  105. package/src/agent/agent-context-packs.ts +296 -0
  106. package/src/agent/agent-context-prompt-sections.js +100 -0
  107. package/src/agent/agent-context-prompt-sections.ts +148 -0
  108. package/src/agent/agent-context-sections.js +25 -334
  109. package/src/agent/agent-context-sections.ts +36 -0
  110. package/src/agent/agent-context-sources.js +96 -149
  111. package/src/agent/agent-context-sources.ts +253 -0
  112. package/src/agent/agent-context-types.js +2 -0
  113. package/src/agent/agent-context-types.ts +132 -0
  114. package/src/agent/agent-context-validation-sections.js +73 -0
  115. package/src/agent/agent-context-validation-sections.ts +129 -0
  116. package/src/agent/agent-input-injector.js +99 -118
  117. package/src/agent/agent-input-injector.ts +195 -0
  118. package/src/agent/agent-liveness-poll.js +74 -78
  119. package/src/agent/agent-liveness-poll.ts +163 -0
  120. package/src/agent/agent-quality-gate-schema.js +77 -86
  121. package/src/agent/agent-quality-gate-schema.ts +135 -0
  122. package/src/agent/agent-quality-gates-context.js +44 -50
  123. package/src/agent/agent-quality-gates-context.ts +91 -0
  124. package/src/agent/agent-stuck-detector.js +171 -239
  125. package/src/agent/agent-stuck-detector.ts +288 -0
  126. package/src/agent/agent-trigger-evaluator.js +29 -46
  127. package/src/agent/agent-trigger-evaluator.ts +98 -0
  128. package/src/agent/context-metrics.js +110 -141
  129. package/src/agent/context-metrics.ts +261 -0
  130. package/src/agent/context-pack-builder.js +72 -358
  131. package/src/agent/context-pack-builder.ts +105 -0
  132. package/src/agent/context-pack-core.js +70 -0
  133. package/src/agent/context-pack-core.ts +96 -0
  134. package/src/agent/context-pack-selection.js +119 -0
  135. package/src/agent/context-pack-selection.ts +187 -0
  136. package/src/agent/context-pack-truncation.js +139 -0
  137. package/src/agent/context-pack-truncation.ts +208 -0
  138. package/src/agent/context-pack-types.js +2 -0
  139. package/src/agent/context-pack-types.ts +98 -0
  140. package/src/agent/context-replay-policy.js +30 -39
  141. package/src/agent/context-replay-policy.ts +71 -0
  142. package/src/agent/critical-agent-policy.js +6 -10
  143. package/src/agent/critical-agent-policy.ts +20 -0
  144. package/src/agent/guidance-queue.js +74 -87
  145. package/src/agent/guidance-queue.ts +166 -0
  146. package/src/agent/output-extraction-error-detail.js +45 -0
  147. package/src/agent/output-extraction-error-detail.ts +49 -0
  148. package/src/agent/output-extraction-failures.js +125 -0
  149. package/src/agent/output-extraction-failures.ts +149 -0
  150. package/src/agent/output-extraction-json.js +234 -0
  151. package/src/agent/output-extraction-json.ts +235 -0
  152. package/src/agent/output-extraction-pi.js +124 -0
  153. package/src/agent/output-extraction-pi.ts +137 -0
  154. package/src/agent/output-extraction-types.js +2 -0
  155. package/src/agent/output-extraction-types.ts +49 -0
  156. package/src/agent/output-extraction.js +17 -617
  157. package/src/agent/output-extraction.ts +30 -0
  158. package/src/agent/output-reformatter-errors.js +83 -0
  159. package/src/agent/output-reformatter-errors.ts +106 -0
  160. package/src/agent/output-reformatter-types.js +2 -0
  161. package/src/agent/output-reformatter-types.ts +86 -0
  162. package/src/agent/output-reformatter.js +140 -185
  163. package/src/agent/output-reformatter.ts +238 -0
  164. package/src/agent/pi-terminal-lifecycle-types.js +2 -0
  165. package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
  166. package/src/agent/pi-terminal-lifecycle.js +186 -206
  167. package/src/agent/pi-terminal-lifecycle.ts +297 -0
  168. package/src/agent/provider-control-plane.js +22 -21
  169. package/src/agent/provider-control-plane.ts +52 -0
  170. package/src/agent/provider-terminal-failure-types.js +2 -0
  171. package/src/agent/provider-terminal-failure-types.ts +60 -0
  172. package/src/agent/provider-terminal-failure.js +194 -191
  173. package/src/agent/provider-terminal-failure.ts +262 -0
  174. package/src/agent/rate-limit-backoff.js +31 -74
  175. package/src/agent/rate-limit-backoff.ts +71 -0
  176. package/src/agent/schema-utils.js +85 -125
  177. package/src/agent/schema-utils.ts +148 -0
  178. package/src/agent/structured-output-error.js +34 -33
  179. package/src/agent/structured-output-error.ts +105 -0
  180. package/src/agent/validation-platform.js +27 -27
  181. package/src/agent/validation-platform.ts +49 -0
  182. package/src/agents/git-pusher-template.js +17 -34
  183. package/src/attach/attach-client.js +232 -405
  184. package/src/attach/attach-client.ts +300 -0
  185. package/src/attach/attach-server-cleanup.js +43 -0
  186. package/src/attach/attach-server-cleanup.ts +39 -0
  187. package/src/attach/attach-server-clients.js +117 -0
  188. package/src/attach/attach-server-clients.ts +122 -0
  189. package/src/attach/attach-server-events.js +38 -0
  190. package/src/attach/attach-server-events.ts +36 -0
  191. package/src/attach/attach-server-pty.js +45 -0
  192. package/src/attach/attach-server-pty.ts +64 -0
  193. package/src/attach/attach-server-runtime.js +73 -0
  194. package/src/attach/attach-server-runtime.ts +62 -0
  195. package/src/attach/attach-server-socket.js +28 -0
  196. package/src/attach/attach-server-socket.ts +23 -0
  197. package/src/attach/attach-server-types.js +2 -0
  198. package/src/attach/attach-server-types.ts +82 -0
  199. package/src/attach/attach-server.js +106 -523
  200. package/src/attach/attach-server.ts +158 -0
  201. package/src/attach/index.js +18 -35
  202. package/src/attach/index.ts +18 -0
  203. package/src/attach/protocol.js +95 -184
  204. package/src/attach/protocol.ts +181 -0
  205. package/src/attach/ring-buffer.js +76 -102
  206. package/src/attach/ring-buffer.ts +109 -0
  207. package/src/attach/send-input.js +64 -75
  208. package/src/attach/send-input.ts +94 -0
  209. package/src/attach/socket-discovery.js +164 -218
  210. package/src/attach/socket-discovery.ts +230 -0
  211. package/src/attach/socket-paths.js +42 -61
  212. package/src/attach/socket-paths.ts +81 -0
  213. package/src/claude-credentials.js +51 -54
  214. package/src/claude-credentials.ts +89 -0
  215. package/src/cluster/generated/protocol-schema.ts +1 -1
  216. package/src/cluster/generated/protocol.ts +2 -1
  217. package/src/command-proofs.js +110 -141
  218. package/src/command-proofs.ts +216 -0
  219. package/src/config-router.js +81 -73
  220. package/src/config-router.ts +131 -0
  221. package/src/copy-containment.js +191 -0
  222. package/src/copy-containment.ts +259 -0
  223. package/src/copy-worker.js +53 -30
  224. package/src/copy-worker.ts +88 -0
  225. package/src/darwin-keychain-boundary.js +80 -111
  226. package/src/darwin-keychain-boundary.ts +148 -0
  227. package/src/guidance-topics.js +4 -5
  228. package/src/guidance-topics.ts +10 -0
  229. package/src/input-helpers.js +33 -54
  230. package/src/input-helpers.ts +58 -0
  231. package/src/isolation-manager.js +59 -20
  232. package/src/ledger-sequence.js +45 -48
  233. package/src/ledger-sequence.ts +63 -0
  234. package/src/legacy-lib/clusters-registry.ts +40 -0
  235. package/src/legacy-lib/completion.ts +148 -0
  236. package/src/legacy-lib/compose-utils.ts +102 -0
  237. package/src/legacy-lib/detached-startup.ts +451 -0
  238. package/src/legacy-lib/docker-config.ts +282 -0
  239. package/src/legacy-lib/docker-env-auth.ts +116 -0
  240. package/src/legacy-lib/git-remote-utils.ts +244 -0
  241. package/src/legacy-lib/id-detector.ts +57 -0
  242. package/src/legacy-lib/js-yaml.d.ts +3 -0
  243. package/src/legacy-lib/omelette.d.ts +15 -0
  244. package/src/legacy-lib/path-check.ts +89 -0
  245. package/src/legacy-lib/process-liveness.ts +36 -0
  246. package/src/legacy-lib/provider-credential-path.ts +57 -0
  247. package/src/legacy-lib/provider-defaults.ts +114 -0
  248. package/src/legacy-lib/provider-detection.ts +67 -0
  249. package/src/legacy-lib/provider-names.ts +126 -0
  250. package/src/legacy-lib/repo-settings.ts +88 -0
  251. package/src/legacy-lib/run-mode.ts +58 -0
  252. package/src/legacy-lib/run-plan.ts +49 -0
  253. package/src/legacy-lib/settings/claude-auth.ts +80 -0
  254. package/src/legacy-lib/settings-defaults.ts +212 -0
  255. package/src/legacy-lib/settings-error.ts +8 -0
  256. package/src/legacy-lib/settings-issue-providers.ts +18 -0
  257. package/src/legacy-lib/settings-models.ts +124 -0
  258. package/src/legacy-lib/settings-storage.ts +277 -0
  259. package/src/legacy-lib/settings-validation.ts +220 -0
  260. package/src/legacy-lib/settings.ts +87 -0
  261. package/src/legacy-lib/setup-apply-types.ts +70 -0
  262. package/src/legacy-lib/setup-apply.ts +456 -0
  263. package/src/legacy-lib/setup-journal.ts +185 -0
  264. package/src/legacy-lib/setup-plan-types.ts +96 -0
  265. package/src/legacy-lib/setup-plan.ts +500 -0
  266. package/src/legacy-lib/setup-undo.ts +142 -0
  267. package/src/legacy-lib/start-cluster-config.ts +124 -0
  268. package/src/legacy-lib/start-cluster-environment.ts +166 -0
  269. package/src/legacy-lib/start-cluster-run-options.ts +281 -0
  270. package/src/legacy-lib/start-cluster.ts +237 -0
  271. package/src/legacy-lib/stream-json-parser.ts +88 -0
  272. package/src/message-buffer.js +55 -71
  273. package/src/message-buffer.ts +107 -0
  274. package/src/message-bus-bridge.js +92 -133
  275. package/src/message-bus-bridge.ts +149 -0
  276. package/src/name-generator-shared.js +220 -0
  277. package/src/name-generator-shared.ts +231 -0
  278. package/src/name-generator.js +8 -217
  279. package/src/name-generator.ts +27 -0
  280. package/src/omp-blob-root.js +83 -64
  281. package/src/omp-blob-root.ts +116 -0
  282. package/src/omp-config-overlay.js +65 -38
  283. package/src/omp-config-overlay.ts +110 -0
  284. package/src/omp-execution-fingerprint.js +38 -43
  285. package/src/omp-execution-fingerprint.ts +92 -0
  286. package/src/omp-session-limits.js +10 -15
  287. package/src/omp-session-limits.ts +53 -0
  288. package/src/omp-session-partition.js +2 -2
  289. package/src/omp-session-verifier.js +1 -1
  290. package/src/orchestrator.js +32 -7
  291. package/src/pr-body-template.js +71 -0
  292. package/src/providers/anthropic/index.js +3 -1
  293. package/src/providers/anthropic/index.ts +13 -0
  294. package/src/providers/capabilities.js +19 -27
  295. package/src/providers/capabilities.ts +44 -0
  296. package/src/providers/google/index.js +3 -1
  297. package/src/providers/google/index.ts +13 -0
  298. package/src/providers/openai/index.js +3 -1
  299. package/src/providers/openai/index.ts +13 -0
  300. package/src/providers/opencode/index.js +3 -1
  301. package/src/providers/opencode/index.ts +13 -0
  302. package/src/quality-gates.js +67 -127
  303. package/src/quality-gates.ts +149 -0
  304. package/src/repo-settings-access.js +40 -0
  305. package/src/repo-settings-access.ts +64 -0
  306. package/src/schemas/sub-cluster.js +127 -183
  307. package/src/schemas/sub-cluster.ts +238 -0
  308. package/src/state-snapshot-normalization.js +224 -0
  309. package/src/state-snapshot-normalization.ts +222 -0
  310. package/src/state-snapshot.js +192 -359
  311. package/src/state-snapshot.ts +291 -0
  312. package/src/state-snapshotter.js +118 -130
  313. package/src/state-snapshotter.ts +167 -0
  314. package/src/sub-cluster-wrapper.js +4 -13
  315. package/src/task-run-model-args.js +87 -124
  316. package/src/task-run-model-args.ts +204 -0
  317. package/src/task-runner.js +5 -25
  318. package/src/task-runner.ts +28 -0
  319. package/src/task-startup-error.js +73 -58
  320. package/src/task-startup-error.ts +126 -0
  321. package/src/template-validation/consensus-gate-contracts.js +2 -0
  322. package/src/template-validation/consensus-gate-contracts.ts +70 -0
  323. package/src/template-validation/consensus-gate-scenarios.js +76 -0
  324. package/src/template-validation/consensus-gate-scenarios.ts +130 -0
  325. package/src/template-validation/consensus-gate-stage.js +34 -0
  326. package/src/template-validation/consensus-gate-stage.ts +56 -0
  327. package/src/template-validation/random-topology-contracts.js +2 -0
  328. package/src/template-validation/random-topology-contracts.ts +54 -0
  329. package/src/template-validation/random-topology-dispatch.js +25 -0
  330. package/src/template-validation/random-topology-dispatch.ts +33 -0
  331. package/src/template-validation/random-topology-message-loop.js +53 -0
  332. package/src/template-validation/random-topology-message-loop.ts +73 -0
  333. package/src/template-validation/random-topology-operations.js +79 -0
  334. package/src/template-validation/random-topology-operations.ts +101 -0
  335. package/src/template-validation/random-topology-runtime.js +25 -0
  336. package/src/template-validation/random-topology-runtime.ts +43 -0
  337. package/src/template-validation/random-topology-scenario.js +52 -0
  338. package/src/template-validation/random-topology-scenario.ts +57 -0
  339. package/src/template-validation/random-topology-schema.js +159 -0
  340. package/src/template-validation/random-topology-schema.ts +190 -0
  341. package/src/template-validation/random-topology-state.js +28 -0
  342. package/src/template-validation/random-topology-state.ts +30 -0
  343. package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
  344. package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
  345. package/src/template-validation/random-topology-trigger.js +75 -0
  346. package/src/template-validation/random-topology-trigger.ts +88 -0
  347. package/src/template-validation/report-formatter.js +40 -46
  348. package/src/template-validation/report-formatter.ts +101 -0
  349. package/src/template-validation/simulate-consensus-gates.js +111 -302
  350. package/src/template-validation/simulate-consensus-gates.ts +196 -0
  351. package/src/template-validation/simulate-random-topology.js +26 -519
  352. package/src/template-validation/simulate-random-topology.ts +57 -0
  353. package/src/template-validation/simulate-two-stage-validation.js +41 -265
  354. package/src/template-validation/simulate-two-stage-validation.ts +55 -0
  355. package/src/template-validation/simulation-agent-runtime.js +25 -0
  356. package/src/template-validation/simulation-agent-runtime.ts +40 -0
  357. package/src/template-validation/simulation-agent.js +29 -0
  358. package/src/template-validation/simulation-agent.ts +73 -0
  359. package/src/template-validation/simulation-runtime.js +34 -0
  360. package/src/template-validation/simulation-runtime.ts +72 -0
  361. package/src/template-validation/two-stage-contracts.js +2 -0
  362. package/src/template-validation/two-stage-contracts.ts +41 -0
  363. package/src/template-validation/two-stage-inputs.js +21 -0
  364. package/src/template-validation/two-stage-inputs.ts +29 -0
  365. package/src/template-validation/two-stage-results.js +30 -0
  366. package/src/template-validation/two-stage-results.ts +40 -0
  367. package/src/template-validation/two-stage-scenario.js +86 -0
  368. package/src/template-validation/two-stage-scenario.ts +120 -0
  369. package/src/worktree-claude-config.js +182 -220
  370. package/src/worktree-claude-config.ts +272 -0
  371. package/src/worktree-tooling-env.js +103 -125
  372. package/src/worktree-tooling-env.ts +142 -0
  373. package/task-lib/completion.js +2 -3
  374. package/task-lib/completion.ts +9 -0
  375. package/task-lib/config.js +1 -4
  376. package/task-lib/config.ts +11 -0
  377. package/task-lib/name-generator.js +4 -226
  378. package/task-lib/name-generator.ts +11 -0
  379. package/task-lib/omp-session-cleanup.js +1 -1
  380. package/task-lib/omp-storage-root.js +8 -12
  381. package/task-lib/omp-storage-root.ts +62 -0
  382. package/task-lib/process-termination.js +143 -166
  383. package/task-lib/process-termination.ts +268 -0
@@ -0,0 +1,121 @@
1
+ import chalk = require('chalk');
2
+
3
+ interface MessagePrefixData {
4
+ sender: string;
5
+ cluster_id?: string | null;
6
+ sender_model?: string | null;
7
+ }
8
+
9
+ /**
10
+ * Get color for sender based on consistent hashing.
11
+ */
12
+ function getColorForSender(sender: string): chalk.Chalk {
13
+ const colors = [chalk.cyan, chalk.magenta, chalk.yellow, chalk.green, chalk.blue];
14
+ let hash = 0;
15
+ for (let i = 0; i < sender.length; i++) {
16
+ hash = (hash << 5) - hash + sender.charCodeAt(i);
17
+ hash = hash & hash;
18
+ }
19
+ return colors[Math.abs(hash) % colors.length] ?? chalk.cyan;
20
+ }
21
+
22
+ /**
23
+ * Build message prefix with timestamp, sender, and optional cluster ID.
24
+ */
25
+ function buildMessagePrefix(
26
+ msg: MessagePrefixData,
27
+ showClusterId: boolean,
28
+ isActive: boolean
29
+ ): string {
30
+ const color = isActive ? getColorForSender(msg.sender) : chalk.dim;
31
+
32
+ let senderLabel = msg.sender;
33
+ if (showClusterId && msg.cluster_id) {
34
+ senderLabel = `${msg.cluster_id}/${msg.sender}`;
35
+ }
36
+
37
+ const modelSuffix = msg.sender_model ? chalk.dim(` [${msg.sender_model}]`) : '';
38
+ return color(`${senderLabel.padEnd(showClusterId ? 25 : 15)} |`) + modelSuffix;
39
+ }
40
+
41
+ /**
42
+ * Build cluster prefix for watch mode.
43
+ */
44
+ function buildClusterPrefix(clusterId: string, isActive: boolean): string {
45
+ const color = isActive ? chalk.white : chalk.dim;
46
+ return color(`${clusterId.padEnd(20)} |`);
47
+ }
48
+
49
+ /**
50
+ * Parse and normalize data fields (handles string JSON).
51
+ */
52
+ function parseDataField(data: unknown): unknown {
53
+ if (typeof data === 'string') {
54
+ try {
55
+ const parsed: unknown = JSON.parse(data);
56
+ return parsed;
57
+ } catch {
58
+ return [];
59
+ }
60
+ }
61
+ return Array.isArray(data) ? data : [];
62
+ }
63
+
64
+ interface LifecycleEventData {
65
+ event?: string;
66
+ triggers?: readonly string[];
67
+ triggeredBy?: string | number;
68
+ iteration?: string | number;
69
+ model?: string;
70
+ }
71
+
72
+ interface ValidationCriterion {
73
+ status?: string;
74
+ }
75
+
76
+ function formatLifecycleEvent(data?: LifecycleEventData): { icon: string; eventText: string } {
77
+ const event = data?.event;
78
+ let icon: string;
79
+ let eventText: string;
80
+
81
+ switch (event) {
82
+ case 'STARTED': {
83
+ icon = chalk.green('▶');
84
+ const triggers = data?.triggers?.join(', ') || 'none';
85
+ eventText = `started (listening for: ${chalk.dim(triggers)})`;
86
+ break;
87
+ }
88
+ case 'TASK_STARTED':
89
+ icon = chalk.yellow('⚡');
90
+ eventText = `${chalk.cyan(data?.triggeredBy)} → task #${data?.iteration} (${chalk.dim(data?.model)})`;
91
+ break;
92
+ case 'TASK_COMPLETED':
93
+ icon = chalk.green('✓');
94
+ eventText = `task #${data?.iteration} completed`;
95
+ break;
96
+ default:
97
+ icon = chalk.dim('•');
98
+ eventText = event || 'unknown event';
99
+ }
100
+
101
+ return { icon, eventText };
102
+ }
103
+
104
+ function partitionValidationCriteria<T extends ValidationCriterion>(criteria: readonly T[]): {
105
+ cannotValidateYet: T[];
106
+ cannotValidate: T[];
107
+ } {
108
+ return {
109
+ cannotValidateYet: criteria.filter((criterion) => criterion.status === 'CANNOT_VALIDATE_YET'),
110
+ cannotValidate: criteria.filter((criterion) => criterion.status === 'CANNOT_VALIDATE'),
111
+ };
112
+ }
113
+
114
+ export = {
115
+ getColorForSender,
116
+ buildMessagePrefix,
117
+ buildClusterPrefix,
118
+ parseDataField,
119
+ formatLifecycleEvent,
120
+ partitionValidationCriteria,
121
+ };
@@ -1,283 +1,148 @@
1
- /**
2
- * Normal mode message formatters
3
- * Full-detail message display for non-watch mode
4
- *
5
- * All functions accept an optional `print` parameter for output routing.
6
- * When StatusFooter is active, pass safePrint to avoid terminal garbling.
7
- */
8
-
9
- const chalk = require('chalk');
10
- const { EVENT_COPY, formatMergeStatus } = require('./event-copy');
11
-
12
- /**
13
- * Format AGENT_LIFECYCLE events
14
- * @param {Object} msg - Message object
15
- * @param {string} prefix - Formatted message prefix
16
- * @param {Function} [print=console.log] - Print function for output
17
- * @returns {boolean} True if message was handled
18
- */
1
+ "use strict";
2
+ const chalk = require("chalk");
3
+ const eventCopy = require("./event-copy");
4
+ const formatterUtils = require("./message-formatter-utils");
5
+ const { EVENT_COPY, formatMergeStatus } = eventCopy;
6
+ const { formatLifecycleEvent, partitionValidationCriteria } = formatterUtils;
7
+ function isCriterionResults(value) {
8
+ return Array.isArray(value);
9
+ }
19
10
  function formatAgentLifecycle(msg, prefix, print = console.log) {
20
- const data = msg.content?.data;
21
- const event = data?.event;
22
-
23
- let icon, eventText;
24
- switch (event) {
25
- case 'STARTED':
26
- icon = chalk.green('▶');
27
- const triggers = data.triggers?.join(', ') || 'none';
28
- eventText = `started (listening for: ${chalk.dim(triggers)})`;
29
- break;
30
- case 'TASK_STARTED':
31
- icon = chalk.yellow('⚡');
32
- eventText = `${chalk.cyan(data.triggeredBy)} → task #${data.iteration} (${chalk.dim(data.model)})`;
33
- break;
34
- case 'TASK_COMPLETED':
35
- icon = chalk.green('✓');
36
- eventText = `task #${data.iteration} completed`;
37
- break;
38
- default:
39
- icon = chalk.dim('•');
40
- eventText = event || 'unknown event';
41
- }
42
-
43
- print(`${prefix} ${icon} ${eventText}`);
44
- return true;
11
+ const { icon, eventText } = formatLifecycleEvent(msg.content?.data);
12
+ print(`${prefix} ${icon} ${eventText}`);
13
+ return true;
45
14
  }
46
-
47
- /**
48
- * Format AGENT_ERROR events
49
- * @param {Object} msg - Message object
50
- * @param {string} prefix - Formatted message prefix
51
- * @param {string} timestamp - Formatted timestamp
52
- * @param {Function} [print=console.log] - Print function for output
53
- * @returns {boolean} True if message was handled
54
- */
55
15
  function formatAgentError(msg, prefix, timestamp, print = console.log) {
56
- print('');
57
- print(chalk.bold.red(`${'─'.repeat(60)}`));
58
- print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('Error: agent failed')}`);
59
-
60
- if (msg.content?.text) {
61
- print(`${prefix} ${chalk.red(msg.content.text)}`);
62
- }
63
-
64
- if (msg.content?.data?.stack) {
65
- const stackLines = msg.content.data.stack.split('\n').slice(0, 5);
66
- for (const line of stackLines) {
67
- if (line.trim()) print(`${prefix} ${chalk.dim(line)}`);
16
+ print('');
17
+ print(chalk.bold.red(`${'─'.repeat(60)}`));
18
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('Error: agent failed')}`);
19
+ if (msg.content?.text) {
20
+ print(`${prefix} ${chalk.red(msg.content.text)}`);
21
+ }
22
+ if (msg.content?.data?.stack) {
23
+ const stackLines = msg.content.data.stack.split('\n').slice(0, 5);
24
+ for (const line of stackLines) {
25
+ if (line.trim())
26
+ print(`${prefix} ${chalk.dim(line)}`);
27
+ }
68
28
  }
69
- }
70
-
71
- print(`${prefix} Next: inspect the agent logs and retry after fixing the cause.`);
72
- print(chalk.bold.red(`${'─'.repeat(60)}`));
73
- return true;
29
+ print(`${prefix} Next: inspect the agent logs and retry after fixing the cause.`);
30
+ print(chalk.bold.red(`${'─'.repeat(60)}`));
31
+ return true;
74
32
  }
75
-
76
- /**
77
- * Format ISSUE_OPENED events
78
- * @param {Object} msg - Message object
79
- * @param {string} prefix - Formatted message prefix
80
- * @param {string} timestamp - Formatted timestamp
81
- * @param {Set} shownNewTaskForCluster - Set tracking shown tasks
82
- * @param {Function} [print=console.log] - Print function for output
83
- * @returns {boolean} True if message was handled
84
- */
85
33
  function formatIssueOpened(msg, prefix, timestamp, shownNewTaskForCluster, print = console.log) {
86
- // Skip duplicate - conductor re-publishes after spawning agents
87
- if (shownNewTaskForCluster.has(msg.cluster_id)) {
88
- return true;
89
- }
90
- shownNewTaskForCluster.add(msg.cluster_id);
91
-
92
- print('');
93
- print(chalk.bold.blue(`${''.repeat(60)}`));
94
- print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.blue('📋 New task')}`);
95
-
96
- if (msg.content?.text) {
97
- const lines = msg.content.text.split('\n').slice(0, 3);
98
- for (const line of lines) {
99
- if (line.trim() && line.trim() !== '# Manual Input') {
100
- print(`${prefix} ${chalk.white(line)}`);
101
- }
34
+ // Skip duplicate - conductor re-publishes after spawning agents
35
+ if (!shownNewTaskForCluster.has(msg.cluster_id)) {
36
+ shownNewTaskForCluster.add(msg.cluster_id);
37
+ print('');
38
+ print(chalk.bold.blue(`${'─'.repeat(60)}`));
39
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.blue('📋 New task')}`);
40
+ if (msg.content?.text) {
41
+ const lines = msg.content.text.split('\n').slice(0, 3);
42
+ for (const line of lines) {
43
+ if (line.trim() && line.trim() !== '# Manual Input') {
44
+ print(`${prefix} ${chalk.white(line)}`);
45
+ }
46
+ }
47
+ }
48
+ print(chalk.bold.blue(`${'─'.repeat(60)}`));
102
49
  }
103
- }
104
-
105
- print(chalk.bold.blue(`${'─'.repeat(60)}`));
106
- return true;
50
+ return true;
107
51
  }
108
-
109
- /**
110
- * Format IMPLEMENTATION_READY events
111
- * @param {Object} msg - Message object
112
- * @param {string} prefix - Formatted message prefix
113
- * @param {string} timestamp - Formatted timestamp
114
- * @param {Function} [print=console.log] - Print function for output
115
- * @returns {boolean} True if message was handled
116
- */
117
52
  function formatImplementationReady(msg, prefix, timestamp, print = console.log) {
118
- print(
119
- `${prefix} ${chalk.gray(timestamp)} ${chalk.bold.yellow(`✅ ${EVENT_COPY.IMPLEMENTATION_READY.toUpperCase()}`)}`
120
- );
121
-
122
- if (msg.content?.data?.commit) {
123
- print(
124
- `${prefix} ${chalk.gray('Commit:')} ${chalk.cyan(msg.content.data.commit.substring(0, 8))}`
125
- );
126
- }
127
-
128
- return true;
53
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.yellow(`✅ ${EVENT_COPY.IMPLEMENTATION_READY.toUpperCase()}`)}`);
54
+ if (msg.content?.data?.commit) {
55
+ print(`${prefix} ${chalk.gray('Commit:')} ${chalk.cyan(msg.content.data.commit.substring(0, 8))}`);
56
+ }
57
+ return true;
129
58
  }
130
-
131
- /**
132
- * Format VALIDATION_RESULT events
133
- * @param {Object} msg - Message object
134
- * @param {string} prefix - Formatted message prefix
135
- * @param {string} timestamp - Formatted timestamp
136
- * @param {Function} [print=console.log] - Print function for output
137
- * @returns {boolean} True if message was handled
138
- */
139
59
  function formatValidationResult(msg, prefix, timestamp, print = console.log) {
140
- const data = msg.content?.data || {};
141
- const approved = data.approved === true || data.approved === 'true';
142
- const status = approved ? chalk.bold.green('✓ Approved') : chalk.bold.red('✗ Rejected');
143
-
144
- print(`${prefix} ${chalk.gray(timestamp)} ${status}`);
145
-
146
- // Show summary if present and not a template variable
147
- if (msg.content?.text && !msg.content.text.includes('{{')) {
148
- print(`${prefix} ${msg.content.text.substring(0, 100)}`);
149
- }
150
-
151
- // Show CANNOT_VALIDATE (permanent) as warnings, CANNOT_VALIDATE_YET (temporary) as errors
152
- const criteriaResults = data.criteriaResults;
153
- if (Array.isArray(criteriaResults)) {
154
- // CANNOT_VALIDATE_YET = temporary, treated as FAIL (work incomplete)
155
- const cannotValidateYet = criteriaResults.filter((c) => c.status === 'CANNOT_VALIDATE_YET');
156
- if (cannotValidateYet.length > 0) {
157
- print(
158
- `${prefix} ${chalk.red('❌ Cannot validate yet')} (${cannotValidateYet.length} criteria - work incomplete):`
159
- );
160
- for (const cv of cannotValidateYet) {
161
- print(`${prefix} ${chalk.red('•')} ${cv.id}: ${cv.reason || 'No reason provided'}`);
162
- }
60
+ const data = msg.content?.data || {};
61
+ const approved = data.approved === true || data.approved === 'true';
62
+ const status = approved ? chalk.bold.green('✓ Approved') : chalk.bold.red('✗ Rejected');
63
+ print(`${prefix} ${chalk.gray(timestamp)} ${status}`);
64
+ // Show summary if present and not a template variable
65
+ if (msg.content?.text && !msg.content.text.includes('{{')) {
66
+ print(`${prefix} ${msg.content.text.substring(0, 100)}`);
163
67
  }
164
-
165
- // CANNOT_VALIDATE = permanent, treated as PASS (environmental limitation)
166
- const cannotValidate = criteriaResults.filter((c) => c.status === 'CANNOT_VALIDATE');
167
- if (cannotValidate.length > 0) {
168
- print(
169
- `${prefix} ${chalk.yellow('⚠️ Could not validate')} (${cannotValidate.length} criteria - permanent):`
170
- );
171
- for (const cv of cannotValidate) {
172
- print(`${prefix} ${chalk.yellow('•')} ${cv.id}: ${cv.reason || 'No reason provided'}`);
173
- }
68
+ // Show CANNOT_VALIDATE (permanent) as warnings, CANNOT_VALIDATE_YET (temporary) as errors
69
+ const criteriaResults = data.criteriaResults;
70
+ if (isCriterionResults(criteriaResults)) {
71
+ const { cannotValidateYet, cannotValidate } = partitionValidationCriteria(criteriaResults);
72
+ if (cannotValidateYet.length > 0) {
73
+ print(`${prefix} ${chalk.red(' Cannot validate yet')} (${cannotValidateYet.length} criteria - work incomplete):`);
74
+ for (const criterion of cannotValidateYet) {
75
+ print(`${prefix} ${chalk.red('•')} ${criterion.id}: ${criterion.reason || 'No reason provided'}`);
76
+ }
77
+ }
78
+ if (cannotValidate.length > 0) {
79
+ print(`${prefix} ${chalk.yellow('⚠️ Could not validate')} (${cannotValidate.length} criteria - permanent):`);
80
+ for (const criterion of cannotValidate) {
81
+ print(`${prefix} ${chalk.yellow('•')} ${criterion.id}: ${criterion.reason || 'No reason provided'}`);
82
+ }
83
+ }
174
84
  }
175
- }
176
-
177
- // Show full JSON data structure
178
- print(`${prefix} ${chalk.dim(JSON.stringify(data, null, 2).split('\n').join(`\n${prefix} `))}`);
179
-
180
- return true;
85
+ // Show full JSON data structure
86
+ print(`${prefix} ${chalk.dim(JSON.stringify(data, null, 2).split('\n').join(`\n${prefix} `))}`);
87
+ return true;
181
88
  }
182
-
183
- /**
184
- * Format CLUSTER_COMPLETE events
185
- * @param {Object} msg - Message object
186
- * @param {string} prefix - Formatted message prefix
187
- * @param {string} timestamp - Formatted timestamp
188
- * @param {Function} [print=console.log] - Print function for output
189
- * @returns {boolean} True if message was handled
190
- */
191
89
  function formatClusterComplete(msg, prefix, timestamp, print = console.log) {
192
- print('');
193
- print(chalk.bold.green(`${'═'.repeat(60)}`));
194
- print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green('🎉 Cluster complete')}`);
195
- if (msg.content?.data?.reason) {
196
- print(`${prefix} ${chalk.green(msg.content.data.reason)}`);
197
- }
198
- print(chalk.bold.green(`${'═'.repeat(60)}`));
199
- return true;
90
+ print('');
91
+ print(chalk.bold.green(`${'═'.repeat(60)}`));
92
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green('🎉 Cluster complete')}`);
93
+ if (msg.content?.data?.reason) {
94
+ print(`${prefix} ${chalk.green(msg.content.data.reason)}`);
95
+ }
96
+ print(chalk.bold.green(`${'═'.repeat(60)}`));
97
+ return true;
200
98
  }
201
-
202
- /**
203
- * Format CLUSTER_FAILED events
204
- * @param {Object} msg - Message object
205
- * @param {string} prefix - Formatted message prefix
206
- * @param {string} timestamp - Formatted timestamp
207
- * @param {Function} [print=console.log] - Print function for output
208
- * @returns {boolean} True if message was handled
209
- */
210
99
  function formatClusterFailed(msg, prefix, timestamp, print = console.log) {
211
- print('');
212
- print(chalk.bold.red(`${'═'.repeat(60)}`));
213
- print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('Error: cluster failed')}`);
214
- if (msg.content?.text) print(`${prefix} ${chalk.red(msg.content.text)}`);
215
- if (msg.content?.data?.reason) print(`${prefix} ${chalk.red(msg.content.data.reason)}`);
216
- print(`${prefix} Next: inspect the cluster logs, then resume after fixing the cause.`);
217
- print(chalk.bold.red(`${'═'.repeat(60)}`));
218
- return true;
100
+ print('');
101
+ print(chalk.bold.red(`${'═'.repeat(60)}`));
102
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('Error: cluster failed')}`);
103
+ if (msg.content?.text)
104
+ print(`${prefix} ${chalk.red(msg.content.text)}`);
105
+ if (msg.content?.data?.reason)
106
+ print(`${prefix} ${chalk.red(msg.content.data.reason)}`);
107
+ print(`${prefix} Next: inspect the cluster logs, then resume after fixing the cause.`);
108
+ print(chalk.bold.red(`${'═'.repeat(60)}`));
109
+ return true;
219
110
  }
220
-
221
- /**
222
- * Format PR_CREATED events
223
- * @param {Object} msg - Message object
224
- * @param {string} prefix - Formatted message prefix
225
- * @param {string} timestamp - Formatted timestamp
226
- * @param {Function} [print=console.log] - Print function for output
227
- * @returns {boolean} True if message was handled
228
- */
229
111
  function formatPrCreated(msg, prefix, timestamp, print = console.log) {
230
- const prNumber = msg.content?.data?.pr_number || '';
231
- const prUrl = msg.content?.data?.pr_url || '';
232
-
233
- print(''); // Blank line before PR notification
234
- print(chalk.bold.green(`${'─'.repeat(60)}`));
235
- print(
236
- `${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green(`🎉 ${EVENT_COPY.PR_CREATED.toUpperCase()}`)}`
237
- );
238
-
239
- if (prNumber) {
240
- print(`${prefix} ${chalk.gray('PR:')} ${chalk.cyan(`#${prNumber}`)}`);
241
- }
242
- if (prUrl) {
243
- print(`${prefix} ${chalk.gray('URL:')} ${chalk.blue(prUrl)}`);
244
- }
245
-
246
- const mergeStatus = formatMergeStatus(msg.content?.data?.merged);
247
- if (mergeStatus) {
248
- print(
249
- `${prefix} ${chalk.gray('Merge:')} ${mergeStatus === 'merged' ? chalk.green(mergeStatus) : chalk.yellow(mergeStatus)}`
250
- );
251
- }
252
-
253
- print(chalk.bold.green(`${'─'.repeat(60)}`));
254
- return true;
112
+ const prNumber = msg.content?.data?.pr_number || '';
113
+ const prUrl = msg.content?.data?.pr_url || '';
114
+ print(''); // Blank line before PR notification
115
+ print(chalk.bold.green(`${''.repeat(60)}`));
116
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green(`🎉 ${EVENT_COPY.PR_CREATED.toUpperCase()}`)}`);
117
+ if (prNumber) {
118
+ print(`${prefix} ${chalk.gray('PR:')} ${chalk.cyan(`#${prNumber}`)}`);
119
+ }
120
+ if (prUrl) {
121
+ print(`${prefix} ${chalk.gray('URL:')} ${chalk.blue(prUrl)}`);
122
+ }
123
+ const mergeStatus = formatMergeStatus(msg.content?.data?.merged);
124
+ if (mergeStatus) {
125
+ const formattedMergeStatus = mergeStatus === 'merged' ? chalk.green(mergeStatus) : chalk.yellow(mergeStatus);
126
+ print(`${prefix} ${chalk.gray('Merge:')} ${formattedMergeStatus}`);
127
+ }
128
+ print(chalk.bold.green(`${'─'.repeat(60)}`));
129
+ return true;
255
130
  }
256
-
257
- /**
258
- * Format generic messages (fallback)
259
- * @param {Object} msg - Message object
260
- * @param {string} prefix - Formatted message prefix
261
- * @param {string} timestamp - Formatted timestamp
262
- * @param {Function} [print=console.log] - Print function for output
263
- * @returns {boolean} True if message was handled
264
- */
265
131
  function formatGenericMessage(msg, prefix, timestamp, print = console.log) {
266
- print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold(msg.topic)}`);
267
- if (msg.content?.text) {
268
- print(`${prefix} ${msg.content.text}`);
269
- }
270
- return true;
132
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold(msg.topic)}`);
133
+ if (msg.content?.text) {
134
+ print(`${prefix} ${msg.content.text}`);
135
+ }
136
+ return true;
271
137
  }
272
-
273
138
  module.exports = {
274
- formatAgentLifecycle,
275
- formatAgentError,
276
- formatIssueOpened,
277
- formatImplementationReady,
278
- formatValidationResult,
279
- formatPrCreated,
280
- formatClusterComplete,
281
- formatClusterFailed,
282
- formatGenericMessage,
139
+ formatAgentLifecycle,
140
+ formatAgentError,
141
+ formatIssueOpened,
142
+ formatImplementationReady,
143
+ formatValidationResult,
144
+ formatPrCreated,
145
+ formatClusterComplete,
146
+ formatClusterFailed,
147
+ formatGenericMessage,
283
148
  };