@calliopelabs/cli 2.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. package/README.md +45 -661
  2. package/dist/acp.d.ts +78 -0
  3. package/dist/acp.d.ts.map +1 -0
  4. package/dist/acp.js +572 -0
  5. package/dist/acp.js.map +1 -0
  6. package/dist/bin.d.ts +3 -7
  7. package/dist/bin.d.ts.map +1 -1
  8. package/dist/bin.js +56 -79
  9. package/dist/bin.js.map +1 -1
  10. package/dist/budget.d.ts +64 -0
  11. package/dist/budget.d.ts.map +1 -0
  12. package/dist/budget.js +157 -0
  13. package/dist/budget.js.map +1 -0
  14. package/dist/checkpoint.d.ts +63 -30
  15. package/dist/checkpoint.d.ts.map +1 -1
  16. package/dist/checkpoint.js +247 -160
  17. package/dist/checkpoint.js.map +1 -1
  18. package/dist/circuit-breaker/breaker.js.map +1 -1
  19. package/dist/config.d.ts +86 -81
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +236 -304
  22. package/dist/config.js.map +1 -1
  23. package/dist/cost.d.ts +114 -0
  24. package/dist/cost.d.ts.map +1 -0
  25. package/dist/cost.js +499 -0
  26. package/dist/cost.js.map +1 -0
  27. package/dist/diff.d.ts.map +1 -1
  28. package/dist/diff.js +11 -7
  29. package/dist/diff.js.map +1 -1
  30. package/dist/errors.js +3 -3
  31. package/dist/errors.js.map +1 -1
  32. package/dist/files.js.map +1 -1
  33. package/dist/fleet.d.ts +30 -0
  34. package/dist/fleet.d.ts.map +1 -0
  35. package/dist/fleet.js +86 -0
  36. package/dist/fleet.js.map +1 -0
  37. package/dist/fuzzy-search.d.ts.map +1 -1
  38. package/dist/fuzzy-search.js +2 -1
  39. package/dist/fuzzy-search.js.map +1 -1
  40. package/dist/git-status.js.map +1 -1
  41. package/dist/headless.d.ts +1 -2
  42. package/dist/headless.d.ts.map +1 -1
  43. package/dist/headless.js +166 -24
  44. package/dist/headless.js.map +1 -1
  45. package/dist/hud/api.d.ts +3 -18
  46. package/dist/hud/api.d.ts.map +1 -1
  47. package/dist/hud/api.js +9 -352
  48. package/dist/hud/api.js.map +1 -1
  49. package/dist/hud/palettes.d.ts.map +1 -1
  50. package/dist/hud/palettes.js +0 -180
  51. package/dist/hud/palettes.js.map +1 -1
  52. package/dist/hud/skins.d.ts.map +1 -1
  53. package/dist/hud/skins.js +0 -263
  54. package/dist/hud/skins.js.map +1 -1
  55. package/dist/hud/types.d.ts +2 -5
  56. package/dist/hud/types.d.ts.map +1 -1
  57. package/dist/index.d.ts +1 -4
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +1 -4
  60. package/dist/index.js.map +1 -1
  61. package/dist/iteration-ledger.d.ts.map +1 -1
  62. package/dist/iteration-ledger.js +3 -2
  63. package/dist/iteration-ledger.js.map +1 -1
  64. package/dist/local-model.d.ts +150 -0
  65. package/dist/local-model.d.ts.map +1 -0
  66. package/dist/local-model.js +408 -0
  67. package/dist/local-model.js.map +1 -0
  68. package/dist/mcp.d.ts.map +1 -1
  69. package/dist/mcp.js +5 -2
  70. package/dist/mcp.js.map +1 -1
  71. package/dist/memory.d.ts.map +1 -1
  72. package/dist/memory.js +6 -4
  73. package/dist/memory.js.map +1 -1
  74. package/dist/model-detection.js +2 -2
  75. package/dist/model-detection.js.map +1 -1
  76. package/dist/parallel-tools.js.map +1 -1
  77. package/dist/plugins.d.ts +32 -1
  78. package/dist/plugins.d.ts.map +1 -1
  79. package/dist/plugins.js +116 -5
  80. package/dist/plugins.js.map +1 -1
  81. package/dist/policy.d.ts +43 -0
  82. package/dist/policy.d.ts.map +1 -0
  83. package/dist/policy.js +139 -0
  84. package/dist/policy.js.map +1 -0
  85. package/dist/project-config.d.ts +1 -2
  86. package/dist/project-config.d.ts.map +1 -1
  87. package/dist/project-config.js +0 -3
  88. package/dist/project-config.js.map +1 -1
  89. package/dist/providers/bedrock.d.ts.map +1 -1
  90. package/dist/providers/bedrock.js +2 -5
  91. package/dist/providers/bedrock.js.map +1 -1
  92. package/dist/providers/compat.d.ts +21 -0
  93. package/dist/providers/compat.d.ts.map +1 -1
  94. package/dist/providers/compat.js +176 -6
  95. package/dist/providers/compat.js.map +1 -1
  96. package/dist/providers/google.js.map +1 -1
  97. package/dist/providers/index.d.ts +19 -4
  98. package/dist/providers/index.d.ts.map +1 -1
  99. package/dist/providers/index.js +61 -10
  100. package/dist/providers/index.js.map +1 -1
  101. package/dist/providers/ollama.d.ts +2 -2
  102. package/dist/providers/ollama.d.ts.map +1 -1
  103. package/dist/providers/ollama.js +26 -6
  104. package/dist/providers/ollama.js.map +1 -1
  105. package/dist/providers/openai.d.ts.map +1 -1
  106. package/dist/providers/openai.js +14 -10
  107. package/dist/providers/openai.js.map +1 -1
  108. package/dist/providers/types.d.ts +8 -0
  109. package/dist/providers/types.d.ts.map +1 -1
  110. package/dist/providers/types.js.map +1 -1
  111. package/dist/replay.d.ts +37 -0
  112. package/dist/replay.d.ts.map +1 -0
  113. package/dist/replay.js +168 -0
  114. package/dist/replay.js.map +1 -0
  115. package/dist/router.d.ts +133 -0
  116. package/dist/router.d.ts.map +1 -0
  117. package/dist/{model-router.js → router.js} +329 -3
  118. package/dist/router.js.map +1 -0
  119. package/dist/runlog.d.ts +185 -0
  120. package/dist/runlog.d.ts.map +1 -0
  121. package/dist/runlog.js +398 -0
  122. package/dist/runlog.js.map +1 -0
  123. package/dist/{sandbox.d.ts → sandbox/docker.d.ts} +1 -1
  124. package/dist/sandbox/docker.d.ts.map +1 -0
  125. package/dist/{sandbox.js → sandbox/docker.js} +1 -1
  126. package/dist/sandbox/docker.js.map +1 -0
  127. package/dist/sandbox/index.d.ts +36 -0
  128. package/dist/sandbox/index.d.ts.map +1 -0
  129. package/dist/sandbox/index.js +62 -0
  130. package/dist/sandbox/index.js.map +1 -0
  131. package/dist/{sandbox-native.d.ts → sandbox/native.d.ts} +1 -1
  132. package/dist/sandbox/native.d.ts.map +1 -0
  133. package/dist/{sandbox-native.js → sandbox/native.js} +1 -1
  134. package/dist/sandbox/native.js.map +1 -0
  135. package/dist/scope.js +1 -1
  136. package/dist/scope.js.map +1 -1
  137. package/dist/scuttlebot/config.js.map +1 -1
  138. package/dist/scuttlebot/irc-client.js.map +1 -1
  139. package/dist/setup.d.ts.map +1 -1
  140. package/dist/setup.js +22 -54
  141. package/dist/setup.js.map +1 -1
  142. package/dist/skills.d.ts +39 -0
  143. package/dist/skills.d.ts.map +1 -1
  144. package/dist/skills.js +90 -8
  145. package/dist/skills.js.map +1 -1
  146. package/dist/storage.d.ts.map +1 -1
  147. package/dist/storage.js +6 -3
  148. package/dist/storage.js.map +1 -1
  149. package/dist/streaming.d.ts +25 -0
  150. package/dist/streaming.d.ts.map +1 -1
  151. package/dist/streaming.js +59 -0
  152. package/dist/streaming.js.map +1 -1
  153. package/dist/styles.d.ts +6 -0
  154. package/dist/styles.d.ts.map +1 -1
  155. package/dist/styles.js +11 -0
  156. package/dist/styles.js.map +1 -1
  157. package/dist/summarization.js.map +1 -1
  158. package/dist/terminal-image.js +1 -1
  159. package/dist/terminal-image.js.map +1 -1
  160. package/dist/themes.d.ts +5 -4
  161. package/dist/themes.d.ts.map +1 -1
  162. package/dist/themes.js +35 -90
  163. package/dist/themes.js.map +1 -1
  164. package/dist/tools.d.ts +27 -3
  165. package/dist/tools.d.ts.map +1 -1
  166. package/dist/tools.js +128 -179
  167. package/dist/tools.js.map +1 -1
  168. package/dist/types.d.ts +4 -3
  169. package/dist/types.d.ts.map +1 -1
  170. package/dist/types.js +21 -40
  171. package/dist/types.js.map +1 -1
  172. package/dist/ui/agent.d.ts +3 -6
  173. package/dist/ui/agent.d.ts.map +1 -1
  174. package/dist/ui/agent.js +328 -38
  175. package/dist/ui/agent.js.map +1 -1
  176. package/dist/ui/animations.d.ts +37 -0
  177. package/dist/ui/animations.d.ts.map +1 -0
  178. package/dist/ui/animations.js +227 -0
  179. package/dist/ui/animations.js.map +1 -0
  180. package/dist/ui/chat-input-keys.d.ts +42 -0
  181. package/dist/ui/chat-input-keys.d.ts.map +1 -0
  182. package/dist/ui/chat-input-keys.js +360 -0
  183. package/dist/ui/chat-input-keys.js.map +1 -0
  184. package/dist/ui/chat-input.d.ts +2 -1
  185. package/dist/ui/chat-input.d.ts.map +1 -1
  186. package/dist/ui/chat-input.js +31 -350
  187. package/dist/ui/chat-input.js.map +1 -1
  188. package/dist/ui/commands.d.ts +14 -46
  189. package/dist/ui/commands.d.ts.map +1 -1
  190. package/dist/ui/commands.js +416 -2899
  191. package/dist/ui/commands.js.map +1 -1
  192. package/dist/ui/completions.d.ts +1 -0
  193. package/dist/ui/completions.d.ts.map +1 -1
  194. package/dist/ui/completions.js +36 -107
  195. package/dist/ui/completions.js.map +1 -1
  196. package/dist/ui/components.d.ts +14 -6
  197. package/dist/ui/components.d.ts.map +1 -1
  198. package/dist/ui/components.js +17 -226
  199. package/dist/ui/components.js.map +1 -1
  200. package/dist/ui/context.js +6 -6
  201. package/dist/ui/context.js.map +1 -1
  202. package/dist/ui/debug-log.d.ts +11 -0
  203. package/dist/ui/debug-log.d.ts.map +1 -0
  204. package/dist/ui/debug-log.js +21 -0
  205. package/dist/ui/debug-log.js.map +1 -0
  206. package/dist/ui/error-boundary.d.ts.map +1 -1
  207. package/dist/ui/error-boundary.js.map +1 -1
  208. package/dist/ui/frame.d.ts.map +1 -1
  209. package/dist/ui/frame.js +1 -3
  210. package/dist/ui/frame.js.map +1 -1
  211. package/dist/ui/index.d.ts +11 -3
  212. package/dist/ui/index.d.ts.map +1 -1
  213. package/dist/ui/index.js +45 -1076
  214. package/dist/ui/index.js.map +1 -1
  215. package/dist/ui/messages.d.ts +4 -7
  216. package/dist/ui/messages.d.ts.map +1 -1
  217. package/dist/ui/messages.js +15 -30
  218. package/dist/ui/messages.js.map +1 -1
  219. package/dist/ui/modals/index.d.ts +11 -0
  220. package/dist/ui/modals/index.d.ts.map +1 -0
  221. package/dist/ui/modals/index.js +10 -0
  222. package/dist/ui/modals/index.js.map +1 -0
  223. package/dist/ui/modals/prompts.d.ts +37 -0
  224. package/dist/ui/modals/prompts.d.ts.map +1 -0
  225. package/dist/ui/modals/prompts.js +124 -0
  226. package/dist/ui/modals/prompts.js.map +1 -0
  227. package/dist/ui/modals/selectors.d.ts +33 -0
  228. package/dist/ui/modals/selectors.d.ts.map +1 -0
  229. package/dist/ui/modals/selectors.js +111 -0
  230. package/dist/ui/modals/selectors.js.map +1 -0
  231. package/dist/ui/modals/setup.d.ts +17 -0
  232. package/dist/ui/modals/setup.d.ts.map +1 -0
  233. package/dist/ui/modals/setup.js +51 -0
  234. package/dist/ui/modals/setup.js.map +1 -0
  235. package/dist/ui/regions/input-region.d.ts +40 -0
  236. package/dist/ui/regions/input-region.d.ts.map +1 -0
  237. package/dist/ui/regions/input-region.js +116 -0
  238. package/dist/ui/regions/input-region.js.map +1 -0
  239. package/dist/ui/regions/modal-host.d.ts +41 -0
  240. package/dist/ui/regions/modal-host.d.ts.map +1 -0
  241. package/dist/ui/regions/modal-host.js +51 -0
  242. package/dist/ui/regions/modal-host.js.map +1 -0
  243. package/dist/ui/regions/render-probe.d.ts +22 -0
  244. package/dist/ui/regions/render-probe.d.ts.map +1 -0
  245. package/dist/ui/regions/render-probe.js +45 -0
  246. package/dist/ui/regions/render-probe.js.map +1 -0
  247. package/dist/ui/regions/static-scrollback.d.ts +39 -0
  248. package/dist/ui/regions/static-scrollback.d.ts.map +1 -0
  249. package/dist/ui/regions/static-scrollback.js +68 -0
  250. package/dist/ui/regions/static-scrollback.js.map +1 -0
  251. package/dist/ui/regions/status-region.d.ts +24 -0
  252. package/dist/ui/regions/status-region.d.ts.map +1 -0
  253. package/dist/ui/regions/status-region.js +17 -0
  254. package/dist/ui/regions/status-region.js.map +1 -0
  255. package/dist/ui/regions/transcript-region.d.ts +41 -0
  256. package/dist/ui/regions/transcript-region.d.ts.map +1 -0
  257. package/dist/ui/regions/transcript-region.js +52 -0
  258. package/dist/ui/regions/transcript-region.js.map +1 -0
  259. package/dist/ui/self-restart.d.ts +9 -0
  260. package/dist/ui/self-restart.d.ts.map +1 -0
  261. package/dist/ui/self-restart.js +24 -0
  262. package/dist/ui/self-restart.js.map +1 -0
  263. package/dist/ui/state/use-chat-controller.d.ts +23 -0
  264. package/dist/ui/state/use-chat-controller.d.ts.map +1 -0
  265. package/dist/ui/state/use-chat-controller.js +643 -0
  266. package/dist/ui/state/use-chat-controller.js.map +1 -0
  267. package/dist/ui/state/use-loop-state.d.ts +23 -0
  268. package/dist/ui/state/use-loop-state.d.ts.map +1 -0
  269. package/dist/ui/state/use-loop-state.js +39 -0
  270. package/dist/ui/state/use-loop-state.js.map +1 -0
  271. package/dist/ui/state/use-modal-state.d.ts +52 -0
  272. package/dist/ui/state/use-modal-state.d.ts.map +1 -0
  273. package/dist/ui/state/use-modal-state.js +44 -0
  274. package/dist/ui/state/use-modal-state.js.map +1 -0
  275. package/dist/ui/state/use-model-state.d.ts +29 -0
  276. package/dist/ui/state/use-model-state.d.ts.map +1 -0
  277. package/dist/ui/state/use-model-state.js +47 -0
  278. package/dist/ui/state/use-model-state.js.map +1 -0
  279. package/dist/ui/state/use-processing-state.d.ts +24 -0
  280. package/dist/ui/state/use-processing-state.d.ts.map +1 -0
  281. package/dist/ui/state/use-processing-state.js +46 -0
  282. package/dist/ui/state/use-processing-state.js.map +1 -0
  283. package/dist/ui/state/use-queue-state.d.ts +19 -0
  284. package/dist/ui/state/use-queue-state.d.ts.map +1 -0
  285. package/dist/ui/state/use-queue-state.js +30 -0
  286. package/dist/ui/state/use-queue-state.js.map +1 -0
  287. package/dist/ui/state/use-session-init.d.ts +22 -0
  288. package/dist/ui/state/use-session-init.d.ts.map +1 -0
  289. package/dist/ui/state/use-session-init.js +77 -0
  290. package/dist/ui/state/use-session-init.js.map +1 -0
  291. package/dist/ui/state/use-session-stats.d.ts +16 -0
  292. package/dist/ui/state/use-session-stats.d.ts.map +1 -0
  293. package/dist/ui/state/use-session-stats.js +18 -0
  294. package/dist/ui/state/use-session-stats.js.map +1 -0
  295. package/dist/ui/state/use-terminal-width.d.ts +8 -0
  296. package/dist/ui/state/use-terminal-width.d.ts.map +1 -0
  297. package/dist/ui/state/use-terminal-width.js +22 -0
  298. package/dist/ui/state/use-terminal-width.js.map +1 -0
  299. package/dist/ui/state/use-transcript-state.d.ts +21 -0
  300. package/dist/ui/state/use-transcript-state.d.ts.map +1 -0
  301. package/dist/ui/state/use-transcript-state.js +49 -0
  302. package/dist/ui/state/use-transcript-state.js.map +1 -0
  303. package/dist/ui/status-bar.d.ts.map +1 -1
  304. package/dist/ui/status-bar.js +2 -3
  305. package/dist/ui/status-bar.js.map +1 -1
  306. package/dist/version-check.d.ts.map +1 -1
  307. package/dist/version-check.js +10 -0
  308. package/dist/version-check.js.map +1 -1
  309. package/package.json +10 -3
  310. package/dist/agents/agent-config-loader.d.ts +0 -60
  311. package/dist/agents/agent-config-loader.d.ts.map +0 -1
  312. package/dist/agents/agent-config-loader.js +0 -402
  313. package/dist/agents/agent-config-loader.js.map +0 -1
  314. package/dist/agents/agent-config-presets.d.ts +0 -10
  315. package/dist/agents/agent-config-presets.d.ts.map +0 -1
  316. package/dist/agents/agent-config-presets.js +0 -940
  317. package/dist/agents/agent-config-presets.js.map +0 -1
  318. package/dist/agents/agent-config-types.d.ts +0 -145
  319. package/dist/agents/agent-config-types.d.ts.map +0 -1
  320. package/dist/agents/agent-config-types.js +0 -12
  321. package/dist/agents/agent-config-types.js.map +0 -1
  322. package/dist/agents/agent-detection.d.ts +0 -35
  323. package/dist/agents/agent-detection.d.ts.map +0 -1
  324. package/dist/agents/agent-detection.js +0 -110
  325. package/dist/agents/agent-detection.js.map +0 -1
  326. package/dist/agents/aggregator.d.ts +0 -19
  327. package/dist/agents/aggregator.d.ts.map +0 -1
  328. package/dist/agents/aggregator.js +0 -141
  329. package/dist/agents/aggregator.js.map +0 -1
  330. package/dist/agents/cli-backend.d.ts +0 -32
  331. package/dist/agents/cli-backend.d.ts.map +0 -1
  332. package/dist/agents/cli-backend.js +0 -271
  333. package/dist/agents/cli-backend.js.map +0 -1
  334. package/dist/agents/council-types.d.ts +0 -115
  335. package/dist/agents/council-types.d.ts.map +0 -1
  336. package/dist/agents/council-types.js +0 -81
  337. package/dist/agents/council-types.js.map +0 -1
  338. package/dist/agents/council.d.ts +0 -112
  339. package/dist/agents/council.d.ts.map +0 -1
  340. package/dist/agents/council.js +0 -722
  341. package/dist/agents/council.js.map +0 -1
  342. package/dist/agents/decomposer.d.ts +0 -33
  343. package/dist/agents/decomposer.d.ts.map +0 -1
  344. package/dist/agents/decomposer.js +0 -138
  345. package/dist/agents/decomposer.js.map +0 -1
  346. package/dist/agents/dynamic-tools.d.ts +0 -52
  347. package/dist/agents/dynamic-tools.d.ts.map +0 -1
  348. package/dist/agents/dynamic-tools.js +0 -424
  349. package/dist/agents/dynamic-tools.js.map +0 -1
  350. package/dist/agents/index.d.ts +0 -29
  351. package/dist/agents/index.d.ts.map +0 -1
  352. package/dist/agents/index.js +0 -29
  353. package/dist/agents/index.js.map +0 -1
  354. package/dist/agents/installer.d.ts +0 -39
  355. package/dist/agents/installer.d.ts.map +0 -1
  356. package/dist/agents/installer.js +0 -205
  357. package/dist/agents/installer.js.map +0 -1
  358. package/dist/agents/orchestrator.d.ts +0 -106
  359. package/dist/agents/orchestrator.d.ts.map +0 -1
  360. package/dist/agents/orchestrator.js +0 -363
  361. package/dist/agents/orchestrator.js.map +0 -1
  362. package/dist/agents/sdk-backend.d.ts +0 -63
  363. package/dist/agents/sdk-backend.d.ts.map +0 -1
  364. package/dist/agents/sdk-backend.js +0 -489
  365. package/dist/agents/sdk-backend.js.map +0 -1
  366. package/dist/agents/swarm-types.d.ts +0 -84
  367. package/dist/agents/swarm-types.d.ts.map +0 -1
  368. package/dist/agents/swarm-types.js +0 -20
  369. package/dist/agents/swarm-types.js.map +0 -1
  370. package/dist/agents/swarm.d.ts +0 -79
  371. package/dist/agents/swarm.d.ts.map +0 -1
  372. package/dist/agents/swarm.js +0 -375
  373. package/dist/agents/swarm.js.map +0 -1
  374. package/dist/agents/tools.d.ts +0 -26
  375. package/dist/agents/tools.d.ts.map +0 -1
  376. package/dist/agents/tools.js +0 -776
  377. package/dist/agents/tools.js.map +0 -1
  378. package/dist/agents/types.d.ts +0 -108
  379. package/dist/agents/types.d.ts.map +0 -1
  380. package/dist/agents/types.js +0 -43
  381. package/dist/agents/types.js.map +0 -1
  382. package/dist/api-server.d.ts +0 -45
  383. package/dist/api-server.d.ts.map +0 -1
  384. package/dist/api-server.js +0 -326
  385. package/dist/api-server.js.map +0 -1
  386. package/dist/auto-checkpoint.d.ts +0 -35
  387. package/dist/auto-checkpoint.d.ts.map +0 -1
  388. package/dist/auto-checkpoint.js +0 -176
  389. package/dist/auto-checkpoint.js.map +0 -1
  390. package/dist/background-jobs.d.ts +0 -45
  391. package/dist/background-jobs.d.ts.map +0 -1
  392. package/dist/background-jobs.js +0 -127
  393. package/dist/background-jobs.js.map +0 -1
  394. package/dist/branching.d.ts +0 -56
  395. package/dist/branching.d.ts.map +0 -1
  396. package/dist/branching.js +0 -224
  397. package/dist/branching.js.map +0 -1
  398. package/dist/cli/agent.d.ts +0 -9
  399. package/dist/cli/agent.d.ts.map +0 -1
  400. package/dist/cli/agent.js +0 -330
  401. package/dist/cli/agent.js.map +0 -1
  402. package/dist/cli/commands.d.ts +0 -12
  403. package/dist/cli/commands.d.ts.map +0 -1
  404. package/dist/cli/commands.js +0 -1042
  405. package/dist/cli/commands.js.map +0 -1
  406. package/dist/cli/index.d.ts +0 -8
  407. package/dist/cli/index.d.ts.map +0 -1
  408. package/dist/cli/index.js +0 -268
  409. package/dist/cli/index.js.map +0 -1
  410. package/dist/cli/types.d.ts +0 -33
  411. package/dist/cli/types.d.ts.map +0 -1
  412. package/dist/cli/types.js +0 -21
  413. package/dist/cli/types.js.map +0 -1
  414. package/dist/companions.d.ts +0 -54
  415. package/dist/companions.d.ts.map +0 -1
  416. package/dist/companions.js +0 -440
  417. package/dist/companions.js.map +0 -1
  418. package/dist/file-watcher.d.ts +0 -91
  419. package/dist/file-watcher.d.ts.map +0 -1
  420. package/dist/file-watcher.js +0 -269
  421. package/dist/file-watcher.js.map +0 -1
  422. package/dist/hud/theme-packs/api.d.ts +0 -51
  423. package/dist/hud/theme-packs/api.d.ts.map +0 -1
  424. package/dist/hud/theme-packs/api.js +0 -145
  425. package/dist/hud/theme-packs/api.js.map +0 -1
  426. package/dist/hud/theme-packs/index.d.ts +0 -18
  427. package/dist/hud/theme-packs/index.d.ts.map +0 -1
  428. package/dist/hud/theme-packs/index.js +0 -38
  429. package/dist/hud/theme-packs/index.js.map +0 -1
  430. package/dist/hud/theme-packs/types.d.ts +0 -29
  431. package/dist/hud/theme-packs/types.d.ts.map +0 -1
  432. package/dist/hud/theme-packs/types.js +0 -9
  433. package/dist/hud/theme-packs/types.js.map +0 -1
  434. package/dist/idle-eviction.d.ts +0 -34
  435. package/dist/idle-eviction.d.ts.map +0 -1
  436. package/dist/idle-eviction.js +0 -85
  437. package/dist/idle-eviction.js.map +0 -1
  438. package/dist/model-router.d.ts +0 -67
  439. package/dist/model-router.d.ts.map +0 -1
  440. package/dist/model-router.js.map +0 -1
  441. package/dist/providers/openai-compat-shims.d.ts +0 -31
  442. package/dist/providers/openai-compat-shims.d.ts.map +0 -1
  443. package/dist/providers/openai-compat-shims.js +0 -179
  444. package/dist/providers/openai-compat-shims.js.map +0 -1
  445. package/dist/sandbox-native.d.ts.map +0 -1
  446. package/dist/sandbox-native.js.map +0 -1
  447. package/dist/sandbox.d.ts.map +0 -1
  448. package/dist/sandbox.js.map +0 -1
  449. package/dist/session-timeout.d.ts +0 -31
  450. package/dist/session-timeout.d.ts.map +0 -1
  451. package/dist/session-timeout.js +0 -100
  452. package/dist/session-timeout.js.map +0 -1
  453. package/dist/smart-router.d.ts +0 -73
  454. package/dist/smart-router.d.ts.map +0 -1
  455. package/dist/smart-router.js +0 -332
  456. package/dist/smart-router.js.map +0 -1
  457. package/dist/terminal-recording.d.ts +0 -55
  458. package/dist/terminal-recording.d.ts.map +0 -1
  459. package/dist/terminal-recording.js +0 -182
  460. package/dist/terminal-recording.js.map +0 -1
  461. package/dist/tmux.d.ts +0 -35
  462. package/dist/tmux.d.ts.map +0 -1
  463. package/dist/tmux.js +0 -106
  464. package/dist/tmux.js.map +0 -1
  465. package/dist/ui/modals.d.ts +0 -72
  466. package/dist/ui/modals.d.ts.map +0 -1
  467. package/dist/ui/modals.js +0 -266
  468. package/dist/ui/modals.js.map +0 -1
  469. package/dist/ui/pack-picker.d.ts +0 -12
  470. package/dist/ui/pack-picker.d.ts.map +0 -1
  471. package/dist/ui/pack-picker.js +0 -101
  472. package/dist/ui/pack-picker.js.map +0 -1
  473. package/dist/ui/theme-picker.d.ts +0 -24
  474. package/dist/ui/theme-picker.d.ts.map +0 -1
  475. package/dist/ui/theme-picker.js +0 -190
  476. package/dist/ui/theme-picker.js.map +0 -1
@@ -0,0 +1,643 @@
1
+ /**
2
+ * UI orchestration - chat controller
3
+ *
4
+ * Assembles every state group, the long-lived refs, the agent/command context
5
+ * builders, and all handlers, then returns flat prop bags for the four regions
6
+ * plus resetSession(). This is the "orchestration" half of the old TerminalChat
7
+ * body; index.tsx keeps only composition. It carries no JSX, so it is a plain
8
+ * module (not a component file).
9
+ */
10
+ import { useCallback, useEffect, useRef } from 'react';
11
+ import { useApp } from 'ink';
12
+ import * as config from '../../config.js';
13
+ import { selectProvider, ProviderUnavailableError } from '../../providers/index.js';
14
+ import { DEFAULT_MODELS, supportsVision } from '../../types.js';
15
+ import { getSystemPromptForProvider } from '../../local-model.js';
16
+ import { getModelContextLimit } from '../../model-detection.js';
17
+ import { detectComplexity } from '../../risk.js';
18
+ import * as storage from '../../storage.js';
19
+ import { parseFileReferences, processFilesForMessage, formatFileInfo } from '../../files.js';
20
+ import * as memory from '../../memory.js';
21
+ import { CircuitBreaker } from '../../circuit-breaker.js';
22
+ import { IterationLedger } from '../../iteration-ledger.js';
23
+ import { getDefaultSmartRoutingConfig } from '../../router.js';
24
+ import { fleetActive, fleetStartPolling, fleetPostMessage } from '../../fleet.js';
25
+ import { runAgentImpl, runLoopImpl, validateAndRepairMessagesImpl } from '../agent.js';
26
+ import { handleCommand } from '../commands.js';
27
+ import { resetContextWarnings } from '../context.js';
28
+ import { requestSelfRestart } from '../self-restart.js';
29
+ import { isDebugEnabled, setDebugEnabled, debugLog } from '../debug-log.js';
30
+ import { useTerminalWidth } from './use-terminal-width.js';
31
+ import { useProcessingState } from './use-processing-state.js';
32
+ import { useTranscriptState } from './use-transcript-state.js';
33
+ import { useSessionStats } from './use-session-stats.js';
34
+ import { useModelState } from './use-model-state.js';
35
+ import { useModalState } from './use-modal-state.js';
36
+ import { useQueueState } from './use-queue-state.js';
37
+ import { useLoopState } from './use-loop-state.js';
38
+ import { useSessionInit } from './use-session-init.js';
39
+ const MAX_UNDO_HISTORY = 10;
40
+ function makeCircuitBreaker() {
41
+ if (config.get('circuitBreakersEnabled') === false) {
42
+ return null;
43
+ }
44
+ const iterTimeSec = config.get('maxIterationTime');
45
+ const cb = new CircuitBreaker();
46
+ if (typeof iterTimeSec === 'number' && iterTimeSec > 0) {
47
+ cb.adjust('wall-clock', { maxIterationDurationMs: iterTimeSec * 1000 });
48
+ }
49
+ // Local/free providers: disable cost breaker, relax token limits
50
+ const prov = config.get('defaultProvider');
51
+ if (prov === 'ollama' || prov === 'litellm') {
52
+ cb.adjust('cost-runaway', { maxSessionCost: 999999, maxCostPerMinute: 999999 });
53
+ cb.adjust('token-burn', { maxTokensPerIteration: 500_000, maxTotalTokens: 20_000_000 });
54
+ }
55
+ return cb;
56
+ }
57
+ export function useChatController() {
58
+ const { exit } = useApp();
59
+ const width = useTerminalWidth();
60
+ // -- State groups ---------------------------------------------------------
61
+ const proc = useProcessingState();
62
+ const transcript = useTranscriptState();
63
+ const stats = useSessionStats();
64
+ const modelState = useModelState();
65
+ const modal = useModalState();
66
+ const queue = useQueueState();
67
+ const loop = useLoopState();
68
+ const { messages, collapseSettings, clearCount, addMessage, setMessages } = transcript;
69
+ const { isProcessing, thinkingState, streamingResponse, activityState, setIsProcessing, setThinkingState, setStreamingResponse, setActivityState } = proc;
70
+ const { provider, model, mode, confirmMode, autoRoute, smartRouteActive, breakerHealth, setProvider, setModel, setMode, setBreakerHealth } = modelState;
71
+ const { queuedMessages, setQueuedMessages, queuedMessagesRef, editingQueueIndex, setEditingQueueIndex } = queue;
72
+ const { loopActive, loopCancelledRef, setLoopActive } = loop;
73
+ // -- Long-lived refs ------------------------------------------------------
74
+ const isProcessingRef = useRef(false);
75
+ const surfacedProviderErrorRef = useRef(null);
76
+ const inputSubmitRef = useRef(null);
77
+ const openProviderPickerRef = useRef(null);
78
+ const sessionRef = useRef(null);
79
+ const undoStack = useRef([]);
80
+ const redoStack = useRef([]);
81
+ const llmMessages = useRef([{ role: 'system', content: getSystemPromptForProvider(provider) }]);
82
+ const ledgerRef = useRef(new IterationLedger());
83
+ const circuitBreakerRef = useRef(makeCircuitBreaker());
84
+ const smartRoutingConfigRef = useRef({
85
+ ...getDefaultSmartRoutingConfig(),
86
+ enabled: config.get('routing')?.enabled ?? false,
87
+ costSensitivity: config.get('routing')?.costSensitivity ?? 0.3,
88
+ });
89
+ useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);
90
+ // -- Derived --------------------------------------------------------------
91
+ // Resolve the true serving provider. An explicitly-selected provider with no
92
+ // credential must NOT silently fall back (#217): keep the status bar honest
93
+ // (show the real, unconfigured selection — not a provider that won't serve)
94
+ // and surface the fix once, keeping the UI alive so the user can /setup or
95
+ // /config set. 'auto' with no keys degrades to 'auto' for display.
96
+ let actualProvider;
97
+ let providerErrorMessage;
98
+ try {
99
+ actualProvider = selectProvider(provider);
100
+ }
101
+ catch (err) {
102
+ providerErrorMessage = err instanceof Error ? err.message : String(err);
103
+ actualProvider = err instanceof ProviderUnavailableError ? err.provider : 'auto';
104
+ }
105
+ const actualModel = model || DEFAULT_MODELS[actualProvider];
106
+ const isModalActive = modal.modalMode !== 'none';
107
+ const contextPercentage = Math.round((stats.contextTokens / getModelContextLimit(actualProvider, actualModel)) * 100);
108
+ const resolvedBreakerHealth = config.get('circuitBreakersEnabled') !== false ? breakerHealth : undefined;
109
+ // Surface a provider-credential problem once per unique message (per session).
110
+ useEffect(() => {
111
+ if (providerErrorMessage && surfacedProviderErrorRef.current !== providerErrorMessage) {
112
+ surfacedProviderErrorRef.current = providerErrorMessage;
113
+ addMessage('system', `⚠️ ${providerErrorMessage}`);
114
+ }
115
+ }, [providerErrorMessage, addMessage]);
116
+ // -- Core helpers ---------------------------------------------------------
117
+ const handleEditQueuedMessage = useCallback((index, newMsg) => {
118
+ if (newMsg === '') {
119
+ setQueuedMessages(prev => prev.filter((_, i) => i !== index));
120
+ addMessage('system', `🗑️ Deleted queued message #${index + 1}`);
121
+ }
122
+ else {
123
+ setQueuedMessages(prev => prev.map((msg, i) => i === index ? newMsg : msg));
124
+ addMessage('system', `✏️ Updated queued message #${index + 1}`);
125
+ }
126
+ }, [addMessage, setQueuedMessages]);
127
+ const validateAndRepairMessages = useCallback(() => {
128
+ return validateAndRepairMessagesImpl({ llmMessages, addMessage, debugLog });
129
+ }, [addMessage]);
130
+ // Estimate context tokens (conservative: ~2.5 chars/token + 1.35x overhead)
131
+ const estimateContextTokens = useCallback(() => {
132
+ let chars = 0;
133
+ let msgCount = 0;
134
+ for (const msg of llmMessages.current) {
135
+ msgCount++;
136
+ if (typeof msg.content === 'string') {
137
+ chars += msg.content.length;
138
+ }
139
+ else if (Array.isArray(msg.content)) {
140
+ for (const block of msg.content) {
141
+ if (block.type === 'text') {
142
+ chars += block.text.length;
143
+ }
144
+ else if (block.type === 'image') {
145
+ chars += 1000; // Images count as ~250 tokens
146
+ }
147
+ }
148
+ }
149
+ if (msg.toolCalls) {
150
+ for (const tool of msg.toolCalls) {
151
+ chars += JSON.stringify(tool.arguments || {}).length;
152
+ }
153
+ }
154
+ }
155
+ return Math.round((chars / 2.5) * 1.35 + msgCount * 50);
156
+ }, []);
157
+ const saveUndoState = useCallback(() => {
158
+ undoStack.current.push({
159
+ messages: [...messages],
160
+ llmMessages: [...llmMessages.current],
161
+ timestamp: new Date(),
162
+ });
163
+ if (undoStack.current.length > MAX_UNDO_HISTORY) {
164
+ undoStack.current.shift();
165
+ }
166
+ redoStack.current = [];
167
+ }, [messages]);
168
+ // -- Agent / command context builders ------------------------------------
169
+ const buildAgentContext = useCallback(() => ({
170
+ provider, model, mode, confirmMode, autoRoute, actualProvider, actualModel,
171
+ stats: stats.stats,
172
+ ledger: ledgerRef.current,
173
+ circuitBreaker: circuitBreakerRef.current || undefined,
174
+ smartRouteActive,
175
+ smartRoutingConfig: smartRoutingConfigRef.current,
176
+ setBreakerHealth,
177
+ setStats: stats.setStats,
178
+ setStreamingResponse,
179
+ setThinkingState,
180
+ setActivityState,
181
+ setContextTokens: stats.setContextTokens,
182
+ setIsProcessing,
183
+ setQueuedMessages,
184
+ setEditingQueueIndex,
185
+ setLoopIteration: loop.setLoopIteration,
186
+ setLoopActive,
187
+ llmMessages,
188
+ queuedMessagesRef,
189
+ loopCancelledRef,
190
+ sessionRef,
191
+ addMessage,
192
+ estimateContextTokens,
193
+ validateAndRepairMessages,
194
+ debugLog,
195
+ }), [provider, model, mode, confirmMode, autoRoute, smartRouteActive, actualProvider, actualModel,
196
+ stats.stats, stats.setStats, stats.setContextTokens, setBreakerHealth, setStreamingResponse,
197
+ setThinkingState, setActivityState, setIsProcessing, setQueuedMessages, setEditingQueueIndex,
198
+ loop.setLoopIteration, setLoopActive, addMessage, estimateContextTokens, validateAndRepairMessages]);
199
+ const runAgent = useCallback(async (content) => {
200
+ await runAgentImpl(buildAgentContext(), content);
201
+ }, [buildAgentContext]);
202
+ const runLoop = useCallback(async (prompt, maxIter, completionPromise) => {
203
+ await runLoopImpl(buildAgentContext(), prompt, maxIter, completionPromise);
204
+ }, [buildAgentContext]);
205
+ const handleFleetInstruction = useCallback((instruction) => {
206
+ if (isProcessingRef.current) {
207
+ setQueuedMessages(prev => [...prev, instruction]);
208
+ }
209
+ else {
210
+ void inputSubmitRef.current?.(instruction);
211
+ }
212
+ }, [setQueuedMessages]);
213
+ const buildCommandContext = useCallback(() => ({
214
+ actualProvider, actualModel, model, mode, confirmMode,
215
+ messages, stats: stats.stats, loopActive, isProcessing, thinkingState, streamingResponse,
216
+ queuedMessages, debugEnabled: isDebugEnabled(), modalMode: modal.modalMode,
217
+ ledger: ledgerRef.current,
218
+ setProvider, setModel, setMode,
219
+ setMessages,
220
+ setStats: stats.setStats,
221
+ setModalMode: modal.setModalMode,
222
+ setAvailableModels: modal.setAvailableModels,
223
+ setLoopActive,
224
+ setLoopPrompt: loop.setLoopPrompt,
225
+ setLoopMaxIterations: loop.setLoopMaxIterations,
226
+ setLoopCompletionPromise: loop.setLoopCompletionPromise,
227
+ setLoopIteration: loop.setLoopIteration,
228
+ setContextTokens: stats.setContextTokens,
229
+ setDebugEnabled,
230
+ llmMessages,
231
+ undoStack,
232
+ redoStack,
233
+ loopCancelledRef,
234
+ sessionRef,
235
+ addMessage,
236
+ estimateContextTokens,
237
+ runLoop,
238
+ startFleetPolling: () => { fleetStartPolling(handleFleetInstruction); },
239
+ openProviderPicker: () => openProviderPickerRef.current?.(),
240
+ }), [actualProvider, actualModel, model, mode, confirmMode, messages, stats.stats, stats.setStats,
241
+ stats.setContextTokens, loopActive, isProcessing, thinkingState, streamingResponse, queuedMessages,
242
+ modal.modalMode, modal.setModalMode, modal.setAvailableModels, setProvider, setModel, setMode,
243
+ setMessages, setLoopActive, loop.setLoopPrompt, loop.setLoopMaxIterations, loop.setLoopCompletionPromise,
244
+ loop.setLoopIteration, addMessage, estimateContextTokens, runLoop, handleFleetInstruction]);
245
+ const handleCommandWrapped = useCallback(async (cmd) => {
246
+ await handleCommand(cmd, buildCommandContext());
247
+ }, [buildCommandContext]);
248
+ // -- Submit (routing) -----------------------------------------------------
249
+ // The input-widget concerns (history, clearing) live in InputRegion; this is
250
+ // the content-processing half of the original handleSubmit.
251
+ const onSubmitMessage = useCallback(async (trimmed) => {
252
+ if (trimmed.startsWith('/')) {
253
+ await handleCommandWrapped(trimmed);
254
+ return;
255
+ }
256
+ // ! prefix executes shell commands directly
257
+ if (trimmed.startsWith('!')) {
258
+ const shellCmd = trimmed.slice(1).trim();
259
+ if (shellCmd) {
260
+ addMessage('system', `$ ${shellCmd}`);
261
+ try {
262
+ const { execSync } = await import('child_process');
263
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
264
+ const output = execSync(shellCmd, {
265
+ cwd: activeCwd,
266
+ encoding: 'utf-8',
267
+ timeout: 30000,
268
+ stdio: ['pipe', 'pipe', 'pipe'],
269
+ maxBuffer: 10 * 1024 * 1024,
270
+ }).trim();
271
+ addMessage('system', output || '(no output)');
272
+ }
273
+ catch (err) {
274
+ const execErr = err;
275
+ addMessage('error', execErr.stderr?.trim() || execErr.message || String(err));
276
+ }
277
+ }
278
+ return;
279
+ }
280
+ // In hybrid mode, check for complex operations
281
+ if (mode === 'hybrid') {
282
+ const complexity = detectComplexity(trimmed);
283
+ if (complexity.isComplex) {
284
+ modal.setPendingComplexPrompt({ prompt: trimmed, complexity });
285
+ modal.setModalMode('complexity-warning');
286
+ return;
287
+ }
288
+ }
289
+ // Save state for undo before modifying conversation
290
+ saveUndoState();
291
+ // Parse file references from input
292
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
293
+ const { text: cleanText, files } = parseFileReferences(trimmed, activeCwd);
294
+ // Show user message (with file info if any)
295
+ if (files.length > 0) {
296
+ const fileInfo = formatFileInfo(files);
297
+ addMessage('user', `${cleanText}\n📎 ${fileInfo}`);
298
+ }
299
+ else {
300
+ addMessage('user', trimmed);
301
+ }
302
+ // Mirror user input to IRC so observers see what prompted each agent run
303
+ if (fleetActive()) {
304
+ fleetPostMessage(cleanText || trimmed);
305
+ }
306
+ setIsProcessing(true);
307
+ try {
308
+ let messageContent;
309
+ if (files.length > 0) {
310
+ const visionSupported = supportsVision(provider, model);
311
+ const { content, warnings } = processFilesForMessage(cleanText || trimmed, files, visionSupported);
312
+ for (const warning of warnings) {
313
+ addMessage('system', warning);
314
+ }
315
+ messageContent = content;
316
+ }
317
+ else {
318
+ messageContent = trimmed;
319
+ }
320
+ await runAgent(messageContent);
321
+ }
322
+ finally {
323
+ setIsProcessing(false);
324
+ setThinkingState(null);
325
+ setStreamingResponse('');
326
+ }
327
+ }, [handleCommandWrapped, runAgent, addMessage, provider, model, saveUndoState, mode,
328
+ modal, setIsProcessing, setThinkingState, setStreamingResponse]);
329
+ // -- Input action handlers ------------------------------------------------
330
+ const handleQueueMessage = useCallback((msg) => {
331
+ setQueuedMessages(prev => [...prev, msg]);
332
+ addMessage('system', `📨 Queued: "${msg.substring(0, 50)}${msg.length > 50 ? '...' : ''}"`);
333
+ }, [addMessage, setQueuedMessages]);
334
+ const cycleMode = useCallback(() => {
335
+ setMode(current => {
336
+ const modes = ['plan', 'hybrid', 'work'];
337
+ const idx = modes.indexOf(current);
338
+ return modes[(idx + 1) % modes.length];
339
+ });
340
+ }, [setMode]);
341
+ const handleEscape = useCallback(() => {
342
+ if (isProcessing) {
343
+ setIsProcessing(false);
344
+ setThinkingState(null);
345
+ setStreamingResponse('');
346
+ setLoopActive(false);
347
+ setEditingQueueIndex(null);
348
+ addMessage('system', '⏹ Operation cancelled. Press Ctrl+C again to quit.');
349
+ }
350
+ else if (modal.modalMode !== 'none') {
351
+ modal.setModalMode('none');
352
+ modal.setPendingComplexPrompt(null);
353
+ }
354
+ else {
355
+ addMessage('system', '💡 Press Ctrl+C again to quit, or /exit.');
356
+ }
357
+ }, [isProcessing, modal, addMessage, setIsProcessing, setThinkingState, setStreamingResponse,
358
+ setLoopActive, setEditingQueueIndex]);
359
+ const handleExit = useCallback(() => { exit(); }, [exit]);
360
+ const handleDirectSend = useCallback((msg) => {
361
+ setIsProcessing(false);
362
+ setThinkingState(null);
363
+ setStreamingResponse('');
364
+ setEditingQueueIndex(null);
365
+ addMessage('system', '⚡ Direct send - interrupting current operation');
366
+ addMessage('user', msg);
367
+ setIsProcessing(true);
368
+ runAgent(msg).finally(() => {
369
+ setIsProcessing(false);
370
+ setThinkingState(null);
371
+ setStreamingResponse('');
372
+ setEditingQueueIndex(null);
373
+ });
374
+ }, [addMessage, runAgent, setIsProcessing, setThinkingState, setStreamingResponse, setEditingQueueIndex]);
375
+ // -- Modal handlers -------------------------------------------------------
376
+ const handleModelSelect = useCallback((selectedModel) => {
377
+ setModel(selectedModel);
378
+ config.set('defaultModel', selectedModel);
379
+ addMessage('system', `Model: ${selectedModel} (saved as default)`);
380
+ modal.setModalMode('none');
381
+ modal.setAvailableModels([]);
382
+ }, [addMessage, setModel, modal]);
383
+ const handleModalCancel = useCallback(() => {
384
+ modal.setModalMode('none');
385
+ modal.setAvailableModels([]);
386
+ modal.setLatestVersion(null);
387
+ }, [modal]);
388
+ const handleUpgradeConfirm = useCallback(async () => {
389
+ modal.setModalMode('none');
390
+ addMessage('system', 'Upgrading...');
391
+ try {
392
+ const { performUpgrade } = await import('../../version-check.js');
393
+ const success = await performUpgrade();
394
+ if (success) {
395
+ addMessage('system', 'Upgrade complete! Restarting...');
396
+ requestSelfRestart(process.argv.slice(1));
397
+ exit();
398
+ return;
399
+ }
400
+ addMessage('error', 'Upgrade failed. Try: npm install -g @calliopelabs/cli@latest');
401
+ }
402
+ catch (e) {
403
+ addMessage('error', `Upgrade failed: ${e instanceof Error ? e.message : String(e)}`);
404
+ }
405
+ modal.setLatestVersion(null);
406
+ }, [addMessage, modal, exit]);
407
+ const buildProviderEntries = useCallback(() => {
408
+ const hasBedrock = !!(config.getApiKey('bedrock') || config.getBaseUrl('bedrock')
409
+ || process.env.AWS_ACCESS_KEY_ID || process.env.AWS_PROFILE);
410
+ return [
411
+ { id: 'ollama', label: 'Ollama', configured: !!config.getBaseUrl('ollama'), configHint: 'OLLAMA_BASE_URL', recommended: true, note: 'local, free' },
412
+ { id: 'anthropic', label: 'Anthropic', configured: !!config.getApiKey('anthropic'), configHint: 'ANTHROPIC_API_KEY' },
413
+ { id: 'openai', label: 'OpenAI', configured: !!config.getApiKey('openai'), configHint: 'OPENAI_API_KEY' },
414
+ { id: 'google', label: 'Google', configured: !!config.getApiKey('google'), configHint: 'GOOGLE_API_KEY' },
415
+ { id: 'mistral', label: 'Mistral', configured: !!config.getApiKey('mistral'), configHint: 'MISTRAL_API_KEY' },
416
+ { id: 'openrouter', label: 'OpenRouter', configured: !!config.getApiKey('openrouter'), configHint: 'OPENROUTER_API_KEY' },
417
+ { id: 'together', label: 'Together', configured: !!config.getApiKey('together'), configHint: 'TOGETHER_API_KEY' },
418
+ { id: 'groq', label: 'Groq', configured: !!config.getApiKey('groq'), configHint: 'GROQ_API_KEY' },
419
+ { id: 'fireworks', label: 'Fireworks', configured: !!config.getApiKey('fireworks'), configHint: 'FIREWORKS_API_KEY' },
420
+ { id: 'ai21', label: 'AI21', configured: !!config.getApiKey('ai21'), configHint: 'AI21_API_KEY' },
421
+ { id: 'huggingface', label: 'HuggingFace', configured: !!config.getApiKey('huggingface'), configHint: 'HUGGINGFACE_API_KEY' },
422
+ { id: 'bedrock', label: 'AWS Bedrock', configured: hasBedrock, configHint: 'AWS_PROFILE or AWS_ACCESS_KEY_ID', note: 'AWS credentials' },
423
+ { id: 'litellm', label: 'LiteLLM', configured: !!config.getBaseUrl('litellm'), configHint: 'LITELLM_BASE_URL' },
424
+ ];
425
+ }, []);
426
+ const openProviderPicker = useCallback(() => {
427
+ modal.setProviderEntries(buildProviderEntries());
428
+ modal.setModalMode('provider');
429
+ }, [buildProviderEntries, modal]);
430
+ useEffect(() => { openProviderPickerRef.current = openProviderPicker; }, [openProviderPicker]);
431
+ const handleProviderSelect = useCallback((entry) => {
432
+ if (entry.configured) {
433
+ setProvider(entry.id);
434
+ config.set('defaultProvider', entry.id);
435
+ config.unset('defaultModel');
436
+ addMessage('system', `Provider: ${entry.label}${entry.id === 'ollama' ? ' (local)' : ''} (saved as default)`);
437
+ modal.setModalMode('none');
438
+ modal.setProviderEntries([]);
439
+ return;
440
+ }
441
+ modal.setPendingSetupProvider(entry);
442
+ modal.setModalMode('api-key-setup');
443
+ }, [addMessage, setProvider, modal]);
444
+ const handleProviderCancel = useCallback(() => {
445
+ modal.setModalMode('none');
446
+ modal.setProviderEntries([]);
447
+ }, [modal]);
448
+ const handleApiKeySubmit = useCallback((value) => {
449
+ const entry = modal.pendingSetupProvider;
450
+ if (!entry) {
451
+ modal.setModalMode('none');
452
+ return;
453
+ }
454
+ try {
455
+ if (entry.id === 'ollama') {
456
+ config.setProviderCred('ollama', { baseUrl: value });
457
+ }
458
+ else if (entry.id === 'litellm') {
459
+ config.setProviderCred('litellm', { baseUrl: value });
460
+ }
461
+ else if (entry.id === 'bedrock') {
462
+ process.env.AWS_PROFILE = value;
463
+ delete process.env.AWS_ACCESS_KEY_ID;
464
+ delete process.env.AWS_SECRET_ACCESS_KEY;
465
+ delete process.env.AWS_SESSION_TOKEN;
466
+ addMessage('system', `AWS_PROFILE=${value} set for this session. Add to shell rc to persist.`);
467
+ }
468
+ else {
469
+ config.setProviderCred(entry.id, { apiKey: value });
470
+ }
471
+ setProvider(entry.id);
472
+ config.set('defaultProvider', entry.id);
473
+ config.unset('defaultModel');
474
+ addMessage('system', `✓ Configured ${entry.label}. Provider switched and saved as default.`);
475
+ }
476
+ catch (e) {
477
+ addMessage('error', `Failed to configure ${entry.label}: ${e instanceof Error ? e.message : String(e)}`);
478
+ }
479
+ modal.setPendingSetupProvider(null);
480
+ modal.setModalMode('none');
481
+ }, [addMessage, setProvider, modal]);
482
+ const handleApiKeyCancel = useCallback(() => {
483
+ modal.setPendingSetupProvider(null);
484
+ modal.setModalMode('none');
485
+ }, [modal]);
486
+ // -- Session-selector / resume handlers -----------------------------------
487
+ const handleSessionSelect = useCallback((session) => {
488
+ addMessage('system', `Loading session: ${session.projectName}...`);
489
+ addMessage('system', `Session path: ${session.projectPath}\nTo load this session, run calliope from that directory.`);
490
+ modal.setModalMode('none');
491
+ }, [addMessage, modal]);
492
+ const handleSessionDelete = useCallback((session) => {
493
+ if (storage.deleteSession(session.id)) {
494
+ addMessage('system', `🗑️ Deleted session: ${session.projectName}`);
495
+ modal.setAvailableSessions(prev => prev.filter(s => s.id !== session.id));
496
+ }
497
+ else {
498
+ addMessage('error', `Failed to delete session: ${session.projectName}`);
499
+ }
500
+ }, [addMessage, modal]);
501
+ const handleSessionResume = useCallback(() => {
502
+ const savedMessages = storage.loadMessageHistory();
503
+ if (savedMessages && savedMessages.length > 0) {
504
+ llmMessages.current.length = 0;
505
+ for (const msg of savedMessages) {
506
+ llmMessages.current.push(msg);
507
+ }
508
+ addMessage('system', `✓ Resumed session with ${savedMessages.length} saved messages loaded`);
509
+ const activeSessionId = sessionRef.current?.id;
510
+ if (activeSessionId) {
511
+ ledgerRef.current.loadSnapshot(storage.loadIterationLedger(activeSessionId));
512
+ storage.saveIterationLedger(ledgerRef.current, activeSessionId);
513
+ }
514
+ stats.setContextTokens(estimateContextTokens());
515
+ }
516
+ else {
517
+ const history = storage.getChatHistory(20);
518
+ if (history.length > 0) {
519
+ llmMessages.current.length = 0;
520
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
521
+ const basePrompt = getSystemPromptForProvider(actualProvider);
522
+ const memoryContext = memory.buildMemoryContext(activeCwd);
523
+ llmMessages.current.push({
524
+ role: 'system',
525
+ content: memoryContext.trim()
526
+ ? `${basePrompt}\n\n--- Project Context ---\n${memoryContext}`
527
+ : basePrompt,
528
+ });
529
+ for (const msg of history) {
530
+ if (msg.role === 'user' || msg.role === 'assistant') {
531
+ llmMessages.current.push({ role: msg.role, content: msg.content });
532
+ }
533
+ }
534
+ addMessage('system', `✓ Resumed session with ${history.length} chat messages loaded`);
535
+ stats.setContextTokens(estimateContextTokens());
536
+ }
537
+ }
538
+ modal.setModalMode('none');
539
+ modal.setPreviousSession(null);
540
+ }, [addMessage, estimateContextTokens, stats, modal, actualProvider]);
541
+ const handleSessionResumeNew = useCallback(() => {
542
+ addMessage('system', '✓ Starting fresh session');
543
+ modal.setModalMode('none');
544
+ modal.setPreviousSession(null);
545
+ }, [addMessage, modal]);
546
+ // -- Complexity-warning handlers ------------------------------------------
547
+ const handleComplexityProceed = useCallback(async () => {
548
+ modal.setModalMode('none');
549
+ const prompt = modal.pendingComplexPrompt?.prompt;
550
+ modal.setPendingComplexPrompt(null);
551
+ if (prompt === undefined)
552
+ return;
553
+ saveUndoState();
554
+ addMessage('user', typeof prompt === 'string' ? prompt : JSON.stringify(prompt));
555
+ setIsProcessing(true);
556
+ try {
557
+ await runAgent(prompt);
558
+ }
559
+ finally {
560
+ setIsProcessing(false);
561
+ }
562
+ }, [modal, saveUndoState, addMessage, runAgent, setIsProcessing]);
563
+ const handleComplexityPlan = useCallback(() => {
564
+ modal.setModalMode('none');
565
+ const prompt = modal.pendingComplexPrompt?.prompt;
566
+ modal.setPendingComplexPrompt(null);
567
+ if (prompt === undefined)
568
+ return;
569
+ setMode('plan');
570
+ addMessage('system', '📋 Switched to Plan mode - I\'ll describe what I would do without executing.');
571
+ saveUndoState();
572
+ addMessage('user', typeof prompt === 'string' ? prompt : JSON.stringify(prompt));
573
+ setIsProcessing(true);
574
+ runAgent(prompt).finally(() => setIsProcessing(false));
575
+ }, [modal, setMode, saveUndoState, addMessage, runAgent, setIsProcessing]);
576
+ const handleComplexityCancel = useCallback(() => {
577
+ modal.setModalMode('none');
578
+ modal.setPendingComplexPrompt(null);
579
+ addMessage('system', 'Operation cancelled.');
580
+ }, [modal, addMessage]);
581
+ const handleKeybindingsClose = useCallback(() => {
582
+ modal.setModalMode('none');
583
+ }, [modal]);
584
+ // -- Session reset (replaces the old full-remount reset) ------------------
585
+ const resetSession = useCallback(() => {
586
+ proc.reset();
587
+ transcript.reset();
588
+ stats.reset();
589
+ modelState.reset();
590
+ modal.reset();
591
+ queue.reset();
592
+ loop.reset();
593
+ llmMessages.current = [{ role: 'system', content: getSystemPromptForProvider(actualProvider) }];
594
+ undoStack.current = [];
595
+ redoStack.current = [];
596
+ ledgerRef.current.reset();
597
+ resetContextWarnings();
598
+ }, [proc, transcript, stats, modelState, modal, queue, loop, actualProvider]);
599
+ // -- Mount initialization -------------------------------------------------
600
+ useSessionInit({ sessionRef, ledgerRef, llmMessages, addMessage, onFleetInstruction: handleFleetInstruction });
601
+ // -- Region prop bags -----------------------------------------------------
602
+ // Plain objects (not memoized): TerminalChat spreads them, so each region's
603
+ // React.memo compares individual props — all of which are stable values or
604
+ // stable useCallback refs when unchanged. This also keeps module-level reads
605
+ // (debugEnabled) fresh on every render, matching the original.
606
+ const transcriptProps = {
607
+ messages, collapseSettings, clearCount, isProcessing, thinkingState, streamingResponse, activityState,
608
+ debugEnabled: isDebugEnabled(), mode, queuedCount: queuedMessages.length,
609
+ };
610
+ const statusProps = {
611
+ provider: actualProvider, model: actualModel, mode, stats: stats.stats,
612
+ contextTokens: stats.contextTokens, breakerHealth: resolvedBreakerHealth, smartRouteActive, width,
613
+ };
614
+ const inputProps = {
615
+ onSubmitMessage, submitRef: inputSubmitRef, disabled: isModalActive, isProcessing,
616
+ queuedCount: queuedMessages.length, queuedMessages, editingQueueIndex,
617
+ onQueueMessage: handleQueueMessage, onEditQueuedMessage: handleEditQueuedMessage,
618
+ onSetEditingQueueIndex: setEditingQueueIndex, onDirectSend: handleDirectSend,
619
+ onEscape: handleEscape, onExit: handleExit, onCycleMode: cycleMode,
620
+ currentMode: mode, contextPercentage, cwd: process.cwd(),
621
+ };
622
+ const modalProps = {
623
+ modalMode: modal.modalMode,
624
+ availableModels: modal.availableModels, onModelSelect: handleModelSelect, onModalCancel: handleModalCancel,
625
+ availableSessions: modal.availableSessions, onSessionSelect: handleSessionSelect, onSessionDelete: handleSessionDelete,
626
+ latestVersion: modal.latestVersion, onUpgradeConfirm: handleUpgradeConfirm,
627
+ previousSession: modal.previousSession, onSessionResume: handleSessionResume, onSessionResumeNew: handleSessionResumeNew,
628
+ pendingComplexPrompt: modal.pendingComplexPrompt, onComplexityProceed: handleComplexityProceed,
629
+ onComplexityPlan: handleComplexityPlan, onComplexityCancel: handleComplexityCancel,
630
+ onKeybindingsClose: handleKeybindingsClose,
631
+ providerEntries: modal.providerEntries, onProviderSelect: handleProviderSelect, onProviderCancel: handleProviderCancel,
632
+ pendingSetupProvider: modal.pendingSetupProvider, onApiKeySubmit: handleApiKeySubmit, onApiKeyCancel: handleApiKeyCancel,
633
+ };
634
+ return {
635
+ width,
636
+ resetSession,
637
+ transcript: transcriptProps,
638
+ status: statusProps,
639
+ input: inputProps,
640
+ modal: modalProps,
641
+ };
642
+ }
643
+ //# sourceMappingURL=use-chat-controller.js.map