dexto 1.5.5 → 1.5.7

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 (234) hide show
  1. package/README.md +13 -0
  2. package/dist/agents/agent-template.yml +1 -1
  3. package/dist/agents/coding-agent/coding-agent.yml +17 -2
  4. package/dist/agents/coding-agent/skills/code-review.md +46 -0
  5. package/dist/agents/explore-agent/explore-agent.yml +2 -0
  6. package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
  7. package/dist/analytics/events.d.ts +1 -1
  8. package/dist/analytics/events.d.ts.map +1 -1
  9. package/dist/api/server-hono.d.ts.map +1 -1
  10. package/dist/api/server-hono.js +55 -10
  11. package/dist/cli/assets/dexto-logo.svg +31 -0
  12. package/dist/cli/auth/api-client.d.ts +49 -0
  13. package/dist/cli/auth/api-client.d.ts.map +1 -0
  14. package/dist/cli/auth/api-client.js +127 -0
  15. package/dist/cli/auth/constants.d.ts +23 -0
  16. package/dist/cli/auth/constants.d.ts.map +1 -0
  17. package/dist/cli/auth/constants.js +24 -0
  18. package/dist/cli/auth/index.d.ts +5 -0
  19. package/dist/cli/auth/index.d.ts.map +1 -0
  20. package/dist/cli/auth/index.js +6 -0
  21. package/dist/cli/auth/oauth.d.ts +26 -0
  22. package/dist/cli/auth/oauth.d.ts.map +1 -0
  23. package/dist/cli/auth/oauth.js +327 -0
  24. package/dist/cli/auth/service.d.ts +20 -0
  25. package/dist/cli/auth/service.d.ts.map +1 -0
  26. package/dist/cli/auth/service.js +147 -0
  27. package/dist/cli/commands/auth/index.d.ts +4 -0
  28. package/dist/cli/commands/auth/index.d.ts.map +1 -0
  29. package/dist/cli/commands/auth/index.js +4 -0
  30. package/dist/cli/commands/auth/login.d.ts +9 -0
  31. package/dist/cli/commands/auth/login.d.ts.map +1 -0
  32. package/dist/cli/commands/auth/login.js +255 -0
  33. package/dist/cli/commands/auth/logout.d.ts +5 -0
  34. package/dist/cli/commands/auth/logout.d.ts.map +1 -0
  35. package/dist/cli/commands/auth/logout.js +51 -0
  36. package/dist/cli/commands/auth/status.d.ts +2 -0
  37. package/dist/cli/commands/auth/status.d.ts.map +1 -0
  38. package/dist/cli/commands/auth/status.js +22 -0
  39. package/dist/cli/commands/billing/index.d.ts +2 -0
  40. package/dist/cli/commands/billing/index.d.ts.map +1 -0
  41. package/dist/cli/commands/billing/index.js +2 -0
  42. package/dist/cli/commands/billing/status.d.ts +6 -0
  43. package/dist/cli/commands/billing/status.d.ts.map +1 -0
  44. package/dist/cli/commands/billing/status.js +60 -0
  45. package/dist/cli/commands/index.d.ts +4 -0
  46. package/dist/cli/commands/index.d.ts.map +1 -1
  47. package/dist/cli/commands/index.js +9 -0
  48. package/dist/cli/commands/interactive-commands/auth/index.d.ts +12 -0
  49. package/dist/cli/commands/interactive-commands/auth/index.d.ts.map +1 -0
  50. package/dist/cli/commands/interactive-commands/auth/index.js +20 -0
  51. package/dist/cli/commands/interactive-commands/command-parser.d.ts +5 -0
  52. package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
  53. package/dist/cli/commands/interactive-commands/command-parser.js +6 -0
  54. package/dist/cli/commands/interactive-commands/commands.d.ts +1 -0
  55. package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
  56. package/dist/cli/commands/interactive-commands/commands.js +10 -0
  57. package/dist/cli/commands/interactive-commands/export/index.d.ts +13 -0
  58. package/dist/cli/commands/interactive-commands/export/index.d.ts.map +1 -0
  59. package/dist/cli/commands/interactive-commands/export/index.js +21 -0
  60. package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
  61. package/dist/cli/commands/interactive-commands/general-commands.js +1 -0
  62. package/dist/cli/commands/interactive-commands/mcp/index.d.ts +2 -2
  63. package/dist/cli/commands/interactive-commands/mcp/index.d.ts.map +1 -1
  64. package/dist/cli/commands/interactive-commands/mcp/index.js +4 -7
  65. package/dist/cli/commands/interactive-commands/model/index.d.ts +2 -2
  66. package/dist/cli/commands/interactive-commands/model/index.d.ts.map +1 -1
  67. package/dist/cli/commands/interactive-commands/model/index.js +4 -7
  68. package/dist/cli/commands/interactive-commands/plugin/index.d.ts +13 -0
  69. package/dist/cli/commands/interactive-commands/plugin/index.d.ts.map +1 -0
  70. package/dist/cli/commands/interactive-commands/plugin/index.js +18 -0
  71. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts +3 -1
  72. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
  73. package/dist/cli/commands/interactive-commands/prompt-commands.js +72 -36
  74. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
  75. package/dist/cli/commands/interactive-commands/system/system-commands.js +2 -3
  76. package/dist/cli/commands/plugin.d.ts +161 -0
  77. package/dist/cli/commands/plugin.d.ts.map +1 -0
  78. package/dist/cli/commands/plugin.js +376 -0
  79. package/dist/cli/commands/setup.d.ts +9 -9
  80. package/dist/cli/commands/setup.d.ts.map +1 -1
  81. package/dist/cli/commands/setup.js +325 -37
  82. package/dist/cli/commands/sync-agents.d.ts +44 -0
  83. package/dist/cli/commands/sync-agents.d.ts.map +1 -0
  84. package/dist/cli/commands/sync-agents.js +483 -0
  85. package/dist/cli/ink-cli/InkCLIRefactored.d.ts +14 -1
  86. package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
  87. package/dist/cli/ink-cli/InkCLIRefactored.js +8 -2
  88. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +1 -1
  89. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
  90. package/dist/cli/ink-cli/components/ApprovalPrompt.js +80 -12
  91. package/dist/cli/ink-cli/components/Footer.d.ts +2 -1
  92. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
  93. package/dist/cli/ink-cli/components/Footer.js +6 -2
  94. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts.map +1 -1
  95. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +15 -7
  96. package/dist/cli/ink-cli/components/StatusBar.d.ts +9 -1
  97. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  98. package/dist/cli/ink-cli/components/StatusBar.js +17 -5
  99. package/dist/cli/ink-cli/components/TodoPanel.d.ts +11 -8
  100. package/dist/cli/ink-cli/components/TodoPanel.d.ts.map +1 -1
  101. package/dist/cli/ink-cli/components/TodoPanel.js +38 -36
  102. package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
  103. package/dist/cli/ink-cli/components/chat/Header.js +1 -1
  104. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  105. package/dist/cli/ink-cli/components/chat/MessageItem.js +14 -1
  106. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
  107. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  108. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +16 -4
  109. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
  110. package/dist/cli/ink-cli/components/modes/StaticCLI.js +4 -1
  111. package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts +22 -0
  112. package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts.map +1 -0
  113. package/dist/cli/ink-cli/components/overlays/ExportWizard.js +308 -0
  114. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts +1 -0
  115. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts.map +1 -1
  116. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +31 -20
  117. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts +20 -0
  118. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts.map +1 -0
  119. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.js +81 -0
  120. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts +31 -0
  121. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts.map +1 -0
  122. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.js +297 -0
  123. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts.map +1 -1
  124. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +7 -1
  125. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts +1 -1
  126. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts.map +1 -1
  127. package/dist/cli/ink-cli/components/overlays/McpServerActions.js +9 -0
  128. package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts.map +1 -1
  129. package/dist/cli/ink-cli/components/overlays/McpServerList.js +9 -2
  130. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  131. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +15 -2
  132. package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts +27 -0
  133. package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts.map +1 -0
  134. package/dist/cli/ink-cli/components/overlays/PluginActions.js +66 -0
  135. package/dist/cli/ink-cli/components/overlays/PluginList.d.ts +21 -0
  136. package/dist/cli/ink-cli/components/overlays/PluginList.d.ts.map +1 -0
  137. package/dist/cli/ink-cli/components/overlays/PluginList.js +70 -0
  138. package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts +21 -0
  139. package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts.map +1 -0
  140. package/dist/cli/ink-cli/components/overlays/PluginManager.js +63 -0
  141. package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -1
  142. package/dist/cli/ink-cli/components/overlays/PromptList.js +4 -1
  143. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +2 -1
  144. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
  145. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +61 -2
  146. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts +4 -2
  147. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts.map +1 -1
  148. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +4 -4
  149. package/dist/cli/ink-cli/constants/tips.js +2 -2
  150. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  151. package/dist/cli/ink-cli/containers/InputContainer.js +31 -3
  152. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  153. package/dist/cli/ink-cli/containers/OverlayContainer.js +260 -11
  154. package/dist/cli/ink-cli/hooks/index.d.ts +1 -0
  155. package/dist/cli/ink-cli/hooks/index.d.ts.map +1 -1
  156. package/dist/cli/ink-cli/hooks/index.js +1 -0
  157. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  158. package/dist/cli/ink-cli/hooks/useCLIState.js +3 -0
  159. package/dist/cli/ink-cli/hooks/useGitBranch.d.ts +13 -0
  160. package/dist/cli/ink-cli/hooks/useGitBranch.d.ts.map +1 -0
  161. package/dist/cli/ink-cli/hooks/useGitBranch.js +35 -0
  162. package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -1
  163. package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +50 -6
  164. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  165. package/dist/cli/ink-cli/services/processStream.js +42 -10
  166. package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
  167. package/dist/cli/ink-cli/state/initialState.js +3 -0
  168. package/dist/cli/ink-cli/state/types.d.ts +16 -1
  169. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  170. package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
  171. package/dist/cli/ink-cli/utils/commandOverlays.js +2 -0
  172. package/dist/cli/ink-cli/utils/messageFormatting.d.ts +14 -1
  173. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  174. package/dist/cli/ink-cli/utils/messageFormatting.js +68 -8
  175. package/dist/cli/ink-cli/utils/toolUtils.d.ts +11 -0
  176. package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
  177. package/dist/cli/ink-cli/utils/toolUtils.js +17 -0
  178. package/dist/cli/mcp/index.d.ts +8 -0
  179. package/dist/cli/mcp/index.d.ts.map +1 -0
  180. package/dist/cli/mcp/index.js +7 -0
  181. package/dist/cli/mcp/oauth-factory.d.ts +6 -0
  182. package/dist/cli/mcp/oauth-factory.d.ts.map +1 -0
  183. package/dist/cli/mcp/oauth-factory.js +25 -0
  184. package/dist/cli/mcp/oauth-provider.d.ts +10 -0
  185. package/dist/cli/mcp/oauth-provider.d.ts.map +1 -0
  186. package/dist/cli/mcp/oauth-provider.js +77 -0
  187. package/dist/cli/mcp/oauth-redirect.d.ts +3 -0
  188. package/dist/cli/mcp/oauth-redirect.d.ts.map +1 -0
  189. package/dist/cli/mcp/oauth-redirect.js +4 -0
  190. package/dist/cli/mcp/oauth-server.d.ts +2 -0
  191. package/dist/cli/mcp/oauth-server.d.ts.map +1 -0
  192. package/dist/cli/mcp/oauth-server.js +70 -0
  193. package/dist/cli/mcp/oauth-store.d.ts +10 -0
  194. package/dist/cli/mcp/oauth-store.d.ts.map +1 -0
  195. package/dist/cli/mcp/oauth-store.js +27 -0
  196. package/dist/cli/mcp/oauth-ui.d.ts +2 -0
  197. package/dist/cli/mcp/oauth-ui.d.ts.map +1 -0
  198. package/dist/cli/mcp/oauth-ui.js +12 -0
  199. package/dist/cli/mcp/oauth-utils.d.ts +2 -0
  200. package/dist/cli/mcp/oauth-utils.d.ts.map +1 -0
  201. package/dist/cli/mcp/oauth-utils.js +17 -0
  202. package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
  203. package/dist/cli/utils/api-key-setup.js +13 -90
  204. package/dist/cli/utils/api-key-verification.d.ts.map +1 -1
  205. package/dist/cli/utils/api-key-verification.js +36 -0
  206. package/dist/cli/utils/config-validation.d.ts +3 -1
  207. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  208. package/dist/cli/utils/config-validation.js +42 -19
  209. package/dist/cli/utils/dexto-auth-check.d.ts +53 -0
  210. package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -0
  211. package/dist/cli/utils/dexto-auth-check.js +104 -0
  212. package/dist/cli/utils/dexto-setup.d.ts +8 -0
  213. package/dist/cli/utils/dexto-setup.d.ts.map +1 -0
  214. package/dist/cli/utils/dexto-setup.js +17 -0
  215. package/dist/cli/utils/options.d.ts.map +1 -1
  216. package/dist/cli/utils/options.js +5 -1
  217. package/dist/cli/utils/provider-setup.d.ts +4 -0
  218. package/dist/cli/utils/provider-setup.d.ts.map +1 -1
  219. package/dist/cli/utils/provider-setup.js +20 -0
  220. package/dist/cli/utils/version-check.d.ts +45 -0
  221. package/dist/cli/utils/version-check.d.ts.map +1 -0
  222. package/dist/cli/utils/version-check.js +195 -0
  223. package/dist/config/cli-overrides.d.ts +17 -8
  224. package/dist/config/cli-overrides.d.ts.map +1 -1
  225. package/dist/config/cli-overrides.js +36 -22
  226. package/dist/config/effective-llm.d.ts +123 -0
  227. package/dist/config/effective-llm.d.ts.map +1 -0
  228. package/dist/config/effective-llm.js +171 -0
  229. package/dist/index.js +451 -126
  230. package/dist/webui/assets/index-C9JXwpvo.css +1 -0
  231. package/dist/webui/assets/{index-DVQWNLpT.js → index-Dl3mj53P.js} +217 -217
  232. package/dist/webui/index.html +2 -2
  233. package/package.json +9 -8
  234. package/dist/webui/assets/index-BglIVTSG.css +0 -1
@@ -30,7 +30,13 @@ import PromptAddWizard from '../components/overlays/PromptAddWizard.js';
30
30
  import PromptDeleteSelector from '../components/overlays/PromptDeleteSelector.js';
31
31
  import SessionRenameOverlay from '../components/overlays/SessionRenameOverlay.js';
32
32
  import ContextStatsOverlay from '../components/overlays/ContextStatsOverlay.js';
33
- import { DextoValidationError, LLMErrorCode } from '@dexto/core';
33
+ import ExportWizard from '../components/overlays/ExportWizard.js';
34
+ import PluginManager from '../components/overlays/PluginManager.js';
35
+ import PluginList from '../components/overlays/PluginList.js';
36
+ import PluginActions from '../components/overlays/PluginActions.js';
37
+ import MarketplaceBrowser from '../components/overlays/MarketplaceBrowser.js';
38
+ import MarketplaceAddPrompt from '../components/overlays/MarketplaceAddPrompt.js';
39
+ import { DextoValidationError, LLMErrorCode, getModelDisplayName } from '@dexto/core';
34
40
  import { createUserMessage, convertHistoryToUIMessages } from '../utils/messageFormatting.js';
35
41
  import { generateMessageId } from '../utils/idGenerator.js';
36
42
  import { capture } from '../../../analytics/index.js';
@@ -65,6 +71,14 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
65
71
  const promptDeleteSelectorRef = useRef(null);
66
72
  const sessionRenameRef = useRef(null);
67
73
  const contextStatsRef = useRef(null);
74
+ const exportWizardRef = useRef(null);
75
+ const pluginManagerRef = useRef(null);
76
+ const pluginListRef = useRef(null);
77
+ const pluginActionsRef = useRef(null);
78
+ const marketplaceBrowserRef = useRef(null);
79
+ // State for selected plugin (for plugin-actions overlay)
80
+ const [selectedPlugin, setSelectedPlugin] = useState(null);
81
+ const marketplaceAddPromptRef = useRef(null);
68
82
  // Expose handleInput method via ref - routes to appropriate overlay
69
83
  useImperativeHandle(ref, () => ({
70
84
  handleInput: (inputStr, key) => {
@@ -122,6 +136,18 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
122
136
  return sessionRenameRef.current?.handleInput(inputStr, key) ?? false;
123
137
  case 'context-stats':
124
138
  return contextStatsRef.current?.handleInput(inputStr, key) ?? false;
139
+ case 'export-wizard':
140
+ return exportWizardRef.current?.handleInput(inputStr, key) ?? false;
141
+ case 'plugin-manager':
142
+ return pluginManagerRef.current?.handleInput(inputStr, key) ?? false;
143
+ case 'plugin-list':
144
+ return pluginListRef.current?.handleInput(inputStr, key) ?? false;
145
+ case 'plugin-actions':
146
+ return pluginActionsRef.current?.handleInput(inputStr, key) ?? false;
147
+ case 'marketplace-browser':
148
+ return (marketplaceBrowserRef.current?.handleInput(inputStr, key) ?? false);
149
+ case 'marketplace-add':
150
+ return (marketplaceAddPromptRef.current?.handleInput(inputStr, key) ?? false);
125
151
  default:
126
152
  return false;
127
153
  }
@@ -156,6 +182,20 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
156
182
  if (options.enableAcceptEditsMode) {
157
183
  setUi((prev) => ({ ...prev, autoApproveEdits: true }));
158
184
  }
185
+ // Auto-disable plan mode when plan_create or plan_review is approved
186
+ // This signals the transition from planning phase to execution phase
187
+ const toolName = approval.metadata.toolName;
188
+ const isPlanTool = toolName === 'plan_create' ||
189
+ toolName === 'plan_review' ||
190
+ toolName === 'custom--plan_create' ||
191
+ toolName === 'custom--plan_review';
192
+ if (isPlanTool) {
193
+ setUi((prev) => ({
194
+ ...prev,
195
+ planModeActive: false,
196
+ planModeInitialized: false,
197
+ }));
198
+ }
159
199
  eventBus.emit('approval:response', {
160
200
  approvalId: approval.approvalId,
161
201
  status: ApprovalStatus.APPROVED,
@@ -169,15 +209,19 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
169
209
  });
170
210
  completeApproval();
171
211
  }, [approval, eventBus, completeApproval, setUi]);
172
- const handleDeny = useCallback(() => {
212
+ const handleDeny = useCallback((feedback) => {
173
213
  if (!approval || !eventBus)
174
214
  return;
215
+ // Include user feedback in the denial message if provided
216
+ const message = feedback
217
+ ? `User requested changes: ${feedback}`
218
+ : 'User denied the tool execution';
175
219
  eventBus.emit('approval:response', {
176
220
  approvalId: approval.approvalId,
177
221
  status: ApprovalStatus.DENIED,
178
222
  sessionId: approval.sessionId,
179
223
  reason: DenialReason.USER_DENIED,
180
- message: 'User denied the tool execution',
224
+ message,
181
225
  });
182
226
  completeApproval();
183
227
  }, [approval, eventBus, completeApproval]);
@@ -209,6 +253,40 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
209
253
  };
210
254
  // Handle model selection
211
255
  const handleModelSelect = useCallback(async (provider, model, displayName, baseURL, reasoningEffort) => {
256
+ // Pre-check: Dexto provider requires OAuth login AND API key
257
+ // Check BEFORE closing the overlay so user can pick a different model
258
+ if (provider === 'dexto') {
259
+ try {
260
+ const { canUseDextoProvider } = await import('../../utils/dexto-setup.js');
261
+ const canUse = await canUseDextoProvider();
262
+ if (!canUse) {
263
+ setMessages((prev) => [
264
+ ...prev,
265
+ {
266
+ id: generateMessageId('system'),
267
+ role: 'system',
268
+ content: '❌ Cannot switch to Dexto model - authentication required. Run /login to authenticate.',
269
+ timestamp: new Date(),
270
+ },
271
+ ]);
272
+ // Don't close the overlay - let user pick a different model
273
+ return;
274
+ }
275
+ }
276
+ catch (error) {
277
+ setMessages((prev) => [
278
+ ...prev,
279
+ {
280
+ id: generateMessageId('error'),
281
+ role: 'system',
282
+ content: `❌ Failed to verify Dexto auth: ${error instanceof Error ? error.message : String(error)}`,
283
+ timestamp: new Date(),
284
+ },
285
+ ]);
286
+ // Don't close the overlay - let user pick a different model
287
+ return;
288
+ }
289
+ }
212
290
  setUi((prev) => ({ ...prev, activeOverlay: 'none', mcpWizardServerType: null }));
213
291
  buffer.setText('');
214
292
  setInput((prev) => ({ ...prev, historyIndex: -1 }));
@@ -439,16 +517,19 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
439
517
  setMessages([]);
440
518
  setApproval(null);
441
519
  setApprovalQueue([]);
442
- setSession({
443
- id: newSessionId,
444
- hasActiveSession: true,
445
- modelName: session.modelName,
446
- });
447
- // Verify session exists
520
+ // Verify session exists first
448
521
  const sessionData = await agent.getSession(newSessionId);
449
522
  if (!sessionData) {
450
523
  throw new Error(`Session ${newSessionId} not found`);
451
524
  }
525
+ // Get the actual model being used for this session (respects llmOverride)
526
+ const newSessionConfig = agent.getCurrentLLMConfig(newSessionId);
527
+ const newSessionModelName = getModelDisplayName(newSessionConfig.model, newSessionConfig.provider);
528
+ setSession({
529
+ id: newSessionId,
530
+ hasActiveSession: true,
531
+ modelName: newSessionModelName,
532
+ });
452
533
  // Load session history
453
534
  const history = await agent.getSessionHistory(newSessionId);
454
535
  if (history && history.length > 0) {
@@ -759,6 +840,8 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
759
840
  activeOverlay: 'none',
760
841
  selectedMcpServer: null,
761
842
  mcpWizardServerType: null,
843
+ isProcessing: true,
844
+ isCancelling: false,
762
845
  }));
763
846
  buffer.setText('');
764
847
  setInput((prev) => ({ ...prev, historyIndex: -1 }));
@@ -791,6 +874,12 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
791
874
  timestamp: new Date(),
792
875
  },
793
876
  ]);
877
+ setUi((prev) => ({
878
+ ...prev,
879
+ isProcessing: false,
880
+ isCancelling: false,
881
+ isThinking: false,
882
+ }));
794
883
  return;
795
884
  }
796
885
  }
@@ -834,6 +923,40 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
834
923
  ]);
835
924
  }
836
925
  }
926
+ else if (action.type === 'authenticate') {
927
+ setMessages((prev) => [
928
+ ...prev,
929
+ {
930
+ id: generateMessageId('system'),
931
+ role: 'system',
932
+ content: `🔐 Authenticating ${server.name}...`,
933
+ timestamp: new Date(),
934
+ },
935
+ ]);
936
+ try {
937
+ await agent.restartMcpServer(server.name);
938
+ setMessages((prev) => [
939
+ ...prev,
940
+ {
941
+ id: generateMessageId('system'),
942
+ role: 'system',
943
+ content: `✅ Authenticated ${server.name}`,
944
+ timestamp: new Date(),
945
+ },
946
+ ]);
947
+ }
948
+ catch (error) {
949
+ setMessages((prev) => [
950
+ ...prev,
951
+ {
952
+ id: generateMessageId('error'),
953
+ role: 'system',
954
+ content: `❌ Failed to authenticate server: ${error instanceof Error ? error.message : String(error)}`,
955
+ timestamp: new Date(),
956
+ },
957
+ ]);
958
+ }
959
+ }
837
960
  else if (action.type === 'delete') {
838
961
  setMessages((prev) => [
839
962
  ...prev,
@@ -878,6 +1001,12 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
878
1001
  ]);
879
1002
  }
880
1003
  }
1004
+ setUi((prev) => ({
1005
+ ...prev,
1006
+ isProcessing: false,
1007
+ isCancelling: false,
1008
+ isThinking: false,
1009
+ }));
881
1010
  }, [setUi, setInput, setMessages, agent, buffer]);
882
1011
  // Handle MCP add choice (registry/custom/back)
883
1012
  const handleMcpAddChoice = useCallback((choice) => {
@@ -1036,6 +1165,120 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
1036
1165
  isThinking: false,
1037
1166
  }));
1038
1167
  }, [setUi, setInput, setMessages, agent, buffer]);
1168
+ // Handle plugin manager actions
1169
+ const handlePluginManagerAction = useCallback((action) => {
1170
+ if (action === 'list') {
1171
+ setUi((prev) => ({
1172
+ ...prev,
1173
+ activeOverlay: 'plugin-list',
1174
+ }));
1175
+ }
1176
+ else if (action === 'marketplace') {
1177
+ setUi((prev) => ({
1178
+ ...prev,
1179
+ activeOverlay: 'marketplace-browser',
1180
+ }));
1181
+ }
1182
+ }, [setUi]);
1183
+ // Handle plugin selection from plugin list
1184
+ const handlePluginSelect = useCallback((plugin) => {
1185
+ setSelectedPlugin(plugin);
1186
+ setUi((prev) => ({
1187
+ ...prev,
1188
+ activeOverlay: 'plugin-actions',
1189
+ }));
1190
+ }, [setUi]);
1191
+ // Handle plugin actions (uninstall, back)
1192
+ const handlePluginAction = useCallback(async (action) => {
1193
+ if (action.type === 'back') {
1194
+ setSelectedPlugin(null);
1195
+ setUi((prev) => ({
1196
+ ...prev,
1197
+ activeOverlay: 'plugin-list',
1198
+ }));
1199
+ return;
1200
+ }
1201
+ if (action.type === 'uninstall') {
1202
+ setUi((prev) => ({ ...prev, activeOverlay: 'none', isProcessing: true }));
1203
+ try {
1204
+ const { uninstallPlugin, reloadAgentConfigFromFile, enrichAgentConfig } = await import('@dexto/agent-management');
1205
+ await uninstallPlugin(action.plugin.name);
1206
+ setMessages((prev) => [
1207
+ ...prev,
1208
+ {
1209
+ id: generateMessageId('system'),
1210
+ role: 'system',
1211
+ content: `Plugin '${action.plugin.name}' has been uninstalled.`,
1212
+ timestamp: new Date(),
1213
+ },
1214
+ ]);
1215
+ // Refresh prompts to remove uninstalled plugin skills
1216
+ try {
1217
+ const newConfig = await reloadAgentConfigFromFile(agent.getAgentFilePath());
1218
+ const enrichedConfig = enrichAgentConfig(newConfig, agent.getAgentFilePath());
1219
+ await agent.refreshPrompts(enrichedConfig.prompts);
1220
+ }
1221
+ catch {
1222
+ // Non-critical: prompts will refresh on next agent restart
1223
+ }
1224
+ }
1225
+ catch (error) {
1226
+ setMessages((prev) => [
1227
+ ...prev,
1228
+ {
1229
+ id: generateMessageId('error'),
1230
+ role: 'system',
1231
+ content: `Failed to uninstall plugin: ${error instanceof Error ? error.message : String(error)}`,
1232
+ timestamp: new Date(),
1233
+ },
1234
+ ]);
1235
+ }
1236
+ setSelectedPlugin(null);
1237
+ setUi((prev) => ({ ...prev, isProcessing: false }));
1238
+ }
1239
+ }, [setUi, setMessages, agent]);
1240
+ // Handle marketplace browser actions
1241
+ const handleMarketplaceBrowserAction = useCallback(async (action) => {
1242
+ if (action.type === 'add-marketplace') {
1243
+ setUi((prev) => ({ ...prev, activeOverlay: 'marketplace-add' }));
1244
+ }
1245
+ else if (action.type === 'plugin-installed') {
1246
+ setUi((prev) => ({ ...prev, activeOverlay: 'none' }));
1247
+ setMessages((prev) => [
1248
+ ...prev,
1249
+ {
1250
+ id: generateMessageId('system'),
1251
+ role: 'system',
1252
+ content: `✅ Plugin '${action.pluginName}' installed from ${action.marketplace}`,
1253
+ timestamp: new Date(),
1254
+ },
1255
+ ]);
1256
+ // Refresh prompts to include new plugin skills
1257
+ try {
1258
+ const { reloadAgentConfigFromFile, enrichAgentConfig } = await import('@dexto/agent-management');
1259
+ const newConfig = await reloadAgentConfigFromFile(agent.getAgentFilePath());
1260
+ const enrichedConfig = enrichAgentConfig(newConfig, agent.getAgentFilePath());
1261
+ await agent.refreshPrompts(enrichedConfig.prompts);
1262
+ }
1263
+ catch (error) {
1264
+ // Non-critical: prompts will refresh on next agent restart
1265
+ // Log but don't show error to user
1266
+ }
1267
+ }
1268
+ }, [setUi, setMessages, agent]);
1269
+ // Handle marketplace add completion
1270
+ const handleMarketplaceAddComplete = useCallback((name, pluginCount) => {
1271
+ setUi((prev) => ({ ...prev, activeOverlay: 'marketplace-browser' }));
1272
+ setMessages((prev) => [
1273
+ ...prev,
1274
+ {
1275
+ id: generateMessageId('system'),
1276
+ role: 'system',
1277
+ content: `✅ Marketplace '${name}' added (${pluginCount} plugins found)`,
1278
+ timestamp: new Date(),
1279
+ },
1280
+ ]);
1281
+ }, [setUi, setMessages]);
1039
1282
  // Handle session subcommand selection
1040
1283
  const handleSessionSubcommandSelect = useCallback(async (action) => {
1041
1284
  if (action === 'switch') {
@@ -1412,8 +1655,14 @@ export const OverlayContainer = forwardRef(function OverlayContainer({ ui, input
1412
1655
  const handleSessionRenameClose = useCallback(() => {
1413
1656
  setUi((prev) => ({ ...prev, activeOverlay: 'none' }));
1414
1657
  }, [setUi]);
1415
- return (_jsxs(_Fragment, { children: [approval && (_jsx(ApprovalPrompt, { ref: approvalRef, approval: approval, onApprove: handleApprove, onDeny: handleDeny, onCancel: handleCancelApproval })), ui.activeOverlay === 'slash-autocomplete' && (_jsx(Box, { marginTop: 1, children: _jsx(SlashCommandAutocomplete, { ref: slashAutocompleteRef, isVisible: true, searchQuery: input.value, onSelectPrompt: handlePromptSelect, onSelectSystemCommand: handleSystemCommandSelect, onLoadIntoInput: handleLoadIntoInput, onSubmitRaw: onSubmitPromptCommand, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'resource-autocomplete' && (_jsx(Box, { marginTop: 1, children: _jsx(ResourceAutocomplete, { ref: resourceAutocompleteRef, isVisible: true, searchQuery: input.value, onSelectResource: handleResourceSelect, onLoadIntoInput: handleLoadIntoInput, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'model-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(ModelSelectorRefactored, { ref: modelSelectorRef, isVisible: true, onSelectModel: handleModelSelect, onClose: handleClose, onAddCustomModel: handleAddCustomModel, onEditCustomModel: handleEditCustomModel, agent: agent }) })), ui.activeOverlay === 'session-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(SessionSelectorRefactored, { ref: sessionSelectorRef, isVisible: true, onSelectSession: handleSessionSelect, onClose: handleClose, agent: agent, currentSessionId: session.id || undefined }) })), ui.activeOverlay === 'log-level-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(LogLevelSelector, { ref: logLevelSelectorRef, isVisible: true, onSelect: handleLogLevelSelect, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'stream-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(StreamSelector, { ref: streamSelectorRef, isVisible: true, onSelect: handleStreamSelect, onClose: handleClose }) })), ui.activeOverlay === 'tool-browser' && (_jsx(Box, { marginTop: 1, children: _jsx(ToolBrowser, { ref: toolBrowserRef, isVisible: true, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'mcp-server-list' && (_jsx(Box, { marginTop: 1, children: _jsx(McpServerList, { ref: mcpServerListRef, isVisible: true, onAction: handleMcpServerListAction, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'mcp-server-actions' && ui.selectedMcpServer && (_jsx(Box, { marginTop: 1, children: _jsx(McpServerActions, { ref: mcpServerActionsRef, isVisible: true, server: ui.selectedMcpServer, onAction: handleMcpServerAction, onClose: handleClose }) })), ui.activeOverlay === 'mcp-add-choice' && (_jsx(Box, { marginTop: 1, children: _jsx(McpAddChoice, { ref: mcpAddChoiceRef, isVisible: true, onSelect: handleMcpAddChoice, onClose: handleClose }) })), ui.activeOverlay === 'mcp-add-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(McpAddSelector, { ref: mcpAddSelectorRef, isVisible: true, onSelect: handleMcpAddSelect, onClose: handleClose }) })), ui.activeOverlay === 'mcp-custom-type-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(McpCustomTypeSelector, { ref: mcpCustomTypeSelectorRef, isVisible: true, onSelect: handleMcpCustomTypeSelect, onClose: handleClose }) })), ui.activeOverlay === 'mcp-custom-wizard' && ui.mcpWizardServerType && (_jsx(McpCustomWizard, { ref: mcpCustomWizardRef, isVisible: true, serverType: ui.mcpWizardServerType, onComplete: handleMcpCustomWizardComplete, onClose: handleClose })), ui.activeOverlay === 'custom-model-wizard' && (_jsx(CustomModelWizard, { ref: customModelWizardRef, isVisible: true, onComplete: handleCustomModelComplete, onClose: () => {
1658
+ return (_jsxs(_Fragment, { children: [approval && (_jsx(ApprovalPrompt, { ref: approvalRef, approval: approval, onApprove: handleApprove, onDeny: handleDeny, onCancel: handleCancelApproval })), ui.activeOverlay === 'slash-autocomplete' && (_jsx(Box, { marginTop: 1, children: _jsx(SlashCommandAutocomplete, { ref: slashAutocompleteRef, isVisible: true, searchQuery: input.value, onSelectPrompt: handlePromptSelect, onSelectSystemCommand: handleSystemCommandSelect, onLoadIntoInput: handleLoadIntoInput, onSubmitRaw: onSubmitPromptCommand, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'resource-autocomplete' && (_jsx(Box, { marginTop: 1, children: _jsx(ResourceAutocomplete, { ref: resourceAutocompleteRef, isVisible: true, searchQuery: input.value, onSelectResource: handleResourceSelect, onLoadIntoInput: handleLoadIntoInput, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'model-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(ModelSelectorRefactored, { ref: modelSelectorRef, isVisible: true, onSelectModel: handleModelSelect, onClose: handleClose, onAddCustomModel: handleAddCustomModel, onEditCustomModel: handleEditCustomModel, agent: agent }) })), ui.activeOverlay === 'session-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(SessionSelectorRefactored, { ref: sessionSelectorRef, isVisible: true, onSelectSession: handleSessionSelect, onClose: handleClose, agent: agent, currentSessionId: session.id || undefined }) })), ui.activeOverlay === 'log-level-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(LogLevelSelector, { ref: logLevelSelectorRef, isVisible: true, onSelect: handleLogLevelSelect, onClose: handleClose, agent: agent, sessionId: session.id }) })), ui.activeOverlay === 'stream-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(StreamSelector, { ref: streamSelectorRef, isVisible: true, onSelect: handleStreamSelect, onClose: handleClose }) })), ui.activeOverlay === 'tool-browser' && (_jsx(Box, { marginTop: 1, children: _jsx(ToolBrowser, { ref: toolBrowserRef, isVisible: true, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'mcp-server-list' && (_jsx(Box, { marginTop: 1, children: _jsx(McpServerList, { ref: mcpServerListRef, isVisible: true, onAction: handleMcpServerListAction, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'mcp-server-actions' && ui.selectedMcpServer && (_jsx(Box, { marginTop: 1, children: _jsx(McpServerActions, { ref: mcpServerActionsRef, isVisible: true, server: ui.selectedMcpServer, onAction: handleMcpServerAction, onClose: handleClose }) })), ui.activeOverlay === 'mcp-add-choice' && (_jsx(Box, { marginTop: 1, children: _jsx(McpAddChoice, { ref: mcpAddChoiceRef, isVisible: true, onSelect: handleMcpAddChoice, onClose: handleClose }) })), ui.activeOverlay === 'mcp-add-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(McpAddSelector, { ref: mcpAddSelectorRef, isVisible: true, onSelect: handleMcpAddSelect, onClose: handleClose }) })), ui.activeOverlay === 'mcp-custom-type-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(McpCustomTypeSelector, { ref: mcpCustomTypeSelectorRef, isVisible: true, onSelect: handleMcpCustomTypeSelect, onClose: handleClose }) })), ui.activeOverlay === 'mcp-custom-wizard' && ui.mcpWizardServerType && (_jsx(McpCustomWizard, { ref: mcpCustomWizardRef, isVisible: true, serverType: ui.mcpWizardServerType, onComplete: handleMcpCustomWizardComplete, onClose: handleClose })), ui.activeOverlay === 'custom-model-wizard' && (_jsx(CustomModelWizard, { ref: customModelWizardRef, isVisible: true, onComplete: handleCustomModelComplete, onClose: () => {
1416
1659
  setEditingModel(null);
1417
1660
  handleClose();
1418
- }, initialModel: editingModel })), ui.activeOverlay === 'session-subcommand-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(SessionSubcommandSelector, { ref: sessionSubcommandSelectorRef, isVisible: true, onSelect: handleSessionSubcommandSelect, onClose: handleClose }) })), ui.activeOverlay === 'api-key-input' && ui.pendingModelSwitch && (_jsx(ApiKeyInput, { ref: apiKeyInputRef, isVisible: true, provider: ui.pendingModelSwitch.provider, onSaved: handleApiKeySaved, onClose: handleApiKeyClose })), ui.activeOverlay === 'search' && (_jsx(SearchOverlay, { ref: searchOverlayRef, isVisible: true, agent: agent, onClose: handleClose, onSelectResult: handleSearchResultSelect })), ui.activeOverlay === 'prompt-list' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptList, { ref: promptListRef, isVisible: true, onAction: handlePromptListAction, onLoadIntoInput: handlePromptLoadIntoInput, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'prompt-add-choice' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptAddChoice, { ref: promptAddChoiceRef, isVisible: true, onSelect: handlePromptAddChoice, onClose: handlePromptAddChoiceClose }) })), ui.activeOverlay === 'prompt-add-wizard' && ui.promptAddWizard && (_jsx(PromptAddWizard, { ref: promptAddWizardRef, isVisible: true, scope: ui.promptAddWizard.scope, onComplete: handlePromptAddComplete, onClose: handlePromptAddWizardClose })), ui.activeOverlay === 'prompt-delete-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptDeleteSelector, { ref: promptDeleteSelectorRef, isVisible: true, onDelete: handlePromptDelete, onClose: handlePromptDeleteClose, agent: agent }) })), ui.activeOverlay === 'session-rename' && (_jsx(SessionRenameOverlay, { ref: sessionRenameRef, isVisible: true, currentTitle: currentSessionTitle, onRename: handleSessionRename, onClose: handleSessionRenameClose })), ui.activeOverlay === 'context-stats' && session.id && (_jsx(Box, { marginTop: 1, children: _jsx(ContextStatsOverlay, { ref: contextStatsRef, isVisible: true, onClose: handleClose, agent: agent, sessionId: session.id }) }))] }));
1661
+ }, initialModel: editingModel })), ui.activeOverlay === 'plugin-manager' && (_jsx(Box, { marginTop: 1, children: _jsx(PluginManager, { ref: pluginManagerRef, isVisible: true, onAction: handlePluginManagerAction, onClose: handleClose }) })), ui.activeOverlay === 'plugin-list' && (_jsx(Box, { marginTop: 1, children: _jsx(PluginList, { ref: pluginListRef, isVisible: true, onPluginSelect: handlePluginSelect, onClose: handleClose }) })), ui.activeOverlay === 'plugin-actions' && (_jsx(Box, { marginTop: 1, children: _jsx(PluginActions, { ref: pluginActionsRef, isVisible: true, plugin: selectedPlugin, onAction: handlePluginAction, onClose: () => {
1662
+ setSelectedPlugin(null);
1663
+ setUi((prev) => ({
1664
+ ...prev,
1665
+ activeOverlay: 'plugin-list',
1666
+ }));
1667
+ } }) })), ui.activeOverlay === 'marketplace-browser' && (_jsx(Box, { marginTop: 1, children: _jsx(MarketplaceBrowser, { ref: marketplaceBrowserRef, isVisible: true, onAction: handleMarketplaceBrowserAction, onClose: handleClose }) })), ui.activeOverlay === 'marketplace-add' && (_jsx(Box, { marginTop: 1, children: _jsx(MarketplaceAddPrompt, { ref: marketplaceAddPromptRef, isVisible: true, onComplete: handleMarketplaceAddComplete, onClose: () => setUi((prev) => ({ ...prev, activeOverlay: 'marketplace-browser' })) }) })), ui.activeOverlay === 'session-subcommand-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(SessionSubcommandSelector, { ref: sessionSubcommandSelectorRef, isVisible: true, onSelect: handleSessionSubcommandSelect, onClose: handleClose }) })), ui.activeOverlay === 'api-key-input' && ui.pendingModelSwitch && (_jsx(ApiKeyInput, { ref: apiKeyInputRef, isVisible: true, provider: ui.pendingModelSwitch.provider, onSaved: handleApiKeySaved, onClose: handleApiKeyClose })), ui.activeOverlay === 'search' && (_jsx(SearchOverlay, { ref: searchOverlayRef, isVisible: true, agent: agent, onClose: handleClose, onSelectResult: handleSearchResultSelect })), ui.activeOverlay === 'prompt-list' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptList, { ref: promptListRef, isVisible: true, onAction: handlePromptListAction, onLoadIntoInput: handlePromptLoadIntoInput, onClose: handleClose, agent: agent }) })), ui.activeOverlay === 'prompt-add-choice' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptAddChoice, { ref: promptAddChoiceRef, isVisible: true, onSelect: handlePromptAddChoice, onClose: handlePromptAddChoiceClose }) })), ui.activeOverlay === 'prompt-add-wizard' && ui.promptAddWizard && (_jsx(PromptAddWizard, { ref: promptAddWizardRef, isVisible: true, scope: ui.promptAddWizard.scope, onComplete: handlePromptAddComplete, onClose: handlePromptAddWizardClose })), ui.activeOverlay === 'prompt-delete-selector' && (_jsx(Box, { marginTop: 1, children: _jsx(PromptDeleteSelector, { ref: promptDeleteSelectorRef, isVisible: true, onDelete: handlePromptDelete, onClose: handlePromptDeleteClose, agent: agent }) })), ui.activeOverlay === 'session-rename' && (_jsx(SessionRenameOverlay, { ref: sessionRenameRef, isVisible: true, currentTitle: currentSessionTitle, onRename: handleSessionRename, onClose: handleSessionRenameClose })), ui.activeOverlay === 'context-stats' && session.id && (_jsx(Box, { marginTop: 1, children: _jsx(ContextStatsOverlay, { ref: contextStatsRef, isVisible: true, onClose: handleClose, agent: agent, sessionId: session.id ?? '' }) })), ui.activeOverlay === 'export-wizard' && (_jsx(ExportWizard, { ref: exportWizardRef, isVisible: true, agent: agent, sessionId: session.id, onClose: handleClose }))] }));
1419
1668
  });
@@ -6,6 +6,7 @@ export { useKeyboardShortcuts } from './useKeyboardShortcuts.js';
6
6
  export { useInputOrchestrator, createApprovalInputHandler, createSelectorInputHandler, createAutocompleteInputHandler, createMainInputHandler, type InputHandler, type InputHandlers, type UseInputOrchestratorProps, type ApprovalHandlerProps, type SelectorHandlerProps, type AutocompleteHandlerProps, type MainInputHandlerProps, } from './useInputOrchestrator.js';
7
7
  export { useKeypress } from './useKeypress.js';
8
8
  export { useTerminalSize, type TerminalSize } from './useTerminalSize.js';
9
+ export { useGitBranch } from './useGitBranch.js';
9
10
  export { useCLIState, type UseCLIStateProps, type CLIStateReturn, type UIState, type InputState, type SessionState, } from './useCLIState.js';
10
11
  export type { Key } from './useInputOrchestrator.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACH,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EACH,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,YAAY,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACH,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACH,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,YAAY,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC"}
@@ -6,6 +6,7 @@ export { useKeyboardShortcuts } from './useKeyboardShortcuts.js';
6
6
  export { useInputOrchestrator, createApprovalInputHandler, createSelectorInputHandler, createAutocompleteInputHandler, createMainInputHandler, } from './useInputOrchestrator.js';
7
7
  export { useKeypress } from './useKeypress.js';
8
8
  export { useTerminalSize } from './useTerminalSize.js';
9
+ export { useGitBranch } from './useGitBranch.js';
9
10
  export { useCLIState, } from './useCLIState.js';
10
11
  // useMouseScroll removed - mouse events now handled by MouseProvider/ScrollProvider
11
12
  // useInputHistory removed - history navigation now handled by TextBufferInput
@@ -1 +1 @@
1
- {"version":3,"file":"useCLIState.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/useCLIState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCLIState.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/useCLIState.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,9 @@ export function useCLIState({ agent, initialSessionId, startupInfo, onKeyboardSc
45
45
  },
46
46
  promptAddWizard: null,
47
47
  autoApproveEdits: false,
48
+ todoExpanded: true, // Default to expanded to show full todo list
49
+ planModeActive: false,
50
+ planModeInitialized: false,
48
51
  });
49
52
  // Input state
50
53
  const [input, setInput] = useState({
@@ -0,0 +1,13 @@
1
+ /**
2
+ * useGitBranch Hook
3
+ *
4
+ * Detects the current git branch name for the working directory.
5
+ * Returns undefined if not in a git repository or if git command fails.
6
+ */
7
+ /**
8
+ * Hook that returns the current git branch name
9
+ * @param cwd - Working directory to check (defaults to process.cwd())
10
+ * @returns Branch name string or undefined if not in git repo or command fails
11
+ */
12
+ export declare function useGitBranch(cwd?: string): string | undefined;
13
+ //# sourceMappingURL=useGitBranch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGitBranch.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/useGitBranch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuB7D"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * useGitBranch Hook
3
+ *
4
+ * Detects the current git branch name for the working directory.
5
+ * Returns undefined if not in a git repository or if git command fails.
6
+ */
7
+ import { useState, useEffect } from 'react';
8
+ import { execSync } from 'child_process';
9
+ /**
10
+ * Hook that returns the current git branch name
11
+ * @param cwd - Working directory to check (defaults to process.cwd())
12
+ * @returns Branch name string or undefined if not in git repo or command fails
13
+ */
14
+ export function useGitBranch(cwd) {
15
+ const [branchName, setBranchName] = useState(undefined);
16
+ useEffect(() => {
17
+ const workingDir = cwd || process.cwd();
18
+ try {
19
+ // Get current branch name using git rev-parse --abbrev-ref HEAD
20
+ // This is faster and more reliable than parsing git branch output
21
+ const result = execSync('git rev-parse --abbrev-ref HEAD', {
22
+ cwd: workingDir,
23
+ encoding: 'utf-8',
24
+ stdio: ['pipe', 'pipe', 'pipe'],
25
+ });
26
+ const branch = result.trim();
27
+ setBranchName(branch || undefined);
28
+ }
29
+ catch {
30
+ // Not in a git repo, git not installed, or command failed
31
+ setBranchName(undefined);
32
+ }
33
+ }, [cwd]);
34
+ return branchName;
35
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useInputOrchestrator.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/useInputOrchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useInputOrchestrator.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/hooks/useInputOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -142,9 +142,14 @@ export function useInputOrchestrator({ ui, approval, input, session, queuedMessa
142
142
  // Handle Escape (context-aware)
143
143
  const handleEscape = useCallback(() => {
144
144
  const currentUi = uiRef.current;
145
+ const currentApproval = approvalRef.current;
145
146
  const currentSession = sessionRef.current;
146
147
  const currentQueuedMessages = queuedMessagesRef.current;
147
148
  const currentBuffer = bufferRef.current;
149
+ // If approval prompt is showing, let it handle escape (don't intercept)
150
+ if (currentApproval !== null) {
151
+ return false;
152
+ }
148
153
  // Exit history search mode if active - restore original input
149
154
  if (currentUi.historySearch.isActive) {
150
155
  const originalInput = currentUi.historySearch.originalInput;
@@ -374,10 +379,9 @@ export function useInputOrchestrator({ ui, approval, input, session, queuedMessa
374
379
  disableMouseEvents(); // Disable mouse events so terminal can handle selection
375
380
  return;
376
381
  }
377
- // Shift+Tab: Toggle "accept all edits" mode (when not in approval modal)
378
- // Note: When in approval modal for edit/write tools, ApprovalPrompt handles this
379
- if (key.shift && key.tab && currentApproval === null) {
380
- setUi((prev) => ({ ...prev, autoApproveEdits: !prev.autoApproveEdits }));
382
+ // Ctrl+T: Toggle todo list expansion (collapsed shows only current task)
383
+ if (key.ctrl && inputStr === 't') {
384
+ setUi((prev) => ({ ...prev, todoExpanded: !prev.todoExpanded }));
381
385
  return;
382
386
  }
383
387
  // Ctrl+C: Always handle globally for cancellation/exit
@@ -385,8 +389,49 @@ export function useInputOrchestrator({ ui, approval, input, session, queuedMessa
385
389
  handleCtrlC();
386
390
  return;
387
391
  }
388
- // Escape: Try global handling first
392
+ // Shift+Tab: Cycle through modes (when not in approval modal)
393
+ // Modes: Normal → Plan Mode → Accept All Edits → Normal
394
+ // Note: When in approval modal for edit/write tools, ApprovalPrompt handles Shift+Tab differently
395
+ if (key.shift && key.tab && !key.ctrl && !key.meta && currentApproval === null) {
396
+ setUi((prev) => {
397
+ // Determine current mode and cycle to next
398
+ if (!prev.planModeActive && !prev.autoApproveEdits) {
399
+ // Normal → Plan Mode
400
+ return {
401
+ ...prev,
402
+ planModeActive: true,
403
+ planModeInitialized: false,
404
+ };
405
+ }
406
+ else if (prev.planModeActive) {
407
+ // Plan Mode → Accept All Edits
408
+ return {
409
+ ...prev,
410
+ planModeActive: false,
411
+ planModeInitialized: false,
412
+ autoApproveEdits: true,
413
+ };
414
+ }
415
+ else {
416
+ // Accept All Edits → Normal
417
+ return {
418
+ ...prev,
419
+ autoApproveEdits: false,
420
+ };
421
+ }
422
+ });
423
+ return;
424
+ }
425
+ // Determine focus once (used for routing + Escape priority)
426
+ const focusTarget = getFocusTarget(currentApproval, currentUi.activeOverlay);
427
+ // Escape: route to focused component first.
428
+ // - If an approval is showing, Esc must cancel/deny the approval (NOT global interrupt).
429
+ // - Otherwise, allow global Escape handling (cancel run, close overlays, etc.).
389
430
  if (key.escape) {
431
+ if (focusTarget === 'approval') {
432
+ currentHandlers.approval?.(inputStr, key);
433
+ return;
434
+ }
390
435
  if (handleEscape()) {
391
436
  return; // Consumed by global handler
392
437
  }
@@ -395,7 +440,6 @@ export function useInputOrchestrator({ ui, approval, input, session, queuedMessa
395
440
  // === ROUTE TO FOCUSED COMPONENT ===
396
441
  // Only approval and overlay handlers are routed through the orchestrator.
397
442
  // Main text input handles its own keypress directly (via TextBufferInput).
398
- const focusTarget = getFocusTarget(currentApproval, currentUi.activeOverlay);
399
443
  switch (focusTarget) {
400
444
  case 'approval':
401
445
  if (currentHandlers.approval) {
@@ -1 +1 @@
1
- {"version":3,"file":"processStream.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/services/processStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAwBvE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,kEAAkE;IAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3F,yDAAyD;IACzD,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC/F,4DAA4D;IAC5D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,uDAAuD;IACvD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAC7E;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,qDAAqD;IACrD,QAAQ,EAAE,OAAO,aAAa,EAAE,aAAa,CAAC;IAC9C,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,+BAA+B,EAAE,wBAAwB,CAAC;IAChF,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;CAC3F;AA0BD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAC/B,QAAQ,EAAE,qBAAqB,CAAC,cAAc,CAAC,EAC/C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,oBAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAm7Bf"}
1
+ {"version":3,"file":"processStream.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/services/processStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAwBvE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,kEAAkE;IAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3F,yDAAyD;IACzD,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC/F,4DAA4D;IAC5D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,uDAAuD;IACvD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAC7E;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,qDAAqD;IACrD,QAAQ,EAAE,OAAO,aAAa,EAAE,aAAa,CAAC;IAC9C,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,+BAA+B,EAAE,wBAAwB,CAAC;IAChF,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;CAC3F;AA0BD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAC/B,QAAQ,EAAE,qBAAqB,CAAC,cAAc,CAAC,EAC/C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,oBAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAw9Bf"}