@the-open-engine/zeroshot 5.4.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 (295) hide show
  1. package/CHANGELOG.md +539 -0
  2. package/LICENSE +21 -0
  3. package/README.md +508 -0
  4. package/cli/commands/inspect-render.js +135 -0
  5. package/cli/commands/inspect.js +294 -0
  6. package/cli/commands/providers.js +149 -0
  7. package/cli/index.js +5431 -0
  8. package/cli/lib/first-run.js +211 -0
  9. package/cli/lib/update-checker.js +281 -0
  10. package/cli/message-formatter-utils.js +75 -0
  11. package/cli/message-formatters-normal.js +275 -0
  12. package/cli/message-formatters-watch.js +185 -0
  13. package/cluster-templates/base-templates/debug-workflow.json +422 -0
  14. package/cluster-templates/base-templates/full-workflow.json +727 -0
  15. package/cluster-templates/base-templates/heavy-validation.json +272 -0
  16. package/cluster-templates/base-templates/quick-validation.json +285 -0
  17. package/cluster-templates/base-templates/single-worker.json +71 -0
  18. package/cluster-templates/base-templates/worker-validator.json +230 -0
  19. package/cluster-templates/conductor-bootstrap.json +130 -0
  20. package/docker/zeroshot-cluster/Dockerfile +153 -0
  21. package/docker/zeroshot-cluster/pre-baked-deps.json +28 -0
  22. package/lib/agent-cli-provider/adapters/claude-parser.d.ts +3 -0
  23. package/lib/agent-cli-provider/adapters/claude-parser.d.ts.map +1 -0
  24. package/lib/agent-cli-provider/adapters/claude-parser.js +122 -0
  25. package/lib/agent-cli-provider/adapters/claude-parser.js.map +1 -0
  26. package/lib/agent-cli-provider/adapters/claude-recovery.d.ts +15 -0
  27. package/lib/agent-cli-provider/adapters/claude-recovery.d.ts.map +1 -0
  28. package/lib/agent-cli-provider/adapters/claude-recovery.js +165 -0
  29. package/lib/agent-cli-provider/adapters/claude-recovery.js.map +1 -0
  30. package/lib/agent-cli-provider/adapters/claude.d.ts +3 -0
  31. package/lib/agent-cli-provider/adapters/claude.d.ts.map +1 -0
  32. package/lib/agent-cli-provider/adapters/claude.js +181 -0
  33. package/lib/agent-cli-provider/adapters/claude.js.map +1 -0
  34. package/lib/agent-cli-provider/adapters/codex-parser.d.ts +3 -0
  35. package/lib/agent-cli-provider/adapters/codex-parser.d.ts.map +1 -0
  36. package/lib/agent-cli-provider/adapters/codex-parser.js +192 -0
  37. package/lib/agent-cli-provider/adapters/codex-parser.js.map +1 -0
  38. package/lib/agent-cli-provider/adapters/codex.d.ts +3 -0
  39. package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -0
  40. package/lib/agent-cli-provider/adapters/codex.js +151 -0
  41. package/lib/agent-cli-provider/adapters/codex.js.map +1 -0
  42. package/lib/agent-cli-provider/adapters/common.d.ts +28 -0
  43. package/lib/agent-cli-provider/adapters/common.d.ts.map +1 -0
  44. package/lib/agent-cli-provider/adapters/common.js +71 -0
  45. package/lib/agent-cli-provider/adapters/common.js.map +1 -0
  46. package/lib/agent-cli-provider/adapters/gemini.d.ts +3 -0
  47. package/lib/agent-cli-provider/adapters/gemini.d.ts.map +1 -0
  48. package/lib/agent-cli-provider/adapters/gemini.js +176 -0
  49. package/lib/agent-cli-provider/adapters/gemini.js.map +1 -0
  50. package/lib/agent-cli-provider/adapters/index.d.ts +9 -0
  51. package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -0
  52. package/lib/agent-cli-provider/adapters/index.js +95 -0
  53. package/lib/agent-cli-provider/adapters/index.js.map +1 -0
  54. package/lib/agent-cli-provider/adapters/opencode.d.ts +3 -0
  55. package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -0
  56. package/lib/agent-cli-provider/adapters/opencode.js +228 -0
  57. package/lib/agent-cli-provider/adapters/opencode.js.map +1 -0
  58. package/lib/agent-cli-provider/contract-actions.d.ts +5 -0
  59. package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -0
  60. package/lib/agent-cli-provider/contract-actions.js +140 -0
  61. package/lib/agent-cli-provider/contract-actions.js.map +1 -0
  62. package/lib/agent-cli-provider/contract-env.d.ts +11 -0
  63. package/lib/agent-cli-provider/contract-env.d.ts.map +1 -0
  64. package/lib/agent-cli-provider/contract-env.js +113 -0
  65. package/lib/agent-cli-provider/contract-env.js.map +1 -0
  66. package/lib/agent-cli-provider/contract-envelope.d.ts +49 -0
  67. package/lib/agent-cli-provider/contract-envelope.d.ts.map +1 -0
  68. package/lib/agent-cli-provider/contract-envelope.js +52 -0
  69. package/lib/agent-cli-provider/contract-envelope.js.map +1 -0
  70. package/lib/agent-cli-provider/contract-errors.d.ts +22 -0
  71. package/lib/agent-cli-provider/contract-errors.d.ts.map +1 -0
  72. package/lib/agent-cli-provider/contract-errors.js +71 -0
  73. package/lib/agent-cli-provider/contract-errors.js.map +1 -0
  74. package/lib/agent-cli-provider/contract-fallback.d.ts +7 -0
  75. package/lib/agent-cli-provider/contract-fallback.d.ts.map +1 -0
  76. package/lib/agent-cli-provider/contract-fallback.js +102 -0
  77. package/lib/agent-cli-provider/contract-fallback.js.map +1 -0
  78. package/lib/agent-cli-provider/contract-invoke.d.ts +5 -0
  79. package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -0
  80. package/lib/agent-cli-provider/contract-invoke.js +89 -0
  81. package/lib/agent-cli-provider/contract-invoke.js.map +1 -0
  82. package/lib/agent-cli-provider/contract-options.d.ts +3 -0
  83. package/lib/agent-cli-provider/contract-options.d.ts.map +1 -0
  84. package/lib/agent-cli-provider/contract-options.js +140 -0
  85. package/lib/agent-cli-provider/contract-options.js.map +1 -0
  86. package/lib/agent-cli-provider/contract-parse.d.ts +15 -0
  87. package/lib/agent-cli-provider/contract-parse.d.ts.map +1 -0
  88. package/lib/agent-cli-provider/contract-parse.js +81 -0
  89. package/lib/agent-cli-provider/contract-parse.js.map +1 -0
  90. package/lib/agent-cli-provider/contract-support.d.ts +18 -0
  91. package/lib/agent-cli-provider/contract-support.d.ts.map +1 -0
  92. package/lib/agent-cli-provider/contract-support.js +154 -0
  93. package/lib/agent-cli-provider/contract-support.js.map +1 -0
  94. package/lib/agent-cli-provider/contract.d.ts +13 -0
  95. package/lib/agent-cli-provider/contract.d.ts.map +1 -0
  96. package/lib/agent-cli-provider/contract.js +30 -0
  97. package/lib/agent-cli-provider/contract.js.map +1 -0
  98. package/lib/agent-cli-provider/env-safety.d.ts +11 -0
  99. package/lib/agent-cli-provider/env-safety.d.ts.map +1 -0
  100. package/lib/agent-cli-provider/env-safety.js +83 -0
  101. package/lib/agent-cli-provider/env-safety.js.map +1 -0
  102. package/lib/agent-cli-provider/errors.d.ts +5 -0
  103. package/lib/agent-cli-provider/errors.d.ts.map +1 -0
  104. package/lib/agent-cli-provider/errors.js +115 -0
  105. package/lib/agent-cli-provider/errors.js.map +1 -0
  106. package/lib/agent-cli-provider/executable.d.ts +3 -0
  107. package/lib/agent-cli-provider/executable.d.ts.map +1 -0
  108. package/lib/agent-cli-provider/executable.js +24 -0
  109. package/lib/agent-cli-provider/executable.js.map +1 -0
  110. package/lib/agent-cli-provider/index.d.ts +8 -0
  111. package/lib/agent-cli-provider/index.d.ts.map +1 -0
  112. package/lib/agent-cli-provider/index.js +31 -0
  113. package/lib/agent-cli-provider/index.js.map +1 -0
  114. package/lib/agent-cli-provider/invoke-evidence.d.ts +4 -0
  115. package/lib/agent-cli-provider/invoke-evidence.d.ts.map +1 -0
  116. package/lib/agent-cli-provider/invoke-evidence.js +17 -0
  117. package/lib/agent-cli-provider/invoke-evidence.js.map +1 -0
  118. package/lib/agent-cli-provider/json.d.ts +16 -0
  119. package/lib/agent-cli-provider/json.d.ts.map +1 -0
  120. package/lib/agent-cli-provider/json.js +110 -0
  121. package/lib/agent-cli-provider/json.js.map +1 -0
  122. package/lib/agent-cli-provider/log-prefix.d.ts +2 -0
  123. package/lib/agent-cli-provider/log-prefix.d.ts.map +1 -0
  124. package/lib/agent-cli-provider/log-prefix.js +22 -0
  125. package/lib/agent-cli-provider/log-prefix.js.map +1 -0
  126. package/lib/agent-cli-provider/process-runner.d.ts +17 -0
  127. package/lib/agent-cli-provider/process-runner.d.ts.map +1 -0
  128. package/lib/agent-cli-provider/process-runner.js +89 -0
  129. package/lib/agent-cli-provider/process-runner.js.map +1 -0
  130. package/lib/agent-cli-provider/redaction.d.ts +9 -0
  131. package/lib/agent-cli-provider/redaction.d.ts.map +1 -0
  132. package/lib/agent-cli-provider/redaction.js +227 -0
  133. package/lib/agent-cli-provider/redaction.js.map +1 -0
  134. package/lib/agent-cli-provider/schema.d.ts +5 -0
  135. package/lib/agent-cli-provider/schema.d.ts.map +1 -0
  136. package/lib/agent-cli-provider/schema.js +136 -0
  137. package/lib/agent-cli-provider/schema.js.map +1 -0
  138. package/lib/agent-cli-provider/single-agent-runtime.d.ts +15 -0
  139. package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -0
  140. package/lib/agent-cli-provider/single-agent-runtime.js +228 -0
  141. package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -0
  142. package/lib/agent-cli-provider/types.d.ts +194 -0
  143. package/lib/agent-cli-provider/types.d.ts.map +1 -0
  144. package/lib/agent-cli-provider/types.js +12 -0
  145. package/lib/agent-cli-provider/types.js.map +1 -0
  146. package/lib/completion.js +174 -0
  147. package/lib/detached-startup.js +220 -0
  148. package/lib/docker-config.js +220 -0
  149. package/lib/git-remote-utils.js +165 -0
  150. package/lib/id-detector.js +55 -0
  151. package/lib/provider-defaults.js +62 -0
  152. package/lib/provider-detection.js +59 -0
  153. package/lib/provider-names.js +57 -0
  154. package/lib/repo-settings.js +69 -0
  155. package/lib/settings/claude-auth.js +78 -0
  156. package/lib/settings.js +542 -0
  157. package/lib/start-cluster.js +321 -0
  158. package/lib/stream-json-parser.js +67 -0
  159. package/package.json +162 -0
  160. package/scripts/fix-node-pty-permissions.js +75 -0
  161. package/scripts/record-demo.sh +279 -0
  162. package/scripts/setup-merge-queue.sh +170 -0
  163. package/scripts/test-install.sh +40 -0
  164. package/scripts/validate-templates.js +107 -0
  165. package/src/agent/agent-config.js +266 -0
  166. package/src/agent/agent-context-builder.js +189 -0
  167. package/src/agent/agent-context-sections.js +338 -0
  168. package/src/agent/agent-context-sources.js +147 -0
  169. package/src/agent/agent-hook-executor.js +721 -0
  170. package/src/agent/agent-input-injector.js +141 -0
  171. package/src/agent/agent-lifecycle.js +982 -0
  172. package/src/agent/agent-quality-gate-schema.js +93 -0
  173. package/src/agent/agent-quality-gates-context.js +51 -0
  174. package/src/agent/agent-stuck-detector.js +256 -0
  175. package/src/agent/agent-task-executor.js +2028 -0
  176. package/src/agent/agent-trigger-evaluator.js +67 -0
  177. package/src/agent/context-metrics.js +160 -0
  178. package/src/agent/context-pack-builder.js +367 -0
  179. package/src/agent/context-replay-policy.js +51 -0
  180. package/src/agent/guidance-queue.js +77 -0
  181. package/src/agent/output-extraction.js +367 -0
  182. package/src/agent/output-reformatter.js +175 -0
  183. package/src/agent/pr-verification.js +653 -0
  184. package/src/agent/rate-limit-backoff.js +82 -0
  185. package/src/agent/schema-utils.js +146 -0
  186. package/src/agent/validation-platform.js +35 -0
  187. package/src/agent-cli-provider/adapters/claude-parser.ts +133 -0
  188. package/src/agent-cli-provider/adapters/claude-recovery.ts +203 -0
  189. package/src/agent-cli-provider/adapters/claude.ts +247 -0
  190. package/src/agent-cli-provider/adapters/codex-parser.ts +211 -0
  191. package/src/agent-cli-provider/adapters/codex.ts +217 -0
  192. package/src/agent-cli-provider/adapters/common.ts +124 -0
  193. package/src/agent-cli-provider/adapters/gemini.ts +243 -0
  194. package/src/agent-cli-provider/adapters/index.ts +126 -0
  195. package/src/agent-cli-provider/adapters/opencode.ts +286 -0
  196. package/src/agent-cli-provider/contract-actions.ts +150 -0
  197. package/src/agent-cli-provider/contract-env.ts +111 -0
  198. package/src/agent-cli-provider/contract-envelope.ts +110 -0
  199. package/src/agent-cli-provider/contract-errors.ts +66 -0
  200. package/src/agent-cli-provider/contract-fallback.ts +121 -0
  201. package/src/agent-cli-provider/contract-invoke.ts +104 -0
  202. package/src/agent-cli-provider/contract-options.ts +173 -0
  203. package/src/agent-cli-provider/contract-parse.ts +94 -0
  204. package/src/agent-cli-provider/contract-support.ts +167 -0
  205. package/src/agent-cli-provider/contract.ts +56 -0
  206. package/src/agent-cli-provider/env-safety.ts +82 -0
  207. package/src/agent-cli-provider/errors.ts +122 -0
  208. package/src/agent-cli-provider/executable.ts +24 -0
  209. package/src/agent-cli-provider/index.ts +83 -0
  210. package/src/agent-cli-provider/invoke-evidence.ts +18 -0
  211. package/src/agent-cli-provider/json.ts +114 -0
  212. package/src/agent-cli-provider/log-prefix.ts +20 -0
  213. package/src/agent-cli-provider/process-runner.ts +145 -0
  214. package/src/agent-cli-provider/redaction.ts +282 -0
  215. package/src/agent-cli-provider/schema.ts +115 -0
  216. package/src/agent-cli-provider/single-agent-runtime.ts +311 -0
  217. package/src/agent-cli-provider/types.ts +237 -0
  218. package/src/agent-wrapper.js +615 -0
  219. package/src/agents/git-pusher-template.js +705 -0
  220. package/src/attach/attach-client.js +438 -0
  221. package/src/attach/attach-server.js +543 -0
  222. package/src/attach/index.js +37 -0
  223. package/src/attach/protocol.js +220 -0
  224. package/src/attach/ring-buffer.js +121 -0
  225. package/src/attach/send-input.js +88 -0
  226. package/src/attach/socket-discovery.js +267 -0
  227. package/src/claude-task-runner.js +661 -0
  228. package/src/config-router.js +89 -0
  229. package/src/config-validator.js +2202 -0
  230. package/src/copy-worker.js +43 -0
  231. package/src/guidance-topics.js +10 -0
  232. package/src/input-helpers.js +65 -0
  233. package/src/isolation-manager.js +1734 -0
  234. package/src/issue-providers/README.md +305 -0
  235. package/src/issue-providers/azure-devops-provider.js +307 -0
  236. package/src/issue-providers/base-provider.js +232 -0
  237. package/src/issue-providers/github-provider.js +210 -0
  238. package/src/issue-providers/gitlab-provider.js +262 -0
  239. package/src/issue-providers/index.js +196 -0
  240. package/src/issue-providers/jira-provider.js +260 -0
  241. package/src/ledger.js +692 -0
  242. package/src/lib/gc.js +232 -0
  243. package/src/lib/safe-exec.js +88 -0
  244. package/src/logic-engine.js +201 -0
  245. package/src/message-buffer.js +81 -0
  246. package/src/message-bus-bridge.js +144 -0
  247. package/src/message-bus.js +256 -0
  248. package/src/name-generator.js +232 -0
  249. package/src/orchestrator.js +3924 -0
  250. package/src/preflight.js +712 -0
  251. package/src/process-metrics.js +608 -0
  252. package/src/providers/anthropic/index.js +3 -0
  253. package/src/providers/base-provider.js +355 -0
  254. package/src/providers/capabilities.js +60 -0
  255. package/src/providers/google/index.js +3 -0
  256. package/src/providers/index.js +293 -0
  257. package/src/providers/openai/index.js +3 -0
  258. package/src/providers/opencode/index.js +3 -0
  259. package/src/quality-gates.js +143 -0
  260. package/src/schemas/sub-cluster.js +208 -0
  261. package/src/state-snapshot.js +398 -0
  262. package/src/state-snapshotter.js +142 -0
  263. package/src/status-footer.js +1026 -0
  264. package/src/sub-cluster-wrapper.js +693 -0
  265. package/src/task-runner.js +30 -0
  266. package/src/template-resolver.js +425 -0
  267. package/src/template-validation/index.js +338 -0
  268. package/src/template-validation/simulate-consensus-gates.js +324 -0
  269. package/src/template-validation/simulate-random-topology.js +541 -0
  270. package/src/template-validation/simulate-two-stage-validation.js +270 -0
  271. package/src/worktree-claude-config.js +135 -0
  272. package/src/worktree-tooling-env.js +150 -0
  273. package/task-lib/attachable-watcher.js +381 -0
  274. package/task-lib/commands/clean.js +50 -0
  275. package/task-lib/commands/episodes.js +105 -0
  276. package/task-lib/commands/get-log-path.js +23 -0
  277. package/task-lib/commands/kill.js +32 -0
  278. package/task-lib/commands/list.js +105 -0
  279. package/task-lib/commands/logs.js +439 -0
  280. package/task-lib/commands/resume.js +42 -0
  281. package/task-lib/commands/run.js +57 -0
  282. package/task-lib/commands/schedule.js +105 -0
  283. package/task-lib/commands/scheduler-cmd.js +96 -0
  284. package/task-lib/commands/schedules.js +148 -0
  285. package/task-lib/commands/status.js +44 -0
  286. package/task-lib/commands/unschedule.js +16 -0
  287. package/task-lib/completion.js +9 -0
  288. package/task-lib/config.js +11 -0
  289. package/task-lib/name-generator.js +230 -0
  290. package/task-lib/package.json +3 -0
  291. package/task-lib/provider-helper-runtime.js +29 -0
  292. package/task-lib/runner.js +190 -0
  293. package/task-lib/scheduler.js +252 -0
  294. package/task-lib/store.js +529 -0
  295. package/task-lib/watcher.js +305 -0
@@ -0,0 +1,275 @@
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
+
11
+ /**
12
+ * Format AGENT_LIFECYCLE events
13
+ * @param {Object} msg - Message object
14
+ * @param {string} prefix - Formatted message prefix
15
+ * @param {Function} [print=console.log] - Print function for output
16
+ * @returns {boolean} True if message was handled
17
+ */
18
+ function formatAgentLifecycle(msg, prefix, print = console.log) {
19
+ const data = msg.content?.data;
20
+ const event = data?.event;
21
+
22
+ let icon, eventText;
23
+ switch (event) {
24
+ case 'STARTED':
25
+ icon = chalk.green('▶');
26
+ const triggers = data.triggers?.join(', ') || 'none';
27
+ eventText = `started (listening for: ${chalk.dim(triggers)})`;
28
+ break;
29
+ case 'TASK_STARTED':
30
+ icon = chalk.yellow('⚡');
31
+ eventText = `${chalk.cyan(data.triggeredBy)} → task #${data.iteration} (${chalk.dim(data.model)})`;
32
+ break;
33
+ case 'TASK_COMPLETED':
34
+ icon = chalk.green('✓');
35
+ eventText = `task #${data.iteration} completed`;
36
+ break;
37
+ default:
38
+ icon = chalk.dim('•');
39
+ eventText = event || 'unknown event';
40
+ }
41
+
42
+ print(`${prefix} ${icon} ${eventText}`);
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Format AGENT_ERROR events
48
+ * @param {Object} msg - Message object
49
+ * @param {string} prefix - Formatted message prefix
50
+ * @param {string} timestamp - Formatted timestamp
51
+ * @param {Function} [print=console.log] - Print function for output
52
+ * @returns {boolean} True if message was handled
53
+ */
54
+ function formatAgentError(msg, prefix, timestamp, print = console.log) {
55
+ print(''); // Blank line before error
56
+ print(chalk.bold.red(`${'─'.repeat(60)}`));
57
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('🔴 AGENT ERROR')}`);
58
+
59
+ if (msg.content?.text) {
60
+ print(`${prefix} ${chalk.red(msg.content.text)}`);
61
+ }
62
+
63
+ if (msg.content?.data?.stack) {
64
+ const stackLines = msg.content.data.stack.split('\n').slice(0, 5);
65
+ for (const line of stackLines) {
66
+ if (line.trim()) {
67
+ print(`${prefix} ${chalk.dim(line)}`);
68
+ }
69
+ }
70
+ }
71
+
72
+ print(chalk.bold.red(`${'─'.repeat(60)}`));
73
+ return true;
74
+ }
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
+ 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(''); // Blank line before new task
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
+ }
102
+ }
103
+ }
104
+
105
+ print(chalk.bold.blue(`${'─'.repeat(60)}`));
106
+ return true;
107
+ }
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
+ function formatImplementationReady(msg, prefix, timestamp, print = console.log) {
118
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.yellow('✅ IMPLEMENTATION READY')}`);
119
+
120
+ if (msg.content?.data?.commit) {
121
+ print(
122
+ `${prefix} ${chalk.gray('Commit:')} ${chalk.cyan(msg.content.data.commit.substring(0, 8))}`
123
+ );
124
+ }
125
+
126
+ return true;
127
+ }
128
+
129
+ /**
130
+ * Format VALIDATION_RESULT events
131
+ * @param {Object} msg - Message object
132
+ * @param {string} prefix - Formatted message prefix
133
+ * @param {string} timestamp - Formatted timestamp
134
+ * @param {Function} [print=console.log] - Print function for output
135
+ * @returns {boolean} True if message was handled
136
+ */
137
+ function formatValidationResult(msg, prefix, timestamp, print = console.log) {
138
+ const data = msg.content?.data || {};
139
+ const approved = data.approved === true || data.approved === 'true';
140
+ const status = approved ? chalk.bold.green('✓ APPROVED') : chalk.bold.red('✗ REJECTED');
141
+
142
+ print(`${prefix} ${chalk.gray(timestamp)} ${status}`);
143
+
144
+ // Show summary if present and not a template variable
145
+ if (msg.content?.text && !msg.content.text.includes('{{')) {
146
+ print(`${prefix} ${msg.content.text.substring(0, 100)}`);
147
+ }
148
+
149
+ // Show CANNOT_VALIDATE (permanent) as warnings, CANNOT_VALIDATE_YET (temporary) as errors
150
+ const criteriaResults = data.criteriaResults;
151
+ if (Array.isArray(criteriaResults)) {
152
+ // CANNOT_VALIDATE_YET = temporary, treated as FAIL (work incomplete)
153
+ const cannotValidateYet = criteriaResults.filter((c) => c.status === 'CANNOT_VALIDATE_YET');
154
+ if (cannotValidateYet.length > 0) {
155
+ print(
156
+ `${prefix} ${chalk.red('❌ Cannot validate yet')} (${cannotValidateYet.length} criteria - work incomplete):`
157
+ );
158
+ for (const cv of cannotValidateYet) {
159
+ print(`${prefix} ${chalk.red('•')} ${cv.id}: ${cv.reason || 'No reason provided'}`);
160
+ }
161
+ }
162
+
163
+ // CANNOT_VALIDATE = permanent, treated as PASS (environmental limitation)
164
+ const cannotValidate = criteriaResults.filter((c) => c.status === 'CANNOT_VALIDATE');
165
+ if (cannotValidate.length > 0) {
166
+ print(
167
+ `${prefix} ${chalk.yellow('⚠️ Could not validate')} (${cannotValidate.length} criteria - permanent):`
168
+ );
169
+ for (const cv of cannotValidate) {
170
+ print(`${prefix} ${chalk.yellow('•')} ${cv.id}: ${cv.reason || 'No reason provided'}`);
171
+ }
172
+ }
173
+ }
174
+
175
+ // Show full JSON data structure
176
+ print(`${prefix} ${chalk.dim(JSON.stringify(data, null, 2).split('\n').join(`\n${prefix} `))}`);
177
+
178
+ return true;
179
+ }
180
+
181
+ /**
182
+ * Format CLUSTER_COMPLETE events
183
+ * @param {Object} msg - Message object
184
+ * @param {string} prefix - Formatted message prefix
185
+ * @param {string} timestamp - Formatted timestamp
186
+ * @param {Function} [print=console.log] - Print function for output
187
+ * @returns {boolean} True if message was handled
188
+ */
189
+ function formatClusterComplete(msg, prefix, timestamp, print = console.log) {
190
+ print(''); // Blank line
191
+ print(chalk.bold.green(`${'═'.repeat(60)}`));
192
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green('🎉 CLUSTER COMPLETE')}`);
193
+ if (msg.content?.data?.reason) {
194
+ print(`${prefix} ${chalk.green(msg.content.data.reason)}`);
195
+ }
196
+ print(chalk.bold.green(`${'═'.repeat(60)}`));
197
+ return true;
198
+ }
199
+
200
+ /**
201
+ * Format CLUSTER_FAILED events
202
+ * @param {Object} msg - Message object
203
+ * @param {string} prefix - Formatted message prefix
204
+ * @param {string} timestamp - Formatted timestamp
205
+ * @param {Function} [print=console.log] - Print function for output
206
+ * @returns {boolean} True if message was handled
207
+ */
208
+ function formatClusterFailed(msg, prefix, timestamp, print = console.log) {
209
+ print(''); // Blank line
210
+ print(chalk.bold.red(`${'═'.repeat(60)}`));
211
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.red('❌ CLUSTER FAILED')}`);
212
+ if (msg.content?.text) {
213
+ print(`${prefix} ${chalk.red(msg.content.text)}`);
214
+ }
215
+ if (msg.content?.data?.reason) {
216
+ print(`${prefix} ${chalk.red(msg.content.data.reason)}`);
217
+ }
218
+ print(chalk.bold.red(`${'═'.repeat(60)}`));
219
+ return true;
220
+ }
221
+
222
+ /**
223
+ * Format PR_CREATED events
224
+ * @param {Object} msg - Message object
225
+ * @param {string} prefix - Formatted message prefix
226
+ * @param {string} timestamp - Formatted timestamp
227
+ * @param {Function} [print=console.log] - Print function for output
228
+ * @returns {boolean} True if message was handled
229
+ */
230
+ function formatPrCreated(msg, prefix, timestamp, print = console.log) {
231
+ const prNumber = msg.content?.data?.pr_number || '';
232
+ const prUrl = msg.content?.data?.pr_url || '';
233
+
234
+ print(''); // Blank line before PR notification
235
+ print(chalk.bold.green(`${'─'.repeat(60)}`));
236
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold.green('🎉 PULL REQUEST CREATED')}`);
237
+
238
+ if (prNumber) {
239
+ print(`${prefix} ${chalk.gray('PR:')} ${chalk.cyan(`#${prNumber}`)}`);
240
+ }
241
+ if (prUrl) {
242
+ print(`${prefix} ${chalk.gray('URL:')} ${chalk.blue(prUrl)}`);
243
+ }
244
+
245
+ print(chalk.bold.green(`${'─'.repeat(60)}`));
246
+ return true;
247
+ }
248
+
249
+ /**
250
+ * Format generic messages (fallback)
251
+ * @param {Object} msg - Message object
252
+ * @param {string} prefix - Formatted message prefix
253
+ * @param {string} timestamp - Formatted timestamp
254
+ * @param {Function} [print=console.log] - Print function for output
255
+ * @returns {boolean} True if message was handled
256
+ */
257
+ function formatGenericMessage(msg, prefix, timestamp, print = console.log) {
258
+ print(`${prefix} ${chalk.gray(timestamp)} ${chalk.bold(msg.topic)}`);
259
+ if (msg.content?.text) {
260
+ print(`${prefix} ${msg.content.text}`);
261
+ }
262
+ return true;
263
+ }
264
+
265
+ module.exports = {
266
+ formatAgentLifecycle,
267
+ formatAgentError,
268
+ formatIssueOpened,
269
+ formatImplementationReady,
270
+ formatValidationResult,
271
+ formatPrCreated,
272
+ formatClusterComplete,
273
+ formatClusterFailed,
274
+ formatGenericMessage,
275
+ };
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Watch mode message formatters
3
+ * Simplified, high-level event display for zeroshot watch command
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const {
8
+ buildClusterPrefix,
9
+ getColorForSender,
10
+ parseDataField,
11
+ } = require('./message-formatter-utils');
12
+
13
+ /**
14
+ * Format AGENT_ERROR for watch mode
15
+ * @param {Object} msg - Message object
16
+ * @param {string} clusterPrefix - Formatted cluster prefix
17
+ */
18
+ function formatAgentError(msg, clusterPrefix) {
19
+ const errorMsg = `${msg.sender} ${chalk.bold.red('ERROR')}`;
20
+ console.log(`${clusterPrefix} ${errorMsg}`);
21
+ if (msg.content?.text) {
22
+ console.log(`${clusterPrefix} ${chalk.red(msg.content.text)}`);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Format ISSUE_OPENED for watch mode
28
+ * @param {Object} msg - Message object
29
+ * @param {string} clusterPrefix - Formatted cluster prefix
30
+ */
31
+ function formatIssueOpened(msg, clusterPrefix) {
32
+ const issueNum = msg.content?.data?.issue_number || '';
33
+ const title = msg.content?.data?.title || '';
34
+ const prompt = msg.content?.data?.prompt || msg.content?.text || '';
35
+
36
+ const taskDesc = title === 'Manual Input' && prompt ? prompt : title;
37
+ const truncatedDesc =
38
+ taskDesc && taskDesc.length > 60 ? taskDesc.substring(0, 60) + '...' : taskDesc;
39
+
40
+ const eventText = `Started ${issueNum ? `#${issueNum}` : 'task'}${truncatedDesc ? chalk.dim(` - ${truncatedDesc}`) : ''}`;
41
+ console.log(`${clusterPrefix} ${eventText}`);
42
+ }
43
+
44
+ /**
45
+ * Format IMPLEMENTATION_READY for watch mode
46
+ * @param {Object} msg - Message object
47
+ * @param {string} clusterPrefix - Formatted cluster prefix
48
+ */
49
+ function formatImplementationReady(msg, clusterPrefix) {
50
+ const agentColor = getColorForSender(msg.sender);
51
+ const agentName = agentColor(msg.sender);
52
+ const eventText = `${agentName} completed implementation`;
53
+ console.log(`${clusterPrefix} ${eventText}`);
54
+ }
55
+
56
+ /**
57
+ * Format VALIDATION_RESULT for watch mode
58
+ * @param {Object} msg - Message object
59
+ * @param {string} clusterPrefix - Formatted cluster prefix
60
+ */
61
+ function formatValidationResult(msg, clusterPrefix) {
62
+ const agentColor = getColorForSender(msg.sender);
63
+ const agentName = agentColor(msg.sender);
64
+ const data = msg.content?.data;
65
+ const approved = data?.approved === 'true' || data?.approved === true;
66
+ const status = approved ? chalk.green('APPROVED') : chalk.red('REJECTED');
67
+
68
+ let eventText = `${agentName} ${status}`;
69
+ if (data?.summary && !approved) {
70
+ eventText += chalk.dim(` - ${data.summary}`);
71
+ }
72
+ console.log(`${clusterPrefix} ${eventText}`);
73
+
74
+ if (!approved) {
75
+ printRejectionDetails(data, clusterPrefix);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Print rejection details (errors/issues)
81
+ * @param {Object} data - Validation data
82
+ * @param {string} clusterPrefix - Formatted cluster prefix
83
+ */
84
+ function printRejectionDetails(data, clusterPrefix) {
85
+ const errors = parseDataField(data.errors);
86
+ const issues = parseDataField(data.issues);
87
+
88
+ if (errors.length > 0) {
89
+ const errorsCharCount = JSON.stringify(errors).length;
90
+ console.log(
91
+ `${clusterPrefix} ${chalk.red('•')} ${errors.length} error${errors.length > 1 ? 's' : ''} (${errorsCharCount} chars)`
92
+ );
93
+ }
94
+
95
+ if (issues.length > 0) {
96
+ const issuesCharCount = JSON.stringify(issues).length;
97
+ console.log(
98
+ `${clusterPrefix} ${chalk.yellow('•')} ${issues.length} issue${issues.length > 1 ? 's' : ''} (${issuesCharCount} chars)`
99
+ );
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Format PR_CREATED for watch mode
105
+ * @param {Object} msg - Message object
106
+ * @param {string} clusterPrefix - Formatted cluster prefix
107
+ */
108
+ function formatPrCreated(msg, clusterPrefix) {
109
+ const agentColor = getColorForSender(msg.sender);
110
+ const agentName = agentColor(msg.sender);
111
+ const prNum = msg.content?.data?.pr_number || '';
112
+ const eventText = `${agentName} created PR${prNum ? ` #${prNum}` : ''}`;
113
+ console.log(`${clusterPrefix} ${eventText}`);
114
+ }
115
+
116
+ /**
117
+ * Format PR_MERGED for watch mode
118
+ * @param {Object} msg - Message object
119
+ * @param {string} clusterPrefix - Formatted cluster prefix
120
+ */
121
+ function formatPrMerged(msg, clusterPrefix) {
122
+ const agentColor = getColorForSender(msg.sender);
123
+ const agentName = agentColor(msg.sender);
124
+ const eventText = `${agentName} merged PR`;
125
+ console.log(`${clusterPrefix} ${eventText}`);
126
+ }
127
+
128
+ /**
129
+ * Format unknown topic for watch mode (fallback)
130
+ * @param {Object} msg - Message object
131
+ * @param {string} clusterPrefix - Formatted cluster prefix
132
+ */
133
+ function formatUnknownTopic(msg, clusterPrefix) {
134
+ const agentColor = getColorForSender(msg.sender);
135
+ const agentName = agentColor(msg.sender);
136
+ const eventText = `${agentName} ${msg.topic.toLowerCase().replace(/_/g, ' ')}`;
137
+ console.log(`${clusterPrefix} ${eventText}`);
138
+ }
139
+
140
+ /**
141
+ * Main watch mode formatter
142
+ * @param {Object} msg - Message object
143
+ * @param {boolean} isActive - Whether cluster is active
144
+ * @returns {boolean} True if message was handled
145
+ */
146
+ function formatWatchMode(msg, isActive) {
147
+ // Skip low-level topics (too noisy for watch mode)
148
+ if (msg.topic === 'AGENT_OUTPUT' || msg.topic === 'AGENT_LIFECYCLE') {
149
+ return true;
150
+ }
151
+
152
+ // Clear status line, print message, will be redrawn by status interval
153
+ process.stdout.write('\r' + ' '.repeat(120) + '\r');
154
+
155
+ const clusterPrefix = buildClusterPrefix(msg.cluster_id, isActive);
156
+
157
+ switch (msg.topic) {
158
+ case 'AGENT_ERROR':
159
+ formatAgentError(msg, clusterPrefix);
160
+ break;
161
+ case 'ISSUE_OPENED':
162
+ formatIssueOpened(msg, clusterPrefix);
163
+ break;
164
+ case 'IMPLEMENTATION_READY':
165
+ formatImplementationReady(msg, clusterPrefix);
166
+ break;
167
+ case 'VALIDATION_RESULT':
168
+ formatValidationResult(msg, clusterPrefix);
169
+ break;
170
+ case 'PR_CREATED':
171
+ formatPrCreated(msg, clusterPrefix);
172
+ break;
173
+ case 'PR_MERGED':
174
+ formatPrMerged(msg, clusterPrefix);
175
+ break;
176
+ default:
177
+ formatUnknownTopic(msg, clusterPrefix);
178
+ }
179
+
180
+ return true;
181
+ }
182
+
183
+ module.exports = {
184
+ formatWatchMode,
185
+ };