@intrect/openswarm 0.9.3 → 0.10.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 (370) hide show
  1. package/README.md +76 -1
  2. package/config.example.yaml +6 -0
  3. package/dist/adapters/agenticLoop.d.ts +24 -0
  4. package/dist/adapters/agenticLoop.d.ts.map +1 -1
  5. package/dist/adapters/agenticLoop.js +130 -11
  6. package/dist/adapters/agenticLoop.js.map +1 -1
  7. package/dist/adapters/applyPatch.d.ts +21 -0
  8. package/dist/adapters/applyPatch.d.ts.map +1 -0
  9. package/dist/adapters/applyPatch.js +175 -0
  10. package/dist/adapters/applyPatch.js.map +1 -0
  11. package/dist/adapters/base.d.ts.map +1 -1
  12. package/dist/adapters/base.js +7 -0
  13. package/dist/adapters/base.js.map +1 -1
  14. package/dist/adapters/codex.js +10 -0
  15. package/dist/adapters/codex.js.map +1 -1
  16. package/dist/adapters/codexResponses.d.ts +8 -0
  17. package/dist/adapters/codexResponses.d.ts.map +1 -1
  18. package/dist/adapters/codexResponses.js +86 -8
  19. package/dist/adapters/codexResponses.js.map +1 -1
  20. package/dist/adapters/errorClassification.d.ts +8 -0
  21. package/dist/adapters/errorClassification.d.ts.map +1 -0
  22. package/dist/adapters/errorClassification.js +54 -0
  23. package/dist/adapters/errorClassification.js.map +1 -0
  24. package/dist/adapters/gpt.d.ts.map +1 -1
  25. package/dist/adapters/gpt.js +12 -1
  26. package/dist/adapters/gpt.js.map +1 -1
  27. package/dist/adapters/local.d.ts.map +1 -1
  28. package/dist/adapters/local.js +9 -1
  29. package/dist/adapters/local.js.map +1 -1
  30. package/dist/adapters/openrouter.d.ts.map +1 -1
  31. package/dist/adapters/openrouter.js +9 -1
  32. package/dist/adapters/openrouter.js.map +1 -1
  33. package/dist/adapters/rateLimitError.d.ts +29 -0
  34. package/dist/adapters/rateLimitError.d.ts.map +1 -0
  35. package/dist/adapters/rateLimitError.js +64 -0
  36. package/dist/adapters/rateLimitError.js.map +1 -0
  37. package/dist/adapters/resultParsing.d.ts.map +1 -1
  38. package/dist/adapters/resultParsing.js +18 -0
  39. package/dist/adapters/resultParsing.js.map +1 -1
  40. package/dist/adapters/tools.d.ts +3 -0
  41. package/dist/adapters/tools.d.ts.map +1 -1
  42. package/dist/adapters/tools.js +148 -11
  43. package/dist/adapters/tools.js.map +1 -1
  44. package/dist/adapters/types.d.ts +15 -0
  45. package/dist/adapters/types.d.ts.map +1 -1
  46. package/dist/adapters/webTools.d.ts.map +1 -1
  47. package/dist/adapters/webTools.js +44 -21
  48. package/dist/adapters/webTools.js.map +1 -1
  49. package/dist/agents/agentPair.d.ts +9 -0
  50. package/dist/agents/agentPair.d.ts.map +1 -1
  51. package/dist/agents/agentPair.js.map +1 -1
  52. package/dist/agents/auditor.d.ts.map +1 -1
  53. package/dist/agents/auditor.js +3 -0
  54. package/dist/agents/auditor.js.map +1 -1
  55. package/dist/agents/documenter.d.ts.map +1 -1
  56. package/dist/agents/documenter.js +3 -0
  57. package/dist/agents/documenter.js.map +1 -1
  58. package/dist/agents/draftAnalyzer.d.ts +30 -7
  59. package/dist/agents/draftAnalyzer.d.ts.map +1 -1
  60. package/dist/agents/draftAnalyzer.js +181 -30
  61. package/dist/agents/draftAnalyzer.js.map +1 -1
  62. package/dist/agents/pairPipeline.d.ts +7 -1
  63. package/dist/agents/pairPipeline.d.ts.map +1 -1
  64. package/dist/agents/pairPipeline.js +110 -66
  65. package/dist/agents/pairPipeline.js.map +1 -1
  66. package/dist/agents/pipelineFormat.d.ts.map +1 -1
  67. package/dist/agents/pipelineFormat.js +4 -0
  68. package/dist/agents/pipelineFormat.js.map +1 -1
  69. package/dist/agents/reviewer.d.ts +16 -0
  70. package/dist/agents/reviewer.d.ts.map +1 -1
  71. package/dist/agents/reviewer.js +30 -0
  72. package/dist/agents/reviewer.js.map +1 -1
  73. package/dist/agents/skillDocumenter.d.ts.map +1 -1
  74. package/dist/agents/skillDocumenter.js +3 -0
  75. package/dist/agents/skillDocumenter.js.map +1 -1
  76. package/dist/agents/tester.d.ts.map +1 -1
  77. package/dist/agents/tester.js +3 -0
  78. package/dist/agents/tester.js.map +1 -1
  79. package/dist/agents/worker.d.ts +14 -0
  80. package/dist/agents/worker.d.ts.map +1 -1
  81. package/dist/agents/worker.js +123 -22
  82. package/dist/agents/worker.js.map +1 -1
  83. package/dist/automation/autonomousRunner.d.ts +12 -0
  84. package/dist/automation/autonomousRunner.d.ts.map +1 -1
  85. package/dist/automation/autonomousRunner.js +218 -29
  86. package/dist/automation/autonomousRunner.js.map +1 -1
  87. package/dist/automation/runnerExecution.d.ts +15 -0
  88. package/dist/automation/runnerExecution.d.ts.map +1 -1
  89. package/dist/automation/runnerExecution.js +77 -1
  90. package/dist/automation/runnerExecution.js.map +1 -1
  91. package/dist/automation/runnerState.d.ts +7 -0
  92. package/dist/automation/runnerState.d.ts.map +1 -1
  93. package/dist/automation/runnerState.js +23 -1
  94. package/dist/automation/runnerState.js.map +1 -1
  95. package/dist/automation/runnerTypes.d.ts +2 -0
  96. package/dist/automation/runnerTypes.d.ts.map +1 -1
  97. package/dist/automation/scheduler.d.ts +12 -0
  98. package/dist/automation/scheduler.d.ts.map +1 -1
  99. package/dist/automation/scheduler.js +29 -2
  100. package/dist/automation/scheduler.js.map +1 -1
  101. package/dist/automation/taskSource.d.ts +9 -1
  102. package/dist/automation/taskSource.d.ts.map +1 -1
  103. package/dist/automation/taskSource.js +13 -2
  104. package/dist/automation/taskSource.js.map +1 -1
  105. package/dist/cli/auditPM.d.ts +40 -0
  106. package/dist/cli/auditPM.d.ts.map +1 -0
  107. package/dist/cli/auditPM.js +132 -0
  108. package/dist/cli/auditPM.js.map +1 -0
  109. package/dist/cli/designPipeline.d.ts +30 -0
  110. package/dist/cli/designPipeline.d.ts.map +1 -0
  111. package/dist/cli/designPipeline.js +113 -0
  112. package/dist/cli/designPipeline.js.map +1 -0
  113. package/dist/cli/mcpCommand.d.ts +22 -0
  114. package/dist/cli/mcpCommand.d.ts.map +1 -0
  115. package/dist/cli/mcpCommand.js +93 -0
  116. package/dist/cli/mcpCommand.js.map +1 -0
  117. package/dist/cli/projectHandler.d.ts.map +1 -1
  118. package/dist/cli/projectHandler.js +4 -2
  119. package/dist/cli/projectHandler.js.map +1 -1
  120. package/dist/cli/reviewAudit.d.ts +130 -0
  121. package/dist/cli/reviewAudit.d.ts.map +1 -0
  122. package/dist/cli/reviewAudit.js +283 -0
  123. package/dist/cli/reviewAudit.js.map +1 -0
  124. package/dist/cli/reviewCommand.d.ts +53 -0
  125. package/dist/cli/reviewCommand.d.ts.map +1 -0
  126. package/dist/cli/reviewCommand.js +207 -0
  127. package/dist/cli/reviewCommand.js.map +1 -0
  128. package/dist/cli/reviewMaxCommand.d.ts +35 -0
  129. package/dist/cli/reviewMaxCommand.d.ts.map +1 -0
  130. package/dist/cli/reviewMaxCommand.js +272 -0
  131. package/dist/cli/reviewMaxCommand.js.map +1 -0
  132. package/dist/cli/reviewProgress.d.ts +34 -0
  133. package/dist/cli/reviewProgress.d.ts.map +1 -0
  134. package/dist/cli/reviewProgress.js +109 -0
  135. package/dist/cli/reviewProgress.js.map +1 -0
  136. package/dist/cli/scheduleCommand.d.ts +15 -0
  137. package/dist/cli/scheduleCommand.d.ts.map +1 -0
  138. package/dist/cli/scheduleCommand.js +68 -0
  139. package/dist/cli/scheduleCommand.js.map +1 -0
  140. package/dist/cli.js +182 -26
  141. package/dist/cli.js.map +1 -1
  142. package/dist/core/config.d.ts +24 -0
  143. package/dist/core/config.d.ts.map +1 -1
  144. package/dist/core/config.js +42 -0
  145. package/dist/core/config.js.map +1 -1
  146. package/dist/core/providerOverride.d.ts.map +1 -1
  147. package/dist/core/providerOverride.js +16 -13
  148. package/dist/core/providerOverride.js.map +1 -1
  149. package/dist/core/service.d.ts.map +1 -1
  150. package/dist/core/service.js +11 -0
  151. package/dist/core/service.js.map +1 -1
  152. package/dist/core/types.d.ts +38 -0
  153. package/dist/core/types.d.ts.map +1 -1
  154. package/dist/discord/discordHandlers.d.ts.map +1 -1
  155. package/dist/discord/discordHandlers.js +1 -0
  156. package/dist/discord/discordHandlers.js.map +1 -1
  157. package/dist/index.js +4 -0
  158. package/dist/index.js.map +1 -1
  159. package/dist/linear/linear.d.ts +21 -0
  160. package/dist/linear/linear.d.ts.map +1 -1
  161. package/dist/linear/linear.js +109 -4
  162. package/dist/linear/linear.js.map +1 -1
  163. package/dist/linear/projectUpdater.js +3 -1
  164. package/dist/linear/projectUpdater.js.map +1 -1
  165. package/dist/locale/prompts/en.d.ts.map +1 -1
  166. package/dist/locale/prompts/en.js +104 -11
  167. package/dist/locale/prompts/en.js.map +1 -1
  168. package/dist/locale/prompts/ko.d.ts.map +1 -1
  169. package/dist/locale/prompts/ko.js +103 -11
  170. package/dist/locale/prompts/ko.js.map +1 -1
  171. package/dist/locale/types.d.ts +12 -0
  172. package/dist/locale/types.d.ts.map +1 -1
  173. package/dist/mcp/mcpClient.d.ts +28 -1
  174. package/dist/mcp/mcpClient.d.ts.map +1 -1
  175. package/dist/mcp/mcpClient.js +74 -3
  176. package/dist/mcp/mcpClient.js.map +1 -1
  177. package/dist/orchestration/decisionEngine.d.ts +20 -0
  178. package/dist/orchestration/decisionEngine.d.ts.map +1 -1
  179. package/dist/orchestration/decisionEngine.js +23 -0
  180. package/dist/orchestration/decisionEngine.js.map +1 -1
  181. package/dist/orchestration/taskScheduler.d.ts.map +1 -1
  182. package/dist/orchestration/taskScheduler.js +12 -1
  183. package/dist/orchestration/taskScheduler.js.map +1 -1
  184. package/dist/support/chatBackend.d.ts +18 -0
  185. package/dist/support/chatBackend.d.ts.map +1 -1
  186. package/dist/support/chatBackend.js +92 -8
  187. package/dist/support/chatBackend.js.map +1 -1
  188. package/dist/support/chatSession.d.ts +51 -0
  189. package/dist/support/chatSession.d.ts.map +1 -0
  190. package/dist/support/chatSession.js +134 -0
  191. package/dist/support/chatSession.js.map +1 -0
  192. package/dist/support/chatTui.d.ts.map +1 -1
  193. package/dist/support/chatTui.js +6 -75
  194. package/dist/support/chatTui.js.map +1 -1
  195. package/dist/support/concurrencyPool.d.ts +18 -0
  196. package/dist/support/concurrencyPool.d.ts.map +1 -0
  197. package/dist/support/concurrencyPool.js +46 -0
  198. package/dist/support/concurrencyPool.js.map +1 -0
  199. package/dist/support/dashboardHtml.d.ts +1 -1
  200. package/dist/support/dashboardHtml.d.ts.map +1 -1
  201. package/dist/support/dashboardHtml.js +0 -28
  202. package/dist/support/dashboardHtml.js.map +1 -1
  203. package/dist/support/editParser.d.ts +26 -0
  204. package/dist/support/editParser.d.ts.map +1 -1
  205. package/dist/support/editParser.js +43 -0
  206. package/dist/support/editParser.js.map +1 -1
  207. package/dist/support/goalCommand.d.ts +35 -0
  208. package/dist/support/goalCommand.d.ts.map +1 -0
  209. package/dist/support/goalCommand.js +112 -0
  210. package/dist/support/goalCommand.js.map +1 -0
  211. package/dist/support/index.d.ts +0 -1
  212. package/dist/support/index.d.ts.map +1 -1
  213. package/dist/support/index.js +0 -1
  214. package/dist/support/index.js.map +1 -1
  215. package/dist/support/web.d.ts.map +1 -1
  216. package/dist/support/web.js +0 -7
  217. package/dist/support/web.js.map +1 -1
  218. package/dist/taskState/store.d.ts +5 -0
  219. package/dist/taskState/store.d.ts.map +1 -1
  220. package/dist/taskState/store.js +16 -0
  221. package/dist/taskState/store.js.map +1 -1
  222. package/dist/telemetry/telemetry.d.ts +42 -0
  223. package/dist/telemetry/telemetry.d.ts.map +1 -0
  224. package/dist/telemetry/telemetry.js +138 -0
  225. package/dist/telemetry/telemetry.js.map +1 -0
  226. package/dist/tui/App.d.ts +20 -0
  227. package/dist/tui/App.d.ts.map +1 -0
  228. package/dist/tui/App.js +52 -0
  229. package/dist/tui/App.js.map +1 -0
  230. package/dist/tui/chatModel.d.ts +81 -0
  231. package/dist/tui/chatModel.d.ts.map +1 -0
  232. package/dist/tui/chatModel.js +129 -0
  233. package/dist/tui/chatModel.js.map +1 -0
  234. package/dist/tui/components/AuditBoard.d.ts +10 -0
  235. package/dist/tui/components/AuditBoard.d.ts.map +1 -0
  236. package/dist/tui/components/AuditBoard.js +50 -0
  237. package/dist/tui/components/AuditBoard.js.map +1 -0
  238. package/dist/tui/components/ChatInput.d.ts +14 -0
  239. package/dist/tui/components/ChatInput.d.ts.map +1 -0
  240. package/dist/tui/components/ChatInput.js +46 -0
  241. package/dist/tui/components/ChatInput.js.map +1 -0
  242. package/dist/tui/components/ChatLog.d.ts +12 -0
  243. package/dist/tui/components/ChatLog.d.ts.map +1 -0
  244. package/dist/tui/components/ChatLog.js +47 -0
  245. package/dist/tui/components/ChatLog.js.map +1 -0
  246. package/dist/tui/components/CommandPalette.d.ts +6 -0
  247. package/dist/tui/components/CommandPalette.d.ts.map +1 -0
  248. package/dist/tui/components/CommandPalette.js +14 -0
  249. package/dist/tui/components/CommandPalette.js.map +1 -0
  250. package/dist/tui/components/ContextBar.d.ts +9 -0
  251. package/dist/tui/components/ContextBar.d.ts.map +1 -0
  252. package/dist/tui/components/ContextBar.js +18 -0
  253. package/dist/tui/components/ContextBar.js.map +1 -0
  254. package/dist/tui/components/DataTable.d.ts +6 -0
  255. package/dist/tui/components/DataTable.d.ts.map +1 -0
  256. package/dist/tui/components/DataTable.js +13 -0
  257. package/dist/tui/components/DataTable.js.map +1 -0
  258. package/dist/tui/components/HelpBar.d.ts +2 -0
  259. package/dist/tui/components/HelpBar.d.ts.map +1 -0
  260. package/dist/tui/components/HelpBar.js +8 -0
  261. package/dist/tui/components/HelpBar.js.map +1 -0
  262. package/dist/tui/components/LiveLog.d.ts +6 -0
  263. package/dist/tui/components/LiveLog.d.ts.map +1 -0
  264. package/dist/tui/components/LiveLog.js +10 -0
  265. package/dist/tui/components/LiveLog.js.map +1 -0
  266. package/dist/tui/components/LogLine.d.ts +4 -0
  267. package/dist/tui/components/LogLine.d.ts.map +1 -0
  268. package/dist/tui/components/LogLine.js +8 -0
  269. package/dist/tui/components/LogLine.js.map +1 -0
  270. package/dist/tui/components/SelectList.d.ts +6 -0
  271. package/dist/tui/components/SelectList.d.ts.map +1 -0
  272. package/dist/tui/components/SelectList.js +15 -0
  273. package/dist/tui/components/SelectList.js.map +1 -0
  274. package/dist/tui/components/StageTimeline.d.ts +7 -0
  275. package/dist/tui/components/StageTimeline.d.ts.map +1 -0
  276. package/dist/tui/components/StageTimeline.js +18 -0
  277. package/dist/tui/components/StageTimeline.js.map +1 -0
  278. package/dist/tui/components/StatusBar.d.ts +7 -0
  279. package/dist/tui/components/StatusBar.d.ts.map +1 -0
  280. package/dist/tui/components/StatusBar.js +8 -0
  281. package/dist/tui/components/StatusBar.js.map +1 -0
  282. package/dist/tui/components/SubagentTree.d.ts +10 -0
  283. package/dist/tui/components/SubagentTree.d.ts.map +1 -0
  284. package/dist/tui/components/SubagentTree.js +12 -0
  285. package/dist/tui/components/SubagentTree.js.map +1 -0
  286. package/dist/tui/components/TabBar.d.ts +5 -0
  287. package/dist/tui/components/TabBar.d.ts.map +1 -0
  288. package/dist/tui/components/TabBar.js +9 -0
  289. package/dist/tui/components/TabBar.js.map +1 -0
  290. package/dist/tui/components/WorkingIndicator.d.ts +6 -0
  291. package/dist/tui/components/WorkingIndicator.d.ts.map +1 -0
  292. package/dist/tui/components/WorkingIndicator.js +20 -0
  293. package/dist/tui/components/WorkingIndicator.js.map +1 -0
  294. package/dist/tui/hooks/useMonitor.d.ts +8 -0
  295. package/dist/tui/hooks/useMonitor.d.ts.map +1 -0
  296. package/dist/tui/hooks/useMonitor.js +42 -0
  297. package/dist/tui/hooks/useMonitor.js.map +1 -0
  298. package/dist/tui/hooks/usePipelineEvents.d.ts +6 -0
  299. package/dist/tui/hooks/usePipelineEvents.d.ts.map +1 -0
  300. package/dist/tui/hooks/usePipelineEvents.js +21 -0
  301. package/dist/tui/hooks/usePipelineEvents.js.map +1 -0
  302. package/dist/tui/hooks/useTerminalSize.d.ts +6 -0
  303. package/dist/tui/hooks/useTerminalSize.d.ts.map +1 -0
  304. package/dist/tui/hooks/useTerminalSize.js +26 -0
  305. package/dist/tui/hooks/useTerminalSize.js.map +1 -0
  306. package/dist/tui/index.d.ts +22 -0
  307. package/dist/tui/index.d.ts.map +1 -0
  308. package/dist/tui/index.js +18 -0
  309. package/dist/tui/index.js.map +1 -0
  310. package/dist/tui/inputDebug.d.ts +20 -0
  311. package/dist/tui/inputDebug.d.ts.map +1 -0
  312. package/dist/tui/inputDebug.js +42 -0
  313. package/dist/tui/inputDebug.js.map +1 -0
  314. package/dist/tui/loadingMessages.d.ts +11 -0
  315. package/dist/tui/loadingMessages.d.ts.map +1 -0
  316. package/dist/tui/loadingMessages.js +39 -0
  317. package/dist/tui/loadingMessages.js.map +1 -0
  318. package/dist/tui/logFormat.d.ts +10 -0
  319. package/dist/tui/logFormat.d.ts.map +1 -0
  320. package/dist/tui/logFormat.js +86 -0
  321. package/dist/tui/logFormat.js.map +1 -0
  322. package/dist/tui/markdown.d.ts +3 -0
  323. package/dist/tui/markdown.d.ts.map +1 -0
  324. package/dist/tui/markdown.js +33 -0
  325. package/dist/tui/markdown.js.map +1 -0
  326. package/dist/tui/monitorApi.d.ts +6 -0
  327. package/dist/tui/monitorApi.d.ts.map +1 -0
  328. package/dist/tui/monitorApi.js +35 -0
  329. package/dist/tui/monitorApi.js.map +1 -0
  330. package/dist/tui/monitorRows.d.ts +43 -0
  331. package/dist/tui/monitorRows.d.ts.map +1 -0
  332. package/dist/tui/monitorRows.js +65 -0
  333. package/dist/tui/monitorRows.js.map +1 -0
  334. package/dist/tui/panels/ChatPanel.d.ts +16 -0
  335. package/dist/tui/panels/ChatPanel.d.ts.map +1 -0
  336. package/dist/tui/panels/ChatPanel.js +305 -0
  337. package/dist/tui/panels/ChatPanel.js.map +1 -0
  338. package/dist/tui/panels/LogsPanel.d.ts +8 -0
  339. package/dist/tui/panels/LogsPanel.d.ts.map +1 -0
  340. package/dist/tui/panels/LogsPanel.js +19 -0
  341. package/dist/tui/panels/LogsPanel.js.map +1 -0
  342. package/dist/tui/panels/MonitorPanel.d.ts +8 -0
  343. package/dist/tui/panels/MonitorPanel.d.ts.map +1 -0
  344. package/dist/tui/panels/MonitorPanel.js +19 -0
  345. package/dist/tui/panels/MonitorPanel.js.map +1 -0
  346. package/dist/tui/panels/PipelinePanel.d.ts +6 -0
  347. package/dist/tui/panels/PipelinePanel.d.ts.map +1 -0
  348. package/dist/tui/panels/PipelinePanel.js +22 -0
  349. package/dist/tui/panels/PipelinePanel.js.map +1 -0
  350. package/dist/tui/pipelineEvents.d.ts +21 -0
  351. package/dist/tui/pipelineEvents.d.ts.map +1 -0
  352. package/dist/tui/pipelineEvents.js +30 -0
  353. package/dist/tui/pipelineEvents.js.map +1 -0
  354. package/dist/tui/sse.d.ts +24 -0
  355. package/dist/tui/sse.d.ts.map +1 -0
  356. package/dist/tui/sse.js +78 -0
  357. package/dist/tui/sse.js.map +1 -0
  358. package/dist/tui/subagentTree.d.ts +10 -0
  359. package/dist/tui/subagentTree.d.ts.map +1 -0
  360. package/dist/tui/subagentTree.js +30 -0
  361. package/dist/tui/subagentTree.js.map +1 -0
  362. package/dist/tui/tabs.d.ts +10 -0
  363. package/dist/tui/tabs.d.ts.map +1 -0
  364. package/dist/tui/tabs.js +26 -0
  365. package/dist/tui/tabs.js.map +1 -0
  366. package/dist/tui/theme.d.ts +29 -0
  367. package/dist/tui/theme.d.ts.map +1 -0
  368. package/dist/tui/theme.js +34 -0
  369. package/dist/tui/theme.js.map +1 -0
  370. package/package.json +13 -3
@@ -0,0 +1,86 @@
1
+ // ============================================
2
+ // OpenSwarm - log line highlighter (INT-1974)
3
+ // ============================================
4
+ //
5
+ // Daemon log lines look like:
6
+ // [worker] [de-artifact | INT-1918 | worktree/0cc4e232] 1) `ab-player.js`: …
7
+ // Parse one into colored segments so the Logs/Pipeline tabs render structured,
8
+ // readable output instead of a monochrome wall. Pure — the Ink <Text> spans are
9
+ // produced by components/LogLine.tsx from these segments.
10
+ import { theme } from './theme.js';
11
+ /** Per-pipeline-stage tag color. */
12
+ const STAGE_COLORS = {
13
+ worker: theme.accent,
14
+ reviewer: theme.accentAlt,
15
+ tester: theme.system,
16
+ planner: theme.info,
17
+ documenter: theme.ok,
18
+ auditor: theme.err,
19
+ 'skill-documenter': theme.ok,
20
+ };
21
+ const ISSUE_RE = /^[A-Z]{2,}-\d+$/;
22
+ /** Level color for the message body. */
23
+ function bodyColor(body) {
24
+ const l = body.toLowerCase();
25
+ if (/(\berror\b|\bfail|✖|✗|"success":\s*false|halt)/.test(l))
26
+ return theme.err;
27
+ if (/(✓|completed|succeed|success|done|approved|passed)/.test(l))
28
+ return theme.ok;
29
+ return undefined;
30
+ }
31
+ /** Split a body into default/level-colored text with `inline code` highlighted cyan. */
32
+ function formatBody(body) {
33
+ if (!body)
34
+ return [];
35
+ const color = bodyColor(body);
36
+ const out = [];
37
+ const re = /`([^`]+)`/g;
38
+ let last = 0;
39
+ let m;
40
+ while ((m = re.exec(body))) {
41
+ if (m.index > last)
42
+ out.push({ text: body.slice(last, m.index), color });
43
+ out.push({ text: `\`${m[1]}\``, color: theme.accent });
44
+ last = m.index + m[0].length;
45
+ }
46
+ if (last < body.length)
47
+ out.push({ text: body.slice(last), color });
48
+ return out;
49
+ }
50
+ /** Parse a daemon log line into colored segments. (INT-1974) */
51
+ export function parseLogLine(line) {
52
+ const segs = [];
53
+ let rest = line;
54
+ // 1) leading [stage]
55
+ const stageM = rest.match(/^\[([a-z][\w-]*)\]\s*/i);
56
+ if (stageM) {
57
+ const stage = stageM[1].toLowerCase();
58
+ segs.push({ text: `[${stageM[1]}]`, color: STAGE_COLORS[stage] ?? theme.assistant, bold: true });
59
+ segs.push({ text: ' ' });
60
+ rest = rest.slice(stageM[0].length);
61
+ }
62
+ // 2) context group [project | ISSUE | worktree/hash]
63
+ const ctxM = rest.match(/^\[([^\]]*)\]\s*/);
64
+ if (ctxM) {
65
+ segs.push({ text: '[', dim: true });
66
+ const parts = ctxM[1].split('|').map((p) => p.trim());
67
+ parts.forEach((p, i) => {
68
+ if (i > 0)
69
+ segs.push({ text: ' | ', dim: true });
70
+ if (ISSUE_RE.test(p))
71
+ segs.push({ text: p, color: theme.system, bold: true });
72
+ else if (p.startsWith('worktree/'))
73
+ segs.push({ text: p, dim: true });
74
+ else
75
+ segs.push({ text: p, color: theme.ok });
76
+ });
77
+ segs.push({ text: ']', dim: true });
78
+ segs.push({ text: ' ' });
79
+ rest = rest.slice(ctxM[0].length);
80
+ }
81
+ // 3) body
82
+ segs.push(...formatBody(rest));
83
+ // A line that was only a (stage/context) prefix still needs at least one segment.
84
+ return segs.length ? segs : [{ text: line }];
85
+ }
86
+ //# sourceMappingURL=logFormat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logFormat.js","sourceRoot":"","sources":["../../src/tui/logFormat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Render markdown to an ANSI-styled string. Falls back to the raw text on error. */
2
+ export declare function renderMarkdown(md: string): string;
3
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/tui/markdown.ts"],"names":[],"mappings":"AAqBA,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjD"}
@@ -0,0 +1,33 @@
1
+ // ============================================
2
+ // OpenSwarm - Markdown → ANSI renderer (INT-1943)
3
+ // Renders assistant messages as terminal-styled markdown (bold/lists/code with
4
+ // syntax highlight) via marked + marked-terminal. Pure string → string, so it
5
+ // is unit-testable and framework-agnostic (used inside an Ink <Text>).
6
+ // ============================================
7
+ import { marked } from 'marked';
8
+ // marked-terminal has no bundled type declarations; see src/types/marked-terminal.d.ts.
9
+ import { markedTerminal } from 'marked-terminal';
10
+ let configured = false;
11
+ function ensureConfigured() {
12
+ if (configured)
13
+ return;
14
+ // marked-terminal styles headings/lists/code; with cli-highlight present it
15
+ // syntax-highlights fenced code blocks. reflowText wraps prose to the terminal.
16
+ marked.use(markedTerminal({ reflowText: true, tab: 2 }));
17
+ configured = true;
18
+ }
19
+ /** Render markdown to an ANSI-styled string. Falls back to the raw text on error. */
20
+ export function renderMarkdown(md) {
21
+ if (!md)
22
+ return '';
23
+ try {
24
+ ensureConfigured();
25
+ const out = marked.parse(md);
26
+ const text = typeof out === 'string' ? out : md;
27
+ return text.replace(/\s+$/, '');
28
+ }
29
+ catch {
30
+ return md;
31
+ }
32
+ }
33
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/tui/markdown.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,kDAAkD;AAClD,+EAA+E;AAC/E,8EAA8E;AAC9E,uEAAuE;AACvE,+CAA+C;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,wFAAwF;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,SAAS,gBAAgB;IACvB,IAAI,UAAU;QAAE,OAAO;IACvB,4EAA4E;IAC5E,gFAAgF;IAChF,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAqC,CAAC,CAAC;IAC7F,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,IAAI,CAAC;QACH,gBAAgB,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type Table } from './monitorRows.js';
2
+ export declare function fetchProjects(port: number): Promise<Table>;
3
+ export declare function fetchTasks(port: number): Promise<Table>;
4
+ export declare function fetchStuck(port: number): Promise<Table>;
5
+ export declare function fetchIssues(port: number): Promise<Table>;
6
+ //# sourceMappingURL=monitorApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitorApi.d.ts","sourceRoot":"","sources":["../../src/tui/monitorApi.ts"],"names":[],"mappings":"AAMA,OAAO,EAAiE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAI7G,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAGhE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAI7D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAI7D;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAW9D"}
@@ -0,0 +1,35 @@
1
+ // ============================================
2
+ // OpenSwarm - Monitor API client (EPIC INT-1813 S6 / INT-1939)
3
+ // Network boundary: fetches daemon snapshots for the monitor tabs. The pure
4
+ // mappers (monitorRows.ts) turn these into tables. Default daemon port 3847.
5
+ // ============================================
6
+ import { projectsToTable, pipelineToTable, stuckToTable, issuesToTable } from './monitorRows.js';
7
+ const base = (port) => `http://127.0.0.1:${port}`;
8
+ export async function fetchProjects(port) {
9
+ const res = await fetch(`${base(port)}/api/projects`);
10
+ return projectsToTable(await res.json());
11
+ }
12
+ export async function fetchTasks(port) {
13
+ const res = await fetch(`${base(port)}/api/pipeline`);
14
+ const { stages } = (await res.json());
15
+ return pipelineToTable((stages ?? []));
16
+ }
17
+ export async function fetchStuck(port) {
18
+ const res = await fetch(`${base(port)}/api/stuck-issues`);
19
+ const { stuckIssues, failedIssues } = (await res.json());
20
+ return stuckToTable(stuckIssues ?? [], failedIssues ?? []);
21
+ }
22
+ export async function fetchIssues(port) {
23
+ const res = await fetch(`${base(port)}/graphql`, {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json' },
26
+ body: JSON.stringify({
27
+ query: '{ issues(filter: { limit: 50 }) { issues { id title status priority } total } }',
28
+ }),
29
+ });
30
+ const json = (await res.json());
31
+ if (json.errors?.length)
32
+ throw new Error(json.errors[0].message);
33
+ return issuesToTable(json.data?.issues?.issues ?? []);
34
+ }
35
+ //# sourceMappingURL=monitorApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitorApi.js","sourceRoot":"","sources":["../../src/tui/monitorApi.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,+DAA+D;AAC/D,4EAA4E;AAC5E,6EAA6E;AAC7E,+CAA+C;AAE/C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAE7G,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,oBAAoB,IAAI,EAAE,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACtD,OAAO,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACtD,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;IAC/D,OAAO,eAAe,CAAC,CAAC,MAAM,IAAI,EAAE,CAAU,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC1D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoD,CAAC;IAC5G,OAAO,YAAY,CAAC,WAAW,IAAI,EAAE,EAAE,YAAY,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;QAC/C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,iFAAiF;SACzF,CAAC;KACH,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsF,CAAC;IACrH,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,43 @@
1
+ export interface Table {
2
+ columns: string[];
3
+ rows: string[][];
4
+ }
5
+ export interface ApiProject {
6
+ name: string;
7
+ path: string;
8
+ enabled: boolean;
9
+ running?: string[];
10
+ queued?: string[];
11
+ }
12
+ export declare function projectsToTable(projects: ApiProject[]): Table;
13
+ export interface ApiPipelineEvent {
14
+ type: string;
15
+ data: {
16
+ taskId?: string;
17
+ stage?: string;
18
+ status?: string;
19
+ model?: string;
20
+ title?: string;
21
+ issueIdentifier?: string;
22
+ };
23
+ }
24
+ /** Most-recent pipeline stage events as task rows (newest first). */
25
+ export declare function pipelineToTable(stages: ApiPipelineEvent[], limit?: number): Table;
26
+ export interface ApiStuckIssue {
27
+ identifier: string;
28
+ title: string;
29
+ reason: string;
30
+ priority: number;
31
+ project?: {
32
+ name: string;
33
+ };
34
+ }
35
+ export declare function stuckToTable(stuck: ApiStuckIssue[], failed: ApiStuckIssue[]): Table;
36
+ export interface ApiIssue {
37
+ id: string;
38
+ title: string;
39
+ status: string;
40
+ priority: number;
41
+ }
42
+ export declare function issuesToTable(issues: ApiIssue[]): Table;
43
+ //# sourceMappingURL=monitorRows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitorRows.d.ts","sourceRoot":"","sources":["../../src/tui/monitorRows.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,CAU7D;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAID,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,KAAK,SAAK,GAAG,KAAK,CAoB7E;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,KAAK,CAYnF;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CASvD"}
@@ -0,0 +1,65 @@
1
+ // ============================================
2
+ // OpenSwarm - Monitor row mappers (EPIC INT-1813 S6 / INT-1939)
3
+ // Pure daemon-JSON → table mappers for the Projects/Tasks/Stuck/Issues tabs.
4
+ // No React/ink/network — unit-tested. DataTable renders the {columns, rows}.
5
+ // ============================================
6
+ export function projectsToTable(projects) {
7
+ return {
8
+ columns: ['', 'PROJECT', 'RUN', 'QUEUE'],
9
+ rows: projects.map((p) => [
10
+ p.enabled ? '●' : '○',
11
+ p.name,
12
+ String(p.running?.length ?? 0),
13
+ String(p.queued?.length ?? 0),
14
+ ]),
15
+ };
16
+ }
17
+ const STAGE_ICON = { start: '◐', complete: '●', fail: '✗' };
18
+ /** Most-recent pipeline stage events as task rows (newest first). */
19
+ export function pipelineToTable(stages, limit = 15) {
20
+ const info = new Map(); // taskId → identifier/title
21
+ const events = [];
22
+ for (const ev of stages) {
23
+ if (ev.type === 'task:started' && ev.data.taskId) {
24
+ info.set(ev.data.taskId, ev.data.issueIdentifier || ev.data.title || ev.data.taskId);
25
+ }
26
+ else if (ev.type === 'pipeline:stage' && ev.data.taskId && ev.data.stage) {
27
+ events.push({ taskId: ev.data.taskId, stage: ev.data.stage, status: ev.data.status ?? '', model: ev.data.model });
28
+ }
29
+ }
30
+ const recent = events.slice(-limit).reverse();
31
+ return {
32
+ columns: ['TASK', 'STAGE', 'MODEL', 'STATUS'],
33
+ rows: recent.map((e) => [
34
+ (info.get(e.taskId) ?? e.taskId).slice(0, 14),
35
+ e.stage,
36
+ e.model ? e.model.split('-').slice(-2).join('-') : '',
37
+ `${STAGE_ICON[e.status] ?? '○'} ${e.status}`,
38
+ ]),
39
+ };
40
+ }
41
+ const PRIO = (p) => (p === 1 ? 'urgent' : p === 2 ? 'high' : p === 3 ? 'med' : 'low');
42
+ export function stuckToTable(stuck, failed) {
43
+ const row = (kind) => (i) => [
44
+ kind,
45
+ i.identifier,
46
+ i.title.length > 40 ? `${i.title.slice(0, 39)}…` : i.title,
47
+ PRIO(i.priority),
48
+ i.reason.length > 30 ? `${i.reason.slice(0, 29)}…` : i.reason,
49
+ ];
50
+ return {
51
+ columns: ['KIND', 'ID', 'TITLE', 'PRIO', 'REASON'],
52
+ rows: [...stuck.map(row('stuck')), ...failed.map(row('failed'))],
53
+ };
54
+ }
55
+ export function issuesToTable(issues) {
56
+ return {
57
+ columns: ['TITLE', 'STATUS', 'PRIO'],
58
+ rows: issues.map((i) => [
59
+ i.title.length > 50 ? `${i.title.slice(0, 49)}…` : i.title,
60
+ i.status,
61
+ PRIO(i.priority),
62
+ ]),
63
+ };
64
+ }
65
+ //# sourceMappingURL=monitorRows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitorRows.js","sourceRoot":"","sources":["../../src/tui/monitorRows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type ChatLine } from '../chatModel.js';
2
+ export interface ChatPanelProps {
3
+ active: boolean;
4
+ provider?: string;
5
+ model?: string;
6
+ /** Project root for /plan + /goal dispatch (defaults to cwd). */
7
+ projectPath?: string;
8
+ /** Session id to persist under; resume passes the existing id. (INT-2014) */
9
+ sessionId?: string;
10
+ /** Conversation restored from a resumed session. (INT-2014) */
11
+ initialHistory?: ChatLine[];
12
+ /** Session goal restored from a resumed session — keeps it "in pursuit". (INT-2014) */
13
+ goal?: string;
14
+ }
15
+ export declare function ChatPanel({ active, provider: providerProp, model: modelProp, projectPath, sessionId: sessionIdProp, initialHistory, goal: goalProp }: ChatPanelProps): import("react").JSX.Element;
16
+ //# sourceMappingURL=ChatPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../../src/tui/panels/ChatPanel.tsx"],"names":[],"mappings":"AAUA,OAAO,EAUL,KAAK,QAAQ,EACd,MAAM,iBAAiB,CAAC;AAYzB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5B,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,cAAc,+BA8UpK"}
@@ -0,0 +1,305 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================
3
+ // OpenSwarm - Chat tab panel (EPIC INT-1813 S4 + S8 / INT-1937, INT-1941)
4
+ // Wires the pure chat model to the input/log components and to
5
+ // chatSession.callChatModel (streaming). S8 adds /plan + /goal orchestration via
6
+ // planCommand.runPlanCommand, with confirms routed through a pending-input flow
7
+ // (the Ink PlanIO implementation). Network/effect boundary.
8
+ // ============================================
9
+ import { Box } from 'ink';
10
+ import { useReducer, useState, useCallback, useEffect, useRef } from 'react';
11
+ import { chatReducer, initialChatState, parseInput, matchSlash, movePaletteSelection, normalizeConfirm, isActivityNoise, historyToMessages, SLASH_COMMANDS, } from '../chatModel.js';
12
+ import { ChatLog } from '../components/ChatLog.js';
13
+ import { ChatInput } from '../components/ChatInput.js';
14
+ import { CommandPalette } from '../components/CommandPalette.js';
15
+ import { SelectList } from '../components/SelectList.js';
16
+ import { listAdapterNames } from '../../adapters/index.js';
17
+ import { callChatModel, loadDefaultProvider, saveSession, generateSessionId } from '../../support/chatSession.js';
18
+ import { getDefaultChatModel, listChatModels } from '../../support/chatBackend.js';
19
+ import { runPlanCommand } from '../../support/planCommand.js';
20
+ import { runGoalCommand, buildGoalPursuitPrompt, GOAL_PURSUIT_MAX_TURNS } from '../../support/goalCommand.js';
21
+ export function ChatPanel({ active, provider: providerProp, model: modelProp, projectPath, sessionId: sessionIdProp, initialHistory, goal: goalProp }) {
22
+ const [state, dispatch] = useReducer(chatReducer, undefined, () => (initialHistory && initialHistory.length > 0 ? { history: initialHistory, streaming: null } : initialChatState));
23
+ const [input, setInput] = useState('');
24
+ const [paletteIndex, setPaletteIndex] = useState(0);
25
+ const [busy, setBusy] = useState(false);
26
+ const [activity, setActivity] = useState([]);
27
+ // A /goal pursuit is active — only /goal clear stops it (no Esc/other input). (INT-2014)
28
+ const [goalActive, setGoalActive] = useState(!!goalProp);
29
+ // Stable across renders: session id, createdAt, the active goal, and the abort
30
+ // controller that /goal clear fires. (INT-2014)
31
+ const sessionIdRef = useRef(sessionIdProp ?? generateSessionId());
32
+ const createdAtRef = useRef(new Date().toISOString());
33
+ const goalRef = useRef(goalProp);
34
+ const abortRef = useRef(null);
35
+ // When set, the next submitted line is routed here (a /plan confirm or edit)
36
+ // instead of being treated as chat — the Ink analogue of blessed pendingInput.
37
+ const [pending, setPending] = useState(null);
38
+ // provider/model are runtime-switchable via /provider and /model (INT-1960/1961).
39
+ const [provider, setProvider] = useState(providerProp ?? loadDefaultProvider());
40
+ const [model, setModel] = useState(modelProp ?? getDefaultChatModel(providerProp ?? loadDefaultProvider()));
41
+ // Active /provider | /model selector overlay (null = none). (INT-1960/1961)
42
+ const [selector, setSelector] = useState(null);
43
+ const [selectorIndex, setSelectorIndex] = useState(0);
44
+ const cwd = projectPath ?? process.cwd();
45
+ // Persist the conversation on every change so it survives exit and can be
46
+ // reopened with `openswarm resume`. System/UI lines are dropped by
47
+ // historyToMessages; the goal rides along so resume keeps pursuing it. (INT-2014)
48
+ useEffect(() => {
49
+ if (state.history.length === 0)
50
+ return;
51
+ void saveSession({
52
+ id: sessionIdRef.current,
53
+ provider,
54
+ model,
55
+ messages: historyToMessages(state.history),
56
+ totalCost: 0,
57
+ totalTokens: 0,
58
+ createdAt: createdAtRef.current,
59
+ updatedAt: '', // saveSession stamps this
60
+ goal: goalRef.current,
61
+ });
62
+ }, [state.history, provider, model]);
63
+ const ask = useCallback((prompt) => new Promise((resolve) => {
64
+ dispatch({ type: 'system', content: prompt });
65
+ setPending({ resolve });
66
+ }), []);
67
+ const planIO = {
68
+ print: (line) => dispatch({ type: 'system', content: line }),
69
+ confirm: async (prompt) => normalizeConfirm(await ask(prompt)),
70
+ promptText: (prompt) => ask(prompt),
71
+ };
72
+ const runPlan = useCallback(async (goal) => {
73
+ setBusy(true);
74
+ try {
75
+ await runPlanCommand(goal, planIO, { projectPath: cwd, model });
76
+ }
77
+ catch (e) {
78
+ dispatch({ type: 'system', content: `✖ plan failed: ${e instanceof Error ? e.message : String(e)}` });
79
+ }
80
+ finally {
81
+ setBusy(false);
82
+ }
83
+ },
84
+ // planIO is rebuilt each render but only closes over stable dispatch/ask.
85
+ [cwd, model]);
86
+ // Stream an agentic chat turn into the reducer. Shared by free chat and simple
87
+ // /goal pursuit (the latter raises maxTurns). (INT-1821)
88
+ const streamChat = useCallback(async (prompt, maxTurns) => {
89
+ dispatch({ type: 'stream', chunk: '' });
90
+ setActivity([]);
91
+ setBusy(true);
92
+ const ac = new AbortController();
93
+ abortRef.current = ac;
94
+ try {
95
+ await callChatModel(prompt, provider, model,
96
+ // Reasoning/thinking deltas (isThinking=true) must NOT land in the answer
97
+ // buffer — that's the /goal token-spam (INT-2013). Drop them here; codex
98
+ // surfaces reasoning separately via onLog ('💭 …'). (INT-2014)
99
+ (t, isThinking) => {
100
+ if (!isThinking)
101
+ dispatch({ type: 'stream', chunk: t });
102
+ }, (line) => {
103
+ if (isActivityNoise(line))
104
+ return;
105
+ setActivity((a) => [...a, line].slice(-10));
106
+ }, maxTurns, ac.signal, // wired so /goal clear can abort a pursuit (INT-2014)
107
+ cwd);
108
+ }
109
+ catch (e) {
110
+ const msg = e instanceof Error ? e.message : String(e);
111
+ // An abort (from /goal clear) is intentional, not an error.
112
+ if (!ac.signal.aborted)
113
+ dispatch({ type: 'stream', chunk: `\n[error] ${msg}` });
114
+ }
115
+ finally {
116
+ dispatch({ type: 'commit' });
117
+ setActivity([]);
118
+ setBusy(false);
119
+ abortRef.current = null;
120
+ }
121
+ }, [provider, model, cwd]);
122
+ // /goal routes by complexity: simple → pursue in-session (streamed), complex →
123
+ // decompose & dispatch via the /plan flow. (INT-1821 / S8)
124
+ const runGoal = useCallback(async (goal) => {
125
+ goalRef.current = goal; // rides along into saveSession so resume keeps it
126
+ setGoalActive(true);
127
+ setBusy(true);
128
+ try {
129
+ await runGoalCommand(goal, planIO, { projectPath: cwd, model, provider }, { pursue: (g) => streamChat(buildGoalPursuitPrompt(g), GOAL_PURSUIT_MAX_TURNS) });
130
+ }
131
+ catch (e) {
132
+ dispatch({ type: 'system', content: `✖ goal failed: ${e instanceof Error ? e.message : String(e)}` });
133
+ }
134
+ finally {
135
+ setBusy(false);
136
+ // Pursuit turn finished — unblock input. The goal itself stays set
137
+ // (goalRef) until /goal clear, so resume keeps pursuing it.
138
+ setGoalActive(false);
139
+ }
140
+ }, [cwd, model, provider, streamChat]);
141
+ // Open the /model selector for the current provider (async catalog). (INT-1961)
142
+ const openModelSelector = useCallback(async () => {
143
+ dispatch({ type: 'system', content: `Fetching models for ${provider}…` });
144
+ try {
145
+ const models = await listChatModels(provider);
146
+ if (!models.length) {
147
+ dispatch({ type: 'system', content: `No models listed for ${provider}. Use /model <name>.` });
148
+ return;
149
+ }
150
+ setSelectorIndex(Math.max(0, models.indexOf(model)));
151
+ setSelector({ kind: 'model', title: `Switch model (${provider}):`, items: models });
152
+ }
153
+ catch (e) {
154
+ dispatch({ type: 'system', content: `✖ failed to list models: ${e instanceof Error ? e.message : String(e)}` });
155
+ }
156
+ }, [provider, model]);
157
+ const runCommand = useCallback((name, args) => {
158
+ switch (name) {
159
+ case '/clear':
160
+ dispatch({ type: 'clear' });
161
+ break;
162
+ case '/help':
163
+ dispatch({ type: 'system', content: SLASH_COMMANDS.map((c) => `${c.name} ${c.args} — ${c.desc}`).join('\n') });
164
+ break;
165
+ case '/plan':
166
+ void runPlan(args);
167
+ break;
168
+ case '/goal': {
169
+ // /goal clear stops the active pursuit — the only way to interrupt it.
170
+ // It aborts the in-flight turn and releases the session goal. (INT-2014)
171
+ if (args.trim() === 'clear') {
172
+ abortRef.current?.abort();
173
+ goalRef.current = undefined;
174
+ setGoalActive(false);
175
+ dispatch({ type: 'system', content: '✖ Goal cleared.' });
176
+ break;
177
+ }
178
+ // /goal routes by complexity (INT-1821): simple → pursue in-session,
179
+ // complex → decompose & dispatch. Shared, UI-agnostic goalCommand.
180
+ void runGoal(args);
181
+ break;
182
+ }
183
+ case '/provider': {
184
+ // `/provider <name>` switches directly; bare `/provider` opens a selector. (INT-1960)
185
+ const items = listAdapterNames();
186
+ const target = args.trim();
187
+ if (target) {
188
+ if (!items.includes(target)) {
189
+ dispatch({ type: 'system', content: `Unknown provider "${target}". Options: ${items.join(', ')}` });
190
+ }
191
+ else {
192
+ setProvider(target);
193
+ setModel(getDefaultChatModel(target));
194
+ dispatch({ type: 'system', content: `Provider → ${target} (model: ${getDefaultChatModel(target)})` });
195
+ }
196
+ break;
197
+ }
198
+ setSelectorIndex(Math.max(0, items.indexOf(provider)));
199
+ setSelector({ kind: 'provider', title: 'Switch provider:', items });
200
+ break;
201
+ }
202
+ case '/model': {
203
+ // `/model <name>` switches directly; bare `/model` opens an async selector. (INT-1961)
204
+ const target = args.trim();
205
+ if (target) {
206
+ setModel(target);
207
+ dispatch({ type: 'system', content: `Model → ${target}` });
208
+ break;
209
+ }
210
+ void openModelSelector();
211
+ break;
212
+ }
213
+ default:
214
+ dispatch({ type: 'system', content: `Unknown command: ${name}` });
215
+ }
216
+ }, [runPlan, runGoal, provider, openModelSelector]);
217
+ // Apply the highlighted choice in the /provider | /model selector. (INT-1960/1961)
218
+ const applySelector = useCallback(() => {
219
+ if (!selector)
220
+ return;
221
+ const choice = selector.items[selectorIndex];
222
+ if (choice) {
223
+ if (selector.kind === 'provider') {
224
+ setProvider(choice);
225
+ setModel(getDefaultChatModel(choice));
226
+ dispatch({ type: 'system', content: `Provider → ${choice} (model: ${getDefaultChatModel(choice)})` });
227
+ }
228
+ else {
229
+ setModel(choice);
230
+ dispatch({ type: 'system', content: `Model → ${choice}` });
231
+ }
232
+ }
233
+ setSelector(null);
234
+ setSelectorIndex(0);
235
+ }, [selector, selectorIndex]);
236
+ const submit = useCallback(async (raw) => {
237
+ setInput('');
238
+ // A pending /plan confirm/edit consumes the next line verbatim.
239
+ if (pending) {
240
+ const { resolve } = pending;
241
+ setPending(null);
242
+ resolve(raw);
243
+ return;
244
+ }
245
+ const parsed = parseInput(raw);
246
+ if (!parsed)
247
+ return;
248
+ // While a goal is actively being pursued, only "/goal clear" is honored —
249
+ // the pursuit runs to completion and nothing else can interrupt it. (INT-2014)
250
+ if (goalActive && busy) {
251
+ if (parsed.kind === 'command' && parsed.name === '/goal' && parsed.args.trim() === 'clear') {
252
+ runCommand(parsed.name, parsed.args);
253
+ }
254
+ else {
255
+ dispatch({ type: 'system', content: 'Goal in progress — type "/goal clear" to stop it.' });
256
+ }
257
+ return;
258
+ }
259
+ if (parsed.kind === 'command') {
260
+ runCommand(parsed.name, parsed.args);
261
+ return;
262
+ }
263
+ dispatch({ type: 'user', content: parsed.text });
264
+ await streamChat(parsed.text);
265
+ }, [pending, runCommand, streamChat, goalActive, busy]);
266
+ // Keep the field active while a /plan confirm is pending, or while a goal is
267
+ // being pursued (so the user can type "/goal clear"). (INT-2014)
268
+ const inputActive = active && (!busy || pending !== null || goalActive);
269
+ // Interactive command palette (INT-1959): ↑/↓ select, Enter/Tab complete.
270
+ // A /provider|/model selector (INT-1960/1961) takes precedence when open.
271
+ const matches = matchSlash(input);
272
+ const selectorOpen = inputActive && selector !== null;
273
+ const slashOpen = inputActive && pending === null && selector === null && matches.length > 0;
274
+ const menuOpen = selectorOpen || slashOpen;
275
+ const handleChange = useCallback((v) => {
276
+ setInput(v);
277
+ setPaletteIndex(0);
278
+ }, []);
279
+ const onSlashSelect = useCallback(() => {
280
+ const cmd = matches[paletteIndex];
281
+ if (!cmd)
282
+ return;
283
+ if (cmd.args) {
284
+ // command takes args → complete to "name " so the user can type them
285
+ setInput(`${cmd.name} `);
286
+ setPaletteIndex(0);
287
+ }
288
+ else {
289
+ setInput('');
290
+ runCommand(cmd.name, '');
291
+ }
292
+ }, [matches, paletteIndex, runCommand]);
293
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(ChatLog, { history: state.history, streaming: state.streaming, activity: activity, busy: busy && pending === null }), _jsx(ChatInput, { value: input, active: inputActive, busy: busy && pending === null && !goalActive, onChange: handleChange, onSubmit: submit, paletteOpen: menuOpen, onPaletteMove: (delta) => selectorOpen
294
+ ? setSelectorIndex((i) => movePaletteSelection(i, delta, selector.items.length))
295
+ : setPaletteIndex((i) => movePaletteSelection(i, delta, matches.length)), onPaletteSelect: () => (selectorOpen ? applySelector() : onSlashSelect()), onPaletteClose: () => {
296
+ if (selectorOpen) {
297
+ setSelector(null);
298
+ setSelectorIndex(0);
299
+ }
300
+ else {
301
+ setInput('');
302
+ }
303
+ } }), selectorOpen ? (_jsx(SelectList, { title: selector.title, items: selector.items, selectedIndex: selectorIndex })) : (_jsx(CommandPalette, { matches: matches, selectedIndex: paletteIndex }))] }));
304
+ }
305
+ //# sourceMappingURL=ChatPanel.js.map