dexto 1.3.0 → 1.5.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 (494) hide show
  1. package/README.md +87 -22
  2. package/dist/agents/agent-registry.json +9 -0
  3. package/dist/agents/agent-template.yml +2 -2
  4. package/dist/agents/coding-agent/coding-agent.yml +27 -16
  5. package/dist/agents/database-agent/database-agent.yml +2 -2
  6. package/dist/agents/default-agent.yml +9 -7
  7. package/dist/agents/github-agent/github-agent.yml +2 -2
  8. package/dist/agents/product-name-researcher/product-name-researcher.yml +2 -2
  9. package/dist/agents/talk2pdf-agent/talk2pdf-agent.yml +2 -2
  10. package/dist/analytics/events.d.ts +13 -6
  11. package/dist/analytics/events.d.ts.map +1 -1
  12. package/dist/analytics/index.d.ts +1 -1
  13. package/dist/analytics/index.d.ts.map +1 -1
  14. package/dist/analytics/index.js +6 -2
  15. package/dist/api/server-hono.d.ts.map +1 -1
  16. package/dist/api/server-hono.js +65 -9
  17. package/dist/cli/cli-subscriber.d.ts +4 -0
  18. package/dist/cli/cli-subscriber.d.ts.map +1 -1
  19. package/dist/cli/cli-subscriber.js +47 -3
  20. package/dist/cli/commands/create-app.d.ts +16 -14
  21. package/dist/cli/commands/create-app.d.ts.map +1 -1
  22. package/dist/cli/commands/create-app.js +626 -102
  23. package/dist/cli/commands/create-image.d.ts +7 -0
  24. package/dist/cli/commands/create-image.d.ts.map +1 -0
  25. package/dist/cli/commands/create-image.js +201 -0
  26. package/dist/cli/commands/helpers/formatters.d.ts.map +1 -1
  27. package/dist/cli/commands/helpers/formatters.js +9 -8
  28. package/dist/cli/commands/index.d.ts +2 -1
  29. package/dist/cli/commands/index.d.ts.map +1 -1
  30. package/dist/cli/commands/index.js +2 -1
  31. package/dist/cli/commands/init-app.js +7 -7
  32. package/dist/cli/commands/install.d.ts +0 -3
  33. package/dist/cli/commands/install.d.ts.map +1 -1
  34. package/dist/cli/commands/install.js +19 -70
  35. package/dist/cli/commands/interactive-commands/command-parser.d.ts +17 -14
  36. package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
  37. package/dist/cli/commands/interactive-commands/command-parser.js +7 -22
  38. package/dist/cli/commands/interactive-commands/commands.d.ts +4 -4
  39. package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
  40. package/dist/cli/commands/interactive-commands/commands.js +34 -42
  41. package/dist/cli/commands/interactive-commands/documentation-commands.d.ts.map +1 -1
  42. package/dist/cli/commands/interactive-commands/documentation-commands.js +4 -7
  43. package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
  44. package/dist/cli/commands/interactive-commands/general-commands.js +159 -117
  45. package/dist/cli/commands/interactive-commands/mcp/index.d.ts +9 -3
  46. package/dist/cli/commands/interactive-commands/mcp/index.d.ts.map +1 -1
  47. package/dist/cli/commands/interactive-commands/mcp/index.js +18 -3
  48. package/dist/cli/commands/interactive-commands/model/index.d.ts +8 -6
  49. package/dist/cli/commands/interactive-commands/model/index.d.ts.map +1 -1
  50. package/dist/cli/commands/interactive-commands/model/index.js +18 -6
  51. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts +3 -2
  52. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
  53. package/dist/cli/commands/interactive-commands/prompt-commands.js +77 -60
  54. package/dist/cli/commands/interactive-commands/session/index.d.ts +7 -12
  55. package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
  56. package/dist/cli/commands/interactive-commands/session/index.js +7 -14
  57. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +10 -24
  58. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
  59. package/dist/cli/commands/interactive-commands/session/session-commands.js +16 -371
  60. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts +1 -0
  61. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
  62. package/dist/cli/commands/interactive-commands/system/system-commands.js +106 -77
  63. package/dist/cli/commands/interactive-commands/tool-commands.d.ts +1 -1
  64. package/dist/cli/commands/interactive-commands/tool-commands.d.ts.map +1 -1
  65. package/dist/cli/commands/interactive-commands/tool-commands.js +5 -62
  66. package/dist/cli/commands/interactive-commands/utils/command-output.d.ts +13 -17
  67. package/dist/cli/commands/interactive-commands/utils/command-output.d.ts.map +1 -1
  68. package/dist/cli/commands/interactive-commands/utils/command-output.js +18 -37
  69. package/dist/cli/commands/list-agents.d.ts +2 -2
  70. package/dist/cli/commands/list-agents.d.ts.map +1 -1
  71. package/dist/cli/commands/list-agents.js +38 -34
  72. package/dist/cli/commands/session-commands.js +16 -16
  73. package/dist/cli/commands/setup.d.ts +13 -5
  74. package/dist/cli/commands/setup.d.ts.map +1 -1
  75. package/dist/cli/commands/setup.js +860 -65
  76. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  77. package/dist/cli/commands/uninstall.js +4 -6
  78. package/dist/cli/commands/which.d.ts.map +1 -1
  79. package/dist/cli/commands/which.js +18 -4
  80. package/dist/cli/ink-cli/InkCLIRefactored.d.ts +9 -22
  81. package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
  82. package/dist/cli/ink-cli/InkCLIRefactored.js +50 -133
  83. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +26 -3
  84. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
  85. package/dist/cli/ink-cli/components/ApprovalPrompt.js +182 -45
  86. package/dist/cli/ink-cli/components/CustomInput.js +1 -1
  87. package/dist/cli/ink-cli/components/EditableMultiLineInput.js +4 -4
  88. package/dist/cli/ink-cli/components/ElicitationForm.d.ts +22 -0
  89. package/dist/cli/ink-cli/components/ElicitationForm.d.ts.map +1 -0
  90. package/dist/cli/ink-cli/components/ElicitationForm.js +358 -0
  91. package/dist/cli/ink-cli/components/ErrorBoundary.d.ts.map +1 -1
  92. package/dist/cli/ink-cli/components/ErrorBoundary.js +1 -1
  93. package/dist/cli/ink-cli/components/Footer.d.ts +16 -0
  94. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -0
  95. package/dist/cli/ink-cli/components/Footer.js +27 -0
  96. package/dist/cli/ink-cli/components/HistorySearchBar.d.ts +17 -0
  97. package/dist/cli/ink-cli/components/HistorySearchBar.d.ts.map +1 -0
  98. package/dist/cli/ink-cli/components/HistorySearchBar.js +8 -0
  99. package/dist/cli/ink-cli/components/MultiLineInput.d.ts.map +1 -1
  100. package/dist/cli/ink-cli/components/MultiLineInput.js +3 -3
  101. package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts +15 -2
  102. package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts.map +1 -1
  103. package/dist/cli/ink-cli/components/ResourceAutocomplete.js +126 -82
  104. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts +15 -2
  105. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts.map +1 -1
  106. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +228 -122
  107. package/dist/cli/ink-cli/components/StatusBar.d.ts +15 -2
  108. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  109. package/dist/cli/ink-cli/components/StatusBar.js +50 -10
  110. package/dist/cli/ink-cli/components/TextBufferInput.d.ts +52 -0
  111. package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -0
  112. package/dist/cli/ink-cli/components/TextBufferInput.js +471 -0
  113. package/dist/cli/ink-cli/components/base/BaseAutocomplete.js +4 -4
  114. package/dist/cli/ink-cli/components/base/BaseSelector.d.ts +11 -1
  115. package/dist/cli/ink-cli/components/base/BaseSelector.d.ts.map +1 -1
  116. package/dist/cli/ink-cli/components/base/BaseSelector.js +90 -49
  117. package/dist/cli/ink-cli/components/chat/Footer.js +1 -1
  118. package/dist/cli/ink-cli/components/chat/Header.d.ts +1 -0
  119. package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
  120. package/dist/cli/ink-cli/components/chat/Header.js +6 -3
  121. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts +3 -0
  122. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  123. package/dist/cli/ink-cli/components/chat/MessageItem.js +95 -9
  124. package/dist/cli/ink-cli/components/chat/MessageList.js +1 -1
  125. package/dist/cli/ink-cli/components/chat/QueuedMessagesDisplay.d.ts +16 -0
  126. package/dist/cli/ink-cli/components/chat/QueuedMessagesDisplay.d.ts.map +1 -0
  127. package/dist/cli/ink-cli/components/chat/QueuedMessagesDisplay.js +27 -0
  128. package/dist/cli/ink-cli/components/chat/ToolIcon.d.ts +5 -3
  129. package/dist/cli/ink-cli/components/chat/ToolIcon.d.ts.map +1 -1
  130. package/dist/cli/ink-cli/components/chat/ToolIcon.js +21 -7
  131. package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.d.ts +10 -0
  132. package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.d.ts.map +1 -0
  133. package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.js +6 -0
  134. package/dist/cli/ink-cli/components/chat/styled-boxes/HelpBox.d.ts +10 -0
  135. package/dist/cli/ink-cli/components/chat/styled-boxes/HelpBox.d.ts.map +1 -0
  136. package/dist/cli/ink-cli/components/chat/styled-boxes/HelpBox.js +15 -0
  137. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.d.ts +10 -0
  138. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.d.ts.map +1 -0
  139. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +9 -0
  140. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionHistoryBox.d.ts +10 -0
  141. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionHistoryBox.d.ts.map +1 -0
  142. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionHistoryBox.js +37 -0
  143. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionListBox.d.ts +10 -0
  144. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionListBox.d.ts.map +1 -0
  145. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionListBox.js +9 -0
  146. package/dist/cli/ink-cli/components/chat/styled-boxes/ShortcutsBox.d.ts +10 -0
  147. package/dist/cli/ink-cli/components/chat/styled-boxes/ShortcutsBox.d.ts.map +1 -0
  148. package/dist/cli/ink-cli/components/chat/styled-boxes/ShortcutsBox.js +6 -0
  149. package/dist/cli/ink-cli/components/chat/styled-boxes/StatsBox.d.ts +10 -0
  150. package/dist/cli/ink-cli/components/chat/styled-boxes/StatsBox.d.ts.map +1 -0
  151. package/dist/cli/ink-cli/components/chat/styled-boxes/StatsBox.js +29 -0
  152. package/dist/cli/ink-cli/components/chat/styled-boxes/StyledBox.d.ts +45 -0
  153. package/dist/cli/ink-cli/components/chat/styled-boxes/StyledBox.d.ts.map +1 -0
  154. package/dist/cli/ink-cli/components/chat/styled-boxes/StyledBox.js +38 -0
  155. package/dist/cli/ink-cli/components/chat/styled-boxes/SyspromptBox.d.ts +10 -0
  156. package/dist/cli/ink-cli/components/chat/styled-boxes/SyspromptBox.d.ts.map +1 -0
  157. package/dist/cli/ink-cli/components/chat/styled-boxes/SyspromptBox.js +6 -0
  158. package/dist/cli/ink-cli/components/chat/styled-boxes/index.d.ts +13 -0
  159. package/dist/cli/ink-cli/components/chat/styled-boxes/index.d.ts.map +1 -0
  160. package/dist/cli/ink-cli/components/chat/styled-boxes/index.js +12 -0
  161. package/dist/cli/ink-cli/components/input/InputArea.d.ts +36 -8
  162. package/dist/cli/ink-cli/components/input/InputArea.d.ts.map +1 -1
  163. package/dist/cli/ink-cli/components/input/InputArea.js +3 -3
  164. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts +25 -0
  165. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -0
  166. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +166 -0
  167. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts +27 -0
  168. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -0
  169. package/dist/cli/ink-cli/components/modes/StaticCLI.js +95 -0
  170. package/dist/cli/ink-cli/components/modes/index.d.ts +10 -0
  171. package/dist/cli/ink-cli/components/modes/index.d.ts.map +1 -0
  172. package/dist/cli/ink-cli/components/modes/index.js +9 -0
  173. package/dist/cli/ink-cli/components/overlays/ApiKeyInput.d.ts +26 -0
  174. package/dist/cli/ink-cli/components/overlays/ApiKeyInput.d.ts.map +1 -0
  175. package/dist/cli/ink-cli/components/overlays/ApiKeyInput.js +92 -0
  176. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts +29 -0
  177. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts.map +1 -0
  178. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.js +286 -0
  179. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts +22 -0
  180. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts.map +1 -0
  181. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +59 -0
  182. package/dist/cli/ink-cli/components/overlays/McpAddChoice.d.ts +22 -0
  183. package/dist/cli/ink-cli/components/overlays/McpAddChoice.d.ts.map +1 -0
  184. package/dist/cli/ink-cli/components/overlays/McpAddChoice.js +59 -0
  185. package/dist/cli/ink-cli/components/overlays/McpAddSelector.d.ts +26 -0
  186. package/dist/cli/ink-cli/components/overlays/McpAddSelector.d.ts.map +1 -0
  187. package/dist/cli/ink-cli/components/overlays/McpAddSelector.js +73 -0
  188. package/dist/cli/ink-cli/components/overlays/McpCustomTypeSelector.d.ts +21 -0
  189. package/dist/cli/ink-cli/components/overlays/McpCustomTypeSelector.d.ts.map +1 -0
  190. package/dist/cli/ink-cli/components/overlays/McpCustomTypeSelector.js +51 -0
  191. package/dist/cli/ink-cli/components/overlays/McpCustomWizard.d.ts +29 -0
  192. package/dist/cli/ink-cli/components/overlays/McpCustomWizard.d.ts.map +1 -0
  193. package/dist/cli/ink-cli/components/overlays/McpCustomWizard.js +215 -0
  194. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts +22 -0
  195. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts.map +1 -0
  196. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +74 -0
  197. package/dist/cli/ink-cli/components/overlays/McpSelector.d.ts +21 -0
  198. package/dist/cli/ink-cli/components/overlays/McpSelector.d.ts.map +1 -0
  199. package/dist/cli/ink-cli/components/overlays/McpSelector.js +52 -0
  200. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts +28 -0
  201. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts.map +1 -0
  202. package/dist/cli/ink-cli/components/overlays/McpServerActions.js +84 -0
  203. package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts +29 -0
  204. package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts.map +1 -0
  205. package/dist/cli/ink-cli/components/overlays/McpServerList.js +109 -0
  206. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts +15 -8
  207. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  208. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +400 -23
  209. package/dist/cli/ink-cli/components/overlays/PromptAddChoice.d.ts +22 -0
  210. package/dist/cli/ink-cli/components/overlays/PromptAddChoice.d.ts.map +1 -0
  211. package/dist/cli/ink-cli/components/overlays/PromptAddChoice.js +52 -0
  212. package/dist/cli/ink-cli/components/overlays/PromptAddWizard.d.ts +29 -0
  213. package/dist/cli/ink-cli/components/overlays/PromptAddWizard.d.ts.map +1 -0
  214. package/dist/cli/ink-cli/components/overlays/PromptAddWizard.js +166 -0
  215. package/dist/cli/ink-cli/components/overlays/PromptDeleteSelector.d.ts +27 -0
  216. package/dist/cli/ink-cli/components/overlays/PromptDeleteSelector.d.ts.map +1 -0
  217. package/dist/cli/ink-cli/components/overlays/PromptDeleteSelector.js +119 -0
  218. package/dist/cli/ink-cli/components/overlays/PromptList.d.ts +33 -0
  219. package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -0
  220. package/dist/cli/ink-cli/components/overlays/PromptList.js +144 -0
  221. package/dist/cli/ink-cli/components/overlays/SearchOverlay.d.ts +23 -0
  222. package/dist/cli/ink-cli/components/overlays/SearchOverlay.d.ts.map +1 -0
  223. package/dist/cli/ink-cli/components/overlays/SearchOverlay.js +189 -0
  224. package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.d.ts +7 -2
  225. package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.d.ts.map +1 -1
  226. package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.js +19 -5
  227. package/dist/cli/ink-cli/components/overlays/SessionSubcommandSelector.d.ts +21 -0
  228. package/dist/cli/ink-cli/components/overlays/SessionSubcommandSelector.d.ts.map +1 -0
  229. package/dist/cli/ink-cli/components/overlays/SessionSubcommandSelector.js +42 -0
  230. package/dist/cli/ink-cli/components/overlays/StreamSelector.d.ts +20 -0
  231. package/dist/cli/ink-cli/components/overlays/StreamSelector.d.ts.map +1 -0
  232. package/dist/cli/ink-cli/components/overlays/StreamSelector.js +58 -0
  233. package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts +25 -0
  234. package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts.map +1 -0
  235. package/dist/cli/ink-cli/components/overlays/ToolBrowser.js +400 -0
  236. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.d.ts +25 -0
  237. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.d.ts.map +1 -0
  238. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.js +609 -0
  239. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.d.ts +15 -0
  240. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.d.ts.map +1 -0
  241. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.js +14 -0
  242. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +33 -0
  243. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -0
  244. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +419 -0
  245. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.d.ts +25 -0
  246. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.d.ts.map +1 -0
  247. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.js +29 -0
  248. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.d.ts +17 -0
  249. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.d.ts.map +1 -0
  250. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.js +11 -0
  251. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.d.ts +20 -0
  252. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.d.ts.map +1 -0
  253. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.js +10 -0
  254. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.d.ts +30 -0
  255. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.d.ts.map +1 -0
  256. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.js +13 -0
  257. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.d.ts +8 -0
  258. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.d.ts.map +1 -0
  259. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.js +7 -0
  260. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts +79 -0
  261. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts.map +1 -0
  262. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.js +38 -0
  263. package/dist/cli/ink-cli/components/renderers/DiffRenderer.d.ts +21 -0
  264. package/dist/cli/ink-cli/components/renderers/DiffRenderer.d.ts.map +1 -0
  265. package/dist/cli/ink-cli/components/renderers/DiffRenderer.js +65 -0
  266. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts +28 -0
  267. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts.map +1 -0
  268. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +66 -0
  269. package/dist/cli/ink-cli/components/renderers/FileRenderer.d.ts +19 -0
  270. package/dist/cli/ink-cli/components/renderers/FileRenderer.d.ts.map +1 -0
  271. package/dist/cli/ink-cli/components/renderers/FileRenderer.js +26 -0
  272. package/dist/cli/ink-cli/components/renderers/GenericRenderer.d.ts +21 -0
  273. package/dist/cli/ink-cli/components/renderers/GenericRenderer.d.ts.map +1 -0
  274. package/dist/cli/ink-cli/components/renderers/GenericRenderer.js +26 -0
  275. package/dist/cli/ink-cli/components/renderers/SearchRenderer.d.ts +20 -0
  276. package/dist/cli/ink-cli/components/renderers/SearchRenderer.d.ts.map +1 -0
  277. package/dist/cli/ink-cli/components/renderers/SearchRenderer.js +12 -0
  278. package/dist/cli/ink-cli/components/renderers/ShellRenderer.d.ts +21 -0
  279. package/dist/cli/ink-cli/components/renderers/ShellRenderer.d.ts.map +1 -0
  280. package/dist/cli/ink-cli/components/renderers/ShellRenderer.js +25 -0
  281. package/dist/cli/ink-cli/components/renderers/diff-shared.d.ts +61 -0
  282. package/dist/cli/ink-cli/components/renderers/diff-shared.d.ts.map +1 -0
  283. package/dist/cli/ink-cli/components/renderers/diff-shared.js +158 -0
  284. package/dist/cli/ink-cli/components/renderers/index.d.ts +28 -0
  285. package/dist/cli/ink-cli/components/renderers/index.d.ts.map +1 -0
  286. package/dist/cli/ink-cli/components/renderers/index.js +36 -0
  287. package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts +38 -0
  288. package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts.map +1 -0
  289. package/dist/cli/ink-cli/components/shared/MarkdownText.js +362 -0
  290. package/dist/cli/ink-cli/components/shared/VirtualizedList.d.ts +44 -0
  291. package/dist/cli/ink-cli/components/shared/VirtualizedList.d.ts.map +1 -0
  292. package/dist/cli/ink-cli/components/shared/VirtualizedList.js +300 -0
  293. package/dist/cli/ink-cli/components/shared/text-buffer.d.ts +185 -0
  294. package/dist/cli/ink-cli/components/shared/text-buffer.d.ts.map +1 -0
  295. package/dist/cli/ink-cli/components/shared/text-buffer.js +1338 -0
  296. package/dist/cli/ink-cli/constants/processingPhrases.d.ts +10 -0
  297. package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -0
  298. package/dist/cli/ink-cli/constants/processingPhrases.js +64 -0
  299. package/dist/cli/ink-cli/constants/tips.d.ts +15 -0
  300. package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -0
  301. package/dist/cli/ink-cli/constants/tips.js +53 -0
  302. package/dist/cli/ink-cli/containers/InputContainer.d.ts +42 -8
  303. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  304. package/dist/cli/ink-cli/containers/InputContainer.js +513 -85
  305. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts +23 -5
  306. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  307. package/dist/cli/ink-cli/containers/OverlayContainer.js +1214 -132
  308. package/dist/cli/ink-cli/containers/index.d.ts +1 -1
  309. package/dist/cli/ink-cli/containers/index.d.ts.map +1 -1
  310. package/dist/cli/ink-cli/contexts/KeypressContext.d.ts +36 -0
  311. package/dist/cli/ink-cli/contexts/KeypressContext.d.ts.map +1 -0
  312. package/dist/cli/ink-cli/contexts/KeypressContext.js +461 -0
  313. package/dist/cli/ink-cli/contexts/MouseContext.d.ts +27 -0
  314. package/dist/cli/ink-cli/contexts/MouseContext.d.ts.map +1 -0
  315. package/dist/cli/ink-cli/contexts/MouseContext.js +102 -0
  316. package/dist/cli/ink-cli/contexts/ScrollProvider.d.ts +33 -0
  317. package/dist/cli/ink-cli/contexts/ScrollProvider.d.ts.map +1 -0
  318. package/dist/cli/ink-cli/contexts/ScrollProvider.js +170 -0
  319. package/dist/cli/ink-cli/contexts/index.d.ts +7 -0
  320. package/dist/cli/ink-cli/contexts/index.d.ts.map +1 -0
  321. package/dist/cli/ink-cli/contexts/index.js +6 -0
  322. package/dist/cli/ink-cli/hooks/index.d.ts +5 -0
  323. package/dist/cli/ink-cli/hooks/index.d.ts.map +1 -1
  324. package/dist/cli/ink-cli/hooks/index.js +6 -1
  325. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +26 -9
  326. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
  327. package/dist/cli/ink-cli/hooks/useAgentEvents.js +90 -198
  328. package/dist/cli/ink-cli/hooks/useBatchedScroll.d.ts +14 -0
  329. package/dist/cli/ink-cli/hooks/useBatchedScroll.d.ts.map +1 -0
  330. package/dist/cli/ink-cli/hooks/useBatchedScroll.js +25 -0
  331. package/dist/cli/ink-cli/hooks/useCLIState.d.ts +50 -0
  332. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -0
  333. package/dist/cli/ink-cli/hooks/useCLIState.js +190 -0
  334. package/dist/cli/ink-cli/hooks/useElapsedTime.d.ts +24 -0
  335. package/dist/cli/ink-cli/hooks/useElapsedTime.d.ts.map +1 -0
  336. package/dist/cli/ink-cli/hooks/useElapsedTime.js +69 -0
  337. package/dist/cli/ink-cli/hooks/useHistorySearch.d.ts +61 -0
  338. package/dist/cli/ink-cli/hooks/useHistorySearch.d.ts.map +1 -0
  339. package/dist/cli/ink-cli/hooks/useHistorySearch.js +210 -0
  340. package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts +136 -0
  341. package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -0
  342. package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +663 -0
  343. package/dist/cli/ink-cli/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  344. package/dist/cli/ink-cli/hooks/useKeyboardShortcuts.js +7 -26
  345. package/dist/cli/ink-cli/hooks/useKeypress.d.ts +18 -0
  346. package/dist/cli/ink-cli/hooks/useKeypress.d.ts.map +1 -0
  347. package/dist/cli/ink-cli/hooks/useKeypress.js +26 -0
  348. package/dist/cli/ink-cli/hooks/usePhraseCycler.d.ts +30 -0
  349. package/dist/cli/ink-cli/hooks/usePhraseCycler.d.ts.map +1 -0
  350. package/dist/cli/ink-cli/hooks/usePhraseCycler.js +68 -0
  351. package/dist/cli/ink-cli/hooks/useStreaming.d.ts +19 -0
  352. package/dist/cli/ink-cli/hooks/useStreaming.d.ts.map +1 -0
  353. package/dist/cli/ink-cli/hooks/useStreaming.js +26 -0
  354. package/dist/cli/ink-cli/hooks/useTerminalSize.d.ts +14 -0
  355. package/dist/cli/ink-cli/hooks/useTerminalSize.d.ts.map +1 -0
  356. package/dist/cli/ink-cli/hooks/useTerminalSize.js +31 -0
  357. package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts +42 -0
  358. package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts.map +1 -0
  359. package/dist/cli/ink-cli/hooks/useTokenCounter.js +96 -0
  360. package/dist/cli/ink-cli/services/CommandService.d.ts +32 -1
  361. package/dist/cli/ink-cli/services/CommandService.d.ts.map +1 -1
  362. package/dist/cli/ink-cli/services/CommandService.js +36 -5
  363. package/dist/cli/ink-cli/services/InputService.d.ts +1 -5
  364. package/dist/cli/ink-cli/services/InputService.d.ts.map +1 -1
  365. package/dist/cli/ink-cli/services/InputService.js +1 -8
  366. package/dist/cli/ink-cli/services/index.d.ts +2 -1
  367. package/dist/cli/ink-cli/services/index.d.ts.map +1 -1
  368. package/dist/cli/ink-cli/services/index.js +2 -1
  369. package/dist/cli/ink-cli/services/processStream.d.ts +69 -0
  370. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -0
  371. package/dist/cli/ink-cli/services/processStream.js +742 -0
  372. package/dist/cli/ink-cli/state/actions.d.ts +30 -60
  373. package/dist/cli/ink-cli/state/actions.d.ts.map +1 -1
  374. package/dist/cli/ink-cli/state/actions.js +3 -0
  375. package/dist/cli/ink-cli/state/index.d.ts +5 -3
  376. package/dist/cli/ink-cli/state/index.d.ts.map +1 -1
  377. package/dist/cli/ink-cli/state/index.js +4 -3
  378. package/dist/cli/ink-cli/state/initialState.d.ts +4 -3
  379. package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
  380. package/dist/cli/ink-cli/state/initialState.js +20 -4
  381. package/dist/cli/ink-cli/state/reducer.d.ts +3 -0
  382. package/dist/cli/ink-cli/state/reducer.d.ts.map +1 -1
  383. package/dist/cli/ink-cli/state/reducer.js +62 -168
  384. package/dist/cli/ink-cli/state/streaming-state.d.ts +27 -0
  385. package/dist/cli/ink-cli/state/streaming-state.d.ts.map +1 -0
  386. package/dist/cli/ink-cli/state/streaming-state.js +39 -0
  387. package/dist/cli/ink-cli/state/types.d.ts +223 -6
  388. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  389. package/dist/cli/ink-cli/utils/bracketedPaste.d.ts +22 -0
  390. package/dist/cli/ink-cli/utils/bracketedPaste.d.ts.map +1 -0
  391. package/dist/cli/ink-cli/utils/bracketedPaste.js +27 -0
  392. package/dist/cli/ink-cli/utils/clipboardUtils.d.ts +49 -0
  393. package/dist/cli/ink-cli/utils/clipboardUtils.d.ts.map +1 -0
  394. package/dist/cli/ink-cli/utils/clipboardUtils.js +356 -0
  395. package/dist/cli/ink-cli/utils/commandOverlays.d.ts +33 -0
  396. package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -0
  397. package/dist/cli/ink-cli/utils/commandOverlays.js +78 -0
  398. package/dist/cli/ink-cli/utils/debugLog.d.ts +38 -0
  399. package/dist/cli/ink-cli/utils/debugLog.d.ts.map +1 -0
  400. package/dist/cli/ink-cli/utils/debugLog.js +66 -0
  401. package/dist/cli/ink-cli/utils/index.d.ts +2 -1
  402. package/dist/cli/ink-cli/utils/index.d.ts.map +1 -1
  403. package/dist/cli/ink-cli/utils/index.js +3 -1
  404. package/dist/cli/ink-cli/utils/input.d.ts +25 -0
  405. package/dist/cli/ink-cli/utils/input.d.ts.map +1 -0
  406. package/dist/cli/ink-cli/utils/input.js +56 -0
  407. package/dist/cli/ink-cli/utils/inputParsing.d.ts +0 -9
  408. package/dist/cli/ink-cli/utils/inputParsing.d.ts.map +1 -1
  409. package/dist/cli/ink-cli/utils/inputParsing.js +0 -27
  410. package/dist/cli/ink-cli/utils/messageFormatting.d.ts +59 -3
  411. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  412. package/dist/cli/ink-cli/utils/messageFormatting.js +348 -20
  413. package/dist/cli/ink-cli/utils/mouse.d.ts +61 -0
  414. package/dist/cli/ink-cli/utils/mouse.d.ts.map +1 -0
  415. package/dist/cli/ink-cli/utils/mouse.js +209 -0
  416. package/dist/cli/ink-cli/utils/streamSplitter.d.ts +44 -0
  417. package/dist/cli/ink-cli/utils/streamSplitter.d.ts.map +1 -0
  418. package/dist/cli/ink-cli/utils/streamSplitter.js +154 -0
  419. package/dist/cli/ink-cli/utils/textUtils.d.ts +63 -0
  420. package/dist/cli/ink-cli/utils/textUtils.d.ts.map +1 -0
  421. package/dist/cli/ink-cli/utils/textUtils.js +248 -0
  422. package/dist/cli/ink-cli/utils/toolUtils.d.ts +9 -0
  423. package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -0
  424. package/dist/cli/ink-cli/utils/toolUtils.js +15 -0
  425. package/dist/cli/utils/api-key-setup.d.ts +54 -4
  426. package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
  427. package/dist/cli/utils/api-key-setup.js +433 -107
  428. package/dist/cli/utils/api-key-verification.d.ts +17 -0
  429. package/dist/cli/utils/api-key-verification.d.ts.map +1 -0
  430. package/dist/cli/utils/api-key-verification.js +211 -0
  431. package/dist/cli/utils/config-validation.d.ts +22 -2
  432. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  433. package/dist/cli/utils/config-validation.js +354 -25
  434. package/dist/cli/utils/local-model-setup.d.ts +46 -0
  435. package/dist/cli/utils/local-model-setup.d.ts.map +1 -0
  436. package/dist/cli/utils/local-model-setup.js +662 -0
  437. package/dist/cli/utils/options.d.ts.map +1 -1
  438. package/dist/cli/utils/options.js +1 -3
  439. package/dist/cli/utils/prompt-helpers.d.ts +47 -0
  440. package/dist/cli/utils/prompt-helpers.d.ts.map +1 -0
  441. package/dist/cli/utils/prompt-helpers.js +66 -0
  442. package/dist/cli/utils/provider-setup.d.ts +66 -8
  443. package/dist/cli/utils/provider-setup.d.ts.map +1 -1
  444. package/dist/cli/utils/provider-setup.js +324 -84
  445. package/dist/cli/utils/scaffolding-utils.d.ts +76 -0
  446. package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -0
  447. package/dist/cli/utils/scaffolding-utils.js +246 -0
  448. package/dist/cli/utils/setup-utils.d.ts +16 -0
  449. package/dist/cli/utils/setup-utils.d.ts.map +1 -1
  450. package/dist/cli/utils/setup-utils.js +72 -21
  451. package/dist/cli/utils/template-engine.d.ts +65 -0
  452. package/dist/cli/utils/template-engine.d.ts.map +1 -0
  453. package/dist/cli/utils/template-engine.js +1089 -0
  454. package/dist/config/cli-overrides.d.ts +45 -2
  455. package/dist/config/cli-overrides.d.ts.map +1 -1
  456. package/dist/config/cli-overrides.js +107 -10
  457. package/dist/index.js +379 -99
  458. package/dist/utils/agent-helpers.d.ts +95 -0
  459. package/dist/utils/agent-helpers.d.ts.map +1 -0
  460. package/dist/utils/agent-helpers.js +117 -0
  461. package/dist/webui/assets/index-8j-KMkX1.js +2054 -0
  462. package/dist/webui/assets/index-c_AX24V4.css +1 -0
  463. package/dist/webui/assets/{tanstack-DgxBONJY.js → tanstack-Br79RQ-n.js} +1 -1
  464. package/dist/webui/index.html +4 -10
  465. package/dist/webui/logos/aws-color.svg +1 -0
  466. package/dist/webui/logos/dexto/dexto_logo.svg +1 -1
  467. package/dist/webui/logos/dexto/dexto_logo_light.svg +6 -6
  468. package/dist/webui/logos/glama.svg +7 -0
  469. package/dist/webui/logos/litellm.svg +7 -0
  470. package/dist/webui/logos/openrouter.svg +1 -0
  471. package/package.json +18 -15
  472. package/dist/cli/commands/interactive-commands/index.d.ts +0 -63
  473. package/dist/cli/commands/interactive-commands/index.d.ts.map +0 -1
  474. package/dist/cli/commands/interactive-commands/index.js +0 -73
  475. package/dist/cli/commands/interactive-commands/mcp/mcp-add-utils.d.ts +0 -34
  476. package/dist/cli/commands/interactive-commands/mcp/mcp-add-utils.d.ts.map +0 -1
  477. package/dist/cli/commands/interactive-commands/mcp/mcp-add-utils.js +0 -178
  478. package/dist/cli/commands/interactive-commands/mcp/mcp-commands.d.ts +0 -9
  479. package/dist/cli/commands/interactive-commands/mcp/mcp-commands.d.ts.map +0 -1
  480. package/dist/cli/commands/interactive-commands/mcp/mcp-commands.js +0 -325
  481. package/dist/cli/commands/interactive-commands/model/model-commands.d.ts +0 -21
  482. package/dist/cli/commands/interactive-commands/model/model-commands.d.ts.map +0 -1
  483. package/dist/cli/commands/interactive-commands/model/model-commands.js +0 -190
  484. package/dist/cli/ink-cli/components/MultiLineTextInput.d.ts +0 -26
  485. package/dist/cli/ink-cli/components/MultiLineTextInput.d.ts.map +0 -1
  486. package/dist/cli/ink-cli/components/MultiLineTextInput.js +0 -220
  487. package/dist/discord/bot.d.ts +0 -4
  488. package/dist/discord/bot.d.ts.map +0 -1
  489. package/dist/discord/bot.js +0 -193
  490. package/dist/telegram/bot.d.ts +0 -5
  491. package/dist/telegram/bot.d.ts.map +0 -1
  492. package/dist/telegram/bot.js +0 -251
  493. package/dist/webui/assets/index-DKq5Xng1.js +0 -687
  494. package/dist/webui/assets/index-D_0_GBu5.css +0 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import { applyLayeredEnvironmentLoading } from './utils/env.js';
4
4
  // Apply layered environment loading before any other imports
5
5
  await applyLayeredEnvironmentLoading();
6
- import { existsSync } from 'fs';
6
+ import { existsSync, readFileSync } from 'fs';
7
7
  import { createRequire } from 'module';
8
8
  import path from 'path';
9
9
  import { Command } from 'commander';
@@ -15,16 +15,14 @@ import { withAnalytics, safeExit, ExitSignal } from './analytics/wrapper.js';
15
15
  const require = createRequire(import.meta.url);
16
16
  const pkg = require('../package.json');
17
17
  import { logger, getProviderFromModel, getAllSupportedModels, DextoAgent, isPath, resolveApiKeyForProvider, getPrimaryApiKeyEnvVar, } from '@dexto/core';
18
- import { resolveAgentPath, getAgentRegistry, loadAgentConfig, globalPreferencesExist, loadGlobalPreferences, } from '@dexto/agent-management';
18
+ import { resolveAgentPath, loadAgentConfig, globalPreferencesExist, loadGlobalPreferences, resolveBundledScript, } from '@dexto/agent-management';
19
19
  import { startHonoApiServer } from './api/server-hono.js';
20
- import { startDiscordBot } from './discord/bot.js';
21
- import { startTelegramBot } from './telegram/bot.js';
22
20
  import { validateCliOptions, handleCliOptionsError } from './cli/utils/options.js';
23
21
  import { validateAgentConfig } from './cli/utils/config-validation.js';
24
- import { applyCLIOverrides } from './config/cli-overrides.js';
22
+ import { applyCLIOverrides, applyUserPreferences, checkAgentCompatibility, } from './config/cli-overrides.js';
25
23
  import { enrichAgentConfig } from '@dexto/agent-management';
26
24
  import { getPort } from './utils/port-utils.js';
27
- import { createDextoProject, createTsconfigJson, addDextoScriptsToPackageJson, postCreateDexto, initDexto, postInitDexto, getUserInputToInitDextoApp, } from './cli/commands/index.js';
25
+ import { createDextoProject, createImage, getUserInputToInitDextoApp, initDexto, postInitDexto, } from './cli/commands/index.js';
28
26
  import { handleSetupCommand, handleInstallCommand, handleUninstallCommand, handleListAgentsCommand, handleWhichCommand, } from './cli/commands/index.js';
29
27
  import { handleSessionListCommand, handleSessionHistoryCommand, handleSessionDeleteCommand, handleSessionSearchCommand, } from './cli/commands/session-commands.js';
30
28
  import { requiresSetup } from './cli/utils/setup-utils.js';
@@ -36,6 +34,41 @@ import { initializeMcpToolAggregationServer } from './api/mcp/tool-aggregation-h
36
34
  const program = new Command();
37
35
  // Initialize analytics early (no-op if disabled)
38
36
  await initAnalytics({ appVersion: pkg.version });
37
+ /**
38
+ * Recursively removes null values from an object.
39
+ * This handles YAML files that have explicit `apiKey: null` entries
40
+ * which would otherwise cause "Expected string, received null" validation errors.
41
+ */
42
+ function cleanNullValues(obj) {
43
+ if (obj === null || obj === undefined)
44
+ return obj;
45
+ if (typeof obj !== 'object')
46
+ return obj;
47
+ if (Array.isArray(obj)) {
48
+ return obj.map((item) => typeof item === 'object' && item !== null
49
+ ? cleanNullValues(item)
50
+ : item);
51
+ }
52
+ const cleaned = {};
53
+ for (const [key, value] of Object.entries(obj)) {
54
+ if (value === null) {
55
+ // Skip null values - they become undefined (missing)
56
+ continue;
57
+ }
58
+ if (typeof value === 'object' && !Array.isArray(value)) {
59
+ cleaned[key] = cleanNullValues(value);
60
+ }
61
+ else if (Array.isArray(value)) {
62
+ cleaned[key] = value.map((item) => typeof item === 'object' && item !== null
63
+ ? cleanNullValues(item)
64
+ : item);
65
+ }
66
+ else {
67
+ cleaned[key] = value;
68
+ }
69
+ }
70
+ return cleaned;
71
+ }
39
72
  // 1) GLOBAL OPTIONS
40
73
  program
41
74
  .name('dexto')
@@ -48,43 +81,28 @@ program
48
81
  .option('--no-interactive', 'Disable interactive prompts and API key setup')
49
82
  .option('--skip-setup', 'Skip global setup validation (useful for MCP mode, automation)')
50
83
  .option('-m, --model <model>', 'Specify the LLM model to use')
51
- .option('--router <router>', 'Specify the LLM router to use (vercel or in-built)')
52
84
  .option('--auto-approve', 'Always approve tool executions without confirmation prompts')
53
85
  .option('-c, --continue', 'Continue most recent session (requires -p/prompt)')
54
86
  .option('-r, --resume <sessionId>', 'Resume specific session (requires -p/prompt)')
55
- .option('--mode <mode>', 'The application in which dexto should talk to you - web | cli | server | discord | telegram | mcp', 'web')
87
+ .option('--mode <mode>', 'The application in which dexto should talk to you - web | cli | server | mcp', 'web')
56
88
  .option('--port <port>', 'port for the server (default: 3000 for web, 3001 for server mode)')
57
89
  .option('--no-auto-install', 'Disable automatic installation of missing agents from registry')
90
+ .option('--image <package>', 'Image package to load (e.g., @dexto/image-local). Overrides config image field.')
58
91
  .enablePositionalOptions();
59
92
  // 2) `create-app` SUB-COMMAND
60
93
  program
61
- .command('create-app')
62
- .description('Scaffold a new Dexto Typescript app')
63
- .action(withAnalytics('create-app', async () => {
94
+ .command('create-app [name]')
95
+ .description('Create a Dexto application (CLI, web, bot, etc.)')
96
+ .option('--from-image <package>', 'Use existing image (e.g., @dexto/image-local)')
97
+ .option('--extend-image <package>', 'Extend image with custom providers')
98
+ .option('--from-core', 'Build from @dexto/core (advanced)')
99
+ .option('--type <type>', 'App type: script, webapp (default: script)')
100
+ .action(withAnalytics('create-app', async (name, options) => {
64
101
  try {
65
- p.intro(chalk.inverse('Dexto Create App'));
66
- // first setup the initial files in the project and get the project path
67
- const appPath = await createDextoProject();
68
- // then get user inputs for directory, llm etc.
69
- const userInput = await getUserInputToInitDextoApp();
70
- try {
71
- capture('dexto_create', {
72
- provider: userInput.llmProvider,
73
- providedKey: Boolean(userInput.llmApiKey),
74
- });
75
- }
76
- catch {
77
- // Analytics failures should not block CLI execution.
78
- }
79
- // move to project directory, then add the dexto scripts to the package.json and create the tsconfig.json
80
- process.chdir(appPath);
81
- await addDextoScriptsToPackageJson(userInput.directory, appPath);
82
- await createTsconfigJson(appPath, userInput.directory);
83
- // then initialize the other parts of the project
84
- await initDexto(userInput.directory, userInput.createExampleFile, userInput.llmProvider, userInput.llmApiKey);
85
- p.outro(chalk.greenBright('Dexto app created and initialized successfully!'));
86
- // add notes for users to get started with their newly created Dexto project
87
- await postCreateDexto(appPath, userInput.directory);
102
+ p.intro(chalk.inverse('Create Dexto App'));
103
+ // Create the app project structure (fully self-contained)
104
+ await createDextoProject(name, options);
105
+ p.outro(chalk.greenBright('Dexto app created successfully!'));
88
106
  safeExit('create-app', 0);
89
107
  }
90
108
  catch (err) {
@@ -94,7 +112,26 @@ program
94
112
  safeExit('create-app', 1, 'error');
95
113
  }
96
114
  }));
97
- // 3) `init-app` SUB-COMMAND
115
+ // 3) `create-image` SUB-COMMAND
116
+ program
117
+ .command('create-image [name]')
118
+ .description('Create a Dexto image - a distributable agent harness package')
119
+ .action(withAnalytics('create-image', async (name) => {
120
+ try {
121
+ p.intro(chalk.inverse('Create Dexto Image'));
122
+ // Create the image project structure
123
+ const projectPath = await createImage(name);
124
+ p.outro(chalk.greenBright(`Dexto image created successfully at ${projectPath}!`));
125
+ safeExit('create-image', 0);
126
+ }
127
+ catch (err) {
128
+ if (err instanceof ExitSignal)
129
+ throw err;
130
+ console.error(`❌ dexto create-image command failed: ${err}`);
131
+ safeExit('create-image', 1, 'error');
132
+ }
133
+ }));
134
+ // 4) `init-app` SUB-COMMAND
98
135
  program
99
136
  .command('init-app')
100
137
  .description('Initialize an existing Typescript app with Dexto')
@@ -133,13 +170,13 @@ program
133
170
  safeExit('init-app', 1, 'error');
134
171
  }
135
172
  }));
136
- // 4) `setup` SUB-COMMAND
173
+ // 5) `setup` SUB-COMMAND
137
174
  program
138
175
  .command('setup')
139
176
  .description('Configure global Dexto preferences')
140
177
  .option('--provider <provider>', 'LLM provider (openai, anthropic, google, groq)')
141
178
  .option('--model <model>', 'Model name (uses provider default if not specified)')
142
- .option('--default-agent <agent>', 'Default agent name (default: default-agent)')
179
+ .option('--default-agent <agent>', 'Default agent name (default: coding-agent)')
143
180
  .option('--no-interactive', 'Skip interactive prompts and API key setup')
144
181
  .option('--force', 'Overwrite existing setup without confirmation')
145
182
  .action(withAnalytics('setup', async (options) => {
@@ -154,7 +191,7 @@ program
154
191
  safeExit('setup', 1, 'error');
155
192
  }
156
193
  }));
157
- // 5) `install` SUB-COMMAND
194
+ // 6) `install` SUB-COMMAND
158
195
  program
159
196
  .command('install [agents...]')
160
197
  .description('Install agents from registry or custom YAML files/directories')
@@ -163,7 +200,7 @@ program
163
200
  .option('--force', 'Force reinstall even if agent is already installed')
164
201
  .addHelpText('after', `
165
202
  Examples:
166
- $ dexto install default-agent Install agent from registry
203
+ $ dexto install coding-agent Install agent from registry
167
204
  $ dexto install agent1 agent2 Install multiple registry agents
168
205
  $ dexto install --all Install all available registry agents
169
206
  $ dexto install ./my-agent.yml Install custom agent from YAML file
@@ -180,12 +217,12 @@ Examples:
180
217
  safeExit('install', 1, 'error');
181
218
  }
182
219
  }));
183
- // 6) `uninstall` SUB-COMMAND
220
+ // 7) `uninstall` SUB-COMMAND
184
221
  program
185
222
  .command('uninstall [agents...]')
186
223
  .description('Uninstall agents from the local installation')
187
224
  .option('--all', 'Uninstall all installed agents')
188
- .option('--force', 'Force uninstall even if agent is protected (e.g., default-agent)')
225
+ .option('--force', 'Force uninstall even if agent is protected (e.g., coding-agent)')
189
226
  .action(withAnalytics('uninstall', async (agents, options) => {
190
227
  try {
191
228
  await handleUninstallCommand(agents, options);
@@ -198,7 +235,7 @@ program
198
235
  safeExit('uninstall', 1, 'error');
199
236
  }
200
237
  }));
201
- // 7) `list-agents` SUB-COMMAND
238
+ // 8) `list-agents` SUB-COMMAND
202
239
  program
203
240
  .command('list-agents')
204
241
  .description('List available and installed agents')
@@ -217,7 +254,7 @@ program
217
254
  safeExit('list-agents', 1, 'error');
218
255
  }
219
256
  }));
220
- // 8) `which` SUB-COMMAND
257
+ // 9) `which` SUB-COMMAND
221
258
  program
222
259
  .command('which <agent>')
223
260
  .description('Show the path to an agent')
@@ -236,21 +273,43 @@ program
236
273
  // Helper to bootstrap a minimal agent for non-interactive session/search ops
237
274
  async function bootstrapAgentFromGlobalOpts() {
238
275
  const globalOpts = program.opts();
239
- const resolvedPath = await resolveAgentPath(globalOpts.agent, globalOpts.autoInstall !== false, true);
276
+ const resolvedPath = await resolveAgentPath(globalOpts.agent, globalOpts.autoInstall !== false);
240
277
  const rawConfig = await loadAgentConfig(resolvedPath);
241
278
  const mergedConfig = applyCLIOverrides(rawConfig, globalOpts);
242
- const enrichedConfig = enrichAgentConfig(mergedConfig, resolvedPath);
279
+ const enrichedConfig = enrichAgentConfig(mergedConfig, resolvedPath, {
280
+ logLevel: 'info', // CLI uses info-level logging for visibility
281
+ });
282
+ // Load image dynamically if specified (same priority as main command)
283
+ // Priority: CLI flag > Agent config > Environment variable > Default
284
+ // Images are optional, but default to image-local for convenience
285
+ const imageName = globalOpts.image || // --image flag
286
+ enrichedConfig.image || // image field in agent config
287
+ process.env.DEXTO_IMAGE || // DEXTO_IMAGE env var
288
+ '@dexto/image-local'; // Default for convenience
289
+ try {
290
+ await import(imageName);
291
+ }
292
+ catch (_err) {
293
+ console.error(`❌ Failed to load image '${imageName}'`);
294
+ console.error(`💡 Install it with: ${existsSync('package.json') ? 'npm install' : 'npm install -g'} ${imageName}`);
295
+ safeExit('bootstrap', 1, 'image-load-failed');
296
+ }
243
297
  // Override approval config for read-only commands (never run conversations)
244
298
  // This avoids needing to set up unused approval handlers
245
299
  enrichedConfig.toolConfirmation = {
246
300
  mode: 'auto-approve',
247
- timeout: enrichedConfig.toolConfirmation?.timeout ?? 120000,
301
+ ...(enrichedConfig.toolConfirmation?.timeout !== undefined && {
302
+ timeout: enrichedConfig.toolConfirmation.timeout,
303
+ }),
248
304
  };
249
305
  enrichedConfig.elicitation = {
250
306
  enabled: false,
251
- timeout: enrichedConfig.elicitation?.timeout ?? 120000,
307
+ ...(enrichedConfig.elicitation?.timeout !== undefined && {
308
+ timeout: enrichedConfig.elicitation.timeout,
309
+ }),
252
310
  };
253
- const agent = new DextoAgent(enrichedConfig, resolvedPath);
311
+ // Use relaxed validation for session commands - they don't need LLM calls
312
+ const agent = new DextoAgent(enrichedConfig, resolvedPath, { strict: false });
254
313
  await agent.start();
255
314
  // Register graceful shutdown
256
315
  const shutdown = async () => {
@@ -289,7 +348,7 @@ async function getMostRecentSessionId(agent, includeHeadless = false) {
289
348
  }
290
349
  return mostRecentId;
291
350
  }
292
- // 9) `session` SUB-COMMAND
351
+ // 10) `session` SUB-COMMAND
293
352
  const sessionCommand = program.command('session').description('Manage chat sessions');
294
353
  sessionCommand
295
354
  .command('list')
@@ -344,7 +403,7 @@ sessionCommand
344
403
  safeExit('session delete', 1, 'error');
345
404
  }
346
405
  }));
347
- // 10) `search` SUB-COMMAND
406
+ // 11) `search` SUB-COMMAND
348
407
  program
349
408
  .command('search')
350
409
  .description('Search session history')
@@ -386,7 +445,7 @@ program
386
445
  safeExit('search', 1, 'error');
387
446
  }
388
447
  }));
389
- // 11) `mcp` SUB-COMMAND
448
+ // 12) `mcp` SUB-COMMAND
390
449
  // For now, this mode simply aggregates and re-expose tools from configured MCP servers (no agent)
391
450
  // dexto --mode mcp will be moved to this sub-command in the future
392
451
  program
@@ -409,7 +468,7 @@ program
409
468
  // Get the global agent option from the main program
410
469
  const globalOpts = program.opts();
411
470
  const nameOrPath = globalOpts.agent;
412
- const configPath = await resolveAgentPath(nameOrPath, globalOpts.autoInstall !== false, true);
471
+ const configPath = await resolveAgentPath(nameOrPath, globalOpts.autoInstall !== false);
413
472
  console.log(`📄 Loading Dexto config from: ${configPath}`);
414
473
  const config = await loadAgentConfig(configPath);
415
474
  logger.info(`Validating MCP servers...`);
@@ -439,7 +498,7 @@ program
439
498
  safeExit('mcp', 1, 'mcp-agg-failed');
440
499
  }
441
500
  }, { timeoutMs: 0 }));
442
- // 10) Main dexto CLI - Interactive/One shot (CLI/HEADLESS) or run in other modes (--mode web/discord/telegram)
501
+ // 13) Main dexto CLI - Interactive/One shot (CLI/HEADLESS) or run in other modes (--mode web/server/mcp)
443
502
  program
444
503
  .argument('[prompt...]', 'Natural-language prompt to run once. If not passed, dexto will start as an interactive CLI')
445
504
  // Main customer facing description
@@ -469,8 +528,6 @@ program
469
528
  ' dexto --auto-approve Auto-approve all tool executions\n\n' +
470
529
  'Advanced Modes:\n' +
471
530
  ' dexto --mode server Run as API server\n' +
472
- ' dexto --mode discord Run as Discord bot\n' +
473
- ' dexto --mode telegram Run as Telegram bot\n' +
474
531
  ' dexto --mode mcp Run as MCP server\n\n' +
475
532
  'See https://docs.dexto.ai for documentation and examples')
476
533
  .action(withAnalytics('main', async (prompt = []) => {
@@ -564,28 +621,42 @@ program
564
621
  // ——— ENHANCED PREFERENCE-AWARE CONFIG LOADING ———
565
622
  let validatedConfig;
566
623
  let resolvedPath;
624
+ // Determine validation mode early - used throughout config loading and agent creation
625
+ // Use relaxed validation for interactive modes (web/cli) where users can configure later
626
+ // Use strict validation for headless modes (server/mcp) that need full config upfront
627
+ const isInteractiveMode = opts.mode === 'web' || opts.mode === 'cli';
567
628
  try {
568
629
  // Case 1: File path - skip all validation and setup
569
630
  if (opts.agent && isPath(opts.agent)) {
570
- resolvedPath = await resolveAgentPath(opts.agent, opts.autoInstall !== false, true);
631
+ resolvedPath = await resolveAgentPath(opts.agent, opts.autoInstall !== false);
571
632
  }
572
633
  // Cases 2 & 3: Default agent or registry agent
573
634
  else {
574
635
  // Early registry validation for named agents
575
636
  if (opts.agent) {
576
- const registry = getAgentRegistry();
577
- if (!registry.hasAgent(opts.agent)) {
578
- console.error(`❌ Agent '${opts.agent}' not found in registry`);
579
- // Show available agents
580
- const available = Object.keys(registry.getAvailableAgents());
581
- if (available.length > 0) {
582
- console.log(`📋 Available agents: ${available.join(', ')}`);
583
- }
584
- else {
585
- console.log('📋 No agents available in registry');
637
+ // Load bundled registry to check if agent exists
638
+ try {
639
+ const bundledRegistryPath = resolveBundledScript('agents/agent-registry.json');
640
+ const registryContent = readFileSync(bundledRegistryPath, 'utf-8');
641
+ const bundledRegistry = JSON.parse(registryContent);
642
+ // Check if agent exists in bundled registry
643
+ if (!(opts.agent in bundledRegistry.agents)) {
644
+ console.error(`❌ Agent '${opts.agent}' not found in registry`);
645
+ // Show available agents
646
+ const available = Object.keys(bundledRegistry.agents);
647
+ if (available.length > 0) {
648
+ console.log(`📋 Available agents: ${available.join(', ')}`);
649
+ }
650
+ else {
651
+ console.log('📋 No agents available in registry');
652
+ }
653
+ safeExit('main', 1, 'agent-not-in-registry');
654
+ return;
586
655
  }
587
- safeExit('main', 1, 'agent-not-in-registry');
588
- return;
656
+ }
657
+ catch (error) {
658
+ logger.warn(`Could not validate agent against registry: ${error instanceof Error ? error.message : String(error)}`);
659
+ // Continue anyway - resolver will handle it
589
660
  }
590
661
  }
591
662
  // Check setup state and auto-trigger if needed
@@ -597,20 +668,190 @@ program
597
668
  safeExit('main', 1, 'setup-required-non-interactive');
598
669
  }
599
670
  await handleSetupCommand({ interactive: true });
671
+ // Reload preferences after setup to get the newly selected default mode
672
+ // (setup may have just saved a different mode than the default 'web')
673
+ try {
674
+ const newPreferences = await loadGlobalPreferences();
675
+ if (newPreferences.defaults?.defaultMode) {
676
+ opts.mode = newPreferences.defaults.defaultMode;
677
+ logger.debug(`Updated mode from setup preferences: ${opts.mode}`);
678
+ }
679
+ }
680
+ catch {
681
+ // Ignore errors - will use default mode
682
+ }
600
683
  }
601
- // Now resolve agent (will auto-install with preferences since setup is complete)
602
- resolvedPath = await resolveAgentPath(opts.agent, opts.autoInstall !== false, true);
684
+ // Now resolve agent (will auto-install since setup is complete)
685
+ resolvedPath = await resolveAgentPath(opts.agent, opts.autoInstall !== false);
603
686
  }
604
687
  // Load raw config and apply CLI overrides
605
688
  const rawConfig = await loadAgentConfig(resolvedPath);
606
- const mergedConfig = applyCLIOverrides(rawConfig, opts);
689
+ let mergedConfig = applyCLIOverrides(rawConfig, opts);
690
+ // ——— PREFERENCE-AWARE CONFIG HANDLING ———
691
+ // For coding-agent (no explicit agent specified): Apply user preferences
692
+ // For specific agents: Check compatibility and warn if needed
693
+ const isDefaultAgent = !opts.agent;
694
+ let preferences = null;
695
+ if (globalPreferencesExist()) {
696
+ try {
697
+ preferences = await loadGlobalPreferences();
698
+ }
699
+ catch {
700
+ // Preferences exist but couldn't load - continue without them
701
+ logger.debug('Could not load preferences, continuing without them');
702
+ }
703
+ }
704
+ // Check for pending API key setup (user skipped during initial setup)
705
+ if (isDefaultAgent &&
706
+ preferences?.setup?.apiKeyPending &&
707
+ opts.interactive !== false) {
708
+ // Check if API key is still missing (user may have set it manually)
709
+ const configuredApiKey = resolveApiKeyForProvider(preferences.llm.provider);
710
+ if (!configuredApiKey) {
711
+ const { promptForPendingApiKey } = await import('./cli/utils/api-key-setup.js');
712
+ const { updateGlobalPreferences } = await import('@dexto/agent-management');
713
+ const result = await promptForPendingApiKey(preferences.llm.provider, preferences.llm.model);
714
+ if (result.action === 'cancel') {
715
+ safeExit('main', 0, 'pending-api-key-cancelled');
716
+ }
717
+ if (result.action === 'setup' && result.apiKey) {
718
+ // API key was configured - update preferences to clear pending flag
719
+ await updateGlobalPreferences({
720
+ setup: { apiKeyPending: false },
721
+ });
722
+ // Update the merged config with the new API key
723
+ mergedConfig.llm.apiKey = result.apiKey;
724
+ logger.debug('API key configured, pending flag cleared');
725
+ }
726
+ // If 'skip', continue without API key (user chose to proceed)
727
+ }
728
+ else {
729
+ // API key exists (user set it manually) - clear the pending flag
730
+ const { updateGlobalPreferences } = await import('@dexto/agent-management');
731
+ await updateGlobalPreferences({
732
+ setup: { apiKeyPending: false },
733
+ });
734
+ logger.debug('API key found in environment, cleared pending flag');
735
+ }
736
+ }
737
+ if (isDefaultAgent && preferences) {
738
+ // Default-agent: Apply user's LLM preferences at runtime
739
+ // This ensures the base agent always uses user's preferred model/provider
740
+ mergedConfig = applyUserPreferences(mergedConfig, preferences);
741
+ logger.debug('Applied user preferences to coding-agent', {
742
+ provider: preferences.llm.provider,
743
+ model: preferences.llm.model,
744
+ });
745
+ }
746
+ else if (!isDefaultAgent && mergedConfig.llm) {
747
+ // Specific agent: Check if user has the required provider configured
748
+ const agentProvider = mergedConfig.llm.provider;
749
+ const resolvedApiKey = resolveApiKeyForProvider(agentProvider);
750
+ const compatibility = checkAgentCompatibility(mergedConfig, preferences, resolvedApiKey);
751
+ if (!compatibility.compatible && opts.interactive !== false) {
752
+ // User is missing API key for the agent's provider
753
+ if (!compatibility.userHasApiKey &&
754
+ preferences?.llm?.provider &&
755
+ preferences?.llm?.model) {
756
+ // User has a default LLM configured - offer choice
757
+ const { promptForMissingAgentApiKey } = await import('./cli/utils/api-key-setup.js');
758
+ const result = await promptForMissingAgentApiKey(compatibility.agentProvider, compatibility.agentModel, preferences.llm.provider, preferences.llm.model);
759
+ if (result.action === 'cancel') {
760
+ safeExit('main', 0, 'agent-api-key-cancelled');
761
+ }
762
+ if (result.action === 'use-default') {
763
+ // Apply user's default LLM to the agent config
764
+ mergedConfig = applyUserPreferences(mergedConfig, preferences);
765
+ // Also resolve the actual API key from environment
766
+ // (preferences store env var reference like $GOOGLE_API_KEY, not the actual key)
767
+ const userApiKey = resolveApiKeyForProvider(preferences.llm.provider);
768
+ if (userApiKey) {
769
+ mergedConfig.llm.apiKey = userApiKey;
770
+ }
771
+ logger.debug('Applied user preferences to agent (user chose default)', {
772
+ provider: preferences.llm.provider,
773
+ model: preferences.llm.model,
774
+ });
775
+ }
776
+ if (result.action === 'add-key' && result.apiKey) {
777
+ // User added the API key - update the config
778
+ mergedConfig.llm.apiKey = result.apiKey;
779
+ logger.debug('Applied new API key to agent config');
780
+ }
781
+ }
782
+ else {
783
+ // No default LLM to fall back to - show warnings only
784
+ console.log(chalk.yellow('\n⚠️ Agent Compatibility Notice:'));
785
+ for (const warning of compatibility.warnings) {
786
+ console.log(chalk.yellow(` ${warning}`));
787
+ }
788
+ if (compatibility.instructions.length > 0) {
789
+ console.log(chalk.dim('\n To fix:'));
790
+ for (const instruction of compatibility.instructions) {
791
+ console.log(chalk.dim(` ${instruction}`));
792
+ }
793
+ }
794
+ console.log(''); // Empty line for spacing
795
+ }
796
+ }
797
+ }
798
+ // Clean up null values from config (can happen from YAML files with explicit nulls)
799
+ // This prevents "Expected string, received null" errors for optional fields
800
+ const cleanedConfig = cleanNullValues(mergedConfig);
607
801
  // Enrich config with per-agent paths BEFORE validation
608
802
  // Enrichment adds filesystem paths to storage (schema has in-memory defaults)
609
803
  // Interactive CLI mode: only log to file (console would interfere with chat UI)
610
804
  const isInteractiveCli = opts.mode === 'cli' && !headlessInput;
611
- const enrichedConfig = enrichAgentConfig(mergedConfig, resolvedPath, isInteractiveCli);
805
+ const enrichedConfig = enrichAgentConfig(cleanedConfig, resolvedPath, {
806
+ isInteractiveCli,
807
+ logLevel: 'info', // CLI uses info-level logging for visibility
808
+ });
612
809
  // Validate enriched config with interactive setup if needed (for API key issues)
613
- validatedConfig = await validateAgentConfig(enrichedConfig, opts.interactive !== false);
810
+ // isInteractiveMode is defined above the try block
811
+ const validationResult = await validateAgentConfig(enrichedConfig, opts.interactive !== false, { strict: !isInteractiveMode });
812
+ if (validationResult.success && validationResult.config) {
813
+ validatedConfig = validationResult.config;
814
+ }
815
+ else if (validationResult.skipped) {
816
+ // User chose to continue despite validation errors
817
+ // SAFETY: This cast is intentionally unsafe - it's an escape hatch for users
818
+ // when validation is overly strict or incorrect. Runtime errors will surface
819
+ // if the config truly doesn't work. Future: explicit `allowUnvalidated` mode.
820
+ logger.warn('Starting with validation warnings - some features may not work');
821
+ validatedConfig = enrichedConfig;
822
+ }
823
+ else {
824
+ // Validation failed and user didn't skip - show next steps and exit
825
+ safeExit('main', 1, 'config-validation-failed');
826
+ }
827
+ // ——— LOAD IMAGE DYNAMICALLY (if specified) ———
828
+ // Priority: CLI flag > Agent config > Environment variable > Default
829
+ // Images are optional, but default to image-local for convenience
830
+ const imageName = opts.image || // --image flag
831
+ validatedConfig.image || // image field in agent config
832
+ process.env.DEXTO_IMAGE || // DEXTO_IMAGE env var
833
+ '@dexto/image-local'; // Default for convenience
834
+ try {
835
+ await import(imageName);
836
+ logger.debug(`Loaded image: ${imageName}`);
837
+ }
838
+ catch (err) {
839
+ console.error(`❌ Failed to load image '${imageName}'`);
840
+ console.error(`💡 Install it with: ${existsSync('package.json') ? 'npm install' : 'npm install -g'} ${imageName}`);
841
+ if (err instanceof Error) {
842
+ logger.debug(`Image load error: ${err.message}`);
843
+ }
844
+ safeExit('main', 1, 'image-load-failed');
845
+ }
846
+ // Validate that if config specifies an image, it matches what was loaded
847
+ // Skip this check if user explicitly provided --image flag (intentional override)
848
+ if (!opts.image &&
849
+ validatedConfig.image &&
850
+ validatedConfig.image !== imageName) {
851
+ console.error(`❌ Config specifies image '${validatedConfig.image}' but '${imageName}' was loaded instead`);
852
+ console.error(`💡 Either remove 'image' from config or ensure it matches the loaded image`);
853
+ safeExit('main', 1, 'image-mismatch');
854
+ }
614
855
  }
615
856
  catch (err) {
616
857
  if (err instanceof ExitSignal)
@@ -663,7 +904,10 @@ program
663
904
  }
664
905
  // Config is already enriched and validated - ready for agent creation
665
906
  // DextoAgent will parse/validate again (parse-twice pattern)
666
- agent = new DextoAgent(validatedConfig, resolvedPath);
907
+ // isInteractiveMode is already defined above for validateAgentConfig
908
+ agent = new DextoAgent(validatedConfig, resolvedPath, {
909
+ strict: !isInteractiveMode,
910
+ });
667
911
  // Start the agent (initialize async services)
668
912
  // - web/server modes: initializeHonoApi will set approval handler and start the agent
669
913
  // - cli mode: handles its own approval setup in the case block
@@ -704,6 +948,15 @@ program
704
948
  const approvalCoordinator = new ApprovalCoordinator();
705
949
  const handler = createManualApprovalHandler(approvalCoordinator);
706
950
  agent.setApprovalHandler(handler);
951
+ // Bridge approval events between coordinator and agent event bus for Ink CLI
952
+ // Forward requests from coordinator to event bus (for UI to receive)
953
+ approvalCoordinator.on('approval:request', (request) => {
954
+ agent.agentEventBus.emit('approval:request', request);
955
+ });
956
+ // Forward responses from event bus to coordinator (for handler to receive)
957
+ agent.agentEventBus.on('approval:response', (response) => {
958
+ approvalCoordinator.emitResponse(response);
959
+ });
707
960
  logger.debug('Event-based approval handler configured for Ink CLI');
708
961
  }
709
962
  // Start the agent now that approval handler is configured
@@ -799,8 +1052,41 @@ program
799
1052
  else {
800
1053
  // Interactive mode - session management handled via /resume command
801
1054
  // Note: -c and -r flags are validated to require a prompt (headless mode only)
802
- // Defer session creation until first message is sent to prevent stale empty sessions
803
- const cliSessionId = null;
1055
+ // Check if API key is configured before trying to create session
1056
+ // Session creation triggers LLM service init which requires API key
1057
+ const llmConfig = agent.getCurrentLLMConfig();
1058
+ const { requiresApiKey } = await import('@dexto/core');
1059
+ if (requiresApiKey(llmConfig.provider) && !llmConfig.apiKey?.trim()) {
1060
+ // Offer interactive API key setup instead of just exiting
1061
+ const { interactiveApiKeySetup } = await import('./cli/utils/api-key-setup.js');
1062
+ console.log(chalk.yellow(`\n⚠️ API key required for provider '${llmConfig.provider}'\n`));
1063
+ const setupResult = await interactiveApiKeySetup(llmConfig.provider, {
1064
+ exitOnCancel: false,
1065
+ model: llmConfig.model,
1066
+ });
1067
+ if (setupResult.cancelled) {
1068
+ await agent.stop().catch(() => { });
1069
+ safeExit('main', 0, 'api-key-setup-cancelled');
1070
+ }
1071
+ if (setupResult.skipped) {
1072
+ // User chose to skip - exit with instructions
1073
+ await agent.stop().catch(() => { });
1074
+ safeExit('main', 0, 'api-key-pending');
1075
+ }
1076
+ if (setupResult.success && setupResult.apiKey) {
1077
+ // API key was entered and saved - reload config and continue
1078
+ // Update the agent's LLM config with the new API key
1079
+ await agent.switchLLM({
1080
+ provider: llmConfig.provider,
1081
+ model: llmConfig.model,
1082
+ apiKey: setupResult.apiKey,
1083
+ });
1084
+ logger.info('API key configured successfully, continuing...');
1085
+ }
1086
+ }
1087
+ // Create session eagerly so slash commands work immediately
1088
+ const session = await agent.createSession();
1089
+ const cliSessionId = session.id;
804
1090
  // Interactive mode - use Ink CLI with session support
805
1091
  // Suppress console output before starting Ink UI
806
1092
  const originalConsole = {
@@ -849,8 +1135,8 @@ program
849
1135
  }
850
1136
  safeExit('main', 0);
851
1137
  }
852
- break;
853
1138
  }
1139
+ // falls through - safeExit returns never, but eslint doesn't know that
854
1140
  case 'web': {
855
1141
  // Default to 3000 for web mode
856
1142
  const defaultPort = opts.port ? parseInt(opts.port, 10) : 3000;
@@ -903,26 +1189,6 @@ program
903
1189
  console.log(' SSE support available for real-time events');
904
1190
  break;
905
1191
  }
906
- case 'discord':
907
- console.log('🤖 Starting Discord bot…');
908
- try {
909
- startDiscordBot(agent);
910
- }
911
- catch (err) {
912
- console.error('❌ Discord startup failed:', err);
913
- safeExit('main', 1, 'discord-startup-failed');
914
- }
915
- break;
916
- case 'telegram':
917
- console.log('🤖 Starting Telegram bot…');
918
- try {
919
- startTelegramBot(agent);
920
- }
921
- catch (err) {
922
- console.error('❌ Telegram startup failed:', err);
923
- safeExit('main', 1, 'telegram-startup-failed');
924
- }
925
- break;
926
1192
  // TODO: Remove if server mode is stable and supports mcp
927
1193
  // Starts dexto as a local mcp server
928
1194
  // Use `dexto --mode mcp` to start dexto as a local mcp server
@@ -953,9 +1219,23 @@ program
953
1219
  break;
954
1220
  }
955
1221
  default:
956
- console.error(`❌ Unknown mode '${opts.mode}'. Use web, cli, server, discord, telegram, or mcp.`);
1222
+ if (opts.mode === 'discord' || opts.mode === 'telegram') {
1223
+ console.error(`❌ Error: '${opts.mode}' mode has been moved to examples`);
1224
+ console.error('');
1225
+ console.error(`The ${opts.mode} bot is now a standalone example that you can customize.`);
1226
+ console.error('');
1227
+ console.error(`📖 See: examples/${opts.mode}-bot/README.md`);
1228
+ console.error('');
1229
+ console.error(`To run it:`);
1230
+ console.error(` cd examples/${opts.mode}-bot`);
1231
+ console.error(` pnpm install`);
1232
+ console.error(` pnpm start`);
1233
+ }
1234
+ else {
1235
+ console.error(`❌ Unknown mode '${opts.mode}'. Use web, cli, server, or mcp.`);
1236
+ }
957
1237
  safeExit('main', 1, 'unknown-mode');
958
1238
  }
959
1239
  }, { timeoutMs: 0 }));
960
- // 11) PARSE & EXECUTE
1240
+ // 14) PARSE & EXECUTE
961
1241
  program.parseAsync(process.argv);