whale-code 6.5.4 → 6.5.6

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 (853) hide show
  1. package/README.md +39 -31
  2. package/bin/{swagmanager-mcp.js → whale-code.js} +17 -2
  3. package/dist/cli/app.js +148 -72
  4. package/dist/cli/app.js.map +1 -0
  5. package/dist/cli/chat/AgentSelector.js +105 -10
  6. package/dist/cli/chat/AgentSelector.js.map +1 -0
  7. package/dist/cli/chat/ChatApp.d.ts +31 -0
  8. package/dist/cli/chat/ChatApp.js +539 -286
  9. package/dist/cli/chat/ChatApp.js.map +1 -0
  10. package/dist/cli/chat/ChatInput.js +1088 -770
  11. package/dist/cli/chat/ChatInput.js.map +1 -0
  12. package/dist/cli/chat/MarkdownText.js +39 -14
  13. package/dist/cli/chat/MarkdownText.js.map +1 -0
  14. package/dist/cli/chat/MemoryManager.js +181 -46
  15. package/dist/cli/chat/MemoryManager.js.map +1 -0
  16. package/dist/cli/chat/MessageList.d.ts +2 -3
  17. package/dist/cli/chat/MessageList.js +186 -45
  18. package/dist/cli/chat/MessageList.js.map +1 -0
  19. package/dist/cli/chat/ModelSelector.js +282 -63
  20. package/dist/cli/chat/ModelSelector.js.map +1 -0
  21. package/dist/cli/chat/NodeManager.js +165 -75
  22. package/dist/cli/chat/NodeManager.js.map +1 -0
  23. package/dist/cli/chat/NodeSelector.js +171 -30
  24. package/dist/cli/chat/NodeSelector.js.map +1 -0
  25. package/dist/cli/chat/PlanApproval.js +281 -57
  26. package/dist/cli/chat/PlanApproval.js.map +1 -0
  27. package/dist/cli/chat/RewindViewer.js +559 -144
  28. package/dist/cli/chat/RewindViewer.js.map +1 -0
  29. package/dist/cli/chat/SessionManager.js +137 -30
  30. package/dist/cli/chat/SessionManager.js.map +1 -0
  31. package/dist/cli/chat/SlashMenu.js +293 -164
  32. package/dist/cli/chat/SlashMenu.js.map +1 -0
  33. package/dist/cli/chat/StatusBar.js +172 -9
  34. package/dist/cli/chat/StatusBar.js.map +1 -0
  35. package/dist/cli/chat/StoreSelector.js +147 -18
  36. package/dist/cli/chat/StoreSelector.js.map +1 -0
  37. package/dist/cli/chat/StreamingText.d.ts +1 -5
  38. package/dist/cli/chat/StreamingText.js +22 -7
  39. package/dist/cli/chat/StreamingText.js.map +1 -0
  40. package/dist/cli/chat/SubagentPanel.d.ts +1 -2
  41. package/dist/cli/chat/SubagentPanel.js +612 -72
  42. package/dist/cli/chat/SubagentPanel.js.map +1 -0
  43. package/dist/cli/chat/TeamPanel.d.ts +1 -0
  44. package/dist/cli/chat/TeamPanel.js +230 -30
  45. package/dist/cli/chat/TeamPanel.js.map +1 -0
  46. package/dist/cli/chat/ThemeSelector.js +84 -24
  47. package/dist/cli/chat/ThemeSelector.js.map +1 -0
  48. package/dist/cli/chat/ToolIndicator.js +1476 -371
  49. package/dist/cli/chat/ToolIndicator.js.map +1 -0
  50. package/dist/cli/chat/hooks/useAgentLoop.d.ts +1 -0
  51. package/dist/cli/chat/hooks/useAgentLoop.js +481 -367
  52. package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -0
  53. package/dist/cli/chat/hooks/useSlashCommands.d.ts +3 -14
  54. package/dist/cli/chat/hooks/useSlashCommands.js +744 -572
  55. package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -0
  56. package/dist/cli/commands/config-cmd.js +56 -57
  57. package/dist/cli/commands/config-cmd.js.map +1 -0
  58. package/dist/cli/commands/db.js +184 -169
  59. package/dist/cli/commands/db.js.map +1 -0
  60. package/dist/cli/commands/doctor.js +212 -122
  61. package/dist/cli/commands/doctor.js.map +1 -0
  62. package/dist/cli/commands/init.js +211 -244
  63. package/dist/cli/commands/init.js.map +1 -0
  64. package/dist/cli/commands/mcp.js +127 -122
  65. package/dist/cli/commands/mcp.js.map +1 -0
  66. package/dist/cli/login/LoginApp.js +355 -141
  67. package/dist/cli/login/LoginApp.js.map +1 -0
  68. package/dist/cli/print-mode.js +196 -177
  69. package/dist/cli/print-mode.js.map +1 -0
  70. package/dist/cli/serve-mode.js +615 -530
  71. package/dist/cli/serve-mode.js.map +1 -0
  72. package/dist/cli/services/agent-config.d.ts +29 -0
  73. package/dist/cli/services/agent-config.js +91 -0
  74. package/dist/cli/services/agent-config.js.map +1 -0
  75. package/dist/cli/services/agent-definitions.d.ts +4 -1
  76. package/dist/cli/services/agent-definitions.js +97 -56
  77. package/dist/cli/services/agent-definitions.js.map +1 -0
  78. package/dist/cli/services/agent-events.js +225 -162
  79. package/dist/cli/services/agent-events.js.map +1 -0
  80. package/dist/cli/services/agent-loop.js +978 -669
  81. package/dist/cli/services/agent-loop.js.map +1 -0
  82. package/dist/cli/services/agent-worker-base.d.ts +35 -5
  83. package/dist/cli/services/agent-worker-base.js +337 -153
  84. package/dist/cli/services/agent-worker-base.js.map +1 -0
  85. package/dist/cli/services/api-retry.js +69 -64
  86. package/dist/cli/services/api-retry.js.map +1 -0
  87. package/dist/cli/services/auth-service.d.ts +3 -3
  88. package/dist/cli/services/auth-service.js +209 -132
  89. package/dist/cli/services/auth-service.js.map +1 -0
  90. package/dist/cli/services/background-processes.js +343 -267
  91. package/dist/cli/services/background-processes.js.map +1 -0
  92. package/dist/cli/services/browser-auth.d.ts +2 -2
  93. package/dist/cli/services/browser-auth.js +159 -118
  94. package/dist/cli/services/browser-auth.js.map +1 -0
  95. package/dist/cli/services/claude-md-loader.js +40 -36
  96. package/dist/cli/services/claude-md-loader.js.map +1 -0
  97. package/dist/cli/services/config-store.d.ts +9 -4
  98. package/dist/cli/services/config-store.js +164 -117
  99. package/dist/cli/services/config-store.js.map +1 -0
  100. package/dist/cli/services/debug-log.d.ts +1 -1
  101. package/dist/cli/services/debug-log.js +34 -35
  102. package/dist/cli/services/debug-log.js.map +1 -0
  103. package/dist/cli/services/env-detect.d.ts +7 -0
  104. package/dist/cli/services/env-detect.js +9 -0
  105. package/dist/cli/services/env-detect.js.map +1 -0
  106. package/dist/cli/services/error-logger.d.ts +2 -3
  107. package/dist/cli/services/error-logger.js +189 -180
  108. package/dist/cli/services/error-logger.js.map +1 -0
  109. package/dist/cli/services/file-history.d.ts +1 -1
  110. package/dist/cli/services/file-history.js +50 -54
  111. package/dist/cli/services/file-history.js.map +1 -0
  112. package/dist/cli/services/format-server-response.js +332 -372
  113. package/dist/cli/services/format-server-response.js.map +1 -0
  114. package/dist/cli/services/git-context.js +61 -45
  115. package/dist/cli/services/git-context.js.map +1 -0
  116. package/dist/cli/services/hooks.d.ts +2 -2
  117. package/dist/cli/services/hooks.js +195 -180
  118. package/dist/cli/services/hooks.js.map +1 -0
  119. package/dist/cli/services/ink-incremental.d.ts +19 -0
  120. package/dist/cli/services/ink-incremental.js +59 -0
  121. package/dist/cli/services/ink-incremental.js.map +1 -0
  122. package/dist/cli/services/ink-resize-fix.js +54 -44
  123. package/dist/cli/services/ink-resize-fix.js.map +1 -0
  124. package/dist/cli/services/ink-sync-output.d.ts +12 -0
  125. package/dist/cli/services/ink-sync-output.js +16 -0
  126. package/dist/cli/services/ink-sync-output.js.map +1 -0
  127. package/dist/cli/services/interactive-tools.js +268 -212
  128. package/dist/cli/services/interactive-tools.js.map +1 -0
  129. package/dist/cli/services/keybinding-manager.d.ts +11 -1
  130. package/dist/cli/services/keybinding-manager.js +126 -63
  131. package/dist/cli/services/keybinding-manager.js.map +1 -0
  132. package/dist/cli/services/local-tools.d.ts +1 -1
  133. package/dist/cli/services/local-tools.js +939 -656
  134. package/dist/cli/services/local-tools.js.map +1 -0
  135. package/dist/cli/services/lsp-manager.js +757 -594
  136. package/dist/cli/services/lsp-manager.js.map +1 -0
  137. package/dist/cli/services/mcp-client.d.ts +1 -1
  138. package/dist/cli/services/mcp-client.js +173 -134
  139. package/dist/cli/services/mcp-client.js.map +1 -0
  140. package/dist/cli/services/memory-manager.js +53 -40
  141. package/dist/cli/services/memory-manager.js.map +1 -0
  142. package/dist/cli/services/model-manager.js +55 -40
  143. package/dist/cli/services/model-manager.js.map +1 -0
  144. package/dist/cli/services/model-router.js +115 -85
  145. package/dist/cli/services/model-router.js.map +1 -0
  146. package/dist/cli/services/paths.d.ts +30 -0
  147. package/dist/cli/services/paths.js +81 -0
  148. package/dist/cli/services/paths.js.map +1 -0
  149. package/dist/cli/services/permission-modes.js +32 -25
  150. package/dist/cli/services/permission-modes.js.map +1 -0
  151. package/dist/cli/services/rewind.js +182 -168
  152. package/dist/cli/services/rewind.js.map +1 -0
  153. package/dist/cli/services/ripgrep.js +115 -115
  154. package/dist/cli/services/ripgrep.js.map +1 -0
  155. package/dist/cli/services/sandbox.d.ts +1 -1
  156. package/dist/cli/services/sandbox.js +58 -37
  157. package/dist/cli/services/sandbox.js.map +1 -0
  158. package/dist/cli/services/server-tools.js +738 -565
  159. package/dist/cli/services/server-tools.js.map +1 -0
  160. package/dist/cli/services/session-persistence.js +69 -74
  161. package/dist/cli/services/session-persistence.js.map +1 -0
  162. package/dist/cli/services/subagent-worker.js +42 -27
  163. package/dist/cli/services/subagent-worker.js.map +1 -0
  164. package/dist/cli/services/subagent.d.ts +2 -0
  165. package/dist/cli/services/subagent.js +606 -430
  166. package/dist/cli/services/subagent.js.map +1 -0
  167. package/dist/cli/services/system-prompt.js +86 -78
  168. package/dist/cli/services/system-prompt.js.map +1 -0
  169. package/dist/cli/services/task-decomposer.d.ts +1 -1
  170. package/dist/cli/services/task-decomposer.js +172 -139
  171. package/dist/cli/services/task-decomposer.js.map +1 -0
  172. package/dist/cli/services/team-lead.d.ts +2 -2
  173. package/dist/cli/services/team-lead.js +727 -529
  174. package/dist/cli/services/team-lead.js.map +1 -0
  175. package/dist/cli/services/team-state.js +319 -319
  176. package/dist/cli/services/team-state.js.map +1 -0
  177. package/dist/cli/services/teammate.d.ts +8 -2
  178. package/dist/cli/services/teammate.js +862 -560
  179. package/dist/cli/services/teammate.js.map +1 -0
  180. package/dist/cli/services/telemetry.d.ts +6 -1
  181. package/dist/cli/services/telemetry.js +180 -157
  182. package/dist/cli/services/telemetry.js.map +1 -0
  183. package/dist/cli/services/tools/agent-tools.d.ts +3 -3
  184. package/dist/cli/services/tools/agent-tools.js +480 -322
  185. package/dist/cli/services/tools/agent-tools.js.map +1 -0
  186. package/dist/cli/services/tools/file-ops.js +563 -450
  187. package/dist/cli/services/tools/file-ops.js.map +1 -0
  188. package/dist/cli/services/tools/search-tools.js +231 -162
  189. package/dist/cli/services/tools/search-tools.js.map +1 -0
  190. package/dist/cli/services/tools/shell-exec.js +197 -151
  191. package/dist/cli/services/tools/shell-exec.js.map +1 -0
  192. package/dist/cli/services/tools/task-manager.js +206 -173
  193. package/dist/cli/services/tools/task-manager.js.map +1 -0
  194. package/dist/cli/services/tools/web-tools.js +388 -341
  195. package/dist/cli/services/tools/web-tools.js.map +1 -0
  196. package/dist/cli/setup/SetupApp.d.ts +2 -2
  197. package/dist/cli/setup/SetupApp.js +608 -160
  198. package/dist/cli/setup/SetupApp.js.map +1 -0
  199. package/dist/cli/shared/ErrorBoundary.d.ts +22 -0
  200. package/dist/cli/shared/ErrorBoundary.js +73 -0
  201. package/dist/cli/shared/ErrorBoundary.js.map +1 -0
  202. package/dist/cli/shared/MatrixIntro.js +66 -69
  203. package/dist/cli/shared/MatrixIntro.js.map +1 -0
  204. package/dist/cli/shared/SpinnerSlot.d.ts +14 -0
  205. package/dist/cli/shared/SpinnerSlot.js +63 -0
  206. package/dist/cli/shared/SpinnerSlot.js.map +1 -0
  207. package/dist/cli/shared/Theme.d.ts +1 -1
  208. package/dist/cli/shared/Theme.js +136 -92
  209. package/dist/cli/shared/Theme.js.map +1 -0
  210. package/dist/cli/shared/WhaleBanner.js +99 -11
  211. package/dist/cli/shared/WhaleBanner.js.map +1 -0
  212. package/dist/cli/shared/markdown.d.ts +3 -1
  213. package/dist/cli/shared/markdown.js +736 -674
  214. package/dist/cli/shared/markdown.js.map +1 -0
  215. package/dist/cli/shared/marked-terminal.d.js +2 -0
  216. package/dist/cli/shared/marked-terminal.d.js.map +1 -0
  217. package/dist/cli/shared/theme-manager.js +99 -90
  218. package/dist/cli/shared/theme-manager.js.map +1 -0
  219. package/dist/cli/shared/theme-presets.js +256 -254
  220. package/dist/cli/shared/theme-presets.js.map +1 -0
  221. package/dist/cli/status/StatusApp.js +235 -86
  222. package/dist/cli/status/StatusApp.js.map +1 -0
  223. package/dist/cli/stores/StoreApp.js +275 -65
  224. package/dist/cli/stores/StoreApp.js.map +1 -0
  225. package/dist/index.d.ts +2 -2
  226. package/dist/index.js +509 -396
  227. package/dist/index.js.map +1 -0
  228. package/dist/local-agent/connection.d.ts +2 -2
  229. package/dist/local-agent/connection.js +352 -293
  230. package/dist/local-agent/connection.js.map +1 -0
  231. package/dist/local-agent/discovery.js +259 -122
  232. package/dist/local-agent/discovery.js.map +1 -0
  233. package/dist/local-agent/executor.js +216 -193
  234. package/dist/local-agent/executor.js.map +1 -0
  235. package/dist/local-agent/index.d.ts +2 -2
  236. package/dist/local-agent/index.js +156 -156
  237. package/dist/local-agent/index.js.map +1 -0
  238. package/dist/node/adapters/base.js +18 -8
  239. package/dist/node/adapters/base.js.map +1 -0
  240. package/dist/node/adapters/discord.js +286 -275
  241. package/dist/node/adapters/discord.js.map +1 -0
  242. package/dist/node/adapters/email.js +189 -202
  243. package/dist/node/adapters/email.js.map +1 -0
  244. package/dist/node/adapters/imessage.js +145 -142
  245. package/dist/node/adapters/imessage.js.map +1 -0
  246. package/dist/node/adapters/slack.js +237 -236
  247. package/dist/node/adapters/slack.js.map +1 -0
  248. package/dist/node/adapters/sms.js +149 -151
  249. package/dist/node/adapters/sms.js.map +1 -0
  250. package/dist/node/adapters/telegram.js +88 -92
  251. package/dist/node/adapters/telegram.js.map +1 -0
  252. package/dist/node/adapters/webchat.js +160 -136
  253. package/dist/node/adapters/webchat.js.map +1 -0
  254. package/dist/node/adapters/whatsapp.js +212 -215
  255. package/dist/node/adapters/whatsapp.js.map +1 -0
  256. package/dist/node/cli.js +884 -653
  257. package/dist/node/cli.js.map +1 -0
  258. package/dist/node/config.js +20 -18
  259. package/dist/node/config.js.map +1 -0
  260. package/dist/node/gateway-client.js +191 -181
  261. package/dist/node/gateway-client.js.map +1 -0
  262. package/dist/node/portal/clipboard.js +161 -130
  263. package/dist/node/portal/clipboard.js.map +1 -0
  264. package/dist/node/portal/discovery.js +51 -45
  265. package/dist/node/portal/discovery.js.map +1 -0
  266. package/dist/node/portal/forward.js +64 -58
  267. package/dist/node/portal/forward.js.map +1 -0
  268. package/dist/node/portal/index.js +246 -221
  269. package/dist/node/portal/index.js.map +1 -0
  270. package/dist/node/portal/multiplexer.js +192 -182
  271. package/dist/node/portal/multiplexer.js.map +1 -0
  272. package/dist/node/portal/permissions.js +102 -70
  273. package/dist/node/portal/permissions.js.map +1 -0
  274. package/dist/node/portal/protocol.js +153 -116
  275. package/dist/node/portal/protocol.js.map +1 -0
  276. package/dist/node/portal/screen.js +80 -69
  277. package/dist/node/portal/screen.js.map +1 -0
  278. package/dist/node/portal/session.js +124 -117
  279. package/dist/node/portal/session.js.map +1 -0
  280. package/dist/node/portal/shell.js +140 -113
  281. package/dist/node/portal/shell.js.map +1 -0
  282. package/dist/node/portal/stream.js +77 -75
  283. package/dist/node/portal/stream.js.map +1 -0
  284. package/dist/node/portal/transfer.js +190 -167
  285. package/dist/node/portal/transfer.js.map +1 -0
  286. package/dist/node/portal/ui.js +124 -99
  287. package/dist/node/portal/ui.js.map +1 -0
  288. package/dist/node/remote-desktop/compile-helper.js +50 -45
  289. package/dist/node/remote-desktop/compile-helper.js.map +1 -0
  290. package/dist/node/remote-desktop/index.js +215 -187
  291. package/dist/node/remote-desktop/index.js.map +1 -0
  292. package/dist/node/remote-desktop/protocol.js +45 -29
  293. package/dist/node/remote-desktop/protocol.js.map +1 -0
  294. package/dist/node/runtime.js +493 -410
  295. package/dist/node/runtime.js.map +1 -0
  296. package/dist/server/handlers/__test-utils__/test-db.js +39 -89
  297. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -0
  298. package/dist/server/handlers/analytics.js +467 -261
  299. package/dist/server/handlers/analytics.js.map +1 -0
  300. package/dist/server/handlers/api-docs.d.ts +6 -0
  301. package/dist/server/handlers/api-docs.js +1613 -0
  302. package/dist/server/handlers/api-docs.js.map +1 -0
  303. package/dist/server/handlers/api-keys.js +295 -232
  304. package/dist/server/handlers/api-keys.js.map +1 -0
  305. package/dist/server/handlers/billing.js +330 -239
  306. package/dist/server/handlers/billing.js.map +1 -0
  307. package/dist/server/handlers/browser.js +468 -395
  308. package/dist/server/handlers/browser.js.map +1 -0
  309. package/dist/server/handlers/catalog.js +1377 -978
  310. package/dist/server/handlers/catalog.js.map +1 -0
  311. package/dist/server/handlers/clickhouse.js +157 -109
  312. package/dist/server/handlers/clickhouse.js.map +1 -0
  313. package/dist/server/handlers/comms.d.ts +0 -53
  314. package/dist/server/handlers/comms.js +1443 -970
  315. package/dist/server/handlers/comms.js.map +1 -0
  316. package/dist/server/handlers/creations.js +461 -394
  317. package/dist/server/handlers/creations.js.map +1 -0
  318. package/dist/server/handlers/crm.js +1082 -791
  319. package/dist/server/handlers/crm.js.map +1 -0
  320. package/dist/server/handlers/discovery.js +251 -232
  321. package/dist/server/handlers/discovery.js.map +1 -0
  322. package/dist/server/handlers/embeddings.js +241 -164
  323. package/dist/server/handlers/embeddings.js.map +1 -0
  324. package/dist/server/handlers/enrichment.js +887 -718
  325. package/dist/server/handlers/enrichment.js.map +1 -0
  326. package/dist/server/handlers/image-gen.js +467 -376
  327. package/dist/server/handlers/image-gen.js.map +1 -0
  328. package/dist/server/handlers/inventory.js +797 -424
  329. package/dist/server/handlers/inventory.js.map +1 -0
  330. package/dist/server/handlers/kali.js +272 -230
  331. package/dist/server/handlers/kali.js.map +1 -0
  332. package/dist/server/handlers/llm-providers.js +803 -580
  333. package/dist/server/handlers/llm-providers.js.map +1 -0
  334. package/dist/server/handlers/local-agent.js +133 -105
  335. package/dist/server/handlers/local-agent.js.map +1 -0
  336. package/dist/server/handlers/media.js +1179 -857
  337. package/dist/server/handlers/media.js.map +1 -0
  338. package/dist/server/handlers/meta-ads.js +2669 -2093
  339. package/dist/server/handlers/meta-ads.js.map +1 -0
  340. package/dist/server/handlers/nodes.js +1321 -913
  341. package/dist/server/handlers/nodes.js.map +1 -0
  342. package/dist/server/handlers/operations.js +183 -157
  343. package/dist/server/handlers/operations.js.map +1 -0
  344. package/dist/server/handlers/platform.js +346 -210
  345. package/dist/server/handlers/platform.js.map +1 -0
  346. package/dist/server/handlers/remove-bg.js +118 -86
  347. package/dist/server/handlers/remove-bg.js.map +1 -0
  348. package/dist/server/handlers/storefront.js +586 -446
  349. package/dist/server/handlers/storefront.js.map +1 -0
  350. package/dist/server/handlers/supply-chain.js +546 -326
  351. package/dist/server/handlers/supply-chain.js.map +1 -0
  352. package/dist/server/handlers/transcription.js +106 -97
  353. package/dist/server/handlers/transcription.js.map +1 -0
  354. package/dist/server/handlers/video-gen.js +593 -424
  355. package/dist/server/handlers/video-gen.js.map +1 -0
  356. package/dist/server/handlers/voice.js +1458 -1017
  357. package/dist/server/handlers/voice.js.map +1 -0
  358. package/dist/server/handlers/workflow-steps.js +2837 -2116
  359. package/dist/server/handlers/workflow-steps.js.map +1 -0
  360. package/dist/server/handlers/workflows.js +1630 -933
  361. package/dist/server/handlers/workflows.js.map +1 -0
  362. package/dist/server/index.js +3166 -2390
  363. package/dist/server/index.js.map +1 -0
  364. package/dist/server/lib/batch-client.js +471 -409
  365. package/dist/server/lib/batch-client.js.map +1 -0
  366. package/dist/server/lib/clickhouse-buffer.js +118 -104
  367. package/dist/server/lib/clickhouse-buffer.js.map +1 -0
  368. package/dist/server/lib/clickhouse-client.js +107 -107
  369. package/dist/server/lib/clickhouse-client.js.map +1 -0
  370. package/dist/server/lib/coa-renderer.js +1786 -356
  371. package/dist/server/lib/coa-renderer.js.map +1 -0
  372. package/dist/server/lib/code-worker-pool.js +227 -177
  373. package/dist/server/lib/code-worker-pool.js.map +1 -0
  374. package/dist/server/lib/code-worker.js +174 -164
  375. package/dist/server/lib/code-worker.js.map +1 -0
  376. package/dist/server/lib/compaction-service.d.ts +2 -12
  377. package/dist/server/lib/compaction-service.js +74 -184
  378. package/dist/server/lib/compaction-service.js.map +1 -0
  379. package/dist/server/lib/logger.js +36 -24
  380. package/dist/server/lib/logger.js.map +1 -0
  381. package/dist/server/lib/otel.js +101 -80
  382. package/dist/server/lib/otel.js.map +1 -0
  383. package/dist/server/lib/pdf-renderer.d.ts +1 -1
  384. package/dist/server/lib/pdf-renderer.js +954 -776
  385. package/dist/server/lib/pdf-renderer.js.map +1 -0
  386. package/dist/server/lib/prompt-sanitizer.js +188 -108
  387. package/dist/server/lib/prompt-sanitizer.js.map +1 -0
  388. package/dist/server/lib/provider-capabilities.js +136 -138
  389. package/dist/server/lib/provider-capabilities.js.map +1 -0
  390. package/dist/server/lib/provider-failover.js +190 -168
  391. package/dist/server/lib/provider-failover.js.map +1 -0
  392. package/dist/server/lib/rate-limiter.js +186 -117
  393. package/dist/server/lib/rate-limiter.js.map +1 -0
  394. package/dist/server/lib/react-pdf-layout.js +551 -382
  395. package/dist/server/lib/react-pdf-layout.js.map +1 -0
  396. package/dist/server/lib/server-agent-loop.d.ts +9 -0
  397. package/dist/server/lib/server-agent-loop.js +906 -624
  398. package/dist/server/lib/server-agent-loop.js.map +1 -0
  399. package/dist/server/lib/server-subagent.d.ts +2 -0
  400. package/dist/server/lib/server-subagent.js +260 -162
  401. package/dist/server/lib/server-subagent.js.map +1 -0
  402. package/dist/server/lib/session-checkpoint.js +105 -96
  403. package/dist/server/lib/session-checkpoint.js.map +1 -0
  404. package/dist/server/lib/ssrf-guard.js +193 -184
  405. package/dist/server/lib/ssrf-guard.js.map +1 -0
  406. package/dist/server/lib/supabase-client.js +94 -82
  407. package/dist/server/lib/supabase-client.js.map +1 -0
  408. package/dist/server/lib/template-resolver.js +154 -176
  409. package/dist/server/lib/template-resolver.js.map +1 -0
  410. package/dist/server/lib/utils.js +242 -133
  411. package/dist/server/lib/utils.js.map +1 -0
  412. package/dist/server/local-agent-gateway.d.ts +2 -2
  413. package/dist/server/local-agent-gateway.js +785 -627
  414. package/dist/server/local-agent-gateway.js.map +1 -0
  415. package/dist/server/providers/anthropic.js +254 -176
  416. package/dist/server/providers/anthropic.js.map +1 -0
  417. package/dist/server/providers/bedrock.js +221 -162
  418. package/dist/server/providers/bedrock.js.map +1 -0
  419. package/dist/server/providers/gemini.js +548 -418
  420. package/dist/server/providers/gemini.js.map +1 -0
  421. package/dist/server/providers/openai.js +571 -437
  422. package/dist/server/providers/openai.js.map +1 -0
  423. package/dist/server/providers/registry.js +23 -18
  424. package/dist/server/providers/registry.js.map +1 -0
  425. package/dist/server/providers/shared.js +123 -95
  426. package/dist/server/providers/shared.js.map +1 -0
  427. package/dist/server/providers/types.js +1 -11
  428. package/dist/server/providers/types.js.map +1 -0
  429. package/dist/server/proxy-handlers.js +209 -165
  430. package/dist/server/proxy-handlers.js.map +1 -0
  431. package/dist/server/tool-router.d.ts +13 -0
  432. package/dist/server/tool-router.js +960 -598
  433. package/dist/server/tool-router.js.map +1 -0
  434. package/dist/server/validation.js +248 -188
  435. package/dist/server/validation.js.map +1 -0
  436. package/dist/server/worker.js +202 -133
  437. package/dist/server/worker.js.map +1 -0
  438. package/dist/setup.d.ts +2 -2
  439. package/dist/setup.js +151 -147
  440. package/dist/setup.js.map +1 -0
  441. package/dist/shared/agent-core.d.ts +191 -24
  442. package/dist/shared/agent-core.js +971 -462
  443. package/dist/shared/agent-core.js.map +1 -0
  444. package/dist/shared/anthropic-types.js +1 -6
  445. package/dist/shared/anthropic-types.js.map +1 -0
  446. package/dist/shared/api-client.d.ts +17 -9
  447. package/dist/shared/api-client.js +419 -327
  448. package/dist/shared/api-client.js.map +1 -0
  449. package/dist/shared/compaction.d.ts +36 -0
  450. package/dist/shared/compaction.js +138 -0
  451. package/dist/shared/compaction.js.map +1 -0
  452. package/dist/shared/constants.js +67 -64
  453. package/dist/shared/constants.js.map +1 -0
  454. package/dist/shared/sse-parser.js +221 -219
  455. package/dist/shared/sse-parser.js.map +1 -0
  456. package/dist/shared/tool-dispatch.d.ts +4 -2
  457. package/dist/shared/tool-dispatch.js +226 -165
  458. package/dist/shared/tool-dispatch.js.map +1 -0
  459. package/dist/shared/types.js +1 -6
  460. package/dist/shared/types.js.map +1 -0
  461. package/dist/types/cli-highlight.d.js +2 -0
  462. package/dist/types/cli-highlight.d.js.map +1 -0
  463. package/dist/types/diff.d.js +2 -0
  464. package/dist/types/diff.d.js.map +1 -0
  465. package/dist/types/pdf-parse.d.js +2 -0
  466. package/dist/types/pdf-parse.d.js.map +1 -0
  467. package/dist/updater.d.ts +1 -1
  468. package/dist/updater.js +118 -92
  469. package/dist/updater.js.map +1 -0
  470. package/dist/webchat/widget.js +227 -380
  471. package/dist/webchat/widget.js.map +1 -0
  472. package/package.json +22 -10
  473. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  474. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  475. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  476. package/vendor/ink/build/apply-styles.js +175 -0
  477. package/vendor/ink/build/build-layout.js +77 -0
  478. package/vendor/ink/build/calculate-wrapped-text.js +53 -0
  479. package/vendor/ink/build/colorize.d.ts +3 -0
  480. package/vendor/ink/build/colorize.js +48 -0
  481. package/vendor/ink/build/colorize.js.map +1 -0
  482. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  483. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  484. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  485. package/vendor/ink/build/components/App.d.ts +18 -0
  486. package/vendor/ink/build/components/App.js +351 -0
  487. package/vendor/ink/build/components/App.js.map +1 -0
  488. package/vendor/ink/build/components/AppContext.d.ts +15 -0
  489. package/vendor/ink/build/components/AppContext.js +11 -0
  490. package/vendor/ink/build/components/AppContext.js.map +1 -0
  491. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  492. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  493. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  494. package/vendor/ink/build/components/Box.d.ts +117 -0
  495. package/vendor/ink/build/components/Box.js +34 -0
  496. package/vendor/ink/build/components/Box.js.map +1 -0
  497. package/vendor/ink/build/components/Color.js +62 -0
  498. package/vendor/ink/build/components/Cursor.d.ts +83 -0
  499. package/vendor/ink/build/components/Cursor.js +53 -0
  500. package/vendor/ink/build/components/Cursor.js.map +1 -0
  501. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  502. package/vendor/ink/build/components/CursorContext.js +8 -0
  503. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  504. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  505. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  506. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  507. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  508. package/vendor/ink/build/components/ErrorOverview.js +84 -0
  509. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  510. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  511. package/vendor/ink/build/components/FocusContext.js +17 -0
  512. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  513. package/vendor/ink/build/components/Newline.d.ts +13 -0
  514. package/vendor/ink/build/components/Newline.js +8 -0
  515. package/vendor/ink/build/components/Newline.js.map +1 -0
  516. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  517. package/vendor/ink/build/components/Spacer.js +11 -0
  518. package/vendor/ink/build/components/Spacer.js.map +1 -0
  519. package/vendor/ink/build/components/Static.d.ts +24 -0
  520. package/vendor/ink/build/components/Static.js +28 -0
  521. package/vendor/ink/build/components/Static.js.map +1 -0
  522. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  523. package/vendor/ink/build/components/StderrContext.js +13 -0
  524. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  525. package/vendor/ink/build/components/StdinContext.d.ts +22 -0
  526. package/vendor/ink/build/components/StdinContext.js +19 -0
  527. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  528. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  529. package/vendor/ink/build/components/StdoutContext.js +13 -0
  530. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  531. package/vendor/ink/build/components/Text.d.ts +55 -0
  532. package/vendor/ink/build/components/Text.js +50 -0
  533. package/vendor/ink/build/components/Text.js.map +1 -0
  534. package/vendor/ink/build/components/Transform.d.ts +16 -0
  535. package/vendor/ink/build/components/Transform.js +15 -0
  536. package/vendor/ink/build/components/Transform.js.map +1 -0
  537. package/vendor/ink/build/cursor-helpers.d.ts +38 -0
  538. package/vendor/ink/build/cursor-helpers.js +56 -0
  539. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  540. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  541. package/vendor/ink/build/devtools-window-polyfill.js +65 -0
  542. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  543. package/vendor/ink/build/devtools.d.ts +1 -0
  544. package/vendor/ink/build/devtools.js +11 -0
  545. package/vendor/ink/build/devtools.js.map +1 -0
  546. package/vendor/ink/build/dom.d.ts +56 -0
  547. package/vendor/ink/build/dom.js +124 -0
  548. package/vendor/ink/build/dom.js.map +1 -0
  549. package/vendor/ink/build/experimental/apply-style.js +140 -0
  550. package/vendor/ink/build/experimental/dom.js +123 -0
  551. package/vendor/ink/build/experimental/output.js +91 -0
  552. package/vendor/ink/build/experimental/reconciler.js +141 -0
  553. package/vendor/ink/build/experimental/renderer.js +81 -0
  554. package/vendor/ink/build/get-max-width.d.ts +3 -0
  555. package/vendor/ink/build/get-max-width.js +10 -0
  556. package/vendor/ink/build/get-max-width.js.map +1 -0
  557. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  558. package/vendor/ink/build/hooks/use-app.js +8 -0
  559. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  560. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  561. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  562. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  563. package/vendor/ink/build/hooks/use-focus-manager.d.ts +28 -0
  564. package/vendor/ink/build/hooks/use-focus-manager.js +17 -0
  565. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  566. package/vendor/ink/build/hooks/use-focus.d.ts +29 -0
  567. package/vendor/ink/build/hooks/use-focus.js +42 -0
  568. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  569. package/vendor/ink/build/hooks/use-input.d.ts +131 -0
  570. package/vendor/ink/build/hooks/use-input.js +124 -0
  571. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  572. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +5 -0
  573. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +11 -0
  574. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  575. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  576. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  577. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  578. package/vendor/ink/build/hooks/use-stdin.d.ts +5 -0
  579. package/vendor/ink/build/hooks/use-stdin.js +8 -0
  580. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  581. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  582. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  583. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  584. package/vendor/ink/build/hooks/useInput.js +38 -0
  585. package/vendor/ink/build/index.d.ts +34 -0
  586. package/vendor/ink/build/index.js +20 -0
  587. package/vendor/ink/build/index.js.map +1 -0
  588. package/vendor/ink/build/ink.d.ts +90 -0
  589. package/vendor/ink/build/ink.js +654 -0
  590. package/vendor/ink/build/ink.js.map +1 -0
  591. package/vendor/ink/build/input-parser.d.ts +7 -0
  592. package/vendor/ink/build/input-parser.js +154 -0
  593. package/vendor/ink/build/input-parser.js.map +1 -0
  594. package/vendor/ink/build/instance.js +205 -0
  595. package/vendor/ink/build/instances.d.ts +3 -0
  596. package/vendor/ink/build/instances.js +8 -0
  597. package/vendor/ink/build/instances.js.map +1 -0
  598. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  599. package/vendor/ink/build/kitty-keyboard.js +32 -0
  600. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  601. package/vendor/ink/build/layout.d.ts +7 -0
  602. package/vendor/ink/build/layout.js +33 -0
  603. package/vendor/ink/build/layout.js.map +1 -0
  604. package/vendor/ink/build/log-update.d.ts +19 -0
  605. package/vendor/ink/build/log-update.js +243 -0
  606. package/vendor/ink/build/log-update.js.map +1 -0
  607. package/vendor/ink/build/measure-element.d.ts +16 -0
  608. package/vendor/ink/build/measure-element.js +9 -0
  609. package/vendor/ink/build/measure-element.js.map +1 -0
  610. package/vendor/ink/build/measure-text.d.ts +6 -0
  611. package/vendor/ink/build/measure-text.js +21 -0
  612. package/vendor/ink/build/measure-text.js.map +1 -0
  613. package/vendor/ink/build/options.d.ts +52 -0
  614. package/vendor/ink/build/options.js +2 -0
  615. package/vendor/ink/build/options.js.map +1 -0
  616. package/vendor/ink/build/output.d.ts +35 -0
  617. package/vendor/ink/build/output.js +183 -0
  618. package/vendor/ink/build/output.js.map +1 -0
  619. package/vendor/ink/build/parse-keypress.d.ts +22 -0
  620. package/vendor/ink/build/parse-keypress.js +493 -0
  621. package/vendor/ink/build/parse-keypress.js.map +1 -0
  622. package/vendor/ink/build/reconciler.d.ts +4 -0
  623. package/vendor/ink/build/reconciler.js +274 -0
  624. package/vendor/ink/build/reconciler.js.map +1 -0
  625. package/vendor/ink/build/render-background.d.ts +4 -0
  626. package/vendor/ink/build/render-background.js +25 -0
  627. package/vendor/ink/build/render-background.js.map +1 -0
  628. package/vendor/ink/build/render-border.d.ts +4 -0
  629. package/vendor/ink/build/render-border.js +73 -0
  630. package/vendor/ink/build/render-border.js.map +1 -0
  631. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  632. package/vendor/ink/build/render-node-to-output.js +147 -0
  633. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  634. package/vendor/ink/build/render-to-string.d.ts +38 -0
  635. package/vendor/ink/build/render-to-string.js +115 -0
  636. package/vendor/ink/build/render-to-string.js.map +1 -0
  637. package/vendor/ink/build/render.d.ts +121 -0
  638. package/vendor/ink/build/render.js +55 -0
  639. package/vendor/ink/build/render.js.map +1 -0
  640. package/vendor/ink/build/renderer.d.ts +8 -0
  641. package/vendor/ink/build/renderer.js +55 -0
  642. package/vendor/ink/build/renderer.js.map +1 -0
  643. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  644. package/vendor/ink/build/sanitize-ansi.js +27 -0
  645. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  646. package/vendor/ink/build/screen-reader-update.d.ts +13 -0
  647. package/vendor/ink/build/screen-reader-update.js +38 -0
  648. package/vendor/ink/build/screen-reader-update.js.map +1 -0
  649. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  650. package/vendor/ink/build/squash-text-nodes.js +36 -0
  651. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  652. package/vendor/ink/build/styles.d.ts +240 -0
  653. package/vendor/ink/build/styles.js +232 -0
  654. package/vendor/ink/build/styles.js.map +1 -0
  655. package/vendor/ink/build/utils.d.ts +2 -0
  656. package/vendor/ink/build/utils.js +4 -0
  657. package/vendor/ink/build/utils.js.map +1 -0
  658. package/vendor/ink/build/wrap-text.d.ts +3 -0
  659. package/vendor/ink/build/wrap-text.js +31 -0
  660. package/vendor/ink/build/wrap-text.js.map +1 -0
  661. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  662. package/vendor/ink/build/write-synchronized.js +7 -0
  663. package/vendor/ink/build/write-synchronized.js.map +1 -0
  664. package/vendor/ink/license +10 -0
  665. package/vendor/ink/node_modules/@types/node/LICENSE +21 -0
  666. package/vendor/ink/node_modules/@types/node/README.md +15 -0
  667. package/vendor/ink/node_modules/@types/node/assert/strict.d.ts +105 -0
  668. package/vendor/ink/node_modules/@types/node/assert.d.ts +955 -0
  669. package/vendor/ink/node_modules/@types/node/async_hooks.d.ts +623 -0
  670. package/vendor/ink/node_modules/@types/node/buffer.buffer.d.ts +466 -0
  671. package/vendor/ink/node_modules/@types/node/buffer.d.ts +1810 -0
  672. package/vendor/ink/node_modules/@types/node/child_process.d.ts +1428 -0
  673. package/vendor/ink/node_modules/@types/node/cluster.d.ts +486 -0
  674. package/vendor/ink/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  675. package/vendor/ink/node_modules/@types/node/console.d.ts +151 -0
  676. package/vendor/ink/node_modules/@types/node/constants.d.ts +20 -0
  677. package/vendor/ink/node_modules/@types/node/crypto.d.ts +4065 -0
  678. package/vendor/ink/node_modules/@types/node/dgram.d.ts +564 -0
  679. package/vendor/ink/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  680. package/vendor/ink/node_modules/@types/node/dns/promises.d.ts +503 -0
  681. package/vendor/ink/node_modules/@types/node/dns.d.ts +922 -0
  682. package/vendor/ink/node_modules/@types/node/domain.d.ts +166 -0
  683. package/vendor/ink/node_modules/@types/node/events.d.ts +1054 -0
  684. package/vendor/ink/node_modules/@types/node/fs/promises.d.ts +1329 -0
  685. package/vendor/ink/node_modules/@types/node/fs.d.ts +4676 -0
  686. package/vendor/ink/node_modules/@types/node/globals.d.ts +150 -0
  687. package/vendor/ink/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  688. package/vendor/ink/node_modules/@types/node/http.d.ts +2167 -0
  689. package/vendor/ink/node_modules/@types/node/http2.d.ts +2480 -0
  690. package/vendor/ink/node_modules/@types/node/https.d.ts +405 -0
  691. package/vendor/ink/node_modules/@types/node/index.d.ts +115 -0
  692. package/vendor/ink/node_modules/@types/node/inspector/promises.d.ts +41 -0
  693. package/vendor/ink/node_modules/@types/node/inspector.d.ts +224 -0
  694. package/vendor/ink/node_modules/@types/node/inspector.generated.d.ts +4226 -0
  695. package/vendor/ink/node_modules/@types/node/module.d.ts +819 -0
  696. package/vendor/ink/node_modules/@types/node/net.d.ts +933 -0
  697. package/vendor/ink/node_modules/@types/node/os.d.ts +507 -0
  698. package/vendor/ink/node_modules/@types/node/package.json +155 -0
  699. package/vendor/ink/node_modules/@types/node/path/posix.d.ts +8 -0
  700. package/vendor/ink/node_modules/@types/node/path/win32.d.ts +8 -0
  701. package/vendor/ink/node_modules/@types/node/path.d.ts +187 -0
  702. package/vendor/ink/node_modules/@types/node/perf_hooks.d.ts +643 -0
  703. package/vendor/ink/node_modules/@types/node/process.d.ts +2156 -0
  704. package/vendor/ink/node_modules/@types/node/punycode.d.ts +117 -0
  705. package/vendor/ink/node_modules/@types/node/querystring.d.ts +152 -0
  706. package/vendor/ink/node_modules/@types/node/quic.d.ts +910 -0
  707. package/vendor/ink/node_modules/@types/node/readline/promises.d.ts +161 -0
  708. package/vendor/ink/node_modules/@types/node/readline.d.ts +541 -0
  709. package/vendor/ink/node_modules/@types/node/repl.d.ts +415 -0
  710. package/vendor/ink/node_modules/@types/node/sea.d.ts +162 -0
  711. package/vendor/ink/node_modules/@types/node/sqlite.d.ts +955 -0
  712. package/vendor/ink/node_modules/@types/node/stream/consumers.d.ts +38 -0
  713. package/vendor/ink/node_modules/@types/node/stream/promises.d.ts +211 -0
  714. package/vendor/ink/node_modules/@types/node/stream/web.d.ts +296 -0
  715. package/vendor/ink/node_modules/@types/node/stream.d.ts +1760 -0
  716. package/vendor/ink/node_modules/@types/node/string_decoder.d.ts +67 -0
  717. package/vendor/ink/node_modules/@types/node/test/reporters.d.ts +96 -0
  718. package/vendor/ink/node_modules/@types/node/test.d.ts +2240 -0
  719. package/vendor/ink/node_modules/@types/node/timers/promises.d.ts +108 -0
  720. package/vendor/ink/node_modules/@types/node/timers.d.ts +159 -0
  721. package/vendor/ink/node_modules/@types/node/tls.d.ts +1198 -0
  722. package/vendor/ink/node_modules/@types/node/trace_events.d.ts +197 -0
  723. package/vendor/ink/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
  724. package/vendor/ink/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  725. package/vendor/ink/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  726. package/vendor/ink/node_modules/@types/node/ts5.6/index.d.ts +117 -0
  727. package/vendor/ink/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  728. package/vendor/ink/node_modules/@types/node/ts5.7/index.d.ts +117 -0
  729. package/vendor/ink/node_modules/@types/node/tty.d.ts +250 -0
  730. package/vendor/ink/node_modules/@types/node/url.d.ts +519 -0
  731. package/vendor/ink/node_modules/@types/node/util/types.d.ts +558 -0
  732. package/vendor/ink/node_modules/@types/node/util.d.ts +1662 -0
  733. package/vendor/ink/node_modules/@types/node/v8.d.ts +983 -0
  734. package/vendor/ink/node_modules/@types/node/vm.d.ts +1208 -0
  735. package/vendor/ink/node_modules/@types/node/wasi.d.ts +202 -0
  736. package/vendor/ink/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  737. package/vendor/ink/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  738. package/vendor/ink/node_modules/@types/node/web-globals/console.d.ts +9 -0
  739. package/vendor/ink/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  740. package/vendor/ink/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  741. package/vendor/ink/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  742. package/vendor/ink/node_modules/@types/node/web-globals/events.d.ts +106 -0
  743. package/vendor/ink/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  744. package/vendor/ink/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  745. package/vendor/ink/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  746. package/vendor/ink/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  747. package/vendor/ink/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  748. package/vendor/ink/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  749. package/vendor/ink/node_modules/@types/node/web-globals/streams.d.ts +115 -0
  750. package/vendor/ink/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  751. package/vendor/ink/node_modules/@types/node/web-globals/url.d.ts +24 -0
  752. package/vendor/ink/node_modules/@types/node/worker_threads.d.ts +717 -0
  753. package/vendor/ink/node_modules/@types/node/zlib.d.ts +618 -0
  754. package/vendor/ink/node_modules/node-pty/LICENSE +69 -0
  755. package/vendor/ink/node_modules/node-pty/README.md +164 -0
  756. package/vendor/ink/node_modules/node-pty/binding.gyp +150 -0
  757. package/vendor/ink/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  758. package/vendor/ink/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  759. package/vendor/ink/node_modules/node-pty/lib/index.js +52 -0
  760. package/vendor/ink/node_modules/node-pty/lib/interfaces.js +7 -0
  761. package/vendor/ink/node_modules/node-pty/lib/shared/conout.js +11 -0
  762. package/vendor/ink/node_modules/node-pty/lib/terminal.js +190 -0
  763. package/vendor/ink/node_modules/node-pty/lib/types.js +7 -0
  764. package/vendor/ink/node_modules/node-pty/lib/unixTerminal.js +349 -0
  765. package/vendor/ink/node_modules/node-pty/lib/utils.js +39 -0
  766. package/vendor/ink/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
  767. package/vendor/ink/node_modules/node-pty/lib/windowsPtyAgent.js +287 -0
  768. package/vendor/ink/node_modules/node-pty/lib/windowsTerminal.js +201 -0
  769. package/vendor/ink/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  770. package/vendor/ink/node_modules/node-pty/package.json +65 -0
  771. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  772. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  773. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  774. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  775. package/vendor/ink/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  776. package/vendor/ink/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  777. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  778. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  779. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  780. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
  781. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  782. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
  783. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  784. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  785. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  786. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
  787. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  788. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
  789. package/vendor/ink/node_modules/node-pty/scripts/post-install.js +76 -0
  790. package/vendor/ink/node_modules/node-pty/scripts/prebuild.js +34 -0
  791. package/vendor/ink/node_modules/node-pty/src/unix/pty.cc +875 -0
  792. package/vendor/ink/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
  793. package/vendor/ink/node_modules/node-pty/src/win/conpty.cc +582 -0
  794. package/vendor/ink/node_modules/node-pty/src/win/conpty.h +41 -0
  795. package/vendor/ink/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
  796. package/vendor/ink/node_modules/node-pty/src/win/path_util.cc +95 -0
  797. package/vendor/ink/node_modules/node-pty/src/win/path_util.h +26 -0
  798. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
  799. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
  800. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
  801. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
  802. package/vendor/ink/node_modules/node-pty/typings/node-pty.d.ts +215 -0
  803. package/vendor/ink/node_modules/undici-types/LICENSE +21 -0
  804. package/vendor/ink/node_modules/undici-types/README.md +6 -0
  805. package/vendor/ink/node_modules/undici-types/agent.d.ts +32 -0
  806. package/vendor/ink/node_modules/undici-types/api.d.ts +43 -0
  807. package/vendor/ink/node_modules/undici-types/balanced-pool.d.ts +30 -0
  808. package/vendor/ink/node_modules/undici-types/cache-interceptor.d.ts +173 -0
  809. package/vendor/ink/node_modules/undici-types/cache.d.ts +36 -0
  810. package/vendor/ink/node_modules/undici-types/client-stats.d.ts +15 -0
  811. package/vendor/ink/node_modules/undici-types/client.d.ts +108 -0
  812. package/vendor/ink/node_modules/undici-types/connector.d.ts +34 -0
  813. package/vendor/ink/node_modules/undici-types/content-type.d.ts +21 -0
  814. package/vendor/ink/node_modules/undici-types/cookies.d.ts +30 -0
  815. package/vendor/ink/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  816. package/vendor/ink/node_modules/undici-types/dispatcher.d.ts +276 -0
  817. package/vendor/ink/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  818. package/vendor/ink/node_modules/undici-types/errors.d.ts +161 -0
  819. package/vendor/ink/node_modules/undici-types/eventsource.d.ts +66 -0
  820. package/vendor/ink/node_modules/undici-types/fetch.d.ts +211 -0
  821. package/vendor/ink/node_modules/undici-types/formdata.d.ts +108 -0
  822. package/vendor/ink/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  823. package/vendor/ink/node_modules/undici-types/global-origin.d.ts +7 -0
  824. package/vendor/ink/node_modules/undici-types/h2c-client.d.ts +73 -0
  825. package/vendor/ink/node_modules/undici-types/handlers.d.ts +15 -0
  826. package/vendor/ink/node_modules/undici-types/header.d.ts +160 -0
  827. package/vendor/ink/node_modules/undici-types/index.d.ts +88 -0
  828. package/vendor/ink/node_modules/undici-types/interceptors.d.ts +73 -0
  829. package/vendor/ink/node_modules/undici-types/mock-agent.d.ts +68 -0
  830. package/vendor/ink/node_modules/undici-types/mock-call-history.d.ts +111 -0
  831. package/vendor/ink/node_modules/undici-types/mock-client.d.ts +27 -0
  832. package/vendor/ink/node_modules/undici-types/mock-errors.d.ts +12 -0
  833. package/vendor/ink/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  834. package/vendor/ink/node_modules/undici-types/mock-pool.d.ts +27 -0
  835. package/vendor/ink/node_modules/undici-types/package.json +55 -0
  836. package/vendor/ink/node_modules/undici-types/patch.d.ts +29 -0
  837. package/vendor/ink/node_modules/undici-types/pool-stats.d.ts +19 -0
  838. package/vendor/ink/node_modules/undici-types/pool.d.ts +41 -0
  839. package/vendor/ink/node_modules/undici-types/proxy-agent.d.ts +29 -0
  840. package/vendor/ink/node_modules/undici-types/readable.d.ts +68 -0
  841. package/vendor/ink/node_modules/undici-types/retry-agent.d.ts +8 -0
  842. package/vendor/ink/node_modules/undici-types/retry-handler.d.ts +125 -0
  843. package/vendor/ink/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  844. package/vendor/ink/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  845. package/vendor/ink/node_modules/undici-types/util.d.ts +18 -0
  846. package/vendor/ink/node_modules/undici-types/utility.d.ts +7 -0
  847. package/vendor/ink/node_modules/undici-types/webidl.d.ts +341 -0
  848. package/vendor/ink/node_modules/undici-types/websocket.d.ts +186 -0
  849. package/vendor/ink/package.json +201 -0
  850. package/vendor/ink/readme.md +2636 -0
  851. package/bin/swag-agent.js +0 -9
  852. package/dist/server/lib/pg-rate-limiter.d.ts +0 -21
  853. package/dist/server/lib/pg-rate-limiter.js +0 -86
@@ -7,37 +7,65 @@
7
7
  * - Can message other teammates directly
8
8
  * - Full tool access (not restricted like subagents)
9
9
  */
10
- import { Worker, parentPort, workerData, isMainThread } from "worker_threads";
10
+
11
+ import { fork } from "child_process";
11
12
  import { fileURLToPath } from "url";
12
- import { loadTeam, claimTask, completeTask, failTask, getAvailableTasks, sendMessage, getUnreadMessages, markMessagesRead, updateTeammate, } from "./team-state.js";
13
- import { LoopDetector, estimateCostUsd } from "../../shared/agent-core.js";
13
+ import { loadTeam, claimTask, completeTask, failTask, getAvailableTasks, sendMessage, getUnreadMessages, markMessagesRead, updateTeammate } from "./team-state.js";
14
+ import { LoopDetector, estimateCostUsd, AGENT_DEFAULTS, resolveAgentLoopConfig } from "../../shared/agent-core.js";
15
+ import { preCompact } from "../../shared/compaction.js";
16
+ import { loadCLIAgentConfig } from "./agent-config.js";
14
17
  import { MODEL_MAP } from "../../shared/constants.js";
15
- import { LOCAL_TOOL_DEFINITIONS, } from "./local-tools.js";
16
- import { loadServerToolDefinitions, } from "./server-tools.js";
18
+ import { LOCAL_TOOL_DEFINITIONS } from "./local-tools.js";
19
+ import { loadServerToolDefinitions } from "./server-tools.js";
17
20
  import { getValidToken } from "./auth-service.js";
18
- import { logSpan, generateSpanId, generateTraceId, getConversationId, initializeTelemetryClient } from "./telemetry.js";
19
- import { callAgentAPI, executeToolBlocks, extractTextBlocks, extractToolUseBlocks, } from "./agent-worker-base.js";
21
+ import { logSpan, generateSpanId, generateTraceId, getConversationId, initializeTelemetryClient, flushCliSpans, PKG_VERSION } from "./telemetry.js";
22
+ import { callAgentAPI, executeToolBlocks, extractTextBlocks, extractToolUseBlocks, deduplicateTools, assertUniqueToolNames } from "./agent-worker-base.js";
23
+
24
+ // ============================================================================
25
+ // TYPES
26
+ // ============================================================================
27
+
20
28
  // ============================================================================
21
29
  // CONSTANTS
22
30
  // ============================================================================
23
- const MAX_TURNS_PER_TASK = 12; // More turns than subagent since tasks are larger
24
- const MAX_OUTPUT_TOKENS = 16384;
25
- const MAX_TEAMMATE_TURNS = 50; // Outer loop safety: max task claim cycles
26
- const MAX_TEAMMATE_DURATION_MS = 10 * 60 * 1000; // 10 minute hard timeout
27
- const API_TIMEOUT_MS = 90_000; // 90s timeout on proxy/API fetch calls
28
- const TOOL_TIMEOUT_MS = 60_000; // 60s timeout on individual tool execution
31
+
32
+ // Teammate constants — ALL from DB via AGENT_DEFAULTS, nothing hardcoded
33
+ let TEAMMATE_MAX_TURNS_PER_TASK = AGENT_DEFAULTS.subagentMaxTurns; // DB overridable
34
+ let TEAMMATE_MAX_OUTPUT_TOKENS = AGENT_DEFAULTS.subagentMaxTokens; // DB overridable
35
+ let TEAMMATE_MAX_TOTAL_TURNS = AGENT_DEFAULTS.teammateMaxTotalTurns;
36
+ let TEAMMATE_MAX_DURATION_MS = AGENT_DEFAULTS.maxDurationMs;
37
+ let API_TIMEOUT_MS = AGENT_DEFAULTS.apiTimeoutMs; // DB overridable
38
+ let TOOL_TIMEOUT_MS = AGENT_DEFAULTS.toolTimeoutMs; // DB overridable
39
+
40
+ // Cached resolved config for LoopDetector creation
41
+ let resolvedTeammateConfig = null;
42
+
43
+ // Lazy init from DB — called once per teammate spawn. ALL knobs from DB, nothing hardcoded.
44
+ async function resolveTeammateConfig() {
45
+ const dbAgent = await loadCLIAgentConfig();
46
+ if (!dbAgent?.context_config) return;
47
+ const cc = dbAgent.context_config;
48
+ TEAMMATE_MAX_TURNS_PER_TASK = cc.subagent_max_turns ?? TEAMMATE_MAX_TURNS_PER_TASK;
49
+ TEAMMATE_MAX_OUTPUT_TOKENS = cc.subagent_max_tokens ?? TEAMMATE_MAX_OUTPUT_TOKENS;
50
+ TEAMMATE_MAX_DURATION_MS = cc.max_duration_ms ?? TEAMMATE_MAX_DURATION_MS;
51
+ TEAMMATE_MAX_TOTAL_TURNS = cc.teammate_max_total_turns ?? TEAMMATE_MAX_TOTAL_TURNS;
52
+ API_TIMEOUT_MS = cc.api_timeout_ms ?? API_TIMEOUT_MS;
53
+ TOOL_TIMEOUT_MS = cc.tool_timeout_ms ?? TOOL_TIMEOUT_MS;
54
+ // Cache resolved config for LoopDetector
55
+ resolvedTeammateConfig = resolveAgentLoopConfig(dbAgent, "sse");
56
+ }
57
+
29
58
  // ============================================================================
30
59
  // TEAMMATE SYSTEM PROMPT
31
60
  // ============================================================================
61
+
32
62
  function buildTeammatePrompt(teammateName, team, currentTask, cwd) {
33
- const taskList = team.tasks.map(t => {
34
- const status = t.status === "in_progress" && t.assignedTo
35
- ? `in_progress (${team.teammates.find(tm => tm.id === t.assignedTo)?.name || "unknown"})`
36
- : t.status;
37
- return `- [${status}] ${t.description}${t.id === currentTask?.id ? " (YOUR TASK)" : ""}`;
38
- }).join("\n");
39
- const teammates = team.teammates.map(t => `- ${t.name} (${t.id}): ${t.status}${t.currentTask ? ` - working on task` : ""}`).join("\n");
40
- return `You are ${teammateName}, a teammate in the "${team.name}" team.
63
+ const taskList = team.tasks.map(t => {
64
+ const status = t.status === "in_progress" && t.assignedTo ? `in_progress (${team.teammates.find(tm => tm.id === t.assignedTo)?.name || "unknown"})` : t.status;
65
+ return `- [${status}] ${t.description}${t.id === currentTask?.id ? " (YOUR TASK)" : ""}`;
66
+ }).join("\n");
67
+ const teammates = team.teammates.map(t => `- ${t.name} (${t.id}): ${t.status}${t.currentTask ? ` - working on task` : ""}`).join("\n");
68
+ return `You are ${teammateName}, a teammate in the "${team.name}" team.
41
69
 
42
70
  ## Working Directory
43
71
  ${cwd}
@@ -71,13 +99,18 @@ You can delegate sub-tasks to specialized subagents using the 'task' tool:
71
99
  - Use model="haiku" for simple lookups (cheapest/fastest)
72
100
  - This lets you work on multiple things in parallel while staying focused on your main task
73
101
 
102
+ ## CRITICAL: Task Completion Protocol
103
+ You MUST call team_complete_task when your work is done. This is NOT optional.
104
+ - Your task is NOT considered complete until you call team_complete_task
105
+ - Include a structured summary: what files were changed, what was done, any issues found
106
+ - If you cannot complete the task, still call team_complete_task with what you accomplished and what remains
107
+
74
108
  ## Guidelines
75
- 1. Focus on YOUR assigned task - don't work on others' tasks
76
- 2. Communicate blockers or discoveries that affect other tasks
77
- 3. When done, use team_complete_task with a clear summary
78
- 4. Check messages periodically for updates from teammates
79
- 5. Avoid modifying files assigned to other teammates' tasks
80
- 6. Delegate research or exploration to subagents when your task requires checking multiple areas
109
+ 1. Focus on YOUR assigned task don't work on others' tasks
110
+ 2. Communicate blockers or discoveries that affect other tasks via team_message
111
+ 3. Check messages periodically for updates from teammates
112
+ 4. Avoid modifying files assigned to other teammates' tasks
113
+ 5. Delegate research or exploration to subagents when your task requires checking multiple areas
81
114
 
82
115
  ## Self-Monitoring
83
116
  If a tool fails, use audit_trail (action="errors") to check patterns before retrying.
@@ -87,603 +120,872 @@ If a tool fails repeatedly, try a different approach instead of retrying the sam
87
120
  ## Output
88
121
  Be concise. Report progress and results clearly. Use tools to do the work.`;
89
122
  }
123
+
90
124
  // ============================================================================
91
125
  // TEAM-SPECIFIC TOOLS
92
126
  // ============================================================================
93
- const TEAM_TOOLS = [
94
- {
95
- name: "team_message",
96
- description: "Send a message to a specific teammate or the team lead",
97
- input_schema: {
98
- type: "object",
99
- properties: {
100
- to: {
101
- type: "string",
102
- description: "Teammate ID or 'lead' for team lead",
103
- },
104
- message: {
105
- type: "string",
106
- description: "Message content",
107
- },
108
- },
109
- required: ["to", "message"],
110
- },
111
- },
112
- {
113
- name: "team_broadcast",
114
- description: "Send a message to all teammates",
115
- input_schema: {
116
- type: "object",
117
- properties: {
118
- message: {
119
- type: "string",
120
- description: "Message to broadcast",
121
- },
122
- },
123
- required: ["message"],
124
- },
127
+
128
+ const TEAM_TOOLS = [{
129
+ name: "team_message",
130
+ description: "Send a message to a specific teammate or the team lead",
131
+ input_schema: {
132
+ type: "object",
133
+ properties: {
134
+ to: {
135
+ type: "string",
136
+ description: "Teammate ID or 'lead' for team lead"
137
+ },
138
+ message: {
139
+ type: "string",
140
+ description: "Message content"
141
+ }
125
142
  },
126
- {
127
- name: "team_claim_task",
128
- description: "Claim an available task to work on",
129
- input_schema: {
130
- type: "object",
131
- properties: {
132
- task_id: {
133
- type: "string",
134
- description: "ID of the task to claim",
135
- },
136
- },
137
- required: ["task_id"],
138
- },
143
+ required: ["to", "message"]
144
+ }
145
+ }, {
146
+ name: "team_broadcast",
147
+ description: "Send a message to all teammates",
148
+ input_schema: {
149
+ type: "object",
150
+ properties: {
151
+ message: {
152
+ type: "string",
153
+ description: "Message to broadcast"
154
+ }
139
155
  },
140
- {
141
- name: "team_complete_task",
142
- description: "Mark your current task as complete",
143
- input_schema: {
144
- type: "object",
145
- properties: {
146
- result: {
147
- type: "string",
148
- description: "Summary of what was accomplished",
149
- },
150
- },
151
- required: ["result"],
152
- },
156
+ required: ["message"]
157
+ }
158
+ }, {
159
+ name: "team_claim_task",
160
+ description: "Claim an available task to work on",
161
+ input_schema: {
162
+ type: "object",
163
+ properties: {
164
+ task_id: {
165
+ type: "string",
166
+ description: "ID of the task to claim"
167
+ }
153
168
  },
154
- {
155
- name: "team_check_messages",
156
- description: "Check for unread messages from teammates",
157
- input_schema: {
158
- type: "object",
159
- properties: {},
160
- },
169
+ required: ["task_id"]
170
+ }
171
+ }, {
172
+ name: "team_complete_task",
173
+ description: "REQUIRED: Mark your current task as complete. You MUST call this tool when done — your task is not considered complete without it. Include a summary of files changed and work done.",
174
+ input_schema: {
175
+ type: "object",
176
+ properties: {
177
+ result: {
178
+ type: "string",
179
+ description: "Summary of what was accomplished"
180
+ }
161
181
  },
162
- ];
182
+ required: ["result"]
183
+ }
184
+ }, {
185
+ name: "team_check_messages",
186
+ description: "Check for unread messages from teammates",
187
+ input_schema: {
188
+ type: "object",
189
+ properties: {}
190
+ }
191
+ }];
192
+
163
193
  // ============================================================================
164
194
  // TOOL EXECUTION
165
195
  // ============================================================================
196
+
166
197
  async function executeTeamTool(toolName, input, teamId, teammateId, currentTaskId) {
167
- switch (toolName) {
168
- case "team_message": {
169
- const to = input.to;
170
- const message = input.message;
171
- const result = await sendMessage(teamId, teammateId, to, message);
172
- return result
173
- ? { success: true, output: `Message sent to ${to}` }
174
- : { success: false, output: "Failed to send message" };
175
- }
176
- case "team_broadcast": {
177
- const message = input.message;
178
- const result = await sendMessage(teamId, teammateId, "all", message);
179
- return result
180
- ? { success: true, output: "Message broadcast to all teammates" }
181
- : { success: false, output: "Failed to broadcast message" };
182
- }
183
- case "team_claim_task": {
184
- const taskId = input.task_id;
185
- const task = await claimTask(teamId, taskId, teammateId);
186
- return task
187
- ? { success: true, output: `Claimed task: ${task.description}` }
188
- : { success: false, output: "Failed to claim task (may be unavailable or have unmet dependencies)" };
189
- }
190
- case "team_complete_task": {
191
- if (!currentTaskId) {
192
- return { success: false, output: "No task currently assigned" };
193
- }
194
- const result = input.result;
195
- const success = await completeTask(teamId, currentTaskId, result);
196
- return success
197
- ? { success: true, output: `Task completed: ${result}` }
198
- : { success: false, output: "Failed to complete task" };
198
+ switch (toolName) {
199
+ case "team_message":
200
+ {
201
+ const to = input.to;
202
+ const message = input.message;
203
+ const result = await sendMessage(teamId, teammateId, to, message);
204
+ return result ? {
205
+ success: true,
206
+ output: `Message sent to ${to}`
207
+ } : {
208
+ success: false,
209
+ output: "Failed to send message"
210
+ };
211
+ }
212
+ case "team_broadcast":
213
+ {
214
+ const message = input.message;
215
+ const result = await sendMessage(teamId, teammateId, "all", message);
216
+ return result ? {
217
+ success: true,
218
+ output: "Message broadcast to all teammates"
219
+ } : {
220
+ success: false,
221
+ output: "Failed to broadcast message"
222
+ };
223
+ }
224
+ case "team_claim_task":
225
+ {
226
+ const taskId = input.task_id;
227
+ const task = await claimTask(teamId, taskId, teammateId);
228
+ return task ? {
229
+ success: true,
230
+ output: `Claimed task: ${task.description}`
231
+ } : {
232
+ success: false,
233
+ output: "Failed to claim task (may be unavailable or have unmet dependencies)"
234
+ };
235
+ }
236
+ case "team_complete_task":
237
+ {
238
+ if (!currentTaskId) {
239
+ return {
240
+ success: false,
241
+ output: "No task currently assigned"
242
+ };
199
243
  }
200
- case "team_check_messages": {
201
- const messages = await getUnreadMessages(teamId, teammateId);
202
- if (messages.length === 0) {
203
- return { success: true, output: "No unread messages" };
204
- }
205
- const msgList = messages.map(m => `From ${m.from}: ${m.content}`).join("\n");
206
- await markMessagesRead(teamId, messages.map(m => m.id));
207
- return { success: true, output: `${messages.length} messages:\n${msgList}` };
244
+ const result = input.result;
245
+ const success = await completeTask(teamId, currentTaskId, result);
246
+ return success ? {
247
+ success: true,
248
+ output: `Task completed: ${result}`
249
+ } : {
250
+ success: false,
251
+ output: "Failed to complete task"
252
+ };
253
+ }
254
+ case "team_check_messages":
255
+ {
256
+ const messages = await getUnreadMessages(teamId, teammateId);
257
+ if (messages.length === 0) {
258
+ return {
259
+ success: true,
260
+ output: "No unread messages"
261
+ };
208
262
  }
209
- default:
210
- return { success: false, output: `Unknown team tool: ${toolName}` };
211
- }
263
+ const msgList = messages.map(m => `From ${m.from}: ${m.content}`).join("\n");
264
+ await markMessagesRead(teamId, messages.map(m => m.id));
265
+ return {
266
+ success: true,
267
+ output: `${messages.length} messages:\n${msgList}`
268
+ };
269
+ }
270
+ default:
271
+ return {
272
+ success: false,
273
+ output: `Unknown team tool: ${toolName}`
274
+ };
275
+ }
212
276
  }
277
+
213
278
  // ============================================================================
214
279
  // API CLIENT — uses shared callAgentAPI from agent-worker-base
215
280
  // ============================================================================
216
- async function callAPI(modelId, systemPrompt, messages, tools, thinkingEnabled = false) {
217
- return callAgentAPI({
218
- modelId,
219
- contextProfile: "teammate",
220
- systemPrompt,
221
- messages,
222
- tools,
223
- thinkingEnabled,
224
- maxOutputTokens: MAX_OUTPUT_TOKENS,
225
- timeoutMs: API_TIMEOUT_MS,
226
- });
281
+
282
+ async function callAPI(modelId, systemPrompt, messages, tools, thinkingEnabled = false, onHeartbeat) {
283
+ return callAgentAPI({
284
+ modelId,
285
+ contextProfile: "teammate",
286
+ systemPrompt,
287
+ messages,
288
+ tools,
289
+ thinkingEnabled,
290
+ maxOutputTokens: TEAMMATE_MAX_OUTPUT_TOKENS,
291
+ timeoutMs: API_TIMEOUT_MS,
292
+ onHeartbeat
293
+ });
227
294
  }
295
+
228
296
  // ============================================================================
229
297
  // TEAMMATE WORKER LOOP
230
298
  // ============================================================================
299
+
231
300
  async function runTeammateLoop(data) {
232
- const { teamId, teammateId, teammateName, model, cwd, parentConversationId, teamName, authToken } = data;
233
- const modelId = MODEL_MAP[model] || MODEL_MAP.opus; // Inherit parent default
234
- const startTime = Date.now();
235
- // Initialize telemetry client with auth token if provided
236
- if (authToken) {
237
- initializeTelemetryClient(authToken);
301
+ const {
302
+ teamId,
303
+ teammateId,
304
+ teammateName,
305
+ model,
306
+ cwd,
307
+ parentConversationId,
308
+ teamName,
309
+ authToken,
310
+ preloadedConfig,
311
+ preloadedServerTools
312
+ } = data;
313
+ const modelId = MODEL_MAP[model] || MODEL_MAP.opus; // Inherit parent default
314
+ const startTime = Date.now();
315
+
316
+ // Initialize telemetry client with auth token if provided (do first for early spans)
317
+ if (authToken) {
318
+ initializeTelemetryClient(authToken);
319
+ }
320
+
321
+ // Use pre-loaded config from parent if available (avoids redundant DB call per child).
322
+ // Falls back to direct DB load if parent didn't pre-load.
323
+ if (preloadedConfig?.context_config) {
324
+ const cc = preloadedConfig.context_config;
325
+ TEAMMATE_MAX_TURNS_PER_TASK = cc.subagent_max_turns ?? TEAMMATE_MAX_TURNS_PER_TASK;
326
+ TEAMMATE_MAX_OUTPUT_TOKENS = cc.subagent_max_tokens ?? TEAMMATE_MAX_OUTPUT_TOKENS;
327
+ TEAMMATE_MAX_DURATION_MS = cc.max_duration_ms ?? TEAMMATE_MAX_DURATION_MS;
328
+ TEAMMATE_MAX_TOTAL_TURNS = cc.teammate_max_total_turns ?? TEAMMATE_MAX_TOTAL_TURNS;
329
+ API_TIMEOUT_MS = cc.api_timeout_ms ?? API_TIMEOUT_MS;
330
+ TOOL_TIMEOUT_MS = cc.tool_timeout_ms ?? TOOL_TIMEOUT_MS;
331
+ resolvedTeammateConfig = resolveAgentLoopConfig(preloadedConfig, "sse");
332
+ } else {
333
+ await resolveTeammateConfig();
334
+ }
335
+
336
+ // Each teammate gets its own conversation_id (separate trace)
337
+ // but links to parent via parent_conversation_id
338
+ const teammateConversationId = getConversationId(); // Worker's own ID
339
+
340
+ // Create trace context for this teammate
341
+ const teammateTraceId = generateTraceId();
342
+ const teammateSpanId = generateSpanId();
343
+
344
+ // Log teammate start - links to parent for tree hierarchy
345
+ logSpan({
346
+ action: "team.teammate_start",
347
+ durationMs: 0,
348
+ context: {
349
+ traceId: teammateTraceId,
350
+ spanId: teammateSpanId,
351
+ conversationId: teammateConversationId,
352
+ source: "claude_code",
353
+ serviceName: "whale-cli",
354
+ serviceVersion: PKG_VERSION,
355
+ model: modelId
356
+ },
357
+ details: {
358
+ is_team: true,
359
+ is_teammate: true,
360
+ team_id: teamId,
361
+ teammate_id: teammateId,
362
+ teammate_name: teammateName,
363
+ team_name: teamName,
364
+ parent_conversation_id: parentConversationId,
365
+ // Link to parent trace
366
+ model: model,
367
+ display_name: teammateName,
368
+ display_icon: "person.fill",
369
+ display_color: "#3B82F6"
238
370
  }
239
- // Each teammate gets its own conversation_id (separate trace)
240
- // but links to parent via parent_conversation_id
241
- const teammateConversationId = getConversationId(); // Worker's own ID
242
- // Create trace context for this teammate
243
- const teammateTraceId = generateTraceId();
244
- const teammateSpanId = generateSpanId();
245
- // Log teammate start - links to parent for tree hierarchy
371
+ });
372
+ const report = msg => {
373
+ if (process.send) {
374
+ process.send(msg);
375
+ }
376
+ };
377
+
378
+ // Report early — let parent know we're alive before async init
379
+ report({
380
+ type: "progress",
381
+ teammateId,
382
+ content: `${teammateName} initializing...`
383
+ });
384
+
385
+ // Get all tools (local + server + team)
386
+ const localTools = LOCAL_TOOL_DEFINITIONS.map(t => ({
387
+ name: t.name,
388
+ description: t.description,
389
+ input_schema: t.input_schema
390
+ }));
391
+
392
+ // Use pre-loaded server tools from parent if available (avoids redundant API call per child)
393
+ let serverTools = preloadedServerTools || [];
394
+ if (!preloadedServerTools) {
395
+ try {
396
+ serverTools = await loadServerToolDefinitions();
397
+ } catch {/* server tools unavailable — continue with local tools only */}
398
+ }
399
+
400
+ // Deduplicate: local tools take priority, then server tools, then team tools
401
+ const allTools = deduplicateTools([...localTools, ...serverTools, ...TEAM_TOOLS]);
402
+ assertUniqueToolNames(allTools);
403
+ const loopDetector = resolvedTeammateConfig ? LoopDetector.fromResolved(resolvedTeammateConfig) : new LoopDetector();
404
+ let totalIn = 0;
405
+ let totalOut = 0;
406
+ let currentTaskId = null;
407
+ let currentTaskModelId = modelId; // Per-task model (defaults to team model)
408
+ let currentTaskThinking = false; // Per-task thinking toggle
409
+ let messages = [];
410
+ let tasksCompleted = 0;
411
+ report({
412
+ type: "progress",
413
+ teammateId,
414
+ content: `${teammateName} ready (${allTools.length} tools)`
415
+ });
416
+
417
+ // Helper to log teammate completion
418
+ const logTeammateComplete = reason => {
419
+ const teammateCost = estimateCostUsd(totalIn, totalOut, modelId);
246
420
  logSpan({
247
- action: "team.teammate_start",
248
- durationMs: 0,
249
- context: {
421
+ action: "team.teammate_done",
422
+ durationMs: Date.now() - startTime,
423
+ context: {
424
+ traceId: teammateTraceId,
425
+ spanId: generateSpanId(),
426
+ parentSpanId: teammateSpanId,
427
+ conversationId: teammateConversationId,
428
+ source: "claude_code",
429
+ serviceName: "whale-cli",
430
+ serviceVersion: PKG_VERSION,
431
+ model: modelId,
432
+ inputTokens: totalIn,
433
+ outputTokens: totalOut,
434
+ totalCost: teammateCost
435
+ },
436
+ details: {
437
+ is_team: true,
438
+ is_teammate: true,
439
+ team_id: teamId,
440
+ teammate_id: teammateId,
441
+ teammate_name: teammateName,
442
+ team_name: teamName,
443
+ parent_conversation_id: parentConversationId,
444
+ tasks_completed: tasksCompleted,
445
+ completion_reason: reason,
446
+ "gen_ai.request.model": modelId,
447
+ "gen_ai.usage.input_tokens": totalIn,
448
+ "gen_ai.usage.output_tokens": totalOut,
449
+ "gen_ai.usage.cost": teammateCost,
450
+ display_name: `${teammateName} done`,
451
+ display_icon: "checkmark.circle.fill",
452
+ display_color: "#10B981"
453
+ }
454
+ });
455
+ };
456
+
457
+ // Main work loop - keep working until no more tasks
458
+ let outerTurn = 0;
459
+ while (true) {
460
+ // Safety: max turns guard (0 = no limit, Claude Code parity)
461
+ if (TEAMMATE_MAX_TOTAL_TURNS > 0 && ++outerTurn > TEAMMATE_MAX_TOTAL_TURNS) {
462
+ logTeammateComplete("max_turns_reached");
463
+ report({
464
+ type: "done",
465
+ teammateId,
466
+ content: `${teammateName} reached max turns (${TEAMMATE_MAX_TOTAL_TURNS})`,
467
+ tokensUsed: {
468
+ input: totalIn,
469
+ output: totalOut
470
+ }
471
+ });
472
+ break;
473
+ }
474
+ // Safety: elapsed time guard
475
+ if (Date.now() - startTime > TEAMMATE_MAX_DURATION_MS) {
476
+ logTeammateComplete("timeout");
477
+ report({
478
+ type: "done",
479
+ teammateId,
480
+ content: `${teammateName} timed out after ${Math.round(TEAMMATE_MAX_DURATION_MS / 60_000)}min`,
481
+ tokensUsed: {
482
+ input: totalIn,
483
+ output: totalOut
484
+ }
485
+ });
486
+ break;
487
+ }
488
+ const team = loadTeam(teamId);
489
+ if (!team || team.status !== "active") {
490
+ logTeammateComplete("team_inactive");
491
+ report({
492
+ type: "done",
493
+ teammateId,
494
+ content: "Team completed or inactive",
495
+ tokensUsed: {
496
+ input: totalIn,
497
+ output: totalOut
498
+ }
499
+ });
500
+ break;
501
+ }
502
+
503
+ // Find current task or claim a new one
504
+ const currentTask = currentTaskId ? team.tasks.find(t => t.id === currentTaskId) : null;
505
+
506
+ // If no current task, try to claim one
507
+ if (!currentTask || currentTask.status === "completed") {
508
+ const available = getAvailableTasks(team);
509
+ if (available.length === 0) {
510
+ // No tasks available, check if all done or waiting
511
+ const inProgress = team.tasks.filter(t => t.status === "in_progress").length;
512
+ if (inProgress === 0) {
513
+ logTeammateComplete("all_tasks_done");
514
+ report({
515
+ type: "done",
516
+ teammateId,
517
+ content: "All tasks completed",
518
+ tokensUsed: {
519
+ input: totalIn,
520
+ output: totalOut
521
+ }
522
+ });
523
+ break;
524
+ }
525
+ // Wait and retry
526
+ await new Promise(r => setTimeout(r, 2000));
527
+ continue;
528
+ }
529
+
530
+ // Claim first available task
531
+ const claimed = await claimTask(teamId, available[0].id, teammateId);
532
+ if (!claimed) {
533
+ await new Promise(r => setTimeout(r, 1000));
534
+ continue;
535
+ }
536
+ currentTaskId = claimed.id;
537
+
538
+ // Resolve per-task model: task-level → team default
539
+ const taskModel = claimed.model || model;
540
+ currentTaskModelId = MODEL_MAP[taskModel] || MODEL_MAP[model] || MODEL_MAP.opus;
541
+
542
+ // Enable thinking for teammates — with 32K output tokens (matching Claude Code),
543
+ // adaptive thinking has room to reason without starving code output.
544
+ currentTaskThinking = true;
545
+ await updateTeammate(teamId, teammateId, {
546
+ status: "working",
547
+ currentTask: currentTaskId
548
+ });
549
+ report({
550
+ type: "task_started",
551
+ teammateId,
552
+ taskId: currentTaskId,
553
+ content: claimed.description
554
+ });
555
+
556
+ // Start fresh conversation for new task
557
+ messages = [{
558
+ role: "user",
559
+ content: `Your task: ${claimed.description}\n\nBegin working on this task. When finished, you MUST call team_complete_task with a summary of changes made. Do not stop without calling team_complete_task.`
560
+ }];
561
+ }
562
+
563
+ // Build system prompt with current state
564
+ const freshTeam = loadTeam(teamId);
565
+ const freshTask = freshTeam.tasks.find(t => t.id === currentTaskId) || null;
566
+ const systemPrompt = buildTeammatePrompt(teammateName, freshTeam, freshTask, cwd);
567
+
568
+ // Agent loop for current task
569
+ let apiError = null;
570
+ let lastTurn = 0;
571
+ // 0 = no limit (agent self-regulates via end_turn, Claude Code parity)
572
+ const taskTurnLimit = TEAMMATE_MAX_TURNS_PER_TASK === 0 ? Number.MAX_SAFE_INTEGER : TEAMMATE_MAX_TURNS_PER_TASK;
573
+ for (let turn = 0; turn < taskTurnLimit; turn++) {
574
+ lastTurn = turn;
575
+ const apiStart = Date.now();
576
+ let response;
577
+ try {
578
+ response = await callAPI(currentTaskModelId, systemPrompt, messages, allTools, currentTaskThinking, () => {
579
+ // Heartbeat during long API calls (thinking/streaming) — keeps parent stall detector alive.
580
+ // Without this, a 90s API call = 90s silence → parent kills worker at WORKER_STALL_MS.
581
+ report({
582
+ type: "progress",
583
+ teammateId,
584
+ content: "streaming..."
585
+ });
586
+ });
587
+ } catch (err) {
588
+ apiError = err.message || String(err);
589
+ report({
590
+ type: "progress",
591
+ teammateId,
592
+ content: `API error: ${apiError.slice(0, 80)}`
593
+ });
594
+ logSpan({
595
+ action: "claude_api_request",
596
+ durationMs: Date.now() - apiStart,
597
+ severity: "error",
598
+ error: apiError || undefined,
599
+ context: {
250
600
  traceId: teammateTraceId,
251
- spanId: teammateSpanId,
601
+ spanId: generateSpanId(),
602
+ parentSpanId: teammateSpanId,
252
603
  conversationId: teammateConversationId,
253
604
  source: "claude_code",
254
605
  serviceName: "whale-cli",
255
- serviceVersion: "2.1.0",
256
- model: modelId,
257
- },
258
- details: {
606
+ serviceVersion: PKG_VERSION,
607
+ model: currentTaskModelId
608
+ },
609
+ details: {
259
610
  is_team: true,
260
611
  is_teammate: true,
261
612
  team_id: teamId,
262
613
  teammate_id: teammateId,
263
614
  teammate_name: teammateName,
264
- team_name: teamName,
265
- parent_conversation_id: parentConversationId, // Link to parent trace
266
- model: model,
267
- display_name: teammateName,
268
- display_icon: "person.fill",
269
- display_color: "#3B82F6",
615
+ parent_conversation_id: parentConversationId,
616
+ turn_number: turn + 1,
617
+ task_id: currentTaskId
618
+ }
619
+ });
620
+ break; // Exit inner loop — force-complete handler below will deal with the task
621
+ }
622
+ const apiDuration = Date.now() - apiStart;
623
+ totalIn += response.usage.input_tokens;
624
+ totalOut += response.usage.output_tokens;
625
+
626
+ // Log Claude API request telemetry — include cache tokens for accurate cost
627
+ const turnCostUsd = estimateCostUsd(response.usage.input_tokens, response.usage.output_tokens, currentTaskModelId, 0,
628
+ // thinkingTokens (disabled for teammates)
629
+ response.usage.cache_read_tokens, response.usage.cache_creation_tokens);
630
+ logSpan({
631
+ action: "claude_api_request",
632
+ durationMs: apiDuration,
633
+ context: {
634
+ traceId: teammateTraceId,
635
+ spanId: generateSpanId(),
636
+ parentSpanId: teammateSpanId,
637
+ conversationId: teammateConversationId,
638
+ source: "claude_code",
639
+ serviceName: "whale-cli",
640
+ serviceVersion: PKG_VERSION,
641
+ model: currentTaskModelId,
642
+ inputTokens: response.usage.input_tokens,
643
+ outputTokens: response.usage.output_tokens,
644
+ cacheReadTokens: response.usage.cache_read_tokens,
645
+ cacheCreationTokens: response.usage.cache_creation_tokens,
646
+ totalCost: turnCostUsd
270
647
  },
271
- });
272
- const report = (msg) => {
273
- if (parentPort) {
274
- parentPort.postMessage(msg);
648
+ details: {
649
+ is_team: true,
650
+ is_teammate: true,
651
+ team_id: teamId,
652
+ teammate_id: teammateId,
653
+ teammate_name: teammateName,
654
+ parent_conversation_id: parentConversationId,
655
+ turn_number: turn + 1,
656
+ task_id: currentTaskId,
657
+ stop_reason: response.stop_reason,
658
+ "gen_ai.request.model": currentTaskModelId,
659
+ "gen_ai.usage.input_tokens": response.usage.input_tokens,
660
+ "gen_ai.usage.output_tokens": response.usage.output_tokens,
661
+ "gen_ai.usage.cache_read_tokens": response.usage.cache_read_tokens,
662
+ "gen_ai.usage.cache_creation_tokens": response.usage.cache_creation_tokens,
663
+ "gen_ai.usage.cost": turnCostUsd
275
664
  }
276
- };
277
- // Report early — let parent know we're alive before async init
278
- report({ type: "progress", teammateId, content: `${teammateName} initializing...` });
279
- // Get all tools (local + server + team)
280
- const localTools = LOCAL_TOOL_DEFINITIONS.map(t => ({
281
- name: t.name,
282
- description: t.description,
283
- input_schema: t.input_schema,
284
- }));
285
- let serverTools = [];
286
- try {
287
- serverTools = await loadServerToolDefinitions();
288
- }
289
- catch { /* server tools unavailable — continue with local tools only */ }
290
- // Deduplicate: local tools take priority over server tools with the same name
291
- const localNames = new Set(localTools.map(t => t.name));
292
- const uniqueServerTools = serverTools.filter(t => !localNames.has(t.name));
293
- const allTools = [...localTools, ...uniqueServerTools, ...TEAM_TOOLS];
294
- const loopDetector = new LoopDetector();
295
- let totalIn = 0;
296
- let totalOut = 0;
297
- let currentTaskId = null;
298
- let currentTaskModelId = modelId; // Per-task model (defaults to team model)
299
- let currentTaskThinking = false; // Per-task thinking toggle
300
- let messages = [];
301
- let tasksCompleted = 0;
302
- report({ type: "progress", teammateId, content: `${teammateName} ready (${allTools.length} tools)` });
303
- // Helper to log teammate completion
304
- const logTeammateComplete = (reason) => {
305
- const teammateCost = estimateCostUsd(totalIn, totalOut, modelId);
306
- logSpan({
307
- action: "team.teammate_done",
308
- durationMs: Date.now() - startTime,
309
- context: {
665
+ });
666
+ const textBlocks = extractTextBlocks(response.content);
667
+ const toolBlocks = extractToolUseBlocks(response.content);
668
+
669
+ // Report progress
670
+ if (textBlocks.length) {
671
+ report({
672
+ type: "progress",
673
+ teammateId,
674
+ taskId: currentTaskId || undefined,
675
+ content: textBlocks[0].text.slice(0, 200)
676
+ });
677
+ }
678
+
679
+ // Compaction handling API paused after generating context summary.
680
+ // Replace entire message history with the compaction block (per Anthropic docs).
681
+ if (response.stop_reason === "compaction") {
682
+ const compactionBlock = response.content.find(b => b.type === "compaction");
683
+ if (compactionBlock) {
684
+ report({
685
+ type: "progress",
686
+ teammateId,
687
+ taskId: currentTaskId || undefined,
688
+ content: "context compacted"
689
+ });
690
+ messages = [{
691
+ role: "assistant",
692
+ content: [{
693
+ type: "compaction",
694
+ content: compactionBlock.content
695
+ }]
696
+ }, {
697
+ role: "user",
698
+ content: [{
699
+ type: "text",
700
+ text: "Continue with your task."
701
+ }]
702
+ }];
703
+ turn--; // Don't count compaction as a turn
704
+ continue;
705
+ }
706
+ }
707
+
708
+ // No tools = done with this turn
709
+ if (toolBlocks.length === 0) break;
710
+
711
+ // Execute tools using shared executeToolBlocks with team-specific custom executor
712
+ let taskCompleted = false;
713
+ const {
714
+ toolResults
715
+ } = await executeToolBlocks({
716
+ toolBlocks,
717
+ loopDetector,
718
+ toolTimeoutMs: TOOL_TIMEOUT_MS,
719
+ customExecutor: async (toolName, input) => {
720
+ // Only handle team tools; return null to fall through to standard routing
721
+ if (!TEAM_TOOLS.some(t => t.name === toolName)) return null;
722
+ const result = await executeTeamTool(toolName, input, teamId, teammateId, currentTaskId);
723
+
724
+ // Check if task was completed
725
+ if (toolName === "team_complete_task" && result.success) {
726
+ taskCompleted = true;
727
+ tasksCompleted++;
728
+ report({
729
+ type: "task_completed",
730
+ teammateId,
731
+ taskId: currentTaskId || undefined,
732
+ content: result.output
733
+ });
734
+
735
+ // Log task completion to telemetry
736
+ logSpan({
737
+ action: "team.task_complete",
738
+ durationMs: 0,
739
+ context: {
310
740
  traceId: teammateTraceId,
311
741
  spanId: generateSpanId(),
312
742
  parentSpanId: teammateSpanId,
313
743
  conversationId: teammateConversationId,
314
744
  source: "claude_code",
315
745
  serviceName: "whale-cli",
316
- serviceVersion: "2.1.0",
317
- model: modelId,
318
- inputTokens: totalIn,
319
- outputTokens: totalOut,
320
- totalCost: teammateCost,
321
- },
322
- details: {
746
+ serviceVersion: PKG_VERSION
747
+ },
748
+ details: {
323
749
  is_team: true,
324
750
  is_teammate: true,
325
751
  team_id: teamId,
326
752
  teammate_id: teammateId,
327
753
  teammate_name: teammateName,
328
- team_name: teamName,
329
754
  parent_conversation_id: parentConversationId,
330
- tasks_completed: tasksCompleted,
331
- completion_reason: reason,
332
- "gen_ai.request.model": modelId,
333
- "gen_ai.usage.input_tokens": totalIn,
334
- "gen_ai.usage.output_tokens": totalOut,
335
- "gen_ai.usage.cost": teammateCost,
336
- display_name: `${teammateName} done`,
337
- display_icon: "checkmark.circle.fill",
338
- display_color: "#10B981",
339
- },
340
- });
341
- };
342
- // Main work loop - keep working until no more tasks
343
- let outerTurn = 0;
344
- while (true) {
345
- // Safety: max turns guard
346
- if (++outerTurn > MAX_TEAMMATE_TURNS) {
347
- logTeammateComplete("max_turns_reached");
348
- report({ type: "done", teammateId, content: `${teammateName} reached max turns (${MAX_TEAMMATE_TURNS})`, tokensUsed: { input: totalIn, output: totalOut } });
349
- break;
350
- }
351
- // Safety: elapsed time guard
352
- if (Date.now() - startTime > MAX_TEAMMATE_DURATION_MS) {
353
- logTeammateComplete("timeout");
354
- report({ type: "done", teammateId, content: `${teammateName} timed out after ${Math.round(MAX_TEAMMATE_DURATION_MS / 60_000)}min`, tokensUsed: { input: totalIn, output: totalOut } });
355
- break;
356
- }
357
- const team = loadTeam(teamId);
358
- if (!team || team.status !== "active") {
359
- logTeammateComplete("team_inactive");
360
- report({ type: "done", teammateId, content: "Team completed or inactive", tokensUsed: { input: totalIn, output: totalOut } });
361
- break;
362
- }
363
- // Find current task or claim a new one
364
- const currentTask = currentTaskId
365
- ? team.tasks.find(t => t.id === currentTaskId)
366
- : null;
367
- // If no current task, try to claim one
368
- if (!currentTask || currentTask.status === "completed") {
369
- const available = getAvailableTasks(team);
370
- if (available.length === 0) {
371
- // No tasks available, check if all done or waiting
372
- const inProgress = team.tasks.filter(t => t.status === "in_progress").length;
373
- if (inProgress === 0) {
374
- logTeammateComplete("all_tasks_done");
375
- report({ type: "done", teammateId, content: "All tasks completed", tokensUsed: { input: totalIn, output: totalOut } });
376
- break;
377
- }
378
- // Wait and retry
379
- await new Promise(r => setTimeout(r, 2000));
380
- continue;
381
- }
382
- // Claim first available task
383
- const claimed = await claimTask(teamId, available[0].id, teammateId);
384
- if (!claimed) {
385
- await new Promise(r => setTimeout(r, 1000));
386
- continue;
387
- }
388
- currentTaskId = claimed.id;
389
- // Resolve per-task model: task-level → team default
390
- const taskModel = claimed.model || model;
391
- currentTaskModelId = MODEL_MAP[taskModel] || MODEL_MAP[model] || MODEL_MAP.opus;
392
- // Disable thinking for teammates — with MAX_OUTPUT_TOKENS=16K, adaptive thinking
393
- // burns 8-12K tokens on reasoning per turn, leaving only 4-8K for actual code output.
394
- // This caused catastrophic token bloat (359K input tokens per task) and truncated responses.
395
- currentTaskThinking = false;
396
- await updateTeammate(teamId, teammateId, { status: "working", currentTask: currentTaskId });
397
- report({ type: "task_started", teammateId, taskId: currentTaskId, content: claimed.description });
398
- // Start fresh conversation for new task
399
- messages = [{
400
- role: "user",
401
- content: `Your task: ${claimed.description}\n\nBegin working on this task. Use the available tools to complete it, then use team_complete_task when done.`,
402
- }];
403
- }
404
- // Build system prompt with current state
405
- const freshTeam = loadTeam(teamId);
406
- const freshTask = freshTeam.tasks.find(t => t.id === currentTaskId) || null;
407
- const systemPrompt = buildTeammatePrompt(teammateName, freshTeam, freshTask, cwd);
408
- // Agent loop for current task
409
- let apiError = null;
410
- for (let turn = 0; turn < MAX_TURNS_PER_TASK; turn++) {
411
- const apiStart = Date.now();
412
- let response;
413
- try {
414
- response = await callAPI(currentTaskModelId, systemPrompt, messages, allTools, currentTaskThinking);
415
- }
416
- catch (err) {
417
- apiError = err.message || String(err);
418
- report({ type: "progress", teammateId, content: `API error: ${apiError.slice(0, 80)}` });
419
- logSpan({
420
- action: "claude_api_request",
421
- durationMs: Date.now() - apiStart,
422
- severity: "error",
423
- error: apiError || undefined,
424
- context: {
425
- traceId: teammateTraceId,
426
- spanId: generateSpanId(),
427
- parentSpanId: teammateSpanId,
428
- conversationId: teammateConversationId,
429
- source: "claude_code",
430
- serviceName: "whale-cli",
431
- serviceVersion: "2.1.0",
432
- model: currentTaskModelId,
433
- },
434
- details: {
435
- is_team: true,
436
- is_teammate: true,
437
- team_id: teamId,
438
- teammate_id: teammateId,
439
- teammate_name: teammateName,
440
- parent_conversation_id: parentConversationId,
441
- turn_number: turn + 1,
442
- task_id: currentTaskId,
443
- },
444
- });
445
- break; // Exit inner loop — force-complete handler below will deal with the task
446
- }
447
- const apiDuration = Date.now() - apiStart;
448
- totalIn += response.usage.input_tokens;
449
- totalOut += response.usage.output_tokens;
450
- // Log Claude API request telemetry
451
- const turnCostUsd = estimateCostUsd(response.usage.input_tokens, response.usage.output_tokens, currentTaskModelId);
452
- logSpan({
453
- action: "claude_api_request",
454
- durationMs: apiDuration,
455
- context: {
456
- traceId: teammateTraceId,
457
- spanId: generateSpanId(),
458
- parentSpanId: teammateSpanId,
459
- conversationId: teammateConversationId,
460
- source: "claude_code",
461
- serviceName: "whale-cli",
462
- serviceVersion: "2.1.0",
463
- model: currentTaskModelId,
464
- inputTokens: response.usage.input_tokens,
465
- outputTokens: response.usage.output_tokens,
466
- totalCost: turnCostUsd,
467
- },
468
- details: {
469
- is_team: true,
470
- is_teammate: true,
471
- team_id: teamId,
472
- teammate_id: teammateId,
473
- teammate_name: teammateName,
474
- parent_conversation_id: parentConversationId,
475
- turn_number: turn + 1,
476
- task_id: currentTaskId,
477
- stop_reason: response.stop_reason,
478
- "gen_ai.request.model": currentTaskModelId,
479
- "gen_ai.usage.input_tokens": response.usage.input_tokens,
480
- "gen_ai.usage.output_tokens": response.usage.output_tokens,
481
- "gen_ai.usage.cost": turnCostUsd,
482
- },
755
+ task_id: currentTaskId,
756
+ task_result: result.output.slice(0, 500),
757
+ display_name: "Task completed",
758
+ display_icon: "checkmark.square.fill",
759
+ display_color: "#10B981"
760
+ }
483
761
  });
484
- const textBlocks = extractTextBlocks(response.content);
485
- const toolBlocks = extractToolUseBlocks(response.content);
486
- // Report progress
487
- if (textBlocks.length) {
488
- report({ type: "progress", teammateId, taskId: currentTaskId || undefined, content: textBlocks[0].text.slice(0, 200) });
489
- }
490
- // No tools = done with this turn
491
- if (toolBlocks.length === 0)
492
- break;
493
- // Execute tools using shared executeToolBlocks with team-specific custom executor
494
- let taskCompleted = false;
495
- const { toolResults } = await executeToolBlocks({
496
- toolBlocks,
497
- loopDetector,
498
- toolTimeoutMs: TOOL_TIMEOUT_MS,
499
- customExecutor: async (toolName, input) => {
500
- // Only handle team tools; return null to fall through to standard routing
501
- if (!TEAM_TOOLS.some(t => t.name === toolName))
502
- return null;
503
- const result = await executeTeamTool(toolName, input, teamId, teammateId, currentTaskId);
504
- // Check if task was completed
505
- if (toolName === "team_complete_task" && result.success) {
506
- taskCompleted = true;
507
- tasksCompleted++;
508
- report({ type: "task_completed", teammateId, taskId: currentTaskId || undefined, content: result.output });
509
- // Log task completion to telemetry
510
- logSpan({
511
- action: "team.task_complete",
512
- durationMs: 0,
513
- context: {
514
- traceId: teammateTraceId,
515
- spanId: generateSpanId(),
516
- parentSpanId: teammateSpanId,
517
- conversationId: teammateConversationId,
518
- source: "claude_code",
519
- serviceName: "whale-cli",
520
- serviceVersion: "2.1.0",
521
- },
522
- details: {
523
- is_team: true,
524
- is_teammate: true,
525
- team_id: teamId,
526
- teammate_id: teammateId,
527
- teammate_name: teammateName,
528
- parent_conversation_id: parentConversationId,
529
- task_id: currentTaskId,
530
- task_result: result.output.slice(0, 500),
531
- display_name: "Task completed",
532
- display_icon: "checkmark.square.fill",
533
- display_color: "#10B981",
534
- },
535
- });
536
- }
537
- return result;
538
- },
539
- callbacks: {
540
- onToolEnd: (toolName, success, durationMs) => {
541
- // Determine tool category for telemetry
542
- const toolCategory = TEAM_TOOLS.some(t => t.name === toolName) ? "team" : "standard";
543
- logSpan({
544
- action: `tool.${toolName}`,
545
- durationMs,
546
- severity: success ? "info" : "error",
547
- context: {
548
- traceId: teammateTraceId,
549
- spanId: generateSpanId(),
550
- parentSpanId: teammateSpanId,
551
- conversationId: teammateConversationId,
552
- source: "claude_code",
553
- serviceName: "whale-cli",
554
- serviceVersion: "2.1.0",
555
- },
556
- error: success ? undefined : "(see tool result)",
557
- details: {
558
- is_team: true,
559
- is_teammate: true,
560
- team_id: teamId,
561
- teammate_id: teammateId,
562
- teammate_name: teammateName,
563
- parent_conversation_id: parentConversationId,
564
- tool_category: toolCategory,
565
- },
566
- });
567
- },
568
- },
762
+ }
763
+ return result;
764
+ },
765
+ callbacks: {
766
+ onToolEnd: (toolName, success, durationMs) => {
767
+ // Heartbeat: report tool activity to parent so stall detector knows we're alive.
768
+ // Without this, tool-only responses (no text blocks) never update lastMessageTime
769
+ // and the worker gets false-positive killed after WORKER_STALL_MS.
770
+ report({
771
+ type: "progress",
772
+ teammateId,
773
+ taskId: currentTaskId || undefined,
774
+ content: `${toolName} (${durationMs}ms)`
569
775
  });
570
- // Append to messages
571
- messages.push({ role: "assistant", content: response.content });
572
- messages.push({ role: "user", content: toolResults });
573
- // If task was completed, break out to get next task
574
- if (taskCompleted) {
575
- currentTaskId = null;
576
- await updateTeammate(teamId, teammateId, { status: "idle", currentTask: undefined });
577
- break;
578
- }
776
+
777
+ // Determine tool category for telemetry
778
+ const toolCategory = TEAM_TOOLS.some(t => t.name === toolName) ? "team" : "standard";
779
+ logSpan({
780
+ action: `tool.${toolName}`,
781
+ durationMs,
782
+ severity: success ? "info" : "error",
783
+ context: {
784
+ traceId: teammateTraceId,
785
+ spanId: generateSpanId(),
786
+ parentSpanId: teammateSpanId,
787
+ conversationId: teammateConversationId,
788
+ source: "claude_code",
789
+ serviceName: "whale-cli",
790
+ serviceVersion: PKG_VERSION
791
+ },
792
+ error: success ? undefined : "(see tool result)",
793
+ details: {
794
+ is_team: true,
795
+ is_teammate: true,
796
+ team_id: teamId,
797
+ teammate_id: teammateId,
798
+ teammate_name: teammateName,
799
+ parent_conversation_id: parentConversationId,
800
+ tool_category: toolCategory
801
+ }
802
+ });
803
+ }
579
804
  }
580
- // If inner loop ended without completing the task (exhausted turns, API error, or no-tool response)
581
- if (currentTaskId) {
582
- const team = loadTeam(teamId);
583
- const task = team?.tasks.find(t => t.id === currentTaskId);
584
- if (task && task.status === "in_progress") {
585
- if (apiError) {
586
- // API failed — mark task as failed, not completed
587
- await failTask(teamId, currentTaskId, apiError);
588
- // Report as progress (not error) — error type causes red flash in UI via handleTeammateFailure double-handling
589
- report({ type: "progress", teammateId, taskId: currentTaskId, content: `Task failed: ${apiError.slice(0, 80)}` });
590
- }
591
- else if (totalIn === 0 && totalOut === 0) {
592
- // Zero tokens used means no real work was done fail the task
593
- await failTask(teamId, currentTaskId, "No API response received (0 tokens)");
594
- report({ type: "progress", teammateId, taskId: currentTaskId, content: "Task failed: no API response" });
595
- }
596
- else {
597
- // Exhausted turns or model stopped — auto-complete with partial result
598
- const lastText = messages.length > 0 ? messages[messages.length - 1] : null;
599
- let partialResult = "Task auto-completed after reaching turn limit.";
600
- if (lastText && typeof lastText === "object" && "content" in lastText) {
601
- const content = lastText.content;
602
- if (typeof content === "string")
603
- partialResult = content.slice(0, 500);
604
- else if (Array.isArray(content)) {
605
- const txt = content.find((b) => b.type === "text");
606
- if (txt && "text" in txt)
607
- partialResult = txt.text.slice(0, 500);
608
- }
609
- }
610
- await completeTask(teamId, currentTaskId, partialResult);
611
- tasksCompleted++;
612
- report({ type: "task_completed", teammateId, taskId: currentTaskId, content: partialResult });
613
- }
805
+ });
806
+
807
+ // Append to messages
808
+ messages.push({
809
+ role: "assistant",
810
+ content: response.content
811
+ });
812
+ messages.push({
813
+ role: "user",
814
+ content: toolResults
815
+ });
816
+
817
+ // Pre-compact: trim large tool results and thinking blocks to prevent context bloat.
818
+ // Without this, teammate context grows unbounded (same issue as subagent pre-fix).
819
+ const maxToolResultChars = resolvedTeammateConfig?.maxToolResultChars ?? AGENT_DEFAULTS.maxToolResultChars;
820
+ const {
821
+ messages: compactedMessages
822
+ } = preCompact(messages, {
823
+ maxToolResultChars,
824
+ stripThinking: true
825
+ });
826
+ messages = compactedMessages;
827
+
828
+ // If task was completed, break out to get next task
829
+ if (taskCompleted) {
830
+ currentTaskId = null;
831
+ await updateTeammate(teamId, teammateId, {
832
+ status: "idle",
833
+ currentTask: undefined
834
+ });
835
+ break;
836
+ }
837
+ }
838
+
839
+ // If inner loop ended without the model calling team_complete_task (exhausted turns, API error, or model end_turn)
840
+ if (currentTaskId) {
841
+ const team = loadTeam(teamId);
842
+ const task = team?.tasks.find(t => t.id === currentTaskId);
843
+ if (task && task.status === "in_progress") {
844
+ if (apiError) {
845
+ // API failed — mark task as failed, not completed
846
+ await failTask(teamId, currentTaskId, apiError);
847
+ // Report as progress (not error) — error type causes red flash in UI via handleTeammateFailure double-handling
848
+ report({
849
+ type: "progress",
850
+ teammateId,
851
+ taskId: currentTaskId,
852
+ content: `Task failed: ${apiError.slice(0, 80)}`
853
+ });
854
+ } else if (totalIn === 0 && totalOut === 0) {
855
+ // Zero tokens used means no real work was done — fail the task
856
+ await failTask(teamId, currentTaskId, "No API response received (0 tokens)");
857
+ report({
858
+ type: "progress",
859
+ teammateId,
860
+ taskId: currentTaskId,
861
+ content: "Task failed: no API response"
862
+ });
863
+ } else {
864
+ // Model stopped (end_turn) or exhausted turns — auto-complete with result
865
+ const hitTurnLimit = lastTurn >= taskTurnLimit - 1;
866
+ const lastText = messages.length > 0 ? messages[messages.length - 1] : null;
867
+ let partialResult = hitTurnLimit ? `Task auto-completed after reaching turn limit (${taskTurnLimit} turns).` : "Task completed (model finished).";
868
+ if (lastText && typeof lastText === "object" && "content" in lastText) {
869
+ const content = lastText.content;
870
+ if (typeof content === "string") partialResult = content.slice(0, 500);else if (Array.isArray(content)) {
871
+ const txt = content.find(b => b.type === "text");
872
+ if (txt && "text" in txt) partialResult = txt.text.slice(0, 500);
614
873
  }
615
- currentTaskId = null;
616
- await updateTeammate(teamId, teammateId, { status: "idle", currentTask: undefined });
874
+ }
875
+ await completeTask(teamId, currentTaskId, partialResult);
876
+ tasksCompleted++;
877
+ report({
878
+ type: "task_completed",
879
+ teammateId,
880
+ taskId: currentTaskId,
881
+ content: partialResult
882
+ });
617
883
  }
884
+ }
885
+ currentTaskId = null;
886
+ await updateTeammate(teamId, teammateId, {
887
+ status: "idle",
888
+ currentTask: undefined
889
+ });
618
890
  }
619
- // Final update
620
- await updateTeammate(teamId, teammateId, {
621
- status: "done",
622
- currentTask: undefined,
623
- tokensUsed: { input: totalIn, output: totalOut },
624
- });
891
+ }
892
+
893
+ // Final update
894
+ await updateTeammate(teamId, teammateId, {
895
+ status: "done",
896
+ currentTask: undefined,
897
+ tokensUsed: {
898
+ input: totalIn,
899
+ output: totalOut
900
+ }
901
+ });
625
902
  }
903
+
626
904
  // ============================================================================
627
- // WORKER ENTRY POINT
905
+ // CHILD PROCESS ENTRY POINT
628
906
  // ============================================================================
629
- if (!isMainThread && parentPort) {
630
- const data = workerData;
631
- // Catch ALL errors including module-level and unhandled rejections
632
- process.on("uncaughtException", (err) => {
907
+
908
+ // Detect if we were forked as a child process (process.send exists when IPC channel is open)
909
+ if (process.send && process.argv.includes("--teammate-child")) {
910
+ // Wait for startup data from parent via IPC
911
+ process.on("message", msg => {
912
+ if (msg?.type === "__teammate_start") {
913
+ const data = msg.data;
914
+
915
+ // Catch ALL errors including module-level and unhandled rejections
916
+ process.on("uncaughtException", err => {
633
917
  try {
634
- parentPort.postMessage({
635
- type: "error",
636
- teammateId: data.teammateId,
637
- content: `Uncaught exception: ${err.message || String(err)}`,
638
- });
639
- }
640
- catch { /* last resort — nothing we can do */ }
918
+ process.send({
919
+ type: "error",
920
+ teammateId: data.teammateId,
921
+ content: `Uncaught exception: ${err.message || String(err)}`
922
+ });
923
+ } catch {/* last resort — nothing we can do */}
641
924
  process.exit(1);
642
- });
643
- process.on("unhandledRejection", (reason) => {
925
+ });
926
+ process.on("unhandledRejection", reason => {
644
927
  try {
645
- parentPort.postMessage({
646
- type: "error",
647
- teammateId: data.teammateId,
648
- content: `Unhandled rejection: ${reason instanceof Error ? reason.message : String(reason)}`,
649
- });
650
- }
651
- catch { /* last resort */ }
652
- });
653
- runTeammateLoop(data)
654
- .catch(err => {
655
- parentPort.postMessage({
928
+ process.send({
656
929
  type: "error",
657
930
  teammateId: data.teammateId,
658
- content: err.message || String(err),
931
+ content: `Unhandled rejection: ${reason instanceof Error ? reason.message : String(reason)}`
932
+ });
933
+ } catch {/* last resort */}
934
+ });
935
+ runTeammateLoop(data).catch(err => {
936
+ process.send({
937
+ type: "error",
938
+ teammateId: data.teammateId,
939
+ content: err.message || String(err)
659
940
  });
660
- })
661
- .finally(() => {
662
- // Force-exit the Worker thread — lingering async resources (HTTP connections,
663
- // Supabase clients, telemetry timers) prevent natural exit and cause the
664
- // team to hang forever waiting for worker.on("exit").
665
- setTimeout(() => process.exit(0), 100); // Brief delay for final messages to flush
666
- });
941
+ }).finally(() => {
942
+ // Flush telemetry spans before exiting
943
+ flushCliSpans();
944
+ // Brief delay for final IPC messages and telemetry to flush,
945
+ // then exit cleanly. With process isolation, OS reclaims all resources.
946
+ setTimeout(() => process.exit(0), 300);
947
+ });
948
+ }
949
+ });
667
950
  }
951
+
668
952
  // ============================================================================
669
953
  // SPAWN TEAMMATE (from main thread)
670
954
  // ============================================================================
671
- export async function spawnTeammate(teamId, teammateId, teammateName, model, cwd, parentConversationId, teamName) {
672
- const __filename = fileURLToPath(import.meta.url);
673
- const workerPath = __filename.replace(".js", ".js"); // Same file
674
- // Get auth token to pass to worker for telemetry
675
- const authToken = await getValidToken();
676
- const worker = new Worker(workerPath, {
677
- workerData: {
678
- teamId,
679
- teammateId,
680
- teammateName,
681
- model,
682
- cwd,
683
- parentConversationId,
684
- teamName,
685
- authToken: authToken || undefined,
686
- },
687
- });
688
- return worker;
955
+
956
+ export async function spawnTeammate(teamId, teammateId, teammateName, model, cwd, parentConversationId, teamName, preloadedConfig, preloadedServerTools) {
957
+ const __filename = fileURLToPath(import.meta.url);
958
+
959
+ // Get auth token to pass to child for telemetry
960
+ const authToken = await getValidToken();
961
+
962
+ // Fork a child process running this same file with --teammate-child flag
963
+ const child = fork(__filename, ["--teammate-child"], {
964
+ cwd,
965
+ stdio: ["pipe", "pipe", "pipe", "ipc"],
966
+ // Inherit parent's env so NODE_PATH, API keys etc. are available
967
+ env: {
968
+ ...process.env
969
+ }
970
+ });
971
+
972
+ // Send startup data via IPC (replaces workerData)
973
+ // Pre-loaded config and tools avoid each child making redundant DB/API calls
974
+ child.send({
975
+ type: "__teammate_start",
976
+ data: {
977
+ teamId,
978
+ teammateId,
979
+ teammateName,
980
+ model,
981
+ cwd,
982
+ parentConversationId,
983
+ teamName,
984
+ authToken: authToken || undefined,
985
+ preloadedConfig: preloadedConfig ?? undefined,
986
+ preloadedServerTools: preloadedServerTools ?? undefined
987
+ }
988
+ });
989
+ return child;
689
990
  }
991
+ //# sourceMappingURL=teammate.js.map