@calliopelabs/cli 2.3.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 (538) hide show
  1. package/README.md +45 -644
  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/auto-compressor.d.ts.map +1 -1
  7. package/dist/auto-compressor.js +9 -5
  8. package/dist/auto-compressor.js.map +1 -1
  9. package/dist/bin.d.ts +9 -5
  10. package/dist/bin.d.ts.map +1 -1
  11. package/dist/bin.js +108 -76
  12. package/dist/bin.js.map +1 -1
  13. package/dist/budget.d.ts +64 -0
  14. package/dist/budget.d.ts.map +1 -0
  15. package/dist/budget.js +157 -0
  16. package/dist/budget.js.map +1 -0
  17. package/dist/checkpoint.d.ts +63 -30
  18. package/dist/checkpoint.d.ts.map +1 -1
  19. package/dist/checkpoint.js +249 -150
  20. package/dist/checkpoint.js.map +1 -1
  21. package/dist/circuit-breaker/breaker.js.map +1 -1
  22. package/dist/config.d.ts +86 -81
  23. package/dist/config.d.ts.map +1 -1
  24. package/dist/config.js +237 -305
  25. package/dist/config.js.map +1 -1
  26. package/dist/cost.d.ts +114 -0
  27. package/dist/cost.d.ts.map +1 -0
  28. package/dist/cost.js +499 -0
  29. package/dist/cost.js.map +1 -0
  30. package/dist/diff.d.ts.map +1 -1
  31. package/dist/diff.js +53 -11
  32. package/dist/diff.js.map +1 -1
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +33 -6
  35. package/dist/errors.js.map +1 -1
  36. package/dist/files.js.map +1 -1
  37. package/dist/fleet.d.ts +30 -0
  38. package/dist/fleet.d.ts.map +1 -0
  39. package/dist/fleet.js +86 -0
  40. package/dist/fleet.js.map +1 -0
  41. package/dist/fuzzy-search.d.ts.map +1 -1
  42. package/dist/fuzzy-search.js +2 -1
  43. package/dist/fuzzy-search.js.map +1 -1
  44. package/dist/git-status.js.map +1 -1
  45. package/dist/headless.d.ts +1 -2
  46. package/dist/headless.d.ts.map +1 -1
  47. package/dist/headless.js +222 -26
  48. package/dist/headless.js.map +1 -1
  49. package/dist/hooks.d.ts +8 -2
  50. package/dist/hooks.d.ts.map +1 -1
  51. package/dist/hooks.js +97 -11
  52. package/dist/hooks.js.map +1 -1
  53. package/dist/hud/api.d.ts +3 -18
  54. package/dist/hud/api.d.ts.map +1 -1
  55. package/dist/hud/api.js +9 -352
  56. package/dist/hud/api.js.map +1 -1
  57. package/dist/hud/palettes.d.ts.map +1 -1
  58. package/dist/hud/palettes.js +0 -180
  59. package/dist/hud/palettes.js.map +1 -1
  60. package/dist/hud/skins.d.ts.map +1 -1
  61. package/dist/hud/skins.js +0 -263
  62. package/dist/hud/skins.js.map +1 -1
  63. package/dist/hud/types.d.ts +2 -5
  64. package/dist/hud/types.d.ts.map +1 -1
  65. package/dist/index.d.ts +1 -4
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +1 -4
  68. package/dist/index.js.map +1 -1
  69. package/dist/iteration-ledger.d.ts.map +1 -1
  70. package/dist/iteration-ledger.js +3 -2
  71. package/dist/iteration-ledger.js.map +1 -1
  72. package/dist/local-model.d.ts +150 -0
  73. package/dist/local-model.d.ts.map +1 -0
  74. package/dist/local-model.js +408 -0
  75. package/dist/local-model.js.map +1 -0
  76. package/dist/markdown.d.ts.map +1 -1
  77. package/dist/markdown.js +32 -10
  78. package/dist/markdown.js.map +1 -1
  79. package/dist/mcp.d.ts +35 -5
  80. package/dist/mcp.d.ts.map +1 -1
  81. package/dist/mcp.js +190 -13
  82. package/dist/mcp.js.map +1 -1
  83. package/dist/memory.d.ts.map +1 -1
  84. package/dist/memory.js +6 -4
  85. package/dist/memory.js.map +1 -1
  86. package/dist/model-detection.d.ts +14 -1
  87. package/dist/model-detection.d.ts.map +1 -1
  88. package/dist/model-detection.js +308 -115
  89. package/dist/model-detection.js.map +1 -1
  90. package/dist/parallel-tools.d.ts +9 -1
  91. package/dist/parallel-tools.d.ts.map +1 -1
  92. package/dist/parallel-tools.js +6 -5
  93. package/dist/parallel-tools.js.map +1 -1
  94. package/dist/plugins.d.ts +68 -0
  95. package/dist/plugins.d.ts.map +1 -1
  96. package/dist/plugins.js +201 -3
  97. package/dist/plugins.js.map +1 -1
  98. package/dist/policy.d.ts +43 -0
  99. package/dist/policy.d.ts.map +1 -0
  100. package/dist/policy.js +139 -0
  101. package/dist/policy.js.map +1 -0
  102. package/dist/project-config.d.ts +1 -2
  103. package/dist/project-config.d.ts.map +1 -1
  104. package/dist/project-config.js +0 -3
  105. package/dist/project-config.js.map +1 -1
  106. package/dist/providers/anthropic.d.ts.map +1 -1
  107. package/dist/providers/anthropic.js +36 -2
  108. package/dist/providers/anthropic.js.map +1 -1
  109. package/dist/providers/bedrock.d.ts.map +1 -1
  110. package/dist/providers/bedrock.js +83 -22
  111. package/dist/providers/bedrock.js.map +1 -1
  112. package/dist/providers/compat.d.ts +21 -0
  113. package/dist/providers/compat.d.ts.map +1 -1
  114. package/dist/providers/compat.js +176 -6
  115. package/dist/providers/compat.js.map +1 -1
  116. package/dist/providers/google.js.map +1 -1
  117. package/dist/providers/index.d.ts +19 -4
  118. package/dist/providers/index.d.ts.map +1 -1
  119. package/dist/providers/index.js +62 -9
  120. package/dist/providers/index.js.map +1 -1
  121. package/dist/providers/ollama.d.ts +2 -2
  122. package/dist/providers/ollama.d.ts.map +1 -1
  123. package/dist/providers/ollama.js +26 -6
  124. package/dist/providers/ollama.js.map +1 -1
  125. package/dist/providers/openai.d.ts.map +1 -1
  126. package/dist/providers/openai.js +14 -10
  127. package/dist/providers/openai.js.map +1 -1
  128. package/dist/providers/types.d.ts +8 -0
  129. package/dist/providers/types.d.ts.map +1 -1
  130. package/dist/providers/types.js +19 -10
  131. package/dist/providers/types.js.map +1 -1
  132. package/dist/replay.d.ts +37 -0
  133. package/dist/replay.d.ts.map +1 -0
  134. package/dist/replay.js +168 -0
  135. package/dist/replay.js.map +1 -0
  136. package/dist/risk.d.ts.map +1 -1
  137. package/dist/risk.js +15 -5
  138. package/dist/risk.js.map +1 -1
  139. package/dist/router.d.ts +133 -0
  140. package/dist/router.d.ts.map +1 -0
  141. package/dist/{model-router.js → router.js} +336 -10
  142. package/dist/router.js.map +1 -0
  143. package/dist/runlog.d.ts +185 -0
  144. package/dist/runlog.d.ts.map +1 -0
  145. package/dist/runlog.js +398 -0
  146. package/dist/runlog.js.map +1 -0
  147. package/dist/{sandbox.d.ts → sandbox/docker.d.ts} +1 -1
  148. package/dist/sandbox/docker.d.ts.map +1 -0
  149. package/dist/{sandbox.js → sandbox/docker.js} +1 -1
  150. package/dist/sandbox/docker.js.map +1 -0
  151. package/dist/sandbox/index.d.ts +36 -0
  152. package/dist/sandbox/index.d.ts.map +1 -0
  153. package/dist/sandbox/index.js +62 -0
  154. package/dist/sandbox/index.js.map +1 -0
  155. package/dist/{sandbox-native.d.ts → sandbox/native.d.ts} +2 -1
  156. package/dist/sandbox/native.d.ts.map +1 -0
  157. package/dist/{sandbox-native.js → sandbox/native.js} +38 -6
  158. package/dist/sandbox/native.js.map +1 -0
  159. package/dist/scope.d.ts +10 -0
  160. package/dist/scope.d.ts.map +1 -1
  161. package/dist/scope.js +76 -16
  162. package/dist/scope.js.map +1 -1
  163. package/dist/scuttlebot/client.d.ts +83 -0
  164. package/dist/scuttlebot/client.d.ts.map +1 -0
  165. package/dist/scuttlebot/client.js +350 -0
  166. package/dist/scuttlebot/client.js.map +1 -0
  167. package/dist/scuttlebot/config.d.ts +28 -0
  168. package/dist/scuttlebot/config.d.ts.map +1 -0
  169. package/dist/scuttlebot/config.js +91 -0
  170. package/dist/scuttlebot/config.js.map +1 -0
  171. package/dist/scuttlebot/http-client.d.ts +63 -0
  172. package/dist/scuttlebot/http-client.d.ts.map +1 -0
  173. package/dist/scuttlebot/http-client.js +124 -0
  174. package/dist/scuttlebot/http-client.js.map +1 -0
  175. package/dist/scuttlebot/index.d.ts +13 -0
  176. package/dist/scuttlebot/index.d.ts.map +1 -0
  177. package/dist/scuttlebot/index.js +10 -0
  178. package/dist/scuttlebot/index.js.map +1 -0
  179. package/dist/scuttlebot/irc-client.d.ts +124 -0
  180. package/dist/scuttlebot/irc-client.d.ts.map +1 -0
  181. package/dist/scuttlebot/irc-client.js +599 -0
  182. package/dist/scuttlebot/irc-client.js.map +1 -0
  183. package/dist/setup.d.ts.map +1 -1
  184. package/dist/setup.js +22 -54
  185. package/dist/setup.js.map +1 -1
  186. package/dist/skills.d.ts +58 -0
  187. package/dist/skills.d.ts.map +1 -1
  188. package/dist/skills.js +186 -16
  189. package/dist/skills.js.map +1 -1
  190. package/dist/storage.d.ts +0 -4
  191. package/dist/storage.d.ts.map +1 -1
  192. package/dist/storage.js +87 -8
  193. package/dist/storage.js.map +1 -1
  194. package/dist/streaming.d.ts +25 -0
  195. package/dist/streaming.d.ts.map +1 -1
  196. package/dist/streaming.js +59 -0
  197. package/dist/streaming.js.map +1 -1
  198. package/dist/styles.d.ts +6 -0
  199. package/dist/styles.d.ts.map +1 -1
  200. package/dist/styles.js +11 -0
  201. package/dist/styles.js.map +1 -1
  202. package/dist/summarization.js.map +1 -1
  203. package/dist/terminal-image.js +1 -1
  204. package/dist/terminal-image.js.map +1 -1
  205. package/dist/themes.d.ts +5 -4
  206. package/dist/themes.d.ts.map +1 -1
  207. package/dist/themes.js +35 -90
  208. package/dist/themes.js.map +1 -1
  209. package/dist/tools.d.ts +27 -3
  210. package/dist/tools.d.ts.map +1 -1
  211. package/dist/tools.js +352 -209
  212. package/dist/tools.js.map +1 -1
  213. package/dist/trust.d.ts +16 -3
  214. package/dist/trust.d.ts.map +1 -1
  215. package/dist/trust.js +23 -4
  216. package/dist/trust.js.map +1 -1
  217. package/dist/types.d.ts +4 -3
  218. package/dist/types.d.ts.map +1 -1
  219. package/dist/types.js +34 -44
  220. package/dist/types.js.map +1 -1
  221. package/dist/ui/agent.d.ts +4 -7
  222. package/dist/ui/agent.d.ts.map +1 -1
  223. package/dist/ui/agent.js +354 -73
  224. package/dist/ui/agent.js.map +1 -1
  225. package/dist/ui/animations.d.ts +37 -0
  226. package/dist/ui/animations.d.ts.map +1 -0
  227. package/dist/ui/animations.js +227 -0
  228. package/dist/ui/animations.js.map +1 -0
  229. package/dist/ui/chat-input-keys.d.ts +42 -0
  230. package/dist/ui/chat-input-keys.d.ts.map +1 -0
  231. package/dist/ui/chat-input-keys.js +360 -0
  232. package/dist/ui/chat-input-keys.js.map +1 -0
  233. package/dist/ui/chat-input.d.ts +5 -2
  234. package/dist/ui/chat-input.d.ts.map +1 -1
  235. package/dist/ui/chat-input.js +54 -308
  236. package/dist/ui/chat-input.js.map +1 -1
  237. package/dist/ui/commands.d.ts +15 -45
  238. package/dist/ui/commands.d.ts.map +1 -1
  239. package/dist/ui/commands.js +461 -2636
  240. package/dist/ui/commands.js.map +1 -1
  241. package/dist/ui/completions.d.ts +1 -0
  242. package/dist/ui/completions.d.ts.map +1 -1
  243. package/dist/ui/completions.js +36 -107
  244. package/dist/ui/completions.js.map +1 -1
  245. package/dist/ui/components.d.ts +14 -6
  246. package/dist/ui/components.d.ts.map +1 -1
  247. package/dist/ui/components.js +17 -226
  248. package/dist/ui/components.js.map +1 -1
  249. package/dist/ui/context.js +6 -6
  250. package/dist/ui/context.js.map +1 -1
  251. package/dist/ui/debug-log.d.ts +11 -0
  252. package/dist/ui/debug-log.d.ts.map +1 -0
  253. package/dist/ui/debug-log.js +21 -0
  254. package/dist/ui/debug-log.js.map +1 -0
  255. package/dist/ui/error-boundary.d.ts.map +1 -1
  256. package/dist/ui/error-boundary.js.map +1 -1
  257. package/dist/ui/frame.d.ts.map +1 -1
  258. package/dist/ui/frame.js +1 -3
  259. package/dist/ui/frame.js.map +1 -1
  260. package/dist/ui/index.d.ts +11 -3
  261. package/dist/ui/index.d.ts.map +1 -1
  262. package/dist/ui/index.js +46 -887
  263. package/dist/ui/index.js.map +1 -1
  264. package/dist/ui/input-utils.d.ts +20 -0
  265. package/dist/ui/input-utils.d.ts.map +1 -0
  266. package/dist/ui/input-utils.js +35 -0
  267. package/dist/ui/input-utils.js.map +1 -0
  268. package/dist/ui/messages.d.ts +8 -7
  269. package/dist/ui/messages.d.ts.map +1 -1
  270. package/dist/ui/messages.js +51 -35
  271. package/dist/ui/messages.js.map +1 -1
  272. package/dist/ui/modals/index.d.ts +11 -0
  273. package/dist/ui/modals/index.d.ts.map +1 -0
  274. package/dist/ui/modals/index.js +10 -0
  275. package/dist/ui/modals/index.js.map +1 -0
  276. package/dist/ui/{modals.d.ts → modals/prompts.d.ts} +5 -20
  277. package/dist/ui/modals/prompts.d.ts.map +1 -0
  278. package/dist/ui/{modals.js → modals/prompts.js} +14 -94
  279. package/dist/ui/modals/prompts.js.map +1 -0
  280. package/dist/ui/modals/selectors.d.ts +33 -0
  281. package/dist/ui/modals/selectors.d.ts.map +1 -0
  282. package/dist/ui/modals/selectors.js +111 -0
  283. package/dist/ui/modals/selectors.js.map +1 -0
  284. package/dist/ui/modals/setup.d.ts +17 -0
  285. package/dist/ui/modals/setup.d.ts.map +1 -0
  286. package/dist/ui/modals/setup.js +51 -0
  287. package/dist/ui/modals/setup.js.map +1 -0
  288. package/dist/ui/regions/input-region.d.ts +40 -0
  289. package/dist/ui/regions/input-region.d.ts.map +1 -0
  290. package/dist/ui/regions/input-region.js +116 -0
  291. package/dist/ui/regions/input-region.js.map +1 -0
  292. package/dist/ui/regions/modal-host.d.ts +41 -0
  293. package/dist/ui/regions/modal-host.d.ts.map +1 -0
  294. package/dist/ui/regions/modal-host.js +51 -0
  295. package/dist/ui/regions/modal-host.js.map +1 -0
  296. package/dist/ui/regions/render-probe.d.ts +22 -0
  297. package/dist/ui/regions/render-probe.d.ts.map +1 -0
  298. package/dist/ui/regions/render-probe.js +45 -0
  299. package/dist/ui/regions/render-probe.js.map +1 -0
  300. package/dist/ui/regions/static-scrollback.d.ts +39 -0
  301. package/dist/ui/regions/static-scrollback.d.ts.map +1 -0
  302. package/dist/ui/regions/static-scrollback.js +68 -0
  303. package/dist/ui/regions/static-scrollback.js.map +1 -0
  304. package/dist/ui/regions/status-region.d.ts +24 -0
  305. package/dist/ui/regions/status-region.d.ts.map +1 -0
  306. package/dist/ui/regions/status-region.js +17 -0
  307. package/dist/ui/regions/status-region.js.map +1 -0
  308. package/dist/ui/regions/transcript-region.d.ts +41 -0
  309. package/dist/ui/regions/transcript-region.d.ts.map +1 -0
  310. package/dist/ui/regions/transcript-region.js +52 -0
  311. package/dist/ui/regions/transcript-region.js.map +1 -0
  312. package/dist/ui/self-restart.d.ts +9 -0
  313. package/dist/ui/self-restart.d.ts.map +1 -0
  314. package/dist/ui/self-restart.js +24 -0
  315. package/dist/ui/self-restart.js.map +1 -0
  316. package/dist/ui/state/use-chat-controller.d.ts +23 -0
  317. package/dist/ui/state/use-chat-controller.d.ts.map +1 -0
  318. package/dist/ui/state/use-chat-controller.js +643 -0
  319. package/dist/ui/state/use-chat-controller.js.map +1 -0
  320. package/dist/ui/state/use-loop-state.d.ts +23 -0
  321. package/dist/ui/state/use-loop-state.d.ts.map +1 -0
  322. package/dist/ui/state/use-loop-state.js +39 -0
  323. package/dist/ui/state/use-loop-state.js.map +1 -0
  324. package/dist/ui/state/use-modal-state.d.ts +52 -0
  325. package/dist/ui/state/use-modal-state.d.ts.map +1 -0
  326. package/dist/ui/state/use-modal-state.js +44 -0
  327. package/dist/ui/state/use-modal-state.js.map +1 -0
  328. package/dist/ui/state/use-model-state.d.ts +29 -0
  329. package/dist/ui/state/use-model-state.d.ts.map +1 -0
  330. package/dist/ui/state/use-model-state.js +47 -0
  331. package/dist/ui/state/use-model-state.js.map +1 -0
  332. package/dist/ui/state/use-processing-state.d.ts +24 -0
  333. package/dist/ui/state/use-processing-state.d.ts.map +1 -0
  334. package/dist/ui/state/use-processing-state.js +46 -0
  335. package/dist/ui/state/use-processing-state.js.map +1 -0
  336. package/dist/ui/state/use-queue-state.d.ts +19 -0
  337. package/dist/ui/state/use-queue-state.d.ts.map +1 -0
  338. package/dist/ui/state/use-queue-state.js +30 -0
  339. package/dist/ui/state/use-queue-state.js.map +1 -0
  340. package/dist/ui/state/use-session-init.d.ts +22 -0
  341. package/dist/ui/state/use-session-init.d.ts.map +1 -0
  342. package/dist/ui/state/use-session-init.js +77 -0
  343. package/dist/ui/state/use-session-init.js.map +1 -0
  344. package/dist/ui/state/use-session-stats.d.ts +16 -0
  345. package/dist/ui/state/use-session-stats.d.ts.map +1 -0
  346. package/dist/ui/state/use-session-stats.js +18 -0
  347. package/dist/ui/state/use-session-stats.js.map +1 -0
  348. package/dist/ui/state/use-terminal-width.d.ts +8 -0
  349. package/dist/ui/state/use-terminal-width.d.ts.map +1 -0
  350. package/dist/ui/state/use-terminal-width.js +22 -0
  351. package/dist/ui/state/use-terminal-width.js.map +1 -0
  352. package/dist/ui/state/use-transcript-state.d.ts +21 -0
  353. package/dist/ui/state/use-transcript-state.d.ts.map +1 -0
  354. package/dist/ui/state/use-transcript-state.js +49 -0
  355. package/dist/ui/state/use-transcript-state.js.map +1 -0
  356. package/dist/ui/status-bar.d.ts +4 -1
  357. package/dist/ui/status-bar.d.ts.map +1 -1
  358. package/dist/ui/status-bar.js +13 -3
  359. package/dist/ui/status-bar.js.map +1 -1
  360. package/dist/ui/types.d.ts +3 -0
  361. package/dist/ui/types.d.ts.map +1 -1
  362. package/dist/version-check.d.ts.map +1 -1
  363. package/dist/version-check.js +10 -0
  364. package/dist/version-check.js.map +1 -1
  365. package/package.json +12 -8
  366. package/dist/agents/agent-config-loader.d.ts +0 -60
  367. package/dist/agents/agent-config-loader.d.ts.map +0 -1
  368. package/dist/agents/agent-config-loader.js +0 -402
  369. package/dist/agents/agent-config-loader.js.map +0 -1
  370. package/dist/agents/agent-config-presets.d.ts +0 -10
  371. package/dist/agents/agent-config-presets.d.ts.map +0 -1
  372. package/dist/agents/agent-config-presets.js +0 -940
  373. package/dist/agents/agent-config-presets.js.map +0 -1
  374. package/dist/agents/agent-config-types.d.ts +0 -145
  375. package/dist/agents/agent-config-types.d.ts.map +0 -1
  376. package/dist/agents/agent-config-types.js +0 -12
  377. package/dist/agents/agent-config-types.js.map +0 -1
  378. package/dist/agents/agent-detection.d.ts +0 -35
  379. package/dist/agents/agent-detection.d.ts.map +0 -1
  380. package/dist/agents/agent-detection.js +0 -110
  381. package/dist/agents/agent-detection.js.map +0 -1
  382. package/dist/agents/aggregator.d.ts +0 -19
  383. package/dist/agents/aggregator.d.ts.map +0 -1
  384. package/dist/agents/aggregator.js +0 -141
  385. package/dist/agents/aggregator.js.map +0 -1
  386. package/dist/agents/cli-backend.d.ts +0 -32
  387. package/dist/agents/cli-backend.d.ts.map +0 -1
  388. package/dist/agents/cli-backend.js +0 -271
  389. package/dist/agents/cli-backend.js.map +0 -1
  390. package/dist/agents/council-types.d.ts +0 -115
  391. package/dist/agents/council-types.d.ts.map +0 -1
  392. package/dist/agents/council-types.js +0 -81
  393. package/dist/agents/council-types.js.map +0 -1
  394. package/dist/agents/council.d.ts +0 -112
  395. package/dist/agents/council.d.ts.map +0 -1
  396. package/dist/agents/council.js +0 -722
  397. package/dist/agents/council.js.map +0 -1
  398. package/dist/agents/decomposer.d.ts +0 -33
  399. package/dist/agents/decomposer.d.ts.map +0 -1
  400. package/dist/agents/decomposer.js +0 -138
  401. package/dist/agents/decomposer.js.map +0 -1
  402. package/dist/agents/dynamic-tools.d.ts +0 -52
  403. package/dist/agents/dynamic-tools.d.ts.map +0 -1
  404. package/dist/agents/dynamic-tools.js +0 -395
  405. package/dist/agents/dynamic-tools.js.map +0 -1
  406. package/dist/agents/index.d.ts +0 -29
  407. package/dist/agents/index.d.ts.map +0 -1
  408. package/dist/agents/index.js +0 -29
  409. package/dist/agents/index.js.map +0 -1
  410. package/dist/agents/installer.d.ts +0 -39
  411. package/dist/agents/installer.d.ts.map +0 -1
  412. package/dist/agents/installer.js +0 -205
  413. package/dist/agents/installer.js.map +0 -1
  414. package/dist/agents/orchestrator.d.ts +0 -106
  415. package/dist/agents/orchestrator.d.ts.map +0 -1
  416. package/dist/agents/orchestrator.js +0 -363
  417. package/dist/agents/orchestrator.js.map +0 -1
  418. package/dist/agents/sdk-backend.d.ts +0 -63
  419. package/dist/agents/sdk-backend.d.ts.map +0 -1
  420. package/dist/agents/sdk-backend.js +0 -489
  421. package/dist/agents/sdk-backend.js.map +0 -1
  422. package/dist/agents/swarm-types.d.ts +0 -84
  423. package/dist/agents/swarm-types.d.ts.map +0 -1
  424. package/dist/agents/swarm-types.js +0 -20
  425. package/dist/agents/swarm-types.js.map +0 -1
  426. package/dist/agents/swarm.d.ts +0 -79
  427. package/dist/agents/swarm.d.ts.map +0 -1
  428. package/dist/agents/swarm.js +0 -375
  429. package/dist/agents/swarm.js.map +0 -1
  430. package/dist/agents/tools.d.ts +0 -26
  431. package/dist/agents/tools.d.ts.map +0 -1
  432. package/dist/agents/tools.js +0 -776
  433. package/dist/agents/tools.js.map +0 -1
  434. package/dist/agents/types.d.ts +0 -108
  435. package/dist/agents/types.d.ts.map +0 -1
  436. package/dist/agents/types.js +0 -43
  437. package/dist/agents/types.js.map +0 -1
  438. package/dist/api-server.d.ts +0 -36
  439. package/dist/api-server.d.ts.map +0 -1
  440. package/dist/api-server.js +0 -255
  441. package/dist/api-server.js.map +0 -1
  442. package/dist/auto-checkpoint.d.ts +0 -35
  443. package/dist/auto-checkpoint.d.ts.map +0 -1
  444. package/dist/auto-checkpoint.js +0 -143
  445. package/dist/auto-checkpoint.js.map +0 -1
  446. package/dist/background-jobs.d.ts +0 -45
  447. package/dist/background-jobs.d.ts.map +0 -1
  448. package/dist/background-jobs.js +0 -127
  449. package/dist/background-jobs.js.map +0 -1
  450. package/dist/branching.d.ts +0 -56
  451. package/dist/branching.d.ts.map +0 -1
  452. package/dist/branching.js +0 -211
  453. package/dist/branching.js.map +0 -1
  454. package/dist/cli/agent.d.ts +0 -9
  455. package/dist/cli/agent.d.ts.map +0 -1
  456. package/dist/cli/agent.js +0 -314
  457. package/dist/cli/agent.js.map +0 -1
  458. package/dist/cli/commands.d.ts +0 -12
  459. package/dist/cli/commands.d.ts.map +0 -1
  460. package/dist/cli/commands.js +0 -943
  461. package/dist/cli/commands.js.map +0 -1
  462. package/dist/cli/index.d.ts +0 -8
  463. package/dist/cli/index.d.ts.map +0 -1
  464. package/dist/cli/index.js +0 -237
  465. package/dist/cli/index.js.map +0 -1
  466. package/dist/cli/types.d.ts +0 -33
  467. package/dist/cli/types.d.ts.map +0 -1
  468. package/dist/cli/types.js +0 -21
  469. package/dist/cli/types.js.map +0 -1
  470. package/dist/companions.d.ts +0 -54
  471. package/dist/companions.d.ts.map +0 -1
  472. package/dist/companions.js +0 -440
  473. package/dist/companions.js.map +0 -1
  474. package/dist/completion.d.ts +0 -75
  475. package/dist/completion.d.ts.map +0 -1
  476. package/dist/completion.js +0 -234
  477. package/dist/completion.js.map +0 -1
  478. package/dist/file-watcher.d.ts +0 -91
  479. package/dist/file-watcher.d.ts.map +0 -1
  480. package/dist/file-watcher.js +0 -269
  481. package/dist/file-watcher.js.map +0 -1
  482. package/dist/hud/theme-packs/api.d.ts +0 -51
  483. package/dist/hud/theme-packs/api.d.ts.map +0 -1
  484. package/dist/hud/theme-packs/api.js +0 -145
  485. package/dist/hud/theme-packs/api.js.map +0 -1
  486. package/dist/hud/theme-packs/index.d.ts +0 -18
  487. package/dist/hud/theme-packs/index.d.ts.map +0 -1
  488. package/dist/hud/theme-packs/index.js +0 -38
  489. package/dist/hud/theme-packs/index.js.map +0 -1
  490. package/dist/hud/theme-packs/types.d.ts +0 -29
  491. package/dist/hud/theme-packs/types.d.ts.map +0 -1
  492. package/dist/hud/theme-packs/types.js +0 -9
  493. package/dist/hud/theme-packs/types.js.map +0 -1
  494. package/dist/idle-eviction.d.ts +0 -34
  495. package/dist/idle-eviction.d.ts.map +0 -1
  496. package/dist/idle-eviction.js +0 -78
  497. package/dist/idle-eviction.js.map +0 -1
  498. package/dist/keyboard.d.ts +0 -57
  499. package/dist/keyboard.d.ts.map +0 -1
  500. package/dist/keyboard.js +0 -265
  501. package/dist/keyboard.js.map +0 -1
  502. package/dist/model-router.d.ts +0 -67
  503. package/dist/model-router.d.ts.map +0 -1
  504. package/dist/model-router.js.map +0 -1
  505. package/dist/providers/openai-compat-shims.d.ts +0 -31
  506. package/dist/providers/openai-compat-shims.d.ts.map +0 -1
  507. package/dist/providers/openai-compat-shims.js +0 -179
  508. package/dist/providers/openai-compat-shims.js.map +0 -1
  509. package/dist/sandbox-native.d.ts.map +0 -1
  510. package/dist/sandbox-native.js.map +0 -1
  511. package/dist/sandbox.d.ts.map +0 -1
  512. package/dist/sandbox.js.map +0 -1
  513. package/dist/session-timeout.d.ts +0 -31
  514. package/dist/session-timeout.d.ts.map +0 -1
  515. package/dist/session-timeout.js +0 -100
  516. package/dist/session-timeout.js.map +0 -1
  517. package/dist/smart-router.d.ts +0 -73
  518. package/dist/smart-router.d.ts.map +0 -1
  519. package/dist/smart-router.js +0 -332
  520. package/dist/smart-router.js.map +0 -1
  521. package/dist/terminal-recording.d.ts +0 -55
  522. package/dist/terminal-recording.d.ts.map +0 -1
  523. package/dist/terminal-recording.js +0 -182
  524. package/dist/terminal-recording.js.map +0 -1
  525. package/dist/tmux.d.ts +0 -35
  526. package/dist/tmux.d.ts.map +0 -1
  527. package/dist/tmux.js +0 -106
  528. package/dist/tmux.js.map +0 -1
  529. package/dist/ui/modals.d.ts.map +0 -1
  530. package/dist/ui/modals.js.map +0 -1
  531. package/dist/ui/pack-picker.d.ts +0 -12
  532. package/dist/ui/pack-picker.d.ts.map +0 -1
  533. package/dist/ui/pack-picker.js +0 -101
  534. package/dist/ui/pack-picker.js.map +0 -1
  535. package/dist/ui/theme-picker.d.ts +0 -24
  536. package/dist/ui/theme-picker.d.ts.map +0 -1
  537. package/dist/ui/theme-picker.js +0 -190
  538. package/dist/ui/theme-picker.js.map +0 -1
package/dist/config.js CHANGED
@@ -5,187 +5,195 @@
5
5
  * Config is stored in ~/.config/calliope/config.json (or platform equivalent)
6
6
  */
7
7
  import Conf from 'conf';
8
- import { randomUUID } from 'crypto';
9
8
  const DEFAULT_CONFIG = {
10
9
  setupComplete: false,
11
10
  defaultProvider: 'auto',
12
- persona: 'calliope',
13
11
  maxIterations: 0, // 0 = unlimited (circuit breakers provide safety)
14
12
  maxIterationTime: 600, // 10 minutes per iteration (seconds, 0 = no limit)
15
- fancyOutput: true,
16
13
  autoSaveHistory: true,
17
14
  autoUpgrade: true,
18
15
  collapseTools: false,
19
- collapseThinking: false,
20
16
  toolDisplayLimit: 0, // 0 = show all expanded
21
- layout: 'response-bottom', // Default: tools scroll up, response at bottom
22
- density: 'normal', // normal or compact
23
- activeSkin: 'clean',
24
- activePalette: 'default',
25
- activeCompanion: 'calliope',
26
- companionIntensity: 'immersive',
27
- useEmojis: true,
28
17
  diffStyle: 'inline',
29
- borderStyle: 'rounded',
30
- bannerStyle: 'full',
31
- renderer: 'ink',
32
- circuitBreakersEnabled: true,
18
+ circuitBreakersEnabled: false,
33
19
  sandboxMode: 'auto',
34
- smartRoutingEnabled: false,
35
- smartRoutingCostSensitivity: 0.3,
36
- recordSessions: true,
37
- recordingRetentionDays: 0,
38
20
  sessionLogLimit: 0, // Unlimited by default; set > 0 to cap retained session log items
39
21
  };
40
- // Pre-migrate config file before Conf validates schema
41
- // (Conf validates before migrations run, so we patch the JSON directly)
42
- function preMigrateConfig() {
43
- try {
44
- const fs = require('fs');
45
- const path = require('path');
46
- const envPaths = require('env-paths');
47
- const configPath = path.join(envPaths('calliope').config, 'config.json');
48
- if (!fs.existsSync(configPath))
49
- return;
50
- const raw = fs.readFileSync(configPath, 'utf-8');
51
- const data = JSON.parse(raw);
52
- let changed = false;
53
- const validPersonas = ['calliope', 'muse', 'minimal'];
54
- if (data.persona === 'professional') {
55
- data.persona = 'calliope';
56
- changed = true;
57
- }
58
- if (data.persona && !validPersonas.includes(data.persona)) {
59
- data.persona = 'calliope';
60
- changed = true;
61
- }
62
- if (data.activeCompanion === 'professional') {
63
- data.activeCompanion = 'calliope';
64
- changed = true;
65
- }
66
- if (changed)
67
- fs.writeFileSync(configPath, JSON.stringify(data, null, '\t'));
22
+ /**
23
+ * Resolve the directory conf stores `config.json` in, and hard-guard tests.
24
+ *
25
+ * `CALLIOPE_CONFIG_DIR` overrides conf's default per-OS config location (conf's
26
+ * `cwd` option). It is the single seam that lets the test suite point every
27
+ * config read/write at a throwaway directory instead of the user's real store.
28
+ *
29
+ * The guard is the safety net behind #217: the config test suite calls
30
+ * `resetConfig()` (conf's `clear()`) in beforeEach/afterEach, and under the old
31
+ * default path that wiped the developer's real store on every run. Under Vitest
32
+ * we therefore REFUSE to open the real store unless the isolation setup
33
+ * (tests/setup/isolate-stores.ts) has pointed CALLIOPE_CONFIG_DIR at a temp dir.
34
+ * Exported so the guard is unit-testable without spawning a subprocess.
35
+ *
36
+ * Outside tests with the override unset it returns `undefined`, which conf
37
+ * treats as "use the env-paths default" (a falsy `cwd` is ignored by conf).
38
+ */
39
+ export function resolveConfigCwd(env = process.env) {
40
+ const dir = env.CALLIOPE_CONFIG_DIR;
41
+ if (env.VITEST && !dir) {
42
+ throw new Error('tests must set CALLIOPE_CONFIG_DIR — refusing to touch the real config store');
68
43
  }
69
- catch { /* ignore migration errors */ }
44
+ return dir || undefined;
70
45
  }
71
- preMigrateConfig();
72
46
  // Create config store
73
47
  const config = new Conf({
74
48
  projectName: 'calliope',
49
+ cwd: resolveConfigCwd(),
75
50
  defaults: DEFAULT_CONFIG,
76
51
  schema: {
77
52
  setupComplete: { type: 'boolean' },
78
53
  defaultProvider: { type: 'string' },
79
54
  defaultModel: { type: 'string' },
80
- anthropicApiKey: { type: 'string' },
81
- googleApiKey: { type: 'string' },
82
- openaiApiKey: { type: 'string' },
83
- togetherApiKey: { type: 'string' },
84
- openrouterApiKey: { type: 'string' },
85
- groqApiKey: { type: 'string' },
86
- fireworksApiKey: { type: 'string' },
87
- mistralApiKey: { type: 'string' },
88
- ollamaBaseUrl: { type: 'string' },
89
- ai21ApiKey: { type: 'string' },
90
- huggingfaceApiKey: { type: 'string' },
91
- litellmBaseUrl: { type: 'string' },
92
- litellmApiKey: { type: 'string' },
93
- bedrockApiKey: { type: 'string' },
94
- bedrockBaseUrl: { type: 'string' },
95
- awsRegion: { type: 'string' },
96
- awsProfile: { type: 'string' },
97
- openaiCompatBaseUrl: { type: 'string' },
98
- openaiCompatApiKey: { type: 'string' },
99
- openaiCompatModel: { type: 'string' },
100
- persona: { type: 'string', enum: ['calliope', 'muse', 'minimal'] },
55
+ providers: { type: 'object' },
56
+ fleet: { type: 'object' },
101
57
  maxIterations: { type: 'number', minimum: 0, maximum: 1000000 },
102
58
  maxIterationTime: { type: 'number', minimum: 0, maximum: 3600 },
103
- fancyOutput: { type: 'boolean' },
104
59
  autoSaveHistory: { type: 'boolean' },
105
- workspaceRoot: { type: 'string' },
106
60
  autoUpgrade: { type: 'boolean' },
107
61
  collapseTools: { type: 'boolean' },
108
- collapseThinking: { type: 'boolean' },
109
62
  toolDisplayLimit: { type: 'number', minimum: 0, maximum: 100 },
110
- layout: { type: 'string', enum: ['classic', 'response-top', 'response-bottom', 'split', 'zen', 'focus', 'dashboard', 'minimal'] },
111
- density: { type: 'string', enum: ['normal', 'compact'] },
112
- activeSkin: { type: 'string' },
113
- activePalette: { type: 'string' },
114
- activeCompanion: { type: 'string' },
115
- activeThemePack: { type: 'string' },
116
- companionIntensity: { type: 'string', enum: ['professional', 'immersive'] },
117
63
  diffStyle: { type: 'string', enum: ['inline', 'unified', 'side-by-side'] },
118
- borderStyle: { type: 'string', enum: ['rounded', 'sharp', 'double', 'ascii', 'none'] },
119
- bannerStyle: { type: 'string', enum: ['full', 'compact', 'none'] },
120
- renderer: { type: 'string', enum: ['ink', 'legacy', 'headless'] },
121
- useEmojis: { type: 'boolean' },
122
64
  circuitBreakersEnabled: { type: 'boolean' },
123
65
  sandboxMode: { type: 'string', enum: ['auto', 'native', 'docker', 'off'] },
124
- smartRoutingEnabled: { type: 'boolean' },
125
- smartRoutingCostSensitivity: { type: 'number', minimum: 0, maximum: 1 },
126
- recordSessions: { type: 'boolean' },
127
- sessionTimeoutMs: { type: 'number', minimum: 0 },
128
- recordingRetentionDays: { type: 'number', minimum: 0 },
66
+ routing: { type: 'object' },
129
67
  sessionLogLimit: { type: 'number', minimum: 0, maximum: 100000 },
130
- apiToken: { type: 'string' },
68
+ audit: { type: 'object' },
69
+ budget: { type: 'object' },
70
+ policy: { type: 'object' },
71
+ plugins: { type: 'object' },
131
72
  },
132
73
  });
133
- /**
134
- * Get the full config object
135
- */
136
- export function getConfig() {
137
- return config.store;
74
+ // ---------------------------------------------------------------------------
75
+ // Provider credential resolution
76
+ //
77
+ // Environment variables take precedence over stored config for every provider
78
+ // except the openai-compat base URL, which historically preferred the stored
79
+ // value — preserved here byte-for-byte. `model` has no environment fallback.
80
+ // ---------------------------------------------------------------------------
81
+ const PROVIDER_ENV = {
82
+ anthropic: { apiKey: 'ANTHROPIC_API_KEY' },
83
+ google: { apiKey: 'GOOGLE_API_KEY' },
84
+ openai: { apiKey: 'OPENAI_API_KEY' },
85
+ together: { apiKey: 'TOGETHER_API_KEY' },
86
+ openrouter: { apiKey: 'OPENROUTER_API_KEY' },
87
+ groq: { apiKey: 'GROQ_API_KEY' },
88
+ fireworks: { apiKey: 'FIREWORKS_API_KEY' },
89
+ mistral: { apiKey: 'MISTRAL_API_KEY' },
90
+ ollama: { baseUrl: 'OLLAMA_BASE_URL' },
91
+ ai21: { apiKey: 'AI21_API_KEY' },
92
+ huggingface: { apiKey: 'HUGGINGFACE_API_KEY' },
93
+ litellm: { apiKey: 'LITELLM_API_KEY', baseUrl: 'LITELLM_BASE_URL' },
94
+ bedrock: { apiKey: 'BEDROCK_API_KEY', baseUrl: 'BEDROCK_BASE_URL', region: ['AWS_REGION', 'AWS_DEFAULT_REGION'], profile: 'AWS_PROFILE' },
95
+ 'openai-compat': { apiKey: 'OPENAI_COMPAT_API_KEY', baseUrl: 'OPENAI_COMPAT_BASE_URL' },
96
+ };
97
+ function firstEnv(names) {
98
+ if (!names)
99
+ return undefined;
100
+ for (const name of Array.isArray(names) ? names : [names]) {
101
+ const value = process.env[name];
102
+ if (value)
103
+ return value;
104
+ }
105
+ return undefined;
138
106
  }
139
107
  /**
140
- * Get a specific config value
108
+ * Resolve credentials for a provider, merging the stored nested config with the
109
+ * same environment-variable fallbacks that existed before the config shrink.
141
110
  */
142
- export function get(key) {
143
- return config.get(key);
111
+ export function getProviderCred(provider) {
112
+ const stored = (config.get('providers') ?? {})[provider] ?? {};
113
+ const env = PROVIDER_ENV[provider] ?? {};
114
+ // openai-compat prefers the stored base URL over the env var; all others prefer env.
115
+ const baseUrl = provider === 'openai-compat'
116
+ ? (stored.baseUrl || firstEnv(env.baseUrl))
117
+ : (firstEnv(env.baseUrl) || stored.baseUrl);
118
+ return {
119
+ apiKey: firstEnv(env.apiKey) || stored.apiKey,
120
+ baseUrl,
121
+ model: stored.model,
122
+ region: firstEnv(env.region) || stored.region,
123
+ profile: firstEnv(env.profile) || stored.profile,
124
+ };
144
125
  }
145
126
  /**
146
- * Set a config value with validation
127
+ * Write (merge) credentials for a provider into the nested `providers` map.
128
+ * Only the fields present in `patch` are updated. Validates non-empty API keys
129
+ * and well-formed base URLs, matching the old flat-key validation.
147
130
  */
148
- export function set(key, value) {
149
- // Validate API keys are non-empty strings when set
150
- if (key.toString().endsWith('ApiKey') && value !== undefined) {
151
- if (typeof value !== 'string' || value.trim().length === 0) {
152
- throw new Error(`API key for ${key} must be a non-empty string`);
131
+ export function setProviderCred(provider, patch) {
132
+ if (patch.apiKey !== undefined) {
133
+ if (typeof patch.apiKey !== 'string' || patch.apiKey.trim().length === 0) {
134
+ throw new Error(`API key for ${provider} must be a non-empty string`);
153
135
  }
154
136
  }
155
- // Validate URLs are proper format
156
- if (key.toString().endsWith('BaseUrl') && value !== undefined) {
157
- if (typeof value !== 'string') {
158
- throw new Error(`Base URL for ${key} must be a string`);
137
+ if (patch.baseUrl !== undefined) {
138
+ if (typeof patch.baseUrl !== 'string') {
139
+ throw new Error(`Base URL for ${provider} must be a string`);
159
140
  }
160
141
  try {
161
- new URL(value);
142
+ new URL(patch.baseUrl);
162
143
  }
163
144
  catch {
164
- throw new Error(`Base URL for ${key} must be a valid URL`);
165
- }
166
- }
167
- // Validate numeric bounds
168
- if (key === 'maxIterations' && typeof value === 'number') {
169
- if (value < 0 || value > 1000000) {
170
- throw new Error('maxIterations must be between 0 and 1000000 (0 = unlimited)');
145
+ throw new Error(`Base URL for ${provider} must be a valid URL`);
171
146
  }
172
147
  }
173
- if (key === 'sessionLogLimit' && typeof value === 'number') {
174
- if (value < 0 || value > 100000) {
175
- throw new Error('sessionLogLimit must be between 0 and 100000 (0 = unlimited)');
148
+ const all = { ...(config.get('providers') ?? {}) };
149
+ const merged = { ...(all[provider] ?? {}) };
150
+ for (const [key, value] of Object.entries(patch)) {
151
+ if (value !== undefined) {
152
+ merged[key] = value;
176
153
  }
177
154
  }
155
+ all[provider] = merged;
156
+ config.set('providers', all);
157
+ }
158
+ /**
159
+ * The credential environment variable(s) a provider reads, surfaced in the
160
+ * "how to fix" hint when an explicitly-selected provider has no credential
161
+ * (see providers/index.ts ProviderUnavailableError). `region`/`profile` arrays
162
+ * are intentionally omitted — only the primary apiKey/baseUrl var is a hint.
163
+ */
164
+ export function getProviderEnvVars(provider) {
165
+ const env = PROVIDER_ENV[provider] ?? {};
166
+ return { apiKey: env.apiKey, baseUrl: env.baseUrl };
167
+ }
168
+ /**
169
+ * Get the full config object
170
+ */
171
+ export function getConfig() {
172
+ return config.store;
173
+ }
174
+ /**
175
+ * Get a specific config value
176
+ */
177
+ export function get(key) {
178
+ return config.get(key);
179
+ }
180
+ /**
181
+ * Set a config value with validation
182
+ */
183
+ export function set(key, value) {
184
+ validateConfigValue(key, value);
178
185
  config.set(key, value);
179
186
  }
180
187
  /**
181
188
  * Set multiple config values with validation
182
189
  */
190
+ export function unset(key) {
191
+ config.delete(key);
192
+ }
183
193
  export function setMultiple(values) {
184
194
  // Validate all values first before setting any
185
195
  for (const [key, value] of Object.entries(values)) {
186
- const typedKey = key;
187
- // Will throw if validation fails
188
- validateConfigValue(typedKey, value);
196
+ validateConfigValue(key, value);
189
197
  }
190
198
  // All validations passed, now set values
191
199
  for (const [key, value] of Object.entries(values)) {
@@ -196,22 +204,6 @@ export function setMultiple(values) {
196
204
  * Validate a single config value without setting it
197
205
  */
198
206
  function validateConfigValue(key, value) {
199
- if (key.toString().endsWith('ApiKey') && value !== undefined) {
200
- if (typeof value !== 'string' || value.trim().length === 0) {
201
- throw new Error(`API key for ${key} must be a non-empty string`);
202
- }
203
- }
204
- if (key.toString().endsWith('BaseUrl') && value !== undefined && value !== null) {
205
- if (typeof value !== 'string') {
206
- throw new Error(`Base URL for ${key} must be a string`);
207
- }
208
- try {
209
- new URL(value);
210
- }
211
- catch {
212
- throw new Error(`Base URL for ${key} must be a valid URL`);
213
- }
214
- }
215
207
  if (key === 'maxIterations' && typeof value === 'number') {
216
208
  if (value < 0 || value > 1000000) {
217
209
  throw new Error('maxIterations must be between 0 and 1000000 (0 = unlimited)');
@@ -252,33 +244,34 @@ export function resetConfig() {
252
244
  */
253
245
  export function getConfiguredProviders() {
254
246
  const providers = [];
255
- if (config.get('anthropicApiKey') || process.env.ANTHROPIC_API_KEY)
247
+ if (getProviderCred('anthropic').apiKey)
256
248
  providers.push('anthropic');
257
- if (config.get('googleApiKey') || process.env.GOOGLE_API_KEY)
249
+ if (getProviderCred('google').apiKey)
258
250
  providers.push('google');
259
- if (config.get('openaiApiKey') || process.env.OPENAI_API_KEY)
251
+ if (getProviderCred('openai').apiKey)
260
252
  providers.push('openai');
261
- if (config.get('togetherApiKey') || process.env.TOGETHER_API_KEY)
253
+ if (getProviderCred('together').apiKey)
262
254
  providers.push('together');
263
- if (config.get('openrouterApiKey') || process.env.OPENROUTER_API_KEY)
255
+ if (getProviderCred('openrouter').apiKey)
264
256
  providers.push('openrouter');
265
- if (config.get('groqApiKey') || process.env.GROQ_API_KEY)
257
+ if (getProviderCred('groq').apiKey)
266
258
  providers.push('groq');
267
- if (config.get('fireworksApiKey') || process.env.FIREWORKS_API_KEY)
259
+ if (getProviderCred('fireworks').apiKey)
268
260
  providers.push('fireworks');
269
- if (config.get('mistralApiKey') || process.env.MISTRAL_API_KEY)
261
+ if (getProviderCred('mistral').apiKey)
270
262
  providers.push('mistral');
271
- if (config.get('ollamaBaseUrl') || process.env.OLLAMA_BASE_URL)
263
+ if (getProviderCred('ollama').baseUrl)
272
264
  providers.push('ollama');
273
- if (config.get('ai21ApiKey') || process.env.AI21_API_KEY)
265
+ if (getProviderCred('ai21').apiKey)
274
266
  providers.push('ai21');
275
- if (config.get('huggingfaceApiKey') || process.env.HUGGINGFACE_API_KEY)
267
+ if (getProviderCred('huggingface').apiKey)
276
268
  providers.push('huggingface');
277
- if (config.get('litellmBaseUrl') || process.env.LITELLM_BASE_URL)
269
+ if (getProviderCred('litellm').baseUrl)
278
270
  providers.push('litellm');
279
- if (config.get('bedrockApiKey') || process.env.BEDROCK_API_KEY || config.get('bedrockBaseUrl') || process.env.BEDROCK_BASE_URL || process.env.AWS_ACCESS_KEY_ID || process.env.AWS_PROFILE)
271
+ const bedrock = getProviderCred('bedrock');
272
+ if (bedrock.apiKey || bedrock.baseUrl || process.env.AWS_ACCESS_KEY_ID || process.env.AWS_PROFILE)
280
273
  providers.push('bedrock');
281
- if (config.get('openaiCompatBaseUrl') || process.env.OPENAI_COMPAT_BASE_URL)
274
+ if (getProviderCred('openai-compat').baseUrl)
282
275
  providers.push('openai-compat');
283
276
  return providers;
284
277
  }
@@ -286,172 +279,111 @@ export function getConfiguredProviders() {
286
279
  * Get API key for a provider
287
280
  */
288
281
  export function getApiKey(provider) {
289
- // Special handling for openai-compat: check env/config, default to 'openai-compat'
290
- if (provider === 'openai-compat') {
291
- return process.env.OPENAI_COMPAT_API_KEY || config.get('openaiCompatApiKey') || 'openai-compat';
292
- }
293
- const keyMap = {
294
- anthropic: 'anthropicApiKey',
295
- google: 'googleApiKey',
296
- openai: 'openaiApiKey',
297
- together: 'togetherApiKey',
298
- openrouter: 'openrouterApiKey',
299
- groq: 'groqApiKey',
300
- fireworks: 'fireworksApiKey',
301
- mistral: 'mistralApiKey',
302
- ollama: 'ollamaBaseUrl', // Returns base URL for Ollama
303
- ai21: 'ai21ApiKey',
304
- huggingface: 'huggingfaceApiKey',
305
- litellm: 'litellmApiKey',
306
- bedrock: 'bedrockApiKey',
307
- 'openai-compat': undefined, // handled above
308
- auto: undefined,
309
- };
310
- const key = keyMap[provider];
311
- if (!key)
312
- return undefined;
313
- // Check environment variable first, then config
314
- const envMap = {
315
- anthropicApiKey: 'ANTHROPIC_API_KEY',
316
- googleApiKey: 'GOOGLE_API_KEY',
317
- openaiApiKey: 'OPENAI_API_KEY',
318
- togetherApiKey: 'TOGETHER_API_KEY',
319
- openrouterApiKey: 'OPENROUTER_API_KEY',
320
- groqApiKey: 'GROQ_API_KEY',
321
- fireworksApiKey: 'FIREWORKS_API_KEY',
322
- mistralApiKey: 'MISTRAL_API_KEY',
323
- ollamaBaseUrl: 'OLLAMA_BASE_URL',
324
- ai21ApiKey: 'AI21_API_KEY',
325
- huggingfaceApiKey: 'HUGGINGFACE_API_KEY',
326
- litellmApiKey: 'LITELLM_API_KEY',
327
- bedrockApiKey: 'BEDROCK_API_KEY',
328
- bedrockBaseUrl: 'BEDROCK_BASE_URL',
329
- };
330
- const envVar = envMap[key];
331
- if (envVar && process.env[envVar]) {
332
- return process.env[envVar];
333
- }
334
- return config.get(key);
282
+ // Ollama has no API key — its "key" is the base URL.
283
+ if (provider === 'ollama')
284
+ return getProviderCred('ollama').baseUrl;
285
+ // openai-compat defaults to a placeholder key when none is configured.
286
+ if (provider === 'openai-compat')
287
+ return getProviderCred('openai-compat').apiKey || 'openai-compat';
288
+ return getProviderCred(provider).apiKey;
335
289
  }
336
290
  /**
337
- * Get base URL for a provider (for Ollama/LiteLLM)
291
+ * Get base URL for a provider (for Ollama/LiteLLM/Bedrock/openai-compat)
338
292
  */
339
293
  export function getBaseUrl(provider) {
340
- if (provider === 'ollama') {
341
- return process.env.OLLAMA_BASE_URL || config.get('ollamaBaseUrl') || 'http://localhost:11434';
342
- }
343
- if (provider === 'litellm') {
344
- return process.env.LITELLM_BASE_URL || config.get('litellmBaseUrl') || 'http://localhost:4000';
345
- }
346
- if (provider === 'bedrock') {
347
- return process.env.BEDROCK_BASE_URL || config.get('bedrockBaseUrl') || undefined;
348
- }
349
- if (provider === 'openai-compat') {
350
- return config.get('openaiCompatBaseUrl') || process.env.OPENAI_COMPAT_BASE_URL;
351
- }
294
+ if (provider === 'ollama')
295
+ return getProviderCred('ollama').baseUrl || 'http://localhost:11434';
296
+ if (provider === 'litellm')
297
+ return getProviderCred('litellm').baseUrl || 'http://localhost:4000';
298
+ if (provider === 'bedrock')
299
+ return getProviderCred('bedrock').baseUrl;
300
+ if (provider === 'openai-compat')
301
+ return getProviderCred('openai-compat').baseUrl;
352
302
  return undefined;
353
303
  }
354
- // Built-in profiles
355
- const BUILTIN_PROFILES = {
356
- fast: {
357
- provider: 'groq',
358
- model: 'llama-3.3-70b-versatile',
359
- persona: 'minimal',
360
- confirmMode: false,
361
- },
362
- smart: {
363
- provider: 'anthropic',
364
- model: 'claude-sonnet-4-20250514',
365
- persona: 'calliope',
366
- confirmMode: true,
367
- },
368
- cheap: {
369
- provider: 'google',
370
- model: 'gemini-2.0-flash',
371
- persona: 'calliope',
372
- confirmMode: true,
373
- },
374
- local: {
375
- provider: 'ollama',
376
- model: 'llama3.3',
377
- persona: 'calliope',
378
- confirmMode: true,
379
- },
380
- };
381
- /**
382
- * Get a profile by name (built-in or custom)
383
- */
384
- export function getProfile(name) {
385
- // Check built-in profiles first
386
- if (BUILTIN_PROFILES[name]) {
387
- return BUILTIN_PROFILES[name];
388
- }
389
- // Check custom profiles
390
- const profiles = config.get('profiles') || {};
391
- return profiles[name];
392
- }
393
- /**
394
- * Save a custom profile
395
- */
396
- export function saveProfile(name, profile) {
397
- const profiles = config.get('profiles') || {};
398
- profiles[name] = profile;
399
- config.set('profiles', profiles);
400
- }
304
+ // ---------------------------------------------------------------------------
305
+ // One-time migration to the nested provider-credential config format (#193)
306
+ // ---------------------------------------------------------------------------
307
+ // Old flat credential keys → [nested provider, field].
308
+ const LEGACY_FLAT_CREDS = [
309
+ ['anthropicApiKey', 'anthropic', 'apiKey'],
310
+ ['googleApiKey', 'google', 'apiKey'],
311
+ ['openaiApiKey', 'openai', 'apiKey'],
312
+ ['togetherApiKey', 'together', 'apiKey'],
313
+ ['openrouterApiKey', 'openrouter', 'apiKey'],
314
+ ['groqApiKey', 'groq', 'apiKey'],
315
+ ['fireworksApiKey', 'fireworks', 'apiKey'],
316
+ ['mistralApiKey', 'mistral', 'apiKey'],
317
+ ['ai21ApiKey', 'ai21', 'apiKey'],
318
+ ['huggingfaceApiKey', 'huggingface', 'apiKey'],
319
+ ['ollamaBaseUrl', 'ollama', 'baseUrl'],
320
+ ['litellmBaseUrl', 'litellm', 'baseUrl'],
321
+ ['litellmApiKey', 'litellm', 'apiKey'],
322
+ ['bedrockApiKey', 'bedrock', 'apiKey'],
323
+ ['bedrockBaseUrl', 'bedrock', 'baseUrl'],
324
+ ['awsRegion', 'bedrock', 'region'],
325
+ ['awsProfile', 'bedrock', 'profile'],
326
+ ['openaiCompatBaseUrl', 'openai-compat', 'baseUrl'],
327
+ ['openaiCompatApiKey', 'openai-compat', 'apiKey'],
328
+ ['openaiCompatModel', 'openai-compat', 'model'],
329
+ ];
330
+ // The complete set of keys the current schema recognises. Anything else in a
331
+ // stored config is legacy (old flat creds, renamed routing keys, or junk from
332
+ // removed subsystems) and is dropped by the migration.
333
+ const SURVIVOR_KEYS = new Set([
334
+ 'setupComplete', 'defaultProvider', 'defaultModel', 'providers', 'fleet',
335
+ 'maxIterations', 'maxIterationTime', 'autoSaveHistory', 'autoUpgrade',
336
+ 'collapseTools', 'toolDisplayLimit', 'diffStyle', 'circuitBreakersEnabled',
337
+ 'sandboxMode', 'routing', 'sessionLogLimit',
338
+ // Governance (#189)
339
+ 'audit', 'budget', 'policy',
340
+ // Plugin trust (#137)
341
+ 'plugins',
342
+ ]);
401
343
  /**
402
- * Delete a custom profile
344
+ * Migrate a stored config from the pre-#193 flat format to the nested format.
345
+ * Runs once at startup and is idempotent — a second run is a no-op.
346
+ *
347
+ * Steps: (1) fold the old flat credential keys into `providers`, (2) rename the
348
+ * smart-routing keys into `routing`, (3) drop every remaining non-survivor key
349
+ * (cut settings + junk from removed subsystems). Values are read from a snapshot
350
+ * so the live deletes below don't disturb the reads.
403
351
  */
404
- export function deleteProfile(name) {
405
- if (BUILTIN_PROFILES[name]) {
406
- return false; // Can't delete built-in profiles
352
+ export function migrateV3() {
353
+ const store = { ...config.store };
354
+ const raw = config;
355
+ let hadFlatCred = false;
356
+ const providers = { ...(store.providers ?? {}) };
357
+ for (const [flatKey, provider, field] of LEGACY_FLAT_CREDS) {
358
+ if (flatKey in store) {
359
+ hadFlatCred = true;
360
+ const value = store[flatKey];
361
+ if (typeof value === 'string' && value.length > 0) {
362
+ providers[provider] = { ...(providers[provider] ?? {}), [field]: value };
363
+ }
364
+ }
407
365
  }
408
- const profiles = config.get('profiles') || {};
409
- if (profiles[name]) {
410
- delete profiles[name];
411
- config.set('profiles', profiles);
412
- return true;
366
+ // Fold the old smart-routing keys into the nested `routing` object.
367
+ if (('smartRoutingEnabled' in store || 'smartRoutingCostSensitivity' in store) && !('routing' in store)) {
368
+ const enabled = store.smartRoutingEnabled === true;
369
+ const costSensitivity = typeof store.smartRoutingCostSensitivity === 'number'
370
+ ? store.smartRoutingCostSensitivity
371
+ : 0.3;
372
+ config.set('routing', { enabled, costSensitivity });
413
373
  }
414
- return false;
415
- }
416
- /**
417
- * List all available profiles
418
- */
419
- export function listProfiles() {
420
- const result = [];
421
- // Add built-in profiles
422
- for (const [name, profile] of Object.entries(BUILTIN_PROFILES)) {
423
- result.push({ name, profile, builtin: true });
374
+ if (hadFlatCred && Object.keys(providers).length > 0) {
375
+ config.set('providers', providers);
424
376
  }
425
- // Add custom profiles
426
- const customProfiles = config.get('profiles') || {};
427
- for (const [name, profile] of Object.entries(customProfiles)) {
428
- result.push({ name, profile, builtin: false });
377
+ // Drop every stored key not in the current schema: old flat creds, the renamed
378
+ // routing keys, cut display settings, and junk from removed subsystems.
379
+ for (const key of Object.keys(store)) {
380
+ if (!SURVIVOR_KEYS.has(key))
381
+ raw.delete(key);
429
382
  }
430
- return result;
431
- }
432
- /**
433
- * Set the active profile
434
- */
435
- export function setActiveProfile(name) {
436
- config.set('activeProfile', name);
437
- }
438
- /**
439
- * Get the active profile name
440
- */
441
- export function getActiveProfile() {
442
- return config.get('activeProfile');
443
- }
444
- /**
445
- * Get or generate the API server Bearer token.
446
- * Generated once using crypto.randomUUID() and persisted in config.
447
- */
448
- export function getOrCreateApiToken() {
449
- let token = config.get('apiToken');
450
- if (!token) {
451
- token = randomUUID();
452
- config.set('apiToken', token);
383
+ if (hadFlatCred) {
384
+ console.error('calliope: migrated provider credentials to the new config format.');
453
385
  }
454
- return token;
455
386
  }
387
+ migrateV3();
456
388
  export default config;
457
389
  //# sourceMappingURL=config.js.map