@within-7/minto 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/commands/agents/AgentsCommand.js +2342 -0
  2. package/dist/commands/agents/AgentsCommand.js.map +7 -0
  3. package/dist/commands/agents/constants.js +58 -0
  4. package/dist/commands/agents/constants.js.map +7 -0
  5. package/dist/commands/agents/index.js +37 -0
  6. package/dist/commands/agents/index.js.map +7 -0
  7. package/dist/commands/agents/types.js +10 -0
  8. package/dist/commands/agents/types.js.map +7 -0
  9. package/dist/commands/agents/utils/fileOperations.js +185 -0
  10. package/dist/commands/agents/utils/fileOperations.js.map +7 -0
  11. package/dist/commands/agents/utils/index.js +21 -0
  12. package/dist/commands/agents/utils/index.js.map +7 -0
  13. package/dist/commands/bug.js +2 -2
  14. package/dist/commands/bug.js.map +2 -2
  15. package/dist/commands/compact.js +5 -5
  16. package/dist/commands/compact.js.map +2 -2
  17. package/dist/commands/ctx_viz.js +55 -22
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/mcp-interactive.js +11 -11
  20. package/dist/commands/mcp-interactive.js.map +2 -2
  21. package/dist/commands/model.js +94 -32
  22. package/dist/commands/model.js.map +3 -3
  23. package/dist/commands/plugin/AddMarketplaceForm.js +49 -21
  24. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  25. package/dist/commands/plugin/ConfirmDialog.js +38 -26
  26. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  27. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +24 -8
  28. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  29. package/dist/commands/plugin/InstalledPluginsManager.js +3 -1
  30. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  31. package/dist/commands/plugin/MainMenu.js +16 -7
  32. package/dist/commands/plugin/MainMenu.js.map +2 -2
  33. package/dist/commands/plugin/MarketplaceManager.js +84 -39
  34. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  35. package/dist/commands/plugin/MarketplaceSelector.js +7 -3
  36. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  37. package/dist/commands/plugin/PlaceholderScreen.js +16 -2
  38. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  39. package/dist/commands/plugin/PluginBrowser.js +4 -2
  40. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  41. package/dist/commands/plugin/PluginDetailsInstall.js +12 -6
  42. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  43. package/dist/commands/plugin/PluginDetailsManage.js +14 -5
  44. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  45. package/dist/commands/plugin/example-usage.js.map +2 -2
  46. package/dist/commands/plugin/utils.js.map +2 -2
  47. package/dist/commands/plugin.js +226 -46
  48. package/dist/commands/plugin.js.map +2 -2
  49. package/dist/commands/refreshCommands.js +6 -3
  50. package/dist/commands/refreshCommands.js.map +2 -2
  51. package/dist/commands/resume.js +2 -1
  52. package/dist/commands/resume.js.map +2 -2
  53. package/dist/commands/setup.js +19 -5
  54. package/dist/commands/setup.js.map +2 -2
  55. package/dist/commands/terminalSetup.js +2 -2
  56. package/dist/commands/terminalSetup.js.map +1 -1
  57. package/dist/commands.js +14 -30
  58. package/dist/commands.js.map +2 -2
  59. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  60. package/dist/components/AskUserQuestionDialog/QuestionView.js +10 -1
  61. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  62. package/dist/components/BackgroundTasksPanel.js +5 -1
  63. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  64. package/dist/components/Config.js +17 -4
  65. package/dist/components/Config.js.map +2 -2
  66. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  67. package/dist/components/CustomSelect/select-option.js +4 -1
  68. package/dist/components/CustomSelect/select-option.js.map +2 -2
  69. package/dist/components/Help.js +6 -8
  70. package/dist/components/Help.js.map +2 -2
  71. package/dist/components/Logo.js +1 -1
  72. package/dist/components/Logo.js.map +2 -2
  73. package/dist/components/ModelListManager.js.map +2 -2
  74. package/dist/components/ModelSelector/ModelSelector.js +2030 -0
  75. package/dist/components/ModelSelector/ModelSelector.js.map +7 -0
  76. package/dist/components/ModelSelector/ScreenContainer.js +27 -0
  77. package/dist/components/ModelSelector/ScreenContainer.js.map +7 -0
  78. package/dist/components/ModelSelector/constants.js +37 -0
  79. package/dist/components/ModelSelector/constants.js.map +7 -0
  80. package/dist/components/ModelSelector/hooks/index.js +5 -0
  81. package/dist/components/ModelSelector/hooks/index.js.map +7 -0
  82. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js +21 -0
  83. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js.map +7 -0
  84. package/dist/components/ModelSelector/index.js +17 -0
  85. package/dist/components/ModelSelector/index.js.map +7 -0
  86. package/dist/components/ModelSelector/types.js +1 -0
  87. package/dist/components/ModelSelector/types.js.map +7 -0
  88. package/dist/components/PressEnterToContinue.js +1 -1
  89. package/dist/components/PressEnterToContinue.js.map +2 -2
  90. package/dist/components/ProjectOnboarding.js +1 -1
  91. package/dist/components/ProjectOnboarding.js.map +2 -2
  92. package/dist/components/PromptInput.js +88 -37
  93. package/dist/components/PromptInput.js.map +2 -2
  94. package/dist/components/QuitSummary.js +17 -10
  95. package/dist/components/QuitSummary.js.map +2 -2
  96. package/dist/components/SentryErrorBoundary.js.map +2 -2
  97. package/dist/components/StreamingBashOutput.js.map +2 -2
  98. package/dist/components/StructuredDiff.js.map +2 -2
  99. package/dist/components/SubagentProgress.js.map +2 -2
  100. package/dist/components/TaskCard.js.map +2 -2
  101. package/dist/components/TextInput.js.map +1 -1
  102. package/dist/components/TodoItem.js.map +1 -1
  103. package/dist/components/binary-feedback/BinaryFeedbackOption.js +1 -3
  104. package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +2 -2
  105. package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +1 -1
  106. package/dist/components/messages/AssistantToolUseMessage.js +3 -1
  107. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  108. package/dist/components/messages/TaskProgressMessage.js.map +2 -2
  109. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  110. package/dist/components/messages/UserToolResultMessage/utils.js.map +2 -2
  111. package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +2 -2
  112. package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +2 -2
  113. package/dist/components/permissions/hooks.js.map +2 -2
  114. package/dist/constants/modelCapabilities.js +1 -1
  115. package/dist/constants/modelCapabilities.js.map +2 -2
  116. package/dist/constants/prompts.js.map +1 -1
  117. package/dist/constants/timing.js +34 -0
  118. package/dist/constants/timing.js.map +7 -0
  119. package/dist/entrypoints/cli.js +128 -33
  120. package/dist/entrypoints/cli.js.map +3 -3
  121. package/dist/entrypoints/mcp.js +13 -18
  122. package/dist/entrypoints/mcp.js.map +2 -2
  123. package/dist/hooks/useCanUseTool.js.map +2 -2
  124. package/dist/hooks/useCancelRequest.js.map +1 -1
  125. package/dist/hooks/useHistorySearch.js.map +2 -2
  126. package/dist/hooks/useLogStartupTime.js.map +2 -2
  127. package/dist/hooks/usePermissionRequestLogging.js.map +2 -2
  128. package/dist/hooks/useTextInput.js.map +1 -1
  129. package/dist/hooks/useUnifiedCompletion.js +493 -394
  130. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  131. package/dist/index.js.map +2 -2
  132. package/dist/permissions.js +4 -7
  133. package/dist/permissions.js.map +2 -2
  134. package/dist/query.js +6 -1
  135. package/dist/query.js.map +2 -2
  136. package/dist/screens/REPL.js +72 -36
  137. package/dist/screens/REPL.js.map +2 -2
  138. package/dist/screens/ResumeConversation.js +2 -1
  139. package/dist/screens/ResumeConversation.js.map +2 -2
  140. package/dist/services/adapters/base.js.map +2 -2
  141. package/dist/services/adapters/chatCompletions.js.map +2 -2
  142. package/dist/services/adapters/responsesAPI.js +3 -1
  143. package/dist/services/adapters/responsesAPI.js.map +2 -2
  144. package/dist/services/claude.js +327 -328
  145. package/dist/services/claude.js.map +2 -2
  146. package/dist/services/customCommands.js +6 -1
  147. package/dist/services/customCommands.js.map +2 -2
  148. package/dist/services/fileFreshness.js.map +2 -2
  149. package/dist/services/gpt5ConnectionTest.js +20 -7
  150. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  151. package/dist/services/hookExecutor.js +6 -12
  152. package/dist/services/hookExecutor.js.map +2 -2
  153. package/dist/services/mcpClient.js +29 -2
  154. package/dist/services/mcpClient.js.map +2 -2
  155. package/dist/services/mentionProcessor.js +23 -10
  156. package/dist/services/mentionProcessor.js.map +2 -2
  157. package/dist/services/modelAdapterFactory.js.map +2 -2
  158. package/dist/services/oauth.js.map +2 -2
  159. package/dist/services/openai.js +109 -72
  160. package/dist/services/openai.js.map +3 -3
  161. package/dist/services/responseStateManager.js.map +2 -2
  162. package/dist/services/systemReminder.js.map +2 -2
  163. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  164. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +14 -8
  165. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  166. package/dist/tools/BashOutputTool/BashOutputTool.js.map +2 -2
  167. package/dist/tools/BashTool/BashTool.js.map +2 -2
  168. package/dist/tools/FileReadTool/FileReadTool.js.map +1 -1
  169. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  170. package/dist/tools/GrepTool/GrepTool.js +1 -4
  171. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  172. package/dist/tools/MultiEditTool/MultiEditTool.js +4 -1
  173. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  174. package/dist/tools/NotebookReadTool/NotebookReadTool.js +3 -1
  175. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  176. package/dist/tools/SkillTool/SkillTool.js +12 -6
  177. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  178. package/dist/tools/TaskTool/TaskTool.js +14 -5
  179. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  180. package/dist/tools/TaskTool/prompt.js.map +2 -2
  181. package/dist/tools/ThinkTool/ThinkTool.js +6 -1
  182. package/dist/tools/ThinkTool/ThinkTool.js.map +2 -2
  183. package/dist/tools/TodoWriteTool/TodoWriteTool.js +23 -3
  184. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  185. package/dist/tools/URLFetcherTool/URLFetcherTool.js +2 -2
  186. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  187. package/dist/tools/URLFetcherTool/cache.js +6 -3
  188. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  189. package/dist/tools/URLFetcherTool/htmlToMarkdown.js +3 -1
  190. package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +2 -2
  191. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  192. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  193. package/dist/tools/WebSearchTool/searchProviders.js +15 -6
  194. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  195. package/dist/tools.js +4 -1
  196. package/dist/tools.js.map +2 -2
  197. package/dist/types/core.js +1 -0
  198. package/dist/types/core.js.map +7 -0
  199. package/dist/types/hooks.js +1 -4
  200. package/dist/types/hooks.js.map +2 -2
  201. package/dist/types/marketplace.js +8 -2
  202. package/dist/types/marketplace.js.map +2 -2
  203. package/dist/types/plugin.js +9 -6
  204. package/dist/types/plugin.js.map +2 -2
  205. package/dist/utils/BackgroundShellManager.js +76 -10
  206. package/dist/utils/BackgroundShellManager.js.map +2 -2
  207. package/dist/utils/PersistentShell.js +7 -2
  208. package/dist/utils/PersistentShell.js.map +2 -2
  209. package/dist/utils/advancedFuzzyMatcher.js +4 -1
  210. package/dist/utils/advancedFuzzyMatcher.js.map +2 -2
  211. package/dist/utils/agentLoader.js +69 -35
  212. package/dist/utils/agentLoader.js.map +2 -2
  213. package/dist/utils/agentStorage.js.map +2 -2
  214. package/dist/utils/async.js +163 -0
  215. package/dist/utils/async.js.map +7 -0
  216. package/dist/utils/autoUpdater.js +8 -2
  217. package/dist/utils/autoUpdater.js.map +2 -2
  218. package/dist/utils/commands.js +23 -11
  219. package/dist/utils/commands.js.map +2 -2
  220. package/dist/utils/commonUnixCommands.js +3 -1
  221. package/dist/utils/commonUnixCommands.js.map +2 -2
  222. package/dist/utils/compressionMode.js.map +2 -2
  223. package/dist/utils/config.js +30 -14
  224. package/dist/utils/config.js.map +2 -2
  225. package/dist/utils/debugLogger.js.map +2 -2
  226. package/dist/utils/env.js.map +2 -2
  227. package/dist/utils/envConfig.js +82 -0
  228. package/dist/utils/envConfig.js.map +7 -0
  229. package/dist/utils/errorHandling.js +89 -0
  230. package/dist/utils/errorHandling.js.map +7 -0
  231. package/dist/utils/expertChatStorage.js.map +2 -2
  232. package/dist/utils/fuzzyMatcher.js +13 -7
  233. package/dist/utils/fuzzyMatcher.js.map +2 -2
  234. package/dist/utils/hookManager.js +14 -4
  235. package/dist/utils/hookManager.js.map +2 -2
  236. package/dist/utils/log.js.map +2 -2
  237. package/dist/utils/marketplaceManager.js +44 -9
  238. package/dist/utils/marketplaceManager.js.map +2 -2
  239. package/dist/utils/messageContextManager.js.map +1 -1
  240. package/dist/utils/messages.js +6 -3
  241. package/dist/utils/messages.js.map +2 -2
  242. package/dist/utils/model.js +3 -1
  243. package/dist/utils/model.js.map +2 -2
  244. package/dist/utils/pluginInstaller.js +3 -15
  245. package/dist/utils/pluginInstaller.js.map +2 -2
  246. package/dist/utils/pluginLoader.js +41 -13
  247. package/dist/utils/pluginLoader.js.map +2 -2
  248. package/dist/utils/pluginRegistry.js.map +2 -2
  249. package/dist/utils/pluginValidator.js +71 -49
  250. package/dist/utils/pluginValidator.js.map +2 -2
  251. package/dist/utils/ptyCompat.js.map +2 -2
  252. package/dist/utils/roundConverter.js.map +2 -2
  253. package/dist/utils/secureFile.js +43 -14
  254. package/dist/utils/secureFile.js.map +2 -2
  255. package/dist/utils/sessionState.js.map +2 -2
  256. package/dist/utils/skillLoader.js.map +2 -2
  257. package/dist/utils/teamConfig.js +7 -4
  258. package/dist/utils/teamConfig.js.map +2 -2
  259. package/dist/utils/theme.js.map +2 -2
  260. package/dist/utils/thinking.js.map +2 -2
  261. package/dist/utils/unaryLogging.js.map +2 -2
  262. package/dist/version.js +2 -2
  263. package/dist/version.js.map +1 -1
  264. package/package.json +5 -5
package/dist/commands.js CHANGED
@@ -1,24 +1,13 @@
1
- import bug from "./commands/bug.js";
2
1
  import clear from "./commands/clear.js";
3
2
  import compact from "./commands/compact.js";
4
- import compression from "./commands/compression.js";
5
3
  import config from "./commands/config.js";
6
4
  import cost from "./commands/cost.js";
7
5
  import ctx_viz from "./commands/ctx_viz.js";
8
- import doctor from "./commands/doctor.js";
9
6
  import help from "./commands/help.js";
10
7
  import init from "./commands/init.js";
11
- import listen from "./commands/listen.js";
12
- import login from "./commands/login.js";
13
- import logout from "./commands/logout.js";
14
8
  import mcp from "./commands/mcp-interactive.js";
15
- import * as model from "./commands/model.js";
16
- import modelstatus from "./commands/modelstatus.js";
17
- import onboarding from "./commands/onboarding.js";
18
- import pr_comments from "./commands/pr_comments.js";
9
+ import model from "./commands/model.js";
19
10
  import refreshCommands from "./commands/refreshCommands.js";
20
- import releaseNotes from "./commands/release-notes.js";
21
- import review from "./commands/review.js";
22
11
  import setup from "./commands/setup.js";
23
12
  import terminalSetup from "./commands/terminalSetup.js";
24
13
  import resume from "./commands/resume.js";
@@ -26,35 +15,27 @@ import agents from "./commands/agents.js";
26
15
  import plugin from "./commands/plugin.js";
27
16
  import { quit } from "./commands/quit.js";
28
17
  import { getMCPCommands } from "./services/mcpClient.js";
29
- import { loadCustomCommands, loadPluginCommands } from "./services/customCommands.js";
18
+ import {
19
+ loadCustomCommands,
20
+ loadPluginCommands
21
+ } from "./services/customCommands.js";
30
22
  import { memoize } from "lodash-es";
31
- import { isAnthropicAuthEnabled } from "./utils/auth.js";
32
- const INTERNAL_ONLY_COMMANDS = [ctx_viz, resume, listen];
23
+ const HIDDEN_COMMANDS = [ctx_viz, refreshCommands, terminalSetup];
33
24
  const COMMANDS = memoize(() => [
34
25
  agents,
35
26
  plugin,
36
27
  clear,
37
28
  compact,
38
- compression,
39
29
  config,
40
30
  cost,
41
- doctor,
42
31
  help,
43
32
  init,
44
33
  mcp,
45
34
  model,
46
- modelstatus,
47
- onboarding,
48
- pr_comments,
49
35
  quit,
50
- refreshCommands,
51
- releaseNotes,
52
- bug,
53
- review,
36
+ resume,
54
37
  setup,
55
- terminalSetup,
56
- ...isAnthropicAuthEnabled() ? [logout, login()] : [],
57
- ...INTERNAL_ONLY_COMMANDS
38
+ ...HIDDEN_COMMANDS
58
39
  ]);
59
40
  const getCommands = memoize(async () => {
60
41
  const [mcpCommands, customCommands, pluginCommands] = await Promise.all([
@@ -75,9 +56,12 @@ const getCommands = memoize(async () => {
75
56
  const sortedCustom = [...customCommands].sort(
76
57
  (a, b) => a.userFacingName().localeCompare(b.userFacingName())
77
58
  );
78
- return [...sortedBuiltIn, ...sortedCustom, ...sortedPlugin, ...sortedMCP].filter(
79
- (_) => _.isEnabled
80
- );
59
+ return [
60
+ ...sortedBuiltIn,
61
+ ...sortedCustom,
62
+ ...sortedPlugin,
63
+ ...sortedMCP
64
+ ].filter((_) => _.isEnabled);
81
65
  });
82
66
  function hasCommand(commandName, commands) {
83
67
  return commands.some(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/commands.ts"],
4
- "sourcesContent": ["import React from 'react'\nimport bug from './commands/bug'\nimport clear from './commands/clear'\nimport compact from './commands/compact'\nimport compression from './commands/compression'\nimport config from './commands/config'\nimport cost from './commands/cost'\nimport ctx_viz from './commands/ctx_viz'\nimport doctor from './commands/doctor'\nimport help from './commands/help'\nimport init from './commands/init'\nimport listen from './commands/listen'\nimport login from './commands/login'\nimport logout from './commands/logout'\nimport mcp from './commands/mcp-interactive'\nimport * as model from './commands/model'\nimport modelstatus from './commands/modelstatus'\nimport onboarding from './commands/onboarding'\nimport pr_comments from './commands/pr_comments'\nimport refreshCommands from './commands/refreshCommands'\nimport releaseNotes from './commands/release-notes'\nimport review from './commands/review'\nimport setup from './commands/setup'\nimport terminalSetup from './commands/terminalSetup'\nimport { Tool, ToolUseContext } from './Tool'\nimport resume from './commands/resume'\nimport agents from './commands/agents'\nimport plugin from './commands/plugin'\nimport { quit } from './commands/quit'\nimport { getMCPCommands } from './services/mcpClient'\nimport { loadCustomCommands, loadPluginCommands } from './services/customCommands'\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { memoize } from 'lodash-es'\nimport type { Message } from './query'\nimport { isAnthropicAuthEnabled } from './utils/auth'\n\ntype PromptCommand = {\n type: 'prompt'\n progressMessage: string\n argNames?: string[]\n getPromptForCommand(args: string): Promise<MessageParam[]>\n}\n\ntype LocalCommand = {\n type: 'local'\n call(\n args: string,\n context: {\n options: {\n commands: Command[]\n tools: Tool[]\n slowAndCapableModel: string\n }\n abortController: AbortController\n setForkConvoWithMessagesOnTheNextRender: (\n forkConvoWithMessages: Message[],\n ) => void\n },\n ): Promise<string>\n}\n\ntype LocalJSXCommand = {\n type: 'local-jsx'\n call(\n onDone: (result?: string) => void,\n context: ToolUseContext & {\n setForkConvoWithMessagesOnTheNextRender: (\n forkConvoWithMessages: Message[],\n ) => void\n },\n ): Promise<React.ReactNode>\n}\n\nexport type Command = {\n description: string\n isEnabled: boolean\n isHidden: boolean\n name: string\n aliases?: string[]\n userFacingName(): string\n} & (PromptCommand | LocalCommand | LocalJSXCommand)\n\nconst INTERNAL_ONLY_COMMANDS = [ctx_viz, resume, listen]\n\n// Declared as a function so that we don't run this until getCommands is called,\n// since underlying functions read from config, which can't be read at module initialization time\nconst COMMANDS = memoize((): Command[] => [\n agents,\n plugin,\n clear,\n compact,\n compression,\n config,\n cost,\n doctor,\n help,\n init,\n mcp,\n model,\n modelstatus,\n onboarding,\n pr_comments,\n quit,\n refreshCommands,\n releaseNotes,\n bug,\n review,\n setup,\n terminalSetup,\n ...(isAnthropicAuthEnabled() ? [logout, login()] : []),\n ...INTERNAL_ONLY_COMMANDS,\n])\n\nexport const getCommands = memoize(async (): Promise<Command[]> => {\n const [mcpCommands, customCommands, pluginCommands] = await Promise.all([\n getMCPCommands(),\n loadCustomCommands(),\n loadPluginCommands(),\n ])\n\n // Get built-in commands\n const builtInCommands = COMMANDS()\n\n // Sort built-in commands alphabetically by name\n const sortedBuiltIn = [...builtInCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName())\n )\n\n // Sort MCP commands alphabetically by name\n const sortedMCP = [...mcpCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName())\n )\n\n // Sort plugin commands alphabetically by name\n const sortedPlugin = [...pluginCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName())\n )\n\n // Sort custom commands alphabetically by name\n const sortedCustom = [...customCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName())\n )\n\n // Command priority (later overrides earlier):\n // 1. MCP commands (lowest priority) - sorted alphabetically\n // 2. Plugin commands - sorted alphabetically\n // 3. Custom commands (user/project) - sorted alphabetically\n // 4. Built-in commands (highest priority) - sorted alphabetically\n // Display order: Built-in first, then custom/plugin/MCP\n return [...sortedBuiltIn, ...sortedCustom, ...sortedPlugin, ...sortedMCP].filter(\n _ => _.isEnabled,\n )\n})\n\nexport function hasCommand(commandName: string, commands: Command[]): boolean {\n return commands.some(\n _ => _.userFacingName() === commandName || _.aliases?.includes(commandName),\n )\n}\n\nexport function getCommand(commandName: string, commands: Command[]): Command {\n const command = commands.find(\n _ => _.userFacingName() === commandName || _.aliases?.includes(commandName),\n ) as Command | undefined\n if (!command) {\n throw ReferenceError(\n `Command ${commandName} not found. Available commands: ${commands\n .map(_ => {\n const name = _.userFacingName()\n return _.aliases ? `${name} (aliases: ${_.aliases.join(', ')})` : name\n })\n .join(', ')}`,\n )\n }\n\n return command\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import React from 'react'\nimport clear from './commands/clear'\nimport compact from './commands/compact'\nimport config from './commands/config'\nimport cost from './commands/cost'\nimport ctx_viz from './commands/ctx_viz'\nimport help from './commands/help'\nimport init from './commands/init'\nimport mcp from './commands/mcp-interactive'\nimport model from './commands/model'\nimport refreshCommands from './commands/refreshCommands'\nimport setup from './commands/setup'\nimport terminalSetup from './commands/terminalSetup'\nimport { Tool, ToolUseContext } from './Tool'\nimport resume from './commands/resume'\nimport agents from './commands/agents'\nimport plugin from './commands/plugin'\nimport { quit } from './commands/quit'\nimport { getMCPCommands } from './services/mcpClient'\nimport {\n loadCustomCommands,\n loadPluginCommands,\n} from './services/customCommands'\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { memoize } from 'lodash-es'\nimport type { Message } from './query'\n\ntype PromptCommand = {\n type: 'prompt'\n progressMessage: string\n argNames?: string[]\n getPromptForCommand(args: string): Promise<MessageParam[]>\n}\n\ntype LocalCommand = {\n type: 'local'\n call(\n args: string,\n context: {\n options: {\n commands: Command[]\n tools: Tool[]\n slowAndCapableModel: string\n }\n abortController: AbortController\n setForkConvoWithMessagesOnTheNextRender: (\n forkConvoWithMessages: Message[],\n ) => void\n },\n ): Promise<string>\n}\n\ntype LocalJSXCommand = {\n type: 'local-jsx'\n call(\n onDone: (result?: string) => void,\n context: ToolUseContext & {\n setForkConvoWithMessagesOnTheNextRender: (\n forkConvoWithMessages: Message[],\n ) => void\n },\n ): Promise<React.ReactNode>\n}\n\nexport type Command = {\n description: string\n isEnabled: boolean\n isHidden: boolean\n name: string\n aliases?: string[]\n userFacingName(): string\n} & (PromptCommand | LocalCommand | LocalJSXCommand)\n\n// Hidden developer commands (not shown in /help but still accessible)\nconst HIDDEN_COMMANDS = [ctx_viz, refreshCommands, terminalSetup]\n\n// Declared as a function so that we don't run this until getCommands is called,\n// since underlying functions read from config, which can't be read at module initialization time\nconst COMMANDS = memoize((): Command[] => [\n agents,\n plugin,\n clear,\n compact,\n config,\n cost,\n help,\n init,\n mcp,\n model,\n quit,\n resume,\n setup,\n ...HIDDEN_COMMANDS,\n])\n\nexport const getCommands = memoize(async (): Promise<Command[]> => {\n const [mcpCommands, customCommands, pluginCommands] = await Promise.all([\n getMCPCommands(),\n loadCustomCommands(),\n loadPluginCommands(),\n ])\n\n // Get built-in commands\n const builtInCommands = COMMANDS()\n\n // Sort built-in commands alphabetically by name\n const sortedBuiltIn = [...builtInCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n )\n\n // Sort MCP commands alphabetically by name\n const sortedMCP = [...mcpCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n )\n\n // Sort plugin commands alphabetically by name\n const sortedPlugin = [...pluginCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n )\n\n // Sort custom commands alphabetically by name\n const sortedCustom = [...customCommands].sort((a, b) =>\n a.userFacingName().localeCompare(b.userFacingName()),\n )\n\n // Command priority (later overrides earlier):\n // 1. MCP commands (lowest priority) - sorted alphabetically\n // 2. Plugin commands - sorted alphabetically\n // 3. Custom commands (user/project) - sorted alphabetically\n // 4. Built-in commands (highest priority) - sorted alphabetically\n // Display order: Built-in first, then custom/plugin/MCP\n return [\n ...sortedBuiltIn,\n ...sortedCustom,\n ...sortedPlugin,\n ...sortedMCP,\n ].filter(_ => _.isEnabled)\n})\n\nexport function hasCommand(commandName: string, commands: Command[]): boolean {\n return commands.some(\n _ => _.userFacingName() === commandName || _.aliases?.includes(commandName),\n )\n}\n\nexport function getCommand(commandName: string, commands: Command[]): Command {\n const command = commands.find(\n _ => _.userFacingName() === commandName || _.aliases?.includes(commandName),\n ) as Command | undefined\n if (!command) {\n throw ReferenceError(\n `Command ${commandName} not found. Available commands: ${commands\n .map(_ => {\n const name = _.userFacingName()\n return _.aliases ? `${name} (aliases: ${_.aliases.join(', ')})` : name\n })\n .join(', ')}`,\n )\n }\n\n return command\n}\n"],
5
+ "mappings": "AACA,OAAO,WAAW;AAClB,OAAO,aAAa;AACpB,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,SAAS;AAChB,OAAO,WAAW;AAClB,OAAO,qBAAqB;AAC5B,OAAO,WAAW;AAClB,OAAO,mBAAmB;AAE1B,OAAO,YAAY;AACnB,OAAO,YAAY;AACnB,OAAO,YAAY;AACnB,SAAS,YAAY;AACrB,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,eAAe;AAkDxB,MAAM,kBAAkB,CAAC,SAAS,iBAAiB,aAAa;AAIhE,MAAM,WAAW,QAAQ,MAAiB;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,CAAC;AAEM,MAAM,cAAc,QAAQ,YAAgC;AACjE,QAAM,CAAC,aAAa,gBAAgB,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtE,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EACrB,CAAC;AAGD,QAAM,kBAAkB,SAAS;AAGjC,QAAM,gBAAgB,CAAC,GAAG,eAAe,EAAE;AAAA,IAAK,CAAC,GAAG,MAClD,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC;AAAA,EACrD;AAGA,QAAM,YAAY,CAAC,GAAG,WAAW,EAAE;AAAA,IAAK,CAAC,GAAG,MAC1C,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC;AAAA,EACrD;AAGA,QAAM,eAAe,CAAC,GAAG,cAAc,EAAE;AAAA,IAAK,CAAC,GAAG,MAChD,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC;AAAA,EACrD;AAGA,QAAM,eAAe,CAAC,GAAG,cAAc,EAAE;AAAA,IAAK,CAAC,GAAG,MAChD,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC;AAAA,EACrD;AAQA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,EAAE,OAAO,OAAK,EAAE,SAAS;AAC3B,CAAC;AAEM,SAAS,WAAW,aAAqB,UAA8B;AAC5E,SAAO,SAAS;AAAA,IACd,OAAK,EAAE,eAAe,MAAM,eAAe,EAAE,SAAS,SAAS,WAAW;AAAA,EAC5E;AACF;AAEO,SAAS,WAAW,aAAqB,UAA8B;AAC5E,QAAM,UAAU,SAAS;AAAA,IACvB,OAAK,EAAE,eAAe,MAAM,eAAe,EAAE,SAAS,SAAS,WAAW;AAAA,EAC5E;AACA,MAAI,CAAC,SAAS;AACZ,UAAM;AAAA,MACJ,WAAW,WAAW,mCAAmC,SACtD,IAAI,OAAK;AACR,cAAM,OAAO,EAAE,eAAe;AAC9B,eAAO,EAAE,UAAU,GAAG,IAAI,cAAc,EAAE,QAAQ,KAAK,IAAI,CAAC,MAAM;AAAA,MACpE,CAAC,EACA,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/AskUserQuestionDialog/AskUserQuestionDialog.tsx"],
4
- "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useCallback } from 'react'\nimport { type AskUserQuestionContext, type UserAnswer } from '@minto-types/askUserQuestion'\nimport { QuestionView } from './QuestionView'\nimport { useNotifyAfterTimeout } from '@hooks/useNotifyAfterTimeout'\nimport { PRODUCT_NAME } from '@constants/product'\nimport TextInput from 'ink-text-input'\n\ninterface AskUserQuestionDialogProps {\n context: AskUserQuestionContext\n onDone: () => void\n}\n\nexport function AskUserQuestionDialog({\n context,\n onDone,\n}: AskUserQuestionDialogProps): React.ReactElement {\n const { questions, resolve, reject } = context\n\n // Current question index (for multi-question scenarios)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0)\n\n // Selected option indices for each question\n const [selectedOptions, setSelectedOptions] = useState<number[]>(\n questions.map(() => 0),\n )\n\n // Custom input mode for \"Other\" option\n const [isCustomInputMode, setIsCustomInputMode] = useState(false)\n const [customInput, setCustomInput] = useState('')\n\n // Notification after timeout\n useNotifyAfterTimeout(`${PRODUCT_NAME} needs your input to continue`)\n\n const currentQuestion = questions[currentQuestionIndex]!\n\n // Handle keyboard input\n useInput(\n (input, key) => {\n // Cancel with Escape or Ctrl+C\n if (key.escape || (key.ctrl && input === 'c')) {\n onDone()\n reject()\n return\n }\n\n // Don't handle other keys in custom input mode\n if (isCustomInputMode) {\n return\n }\n\n // Navigate between questions with left/right arrows\n if (key.leftArrow && currentQuestionIndex > 0) {\n setCurrentQuestionIndex(prev => prev - 1)\n return\n }\n\n if (key.rightArrow && currentQuestionIndex < questions.length - 1) {\n setCurrentQuestionIndex(prev => prev + 1)\n return\n }\n\n // Confirm with Enter\n if (key.return) {\n handleConfirm()\n return\n }\n\n // Press 'o' to enter custom input mode\n if (input === 'o' && currentQuestion.options) {\n setIsCustomInputMode(true)\n setCustomInput('')\n return\n }\n },\n { isActive: true },\n )\n\n // Handle option change\n const handleOptionChange = useCallback(\n (optionIndex: number) => {\n const newSelectedOptions = [...selectedOptions]\n newSelectedOptions[currentQuestionIndex] = optionIndex\n setSelectedOptions(newSelectedOptions)\n\n // If \"Other\" is selected (-1), enter custom input mode\n if (optionIndex === -1) {\n setIsCustomInputMode(true)\n setCustomInput('')\n }\n },\n [selectedOptions, currentQuestionIndex],\n )\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n // If in custom input mode, save the custom input\n if (isCustomInputMode) {\n if (!customInput.trim()) {\n // Don't allow empty custom input\n return\n }\n\n // Save custom input and exit custom input mode\n setIsCustomInputMode(false)\n\n // If this is the last question, submit all answers\n if (currentQuestionIndex === questions.length - 1) {\n submitAnswers(customInput)\n } else {\n // Move to next question\n setCurrentQuestionIndex(prev => prev + 1)\n }\n return\n }\n\n // If this is the last question, submit all answers\n if (currentQuestionIndex === questions.length - 1) {\n submitAnswers()\n } else {\n // Move to next question\n setCurrentQuestionIndex(prev => prev + 1)\n }\n }, [isCustomInputMode, customInput, currentQuestionIndex, questions.length])\n\n // Submit all answers\n const submitAnswers = useCallback(\n (customInputOverride?: string) => {\n const answers: UserAnswer[] = questions.map((question, index) => {\n const selectedOptionIndex = selectedOptions[index]!\n\n // If it's the current question and we have custom input\n if (\n index === currentQuestionIndex &&\n (customInputOverride || isCustomInputMode)\n ) {\n return {\n questionIndex: index,\n customInput: customInputOverride || customInput,\n }\n }\n\n // If \"Other\" was selected (-1), use custom input\n if (selectedOptionIndex === -1) {\n return {\n questionIndex: index,\n customInput: customInput,\n }\n }\n\n // Regular option selection\n return {\n questionIndex: index,\n selectedOptions: [selectedOptionIndex],\n }\n })\n\n onDone()\n resolve(answers)\n },\n [\n questions,\n selectedOptions,\n currentQuestionIndex,\n isCustomInputMode,\n customInput,\n onDone,\n resolve,\n ],\n )\n\n return (\n <Box flexDirection=\"column\" paddingY={1}>\n {/* Custom input mode */}\n {isCustomInputMode ? (\n <Box flexDirection=\"column\" paddingX={2}>\n <Box marginBottom={1}>\n <Text bold>Enter your custom response:</Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"cyan\">&gt; </Text>\n <TextInput\n value={customInput}\n onChange={setCustomInput}\n onSubmit={handleConfirm}\n />\n </Box>\n <Box>\n <Text dimColor>[Enter to confirm] [Esc to cancel]</Text>\n </Box>\n </Box>\n ) : (\n /* Normal question view */\n <QuestionView\n question={currentQuestion}\n questionIndex={currentQuestionIndex}\n totalQuestions={questions.length}\n selectedOptionIndex={selectedOptions[currentQuestionIndex]!}\n onOptionChange={handleOptionChange}\n />\n )}\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useCallback } from 'react'\nimport {\n type AskUserQuestionContext,\n type UserAnswer,\n} from '@minto-types/askUserQuestion'\nimport { QuestionView } from './QuestionView'\nimport { useNotifyAfterTimeout } from '@hooks/useNotifyAfterTimeout'\nimport { PRODUCT_NAME } from '@constants/product'\nimport TextInput from 'ink-text-input'\n\ninterface AskUserQuestionDialogProps {\n context: AskUserQuestionContext\n onDone: () => void\n}\n\nexport function AskUserQuestionDialog({\n context,\n onDone,\n}: AskUserQuestionDialogProps): React.ReactElement {\n const { questions, resolve, reject } = context\n\n // Current question index (for multi-question scenarios)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0)\n\n // Selected option indices for each question\n const [selectedOptions, setSelectedOptions] = useState<number[]>(\n questions.map(() => 0),\n )\n\n // Custom input mode for \"Other\" option\n const [isCustomInputMode, setIsCustomInputMode] = useState(false)\n const [customInput, setCustomInput] = useState('')\n\n // Notification after timeout\n useNotifyAfterTimeout(`${PRODUCT_NAME} needs your input to continue`)\n\n const currentQuestion = questions[currentQuestionIndex]!\n\n // Handle keyboard input\n useInput(\n (input, key) => {\n // Cancel with Escape or Ctrl+C\n if (key.escape || (key.ctrl && input === 'c')) {\n onDone()\n reject()\n return\n }\n\n // Don't handle other keys in custom input mode\n if (isCustomInputMode) {\n return\n }\n\n // Navigate between questions with left/right arrows\n if (key.leftArrow && currentQuestionIndex > 0) {\n setCurrentQuestionIndex(prev => prev - 1)\n return\n }\n\n if (key.rightArrow && currentQuestionIndex < questions.length - 1) {\n setCurrentQuestionIndex(prev => prev + 1)\n return\n }\n\n // Confirm with Enter\n if (key.return) {\n handleConfirm()\n return\n }\n\n // Press 'o' to enter custom input mode\n if (input === 'o' && currentQuestion.options) {\n setIsCustomInputMode(true)\n setCustomInput('')\n return\n }\n },\n { isActive: true },\n )\n\n // Handle option change\n const handleOptionChange = useCallback(\n (optionIndex: number) => {\n const newSelectedOptions = [...selectedOptions]\n newSelectedOptions[currentQuestionIndex] = optionIndex\n setSelectedOptions(newSelectedOptions)\n\n // If \"Other\" is selected (-1), enter custom input mode\n if (optionIndex === -1) {\n setIsCustomInputMode(true)\n setCustomInput('')\n }\n },\n [selectedOptions, currentQuestionIndex],\n )\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n // If in custom input mode, save the custom input\n if (isCustomInputMode) {\n if (!customInput.trim()) {\n // Don't allow empty custom input\n return\n }\n\n // Save custom input and exit custom input mode\n setIsCustomInputMode(false)\n\n // If this is the last question, submit all answers\n if (currentQuestionIndex === questions.length - 1) {\n submitAnswers(customInput)\n } else {\n // Move to next question\n setCurrentQuestionIndex(prev => prev + 1)\n }\n return\n }\n\n // If this is the last question, submit all answers\n if (currentQuestionIndex === questions.length - 1) {\n submitAnswers()\n } else {\n // Move to next question\n setCurrentQuestionIndex(prev => prev + 1)\n }\n }, [isCustomInputMode, customInput, currentQuestionIndex, questions.length])\n\n // Submit all answers\n const submitAnswers = useCallback(\n (customInputOverride?: string) => {\n const answers: UserAnswer[] = questions.map((question, index) => {\n const selectedOptionIndex = selectedOptions[index]!\n\n // If it's the current question and we have custom input\n if (\n index === currentQuestionIndex &&\n (customInputOverride || isCustomInputMode)\n ) {\n return {\n questionIndex: index,\n customInput: customInputOverride || customInput,\n }\n }\n\n // If \"Other\" was selected (-1), use custom input\n if (selectedOptionIndex === -1) {\n return {\n questionIndex: index,\n customInput: customInput,\n }\n }\n\n // Regular option selection\n return {\n questionIndex: index,\n selectedOptions: [selectedOptionIndex],\n }\n })\n\n onDone()\n resolve(answers)\n },\n [\n questions,\n selectedOptions,\n currentQuestionIndex,\n isCustomInputMode,\n customInput,\n onDone,\n resolve,\n ],\n )\n\n return (\n <Box flexDirection=\"column\" paddingY={1}>\n {/* Custom input mode */}\n {isCustomInputMode ? (\n <Box flexDirection=\"column\" paddingX={2}>\n <Box marginBottom={1}>\n <Text bold>Enter your custom response:</Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"cyan\">&gt; </Text>\n <TextInput\n value={customInput}\n onChange={setCustomInput}\n onSubmit={handleConfirm}\n />\n </Box>\n <Box>\n <Text dimColor>[Enter to confirm] [Esc to cancel]</Text>\n </Box>\n </Box>\n ) : (\n /* Normal question view */\n <QuestionView\n question={currentQuestion}\n questionIndex={currentQuestionIndex}\n totalQuestions={questions.length}\n selectedOptionIndex={selectedOptions[currentQuestionIndex]!}\n onOptionChange={handleOptionChange}\n />\n )}\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -37,7 +37,16 @@ function QuestionView({
37
37
  }
38
38
  }
39
39
  }
40
- )), question.options && question.options.length > 0 && selectedOptionIndex >= 0 && selectedOptionIndex < question.options.length && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText, dimColor: true }, question.options[selectedOptionIndex]?.description || "")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, borderStyle: "single", borderColor: theme.secondaryBorder, paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "[\u2191/\u2193 Navigate] [Enter Confirm]", totalQuestions > 1 && " [\u2190/\u2192 Switch Questions]", " [Esc Cancel]")));
40
+ )), question.options && question.options.length > 0 && selectedOptionIndex >= 0 && selectedOptionIndex < question.options.length && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText, dimColor: true }, question.options[selectedOptionIndex]?.description || "")), /* @__PURE__ */ React.createElement(
41
+ Box,
42
+ {
43
+ marginTop: 1,
44
+ borderStyle: "single",
45
+ borderColor: theme.secondaryBorder,
46
+ paddingX: 1
47
+ },
48
+ /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "[\u2191/\u2193 Navigate] [Enter Confirm]", totalQuestions > 1 && " [\u2190/\u2192 Switch Questions]", " [Esc Cancel]")
49
+ ));
41
50
  }
42
51
  export {
43
52
  QuestionView
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/AskUserQuestionDialog/QuestionView.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { Select } from '@components/CustomSelect/select'\nimport { type UserQuestion, type QuestionOption } from '@minto-types/askUserQuestion'\nimport { Option } from '@inkjs/ui'\nimport { getTheme } from '@utils/theme'\n\ninterface QuestionViewProps {\n question: UserQuestion\n questionIndex: number\n totalQuestions: number\n selectedOptionIndex: number\n onOptionChange: (optionIndex: number) => void\n}\n\nexport function QuestionView({\n question,\n questionIndex,\n totalQuestions,\n selectedOptionIndex,\n onOptionChange,\n}: QuestionViewProps): React.ReactElement {\n const theme = getTheme()\n\n // Build options for the Select component\n const options: Option[] = React.useMemo(() => {\n if (!question.options || question.options.length === 0) {\n return []\n }\n\n const selectOptions = question.options.map((opt, index) => ({\n label: opt.label,\n value: String(index),\n }))\n\n // Always add \"Other (custom input)\" option\n selectOptions.push({\n label: 'Other (custom input)',\n value: 'other',\n })\n\n return selectOptions\n }, [question.options])\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1}>\n {/* Header with question counter */}\n <Box marginBottom={1}>\n <Text color={theme.primary} bold>\n \uD83E\uDD14 AI needs your input\n </Text>\n {totalQuestions > 1 && (\n <Text color={theme.secondaryText}>\n {' '}\n (Question {questionIndex + 1} of {totalQuestions})\n </Text>\n )}\n </Box>\n\n {/* Question header tag */}\n {question.header && (\n <Box marginBottom={1}>\n <Text color={theme.minto}>[{question.header}]</Text>\n </Box>\n )}\n\n {/* Question text */}\n <Box marginBottom={1}>\n <Text bold>{question.question}</Text>\n </Box>\n\n {/* Options list */}\n {question.options && question.options.length > 0 && (\n <Box marginBottom={1}>\n <Select\n options={options}\n defaultValue={String(selectedOptionIndex)}\n onChange={value => {\n if (value === 'other') {\n onOptionChange(-1) // -1 indicates \"Other\"\n } else {\n onOptionChange(Number(value))\n }\n }}\n />\n </Box>\n )}\n\n {/* Show option descriptions */}\n {question.options &&\n question.options.length > 0 &&\n selectedOptionIndex >= 0 &&\n selectedOptionIndex < question.options.length && (\n <Box marginLeft={2} marginBottom={1}>\n <Text color={theme.secondaryText} dimColor>\n {question.options[selectedOptionIndex]?.description || ''}\n </Text>\n </Box>\n )}\n\n {/* Help text */}\n <Box marginTop={1} borderStyle=\"single\" borderColor={theme.secondaryBorder} paddingX={1}>\n <Text color={theme.secondaryText}>\n [\u2191/\u2193 Navigate] [Enter Confirm]\n {totalQuestions > 1 && ' [\u2190/\u2192 Switch Questions]'} [Esc Cancel]\n </Text>\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,cAAc;AAGvB,SAAS,gBAAgB;AAUlB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,QAAM,QAAQ,SAAS;AAGvB,QAAM,UAAoB,MAAM,QAAQ,MAAM;AAC5C,QAAI,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG;AACtD,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,gBAAgB,SAAS,QAAQ,IAAI,CAAC,KAAK,WAAW;AAAA,MAC1D,OAAO,IAAI;AAAA,MACX,OAAO,OAAO,KAAK;AAAA,IACrB,EAAE;AAGF,kBAAc,KAAK;AAAA,MACjB,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,OAAO,CAAC;AAErB,SACE,oCAAC,OAAI,eAAc,UAAS,UAAU,GAAG,UAAU,KAEjD,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,OAAO,MAAM,SAAS,MAAI,QAAC,+BAEjC,GACC,iBAAiB,KAChB,oCAAC,QAAK,OAAO,MAAM,iBAChB,KAAI,cACM,gBAAgB,GAAE,QAAK,gBAAe,GACnD,CAEJ,GAGC,SAAS,UACR,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,OAAO,MAAM,SAAO,KAAE,SAAS,QAAO,GAAC,CAC/C,GAIF,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,MAAI,QAAE,SAAS,QAAS,CAChC,GAGC,SAAS,WAAW,SAAS,QAAQ,SAAS,KAC7C,oCAAC,OAAI,cAAc,KACjB;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc,OAAO,mBAAmB;AAAA,MACxC,UAAU,WAAS;AACjB,YAAI,UAAU,SAAS;AACrB,yBAAe,EAAE;AAAA,QACnB,OAAO;AACL,yBAAe,OAAO,KAAK,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA;AAAA,EACF,CACF,GAID,SAAS,WACR,SAAS,QAAQ,SAAS,KAC1B,uBAAuB,KACvB,sBAAsB,SAAS,QAAQ,UACrC,oCAAC,OAAI,YAAY,GAAG,cAAc,KAChC,oCAAC,QAAK,OAAO,MAAM,eAAe,UAAQ,QACvC,SAAS,QAAQ,mBAAmB,GAAG,eAAe,EACzD,CACF,GAIJ,oCAAC,OAAI,WAAW,GAAG,aAAY,UAAS,aAAa,MAAM,iBAAiB,UAAU,KACpF,oCAAC,QAAK,OAAO,MAAM,iBAAe,4CAE/B,iBAAiB,KAAK,qCAA0B,eACnD,CACF,CACF;AAEJ;",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { Select } from '@components/CustomSelect/select'\nimport {\n type UserQuestion,\n type QuestionOption,\n} from '@minto-types/askUserQuestion'\nimport { Option } from '@inkjs/ui'\nimport { getTheme } from '@utils/theme'\n\ninterface QuestionViewProps {\n question: UserQuestion\n questionIndex: number\n totalQuestions: number\n selectedOptionIndex: number\n onOptionChange: (optionIndex: number) => void\n}\n\nexport function QuestionView({\n question,\n questionIndex,\n totalQuestions,\n selectedOptionIndex,\n onOptionChange,\n}: QuestionViewProps): React.ReactElement {\n const theme = getTheme()\n\n // Build options for the Select component\n const options: Option[] = React.useMemo(() => {\n if (!question.options || question.options.length === 0) {\n return []\n }\n\n const selectOptions = question.options.map((opt, index) => ({\n label: opt.label,\n value: String(index),\n }))\n\n // Always add \"Other (custom input)\" option\n selectOptions.push({\n label: 'Other (custom input)',\n value: 'other',\n })\n\n return selectOptions\n }, [question.options])\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1}>\n {/* Header with question counter */}\n <Box marginBottom={1}>\n <Text color={theme.primary} bold>\n \uD83E\uDD14 AI needs your input\n </Text>\n {totalQuestions > 1 && (\n <Text color={theme.secondaryText}>\n {' '}\n (Question {questionIndex + 1} of {totalQuestions})\n </Text>\n )}\n </Box>\n\n {/* Question header tag */}\n {question.header && (\n <Box marginBottom={1}>\n <Text color={theme.minto}>[{question.header}]</Text>\n </Box>\n )}\n\n {/* Question text */}\n <Box marginBottom={1}>\n <Text bold>{question.question}</Text>\n </Box>\n\n {/* Options list */}\n {question.options && question.options.length > 0 && (\n <Box marginBottom={1}>\n <Select\n options={options}\n defaultValue={String(selectedOptionIndex)}\n onChange={value => {\n if (value === 'other') {\n onOptionChange(-1) // -1 indicates \"Other\"\n } else {\n onOptionChange(Number(value))\n }\n }}\n />\n </Box>\n )}\n\n {/* Show option descriptions */}\n {question.options &&\n question.options.length > 0 &&\n selectedOptionIndex >= 0 &&\n selectedOptionIndex < question.options.length && (\n <Box marginLeft={2} marginBottom={1}>\n <Text color={theme.secondaryText} dimColor>\n {question.options[selectedOptionIndex]?.description || ''}\n </Text>\n </Box>\n )}\n\n {/* Help text */}\n <Box\n marginTop={1}\n borderStyle=\"single\"\n borderColor={theme.secondaryBorder}\n paddingX={1}\n >\n <Text color={theme.secondaryText}>\n [\u2191/\u2193 Navigate] [Enter Confirm]\n {totalQuestions > 1 && ' [\u2190/\u2192 Switch Questions]'} [Esc Cancel]\n </Text>\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,cAAc;AAMvB,SAAS,gBAAgB;AAUlB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,QAAM,QAAQ,SAAS;AAGvB,QAAM,UAAoB,MAAM,QAAQ,MAAM;AAC5C,QAAI,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG;AACtD,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,gBAAgB,SAAS,QAAQ,IAAI,CAAC,KAAK,WAAW;AAAA,MAC1D,OAAO,IAAI;AAAA,MACX,OAAO,OAAO,KAAK;AAAA,IACrB,EAAE;AAGF,kBAAc,KAAK;AAAA,MACjB,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,OAAO,CAAC;AAErB,SACE,oCAAC,OAAI,eAAc,UAAS,UAAU,GAAG,UAAU,KAEjD,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,OAAO,MAAM,SAAS,MAAI,QAAC,+BAEjC,GACC,iBAAiB,KAChB,oCAAC,QAAK,OAAO,MAAM,iBAChB,KAAI,cACM,gBAAgB,GAAE,QAAK,gBAAe,GACnD,CAEJ,GAGC,SAAS,UACR,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,OAAO,MAAM,SAAO,KAAE,SAAS,QAAO,GAAC,CAC/C,GAIF,oCAAC,OAAI,cAAc,KACjB,oCAAC,QAAK,MAAI,QAAE,SAAS,QAAS,CAChC,GAGC,SAAS,WAAW,SAAS,QAAQ,SAAS,KAC7C,oCAAC,OAAI,cAAc,KACjB;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc,OAAO,mBAAmB;AAAA,MACxC,UAAU,WAAS;AACjB,YAAI,UAAU,SAAS;AACrB,yBAAe,EAAE;AAAA,QACnB,OAAO;AACL,yBAAe,OAAO,KAAK,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA;AAAA,EACF,CACF,GAID,SAAS,WACR,SAAS,QAAQ,SAAS,KAC1B,uBAAuB,KACvB,sBAAsB,SAAS,QAAQ,UACrC,oCAAC,OAAI,YAAY,GAAG,cAAc,KAChC,oCAAC,QAAK,OAAO,MAAM,eAAe,UAAQ,QACvC,SAAS,QAAQ,mBAAmB,GAAG,eAAe,EACzD,CACF,GAIJ;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACX,aAAY;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,UAAU;AAAA;AAAA,IAEV,oCAAC,QAAK,OAAO,MAAM,iBAAe,4CAE/B,iBAAiB,KAAK,qCAA0B,eACnD;AAAA,EACF,CACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -28,7 +28,11 @@ function BackgroundTasksPanel({
28
28
  } else if (input === "k" || input === "K") {
29
29
  const selected = shells[selectedIndex];
30
30
  if (selected) {
31
- console.log("[BackgroundTasksPanel] Killing shell:", selected.id, selected.command);
31
+ console.log(
32
+ "[BackgroundTasksPanel] Killing shell:",
33
+ selected.id,
34
+ selected.command
35
+ );
32
36
  onKill(selected);
33
37
  if (selectedIndex >= shells.length - 1 && shells.length > 1) {
34
38
  setSelectedIndex(shells.length - 2);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/BackgroundTasksPanel.tsx"],
4
- "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useEffect } from 'react'\nimport { getTheme } from '@utils/theme'\nimport type { BackgroundShell } from '@utils/BackgroundShellManager'\n\ntype Props = {\n shells: BackgroundShell[]\n isVisible: boolean\n onSelect: (shell: BackgroundShell) => void\n onKill: (shell: BackgroundShell) => void\n onClose: () => void\n}\n\nexport function BackgroundTasksPanel({\n shells,\n isVisible,\n onSelect,\n onKill,\n onClose,\n}: Props) {\n const [selectedIndex, setSelectedIndex] = useState(0)\n const theme = getTheme()\n\n // Reset selection when shells list changes\n useEffect(() => {\n if (selectedIndex >= shells.length && shells.length > 0) {\n setSelectedIndex(shells.length - 1)\n }\n }, [shells.length, selectedIndex])\n\n useInput(\n (input, key) => {\n if (key.upArrow) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow) {\n setSelectedIndex(prev => Math.min(shells.length - 1, prev + 1))\n } else if (key.return) {\n const selected = shells[selectedIndex]\n if (selected) onSelect(selected)\n } else if (input === 'k' || input === 'K') {\n const selected = shells[selectedIndex]\n if (selected) {\n console.log('[BackgroundTasksPanel] Killing shell:', selected.id, selected.command)\n onKill(selected)\n // Update selection if we killed the last item\n if (selectedIndex >= shells.length - 1 && shells.length > 1) {\n setSelectedIndex(shells.length - 2)\n }\n }\n } else if (key.escape) {\n onClose()\n } else {\n // Debug: log unhandled input\n console.log('[BackgroundTasksPanel] Unhandled input:', { input, key })\n }\n },\n { isActive: isVisible },\n )\n\n if (!isVisible) return null\n\n const formatDuration = (startTime: number, endTime?: number): string => {\n const duration = endTime\n ? endTime - startTime\n : Date.now() - startTime\n const seconds = Math.floor(duration / 1000)\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`\n const hours = Math.floor(minutes / 60)\n return `${hours}h ${minutes % 60}m`\n }\n\n const getStatusColor = (status: string) => {\n switch (status) {\n case 'running':\n return theme.success\n case 'done':\n return theme.secondaryText\n case 'killed':\n return theme.error\n default:\n return theme.primary\n }\n }\n\n const getStatusIcon = (status: string) => {\n switch (status) {\n case 'running':\n return '\u25B6'\n case 'done':\n return '\u2713'\n case 'killed':\n return '\u2717'\n default:\n return '\u2022'\n }\n }\n\n const activeCount = shells.filter(s => s.status === 'running').length\n const countText =\n activeCount === 1 ? '1 active shell' : `${activeCount} active shells`\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={theme.secondaryBorder}\n paddingX={1}\n marginBottom={1}\n >\n <Box>\n <Text bold color={theme.primary}>\n Background tasks\n </Text>\n </Box>\n <Box>\n <Text color={theme.secondaryText}>{countText}</Text>\n </Box>\n <Box height={1} />\n\n {shells.length === 0 ? (\n <Box>\n <Text color={theme.secondaryText}>(No background tasks)</Text>\n </Box>\n ) : (\n shells.map((shell, index) => {\n const isSelected = index === selectedIndex\n const bgColor = isSelected ? 'cyan' : undefined\n const duration = formatDuration(shell.startTime, shell.endTime)\n const summary = getSummary(shell)\n\n return (\n <Box key={shell.id}>\n <Text\n backgroundColor={bgColor}\n color={isSelected ? 'black' : theme.primary}\n >\n {isSelected ? '\u276F ' : ' '}\n <Text color={getStatusColor(shell.status)}>\n {getStatusIcon(shell.status)}{' '}\n </Text>\n {summary}\n <Text color={theme.secondaryText}> [{duration}]</Text>\n </Text>\n </Box>\n )\n })\n )}\n\n <Box height={1} />\n <Box>\n <Text color={theme.secondaryText}>\n \u2191/\u2193 to select \u00B7 Enter to view \u00B7 k to kill \u00B7 Esc to close\n </Text>\n </Box>\n </Box>\n )\n}\n\nfunction getSummary(shell: BackgroundShell): string {\n // Get command (truncate if too long)\n const maxCmdLen = 40\n const cmd =\n shell.command.length > maxCmdLen\n ? shell.command.slice(0, maxCmdLen) + '\u2026'\n : shell.command\n\n // Get last few lines of output for preview\n const lastLine = shell.stdout[shell.stdout.length - 1] || ''\n const preview = lastLine.slice(0, 30)\n\n return preview ? `${cmd} ${preview}\u2026` : cmd\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState, useEffect } from 'react'\nimport { getTheme } from '@utils/theme'\nimport type { BackgroundShell } from '@utils/BackgroundShellManager'\n\ntype Props = {\n shells: BackgroundShell[]\n isVisible: boolean\n onSelect: (shell: BackgroundShell) => void\n onKill: (shell: BackgroundShell) => void\n onClose: () => void\n}\n\nexport function BackgroundTasksPanel({\n shells,\n isVisible,\n onSelect,\n onKill,\n onClose,\n}: Props) {\n const [selectedIndex, setSelectedIndex] = useState(0)\n const theme = getTheme()\n\n // Reset selection when shells list changes\n useEffect(() => {\n if (selectedIndex >= shells.length && shells.length > 0) {\n setSelectedIndex(shells.length - 1)\n }\n }, [shells.length, selectedIndex])\n\n useInput(\n (input, key) => {\n if (key.upArrow) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow) {\n setSelectedIndex(prev => Math.min(shells.length - 1, prev + 1))\n } else if (key.return) {\n const selected = shells[selectedIndex]\n if (selected) onSelect(selected)\n } else if (input === 'k' || input === 'K') {\n const selected = shells[selectedIndex]\n if (selected) {\n console.log(\n '[BackgroundTasksPanel] Killing shell:',\n selected.id,\n selected.command,\n )\n onKill(selected)\n // Update selection if we killed the last item\n if (selectedIndex >= shells.length - 1 && shells.length > 1) {\n setSelectedIndex(shells.length - 2)\n }\n }\n } else if (key.escape) {\n onClose()\n } else {\n // Debug: log unhandled input\n console.log('[BackgroundTasksPanel] Unhandled input:', { input, key })\n }\n },\n { isActive: isVisible },\n )\n\n if (!isVisible) return null\n\n const formatDuration = (startTime: number, endTime?: number): string => {\n const duration = endTime ? endTime - startTime : Date.now() - startTime\n const seconds = Math.floor(duration / 1000)\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`\n const hours = Math.floor(minutes / 60)\n return `${hours}h ${minutes % 60}m`\n }\n\n const getStatusColor = (status: string) => {\n switch (status) {\n case 'running':\n return theme.success\n case 'done':\n return theme.secondaryText\n case 'killed':\n return theme.error\n default:\n return theme.primary\n }\n }\n\n const getStatusIcon = (status: string) => {\n switch (status) {\n case 'running':\n return '\u25B6'\n case 'done':\n return '\u2713'\n case 'killed':\n return '\u2717'\n default:\n return '\u2022'\n }\n }\n\n const activeCount = shells.filter(s => s.status === 'running').length\n const countText =\n activeCount === 1 ? '1 active shell' : `${activeCount} active shells`\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={theme.secondaryBorder}\n paddingX={1}\n marginBottom={1}\n >\n <Box>\n <Text bold color={theme.primary}>\n Background tasks\n </Text>\n </Box>\n <Box>\n <Text color={theme.secondaryText}>{countText}</Text>\n </Box>\n <Box height={1} />\n\n {shells.length === 0 ? (\n <Box>\n <Text color={theme.secondaryText}>(No background tasks)</Text>\n </Box>\n ) : (\n shells.map((shell, index) => {\n const isSelected = index === selectedIndex\n const bgColor = isSelected ? 'cyan' : undefined\n const duration = formatDuration(shell.startTime, shell.endTime)\n const summary = getSummary(shell)\n\n return (\n <Box key={shell.id}>\n <Text\n backgroundColor={bgColor}\n color={isSelected ? 'black' : theme.primary}\n >\n {isSelected ? '\u276F ' : ' '}\n <Text color={getStatusColor(shell.status)}>\n {getStatusIcon(shell.status)}{' '}\n </Text>\n {summary}\n <Text color={theme.secondaryText}> [{duration}]</Text>\n </Text>\n </Box>\n )\n })\n )}\n\n <Box height={1} />\n <Box>\n <Text color={theme.secondaryText}>\n \u2191/\u2193 to select \u00B7 Enter to view \u00B7 k to kill \u00B7 Esc to close\n </Text>\n </Box>\n </Box>\n )\n}\n\nfunction getSummary(shell: BackgroundShell): string {\n // Get command (truncate if too long)\n const maxCmdLen = 40\n const cmd =\n shell.command.length > maxCmdLen\n ? shell.command.slice(0, maxCmdLen) + '\u2026'\n : shell.command\n\n // Get last few lines of output for preview\n const lastLine = shell.stdout[shell.stdout.length - 1] || ''\n const preview = lastLine.slice(0, 30)\n\n return preview ? `${cmd} ${preview}\u2026` : cmd\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,12 +3,10 @@ import * as React from "react";
3
3
  import { useState } from "react";
4
4
  import figures from "figures";
5
5
  import { getTheme } from "../utils/theme.js";
6
- import {
7
- saveGlobalConfig,
8
- getGlobalConfig
9
- } from "../utils/config.js";
6
+ import { saveGlobalConfig, getGlobalConfig } from "../utils/config.js";
10
7
  import { useExitOnCtrlCD } from "../hooks/useExitOnCtrlCD.js";
11
8
  import { getModelManager } from "../utils/model.js";
9
+ import { getCompressionMode, setCompressionMode } from "../utils/compressionMode.js";
12
10
  function Config({ onClose }) {
13
11
  const [globalConfig, setGlobalConfig] = useState(getGlobalConfig());
14
12
  const initialConfig = React.useRef(getGlobalConfig());
@@ -54,6 +52,21 @@ function Config({ onClose }) {
54
52
  setGlobalConfig(config);
55
53
  },
56
54
  type: "boolean"
55
+ },
56
+ {
57
+ id: "compressionMode",
58
+ label: "Compression mode (/compact)",
59
+ value: getCompressionMode(),
60
+ options: ["business", "code"],
61
+ onChange(mode) {
62
+ setCompressionMode(mode);
63
+ const config = {
64
+ ...getGlobalConfig(),
65
+ compressionMode: mode
66
+ };
67
+ setGlobalConfig(config);
68
+ },
69
+ type: "enum"
57
70
  }
58
71
  ];
59
72
  const theme = getTheme();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/Config.tsx"],
4
- "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState } from 'react'\nimport figures from 'figures'\nimport { getTheme } from '@utils/theme'\nimport {\n GlobalConfig,\n saveGlobalConfig,\n getGlobalConfig,\n} from '@utils/config'\nimport chalk from 'chalk'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { getModelManager } from '@utils/model'\n\ntype Props = {\n onClose: () => void\n}\n\ntype Setting =\n | {\n id: string\n label: string\n value: boolean\n onChange(value: boolean): void\n type: 'boolean'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n options: string[]\n onChange(value: string): void\n type: 'enum'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n onChange(value: string): void\n type: 'string'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: number\n onChange(value: number): void\n type: 'number'\n disabled?: boolean\n }\n\nexport function Config({ onClose }: Props): React.ReactNode {\n const [globalConfig, setGlobalConfig] = useState(getGlobalConfig())\n const initialConfig = React.useRef(getGlobalConfig())\n const [selectedIndex, setSelectedIndex] = useState(0)\n const exitState = useExitOnCtrlCD(() => process.exit(0))\n const [editingString, setEditingString] = useState(false)\n const [currentInput, setCurrentInput] = useState('')\n const [inputError, setInputError] = useState<string | null>(null)\n\n const modelManager = getModelManager()\n const activeProfiles = modelManager.getAvailableModels()\n\n const settings: Setting[] = [\n // Global settings\n {\n id: 'theme',\n label: 'Theme',\n value: globalConfig.theme ?? 'dark',\n options: ['dark', 'light'],\n onChange(theme: string) {\n const config = { ...getGlobalConfig(), theme: theme as any }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n {\n id: 'verbose',\n label: 'Verbose mode',\n value: globalConfig.verbose ?? false,\n onChange(verbose: boolean) {\n const config = { ...getGlobalConfig(), verbose }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'stream',\n label: 'Stream responses',\n value: globalConfig.stream ?? true,\n onChange(stream: boolean) {\n const config = { ...getGlobalConfig(), stream }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n ]\n\n const theme = getTheme()\n\n useInput((input, key) => {\n if (editingString) {\n if (key.return) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.type === 'string') {\n try {\n currentSetting.onChange(currentInput)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n } else if (currentSetting?.type === 'number') {\n const numValue = parseFloat(currentInput)\n if (isNaN(numValue)) {\n setInputError('Please enter a valid number')\n } else {\n try {\n ;(currentSetting as any).onChange(numValue)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n }\n }\n } else if (key.escape) {\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } else if (key.delete || key.backspace) {\n setCurrentInput(prev => prev.slice(0, -1))\n } else if (input) {\n setCurrentInput(prev => prev + input)\n }\n return\n }\n\n if (key.upArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.min(settings.length - 1, prev + 1))\n } else if (key.return && !exitState.pending) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.disabled) return\n\n if (currentSetting?.type === 'boolean') {\n currentSetting.onChange(!currentSetting.value)\n } else if (currentSetting?.type === 'enum') {\n const currentIndex = currentSetting.options.indexOf(\n currentSetting.value,\n )\n const nextIndex = (currentIndex + 1) % currentSetting.options.length\n currentSetting.onChange(currentSetting.options[nextIndex])\n } else if (\n currentSetting?.type === 'string' ||\n currentSetting?.type === 'number'\n ) {\n setCurrentInput(String(currentSetting.value))\n setEditingString(true)\n setInputError(null)\n }\n } else if (key.escape && !exitState.pending) {\n // Check if config has changed\n const currentConfigString = JSON.stringify(getGlobalConfig())\n const initialConfigString = JSON.stringify(initialConfig.current)\n\n if (currentConfigString !== initialConfigString) {\n // Config has changed, save it\n saveGlobalConfig(getGlobalConfig())\n }\n\n onClose()\n }\n })\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.secondaryBorder}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text bold>\n Configuration{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n\n {/* Model Configuration Summary */}\n <Box flexDirection=\"column\" marginY={1}>\n <Text bold color={theme.success}>\n Model Configuration:\n </Text>\n {activeProfiles.length === 0 ? (\n <Text color={theme.secondaryText}>\n No models configured. Use /model to add models.\n </Text>\n ) : (\n <Box flexDirection=\"column\" marginLeft={2}>\n {activeProfiles.map(profile => (\n <React.Fragment key={profile.modelName}>\n <Text color={theme.secondaryText}>\n \u2022 {profile.name} ({profile.provider})\n </Text>\n </React.Fragment>\n ))}\n <Box marginTop={1}>\n <Text color={theme.suggestion}>\n Use /model to manage model configurations\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n\n {/* Settings List */}\n <Box flexDirection=\"column\">\n {settings.map((setting, index) => (\n <Box key={setting.id} flexDirection=\"column\">\n <Box flexDirection=\"row\" gap={1}>\n <Text\n color={\n index === selectedIndex\n ? theme.success\n : setting.disabled\n ? theme.secondaryText\n : theme.text\n }\n >\n {index === selectedIndex ? figures.pointer : ' '}{' '}\n {setting.label}\n </Text>\n <Text\n color={\n setting.disabled ? theme.secondaryText : theme.suggestion\n }\n >\n {setting.type === 'boolean'\n ? setting.value\n ? 'enabled'\n : 'disabled'\n : setting.type === 'enum'\n ? setting.value\n : String(setting.value)}\n </Text>\n </Box>\n {index === selectedIndex && editingString && (\n <Box flexDirection=\"column\" marginLeft={2}>\n <Text color={theme.suggestion}>\n Enter new value: {currentInput}\n </Text>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n {editingString ? (\n 'Enter to save \u00B7 Esc to cancel'\n ) : (\n <>\n \u2191/\u2193 to navigate \u00B7 Enter to change \u00B7 Esc to close\n <Text color={theme.suggestion}>\n {' '}\n \u00B7 Use /model for model config\n </Text>\n </>\n )}\n </Text>\n </Box>\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text, useInput } from 'ink'\nimport * as React from 'react'\nimport { useState } from 'react'\nimport figures from 'figures'\nimport { getTheme } from '@utils/theme'\nimport { GlobalConfig, saveGlobalConfig, getGlobalConfig } from '@utils/config'\nimport chalk from 'chalk'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { getModelManager } from '@utils/model'\nimport { getCompressionMode, setCompressionMode } from '@utils/compressionMode'\nimport type { CompressionMode } from '@constants/compressionPrompts'\n\ntype Props = {\n onClose: () => void\n}\n\ntype Setting =\n | {\n id: string\n label: string\n value: boolean\n onChange(value: boolean): void\n type: 'boolean'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n options: string[]\n onChange(value: string): void\n type: 'enum'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: string\n onChange(value: string): void\n type: 'string'\n disabled?: boolean\n }\n | {\n id: string\n label: string\n value: number\n onChange(value: number): void\n type: 'number'\n disabled?: boolean\n }\n\nexport function Config({ onClose }: Props): React.ReactNode {\n const [globalConfig, setGlobalConfig] = useState(getGlobalConfig())\n const initialConfig = React.useRef(getGlobalConfig())\n const [selectedIndex, setSelectedIndex] = useState(0)\n const exitState = useExitOnCtrlCD(() => process.exit(0))\n const [editingString, setEditingString] = useState(false)\n const [currentInput, setCurrentInput] = useState('')\n const [inputError, setInputError] = useState<string | null>(null)\n\n const modelManager = getModelManager()\n const activeProfiles = modelManager.getAvailableModels()\n\n const settings: Setting[] = [\n // Global settings\n {\n id: 'theme',\n label: 'Theme',\n value: globalConfig.theme ?? 'dark',\n options: ['dark', 'light'],\n onChange(theme: string) {\n const config = { ...getGlobalConfig(), theme: theme as any }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n {\n id: 'verbose',\n label: 'Verbose mode',\n value: globalConfig.verbose ?? false,\n onChange(verbose: boolean) {\n const config = { ...getGlobalConfig(), verbose }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'stream',\n label: 'Stream responses',\n value: globalConfig.stream ?? true,\n onChange(stream: boolean) {\n const config = { ...getGlobalConfig(), stream }\n saveGlobalConfig(config)\n setGlobalConfig(config)\n },\n type: 'boolean',\n },\n {\n id: 'compressionMode',\n label: 'Compression mode (/compact)',\n value: getCompressionMode(),\n options: ['business', 'code'],\n onChange(mode: string) {\n setCompressionMode(mode as CompressionMode)\n const config = {\n ...getGlobalConfig(),\n compressionMode: mode as CompressionMode,\n }\n setGlobalConfig(config)\n },\n type: 'enum',\n },\n ]\n\n const theme = getTheme()\n\n useInput((input, key) => {\n if (editingString) {\n if (key.return) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.type === 'string') {\n try {\n currentSetting.onChange(currentInput)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n } else if (currentSetting?.type === 'number') {\n const numValue = parseFloat(currentInput)\n if (isNaN(numValue)) {\n setInputError('Please enter a valid number')\n } else {\n try {\n ;(currentSetting as any).onChange(numValue)\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } catch (error) {\n setInputError(\n error instanceof Error ? error.message : 'Invalid input',\n )\n }\n }\n }\n } else if (key.escape) {\n setEditingString(false)\n setCurrentInput('')\n setInputError(null)\n } else if (key.delete || key.backspace) {\n setCurrentInput(prev => prev.slice(0, -1))\n } else if (input) {\n setCurrentInput(prev => prev + input)\n }\n return\n }\n\n if (key.upArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.max(0, prev - 1))\n } else if (key.downArrow && !exitState.pending) {\n setSelectedIndex(prev => Math.min(settings.length - 1, prev + 1))\n } else if (key.return && !exitState.pending) {\n const currentSetting = settings[selectedIndex]\n if (currentSetting?.disabled) return\n\n if (currentSetting?.type === 'boolean') {\n currentSetting.onChange(!currentSetting.value)\n } else if (currentSetting?.type === 'enum') {\n const currentIndex = currentSetting.options.indexOf(\n currentSetting.value,\n )\n const nextIndex = (currentIndex + 1) % currentSetting.options.length\n currentSetting.onChange(currentSetting.options[nextIndex])\n } else if (\n currentSetting?.type === 'string' ||\n currentSetting?.type === 'number'\n ) {\n setCurrentInput(String(currentSetting.value))\n setEditingString(true)\n setInputError(null)\n }\n } else if (key.escape && !exitState.pending) {\n // Check if config has changed\n const currentConfigString = JSON.stringify(getGlobalConfig())\n const initialConfigString = JSON.stringify(initialConfig.current)\n\n if (currentConfigString !== initialConfigString) {\n // Config has changed, save it\n saveGlobalConfig(getGlobalConfig())\n }\n\n onClose()\n }\n })\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.secondaryBorder}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text bold>\n Configuration{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n\n {/* Model Configuration Summary */}\n <Box flexDirection=\"column\" marginY={1}>\n <Text bold color={theme.success}>\n Model Configuration:\n </Text>\n {activeProfiles.length === 0 ? (\n <Text color={theme.secondaryText}>\n No models configured. Use /model to add models.\n </Text>\n ) : (\n <Box flexDirection=\"column\" marginLeft={2}>\n {activeProfiles.map(profile => (\n <React.Fragment key={profile.modelName}>\n <Text color={theme.secondaryText}>\n \u2022 {profile.name} ({profile.provider})\n </Text>\n </React.Fragment>\n ))}\n <Box marginTop={1}>\n <Text color={theme.suggestion}>\n Use /model to manage model configurations\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n\n {/* Settings List */}\n <Box flexDirection=\"column\">\n {settings.map((setting, index) => (\n <Box key={setting.id} flexDirection=\"column\">\n <Box flexDirection=\"row\" gap={1}>\n <Text\n color={\n index === selectedIndex\n ? theme.success\n : setting.disabled\n ? theme.secondaryText\n : theme.text\n }\n >\n {index === selectedIndex ? figures.pointer : ' '}{' '}\n {setting.label}\n </Text>\n <Text\n color={\n setting.disabled ? theme.secondaryText : theme.suggestion\n }\n >\n {setting.type === 'boolean'\n ? setting.value\n ? 'enabled'\n : 'disabled'\n : setting.type === 'enum'\n ? setting.value\n : String(setting.value)}\n </Text>\n </Box>\n {index === selectedIndex && editingString && (\n <Box flexDirection=\"column\" marginLeft={2}>\n <Text color={theme.suggestion}>\n Enter new value: {currentInput}\n </Text>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n {editingString ? (\n 'Enter to save \u00B7 Esc to cancel'\n ) : (\n <>\n \u2191/\u2193 to navigate \u00B7 Enter to change \u00B7 Esc to close\n <Text color={theme.suggestion}>\n {' '}\n \u00B7 Use /model for model config\n </Text>\n </>\n )}\n </Text>\n </Box>\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["theme"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/ConsoleOAuthFlow.tsx"],
4
- "sourcesContent": ["import React, { useEffect, useState, useCallback } from 'react'\nimport { Static, Box, Text, useInput } from 'ink'\nimport TextInput from './TextInput'\nimport { OAuthService, createAndStoreApiKey } from '@services/oauth'\nimport { getTheme } from '@utils/theme'\nimport { AsciiLogo } from './AsciiLogo'\nimport { useTerminalSize } from '@hooks/useTerminalSize'\nimport { logError } from '@utils/log'\nimport { clearTerminal } from '@utils/terminal'\nimport { SimpleSpinner } from './Spinner'\nimport { WelcomeBox } from './Onboarding'\nimport { PRODUCT_NAME } from '@constants/product'\nimport { sendNotification } from '@services/notifier'\n\ntype Props = {\n onDone(): void\n}\n\ntype OAuthStatus =\n | { state: 'idle' }\n | { state: 'ready_to_start' }\n | { state: 'waiting_for_login'; url: string }\n | { state: 'creating_api_key' }\n | { state: 'about_to_retry'; nextState: OAuthStatus }\n | { state: 'success'; apiKey: string }\n | {\n state: 'error'\n message: string\n toRetry?: OAuthStatus\n }\n\nconst PASTE_HERE_MSG = 'Paste code here if prompted > '\n\nexport function ConsoleOAuthFlow({ onDone }: Props): React.ReactNode {\n const [oauthStatus, setOAuthStatus] = useState<OAuthStatus>({\n state: 'idle',\n })\n const theme = getTheme()\n\n const [pastedCode, setPastedCode] = useState('')\n const [cursorOffset, setCursorOffset] = useState(0)\n const [oauthService] = useState(() => new OAuthService())\n // After a few seconds we suggest the user to copy/paste url if the\n // browser did not open automatically. In this flow we expect the user to\n // copy the code from the browser and paste it in the terminal\n const [showPastePrompt, setShowPastePrompt] = useState(false)\n // we need a special clearing state to correctly re-render Static elements\n const [isClearing, setIsClearing] = useState(false)\n\n const textInputColumns = useTerminalSize().columns - PASTE_HERE_MSG.length - 1\n\n useEffect(() => {\n if (isClearing) {\n clearTerminal()\n setIsClearing(false)\n }\n }, [isClearing])\n\n // Retry logic\n useEffect(() => {\n if (oauthStatus.state === 'about_to_retry') {\n setIsClearing(true)\n setTimeout(() => {\n setOAuthStatus(oauthStatus.nextState)\n }, 1000)\n }\n }, [oauthStatus])\n\n useInput(async (_, key) => {\n if (key.return) {\n if (oauthStatus.state === 'idle') {\n \n setOAuthStatus({ state: 'ready_to_start' })\n } else if (oauthStatus.state === 'success') {\n \n await clearTerminal() // needed to clear out Static components\n onDone()\n } else if (oauthStatus.state === 'error' && oauthStatus.toRetry) {\n setPastedCode('')\n setOAuthStatus({\n state: 'about_to_retry',\n nextState: oauthStatus.toRetry,\n })\n }\n }\n })\n\n async function handleSubmitCode(value: string, url: string) {\n try {\n // Expecting format \"authorizationCode#state\" from the authorization callback URL\n const [authorizationCode, state] = value.split('#')\n\n if (!authorizationCode || !state) {\n setOAuthStatus({\n state: 'error',\n message: 'Invalid code. Please make sure the full code was copied',\n toRetry: { state: 'waiting_for_login', url },\n })\n return\n }\n\n // Track which path the user is taking (manual code entry)\n \n oauthService.processCallback({\n authorizationCode,\n state,\n useManualRedirect: true,\n })\n } catch (err) {\n logError(err)\n setOAuthStatus({\n state: 'error',\n message: (err as Error).message,\n toRetry: { state: 'waiting_for_login', url },\n })\n }\n }\n\n const startOAuth = useCallback(async () => {\n try {\n const result = await oauthService\n .startOAuthFlow(async url => {\n setOAuthStatus({ state: 'waiting_for_login', url })\n setTimeout(() => setShowPastePrompt(true), 3000)\n })\n .catch(err => {\n // Handle token exchange errors specifically\n if (err.message.includes('Token exchange failed')) {\n setOAuthStatus({\n state: 'error',\n message:\n 'Failed to exchange authorization code for access token. Please try again.',\n toRetry: { state: 'ready_to_start' },\n })\n \n } else {\n // Handle other errors\n setOAuthStatus({\n state: 'error',\n message: err.message,\n toRetry: { state: 'ready_to_start' },\n })\n }\n throw err\n })\n\n setOAuthStatus({ state: 'creating_api_key' })\n\n const apiKey = await createAndStoreApiKey(result.accessToken).catch(\n err => {\n setOAuthStatus({\n state: 'error',\n message: 'Failed to create API key: ' + err.message,\n toRetry: { state: 'ready_to_start' },\n })\n \n throw err\n },\n )\n\n if (apiKey) {\n setOAuthStatus({ state: 'success', apiKey })\n sendNotification({ message: 'Minto login successful' })\n } else {\n setOAuthStatus({\n state: 'error',\n message:\n \"Unable to create API key. The server accepted the request but didn't return a key.\",\n toRetry: { state: 'ready_to_start' },\n })\n \n }\n } catch (err) {\n const errorMessage = (err as Error).message\n }\n }, [oauthService, setShowPastePrompt])\n\n useEffect(() => {\n if (oauthStatus.state === 'ready_to_start') {\n startOAuth()\n }\n }, [oauthStatus.state, startOAuth])\n\n // Helper function to render the appropriate status message\n function renderStatusMessage(): React.ReactNode {\n switch (oauthStatus.state) {\n case 'idle':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text bold>\n {PRODUCT_NAME} is billed based on API usage through your Anthropic\n Console account.\n </Text>\n\n <Box>\n <Text>\n Pricing may evolve as we move towards general availability.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={theme.permission}>\n Press <Text bold>Enter</Text> to login to your Anthropic Console\n account\u2026\n </Text>\n </Box>\n </Box>\n )\n\n case 'waiting_for_login':\n return (\n <Box flexDirection=\"column\" gap={1}>\n {!showPastePrompt && (\n <Box>\n <SimpleSpinner />\n <Text>Opening browser to sign in\u2026</Text>\n </Box>\n )}\n\n {showPastePrompt && (\n <Box>\n <Text>{PASTE_HERE_MSG}</Text>\n <TextInput\n value={pastedCode}\n onChange={setPastedCode}\n onSubmit={(value: string) =>\n handleSubmitCode(value, oauthStatus.url)\n }\n cursorOffset={cursorOffset}\n onChangeCursorOffset={setCursorOffset}\n columns={textInputColumns}\n />\n </Box>\n )}\n </Box>\n )\n\n case 'creating_api_key':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <SimpleSpinner />\n <Text>Creating API key for Minto\u2026</Text>\n </Box>\n </Box>\n )\n\n case 'about_to_retry':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.permission}>Retrying\u2026</Text>\n </Box>\n )\n\n case 'success':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.success}>\n Login successful. Press <Text bold>Enter</Text> to continue\u2026\n </Text>\n </Box>\n )\n\n case 'error':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.error}>OAuth error: {oauthStatus.message}</Text>\n\n {oauthStatus.toRetry && (\n <Box marginTop={1}>\n <Text color={theme.permission}>\n Press <Text bold>Enter</Text> to retry.\n </Text>\n </Box>\n )}\n </Box>\n )\n\n default:\n return null\n }\n }\n\n // We need to render the copy-able URL statically to prevent Ink <Text> from inserting\n // newlines in the middle of the URL (this breaks Safari). Because <Static> components are\n // only rendered once top-to-bottom, we also need to make everything above the URL static.\n const staticItems: Record<string, React.JSX.Element> = {}\n if (!isClearing) {\n staticItems.header = (\n <Box key=\"header\" flexDirection=\"column\" gap={1}>\n <WelcomeBox />\n <Box paddingBottom={1} paddingLeft={1}>\n <AsciiLogo />\n </Box>\n </Box>\n )\n }\n if (oauthStatus.state === 'waiting_for_login' && showPastePrompt) {\n staticItems.urlToCopy = (\n <Box flexDirection=\"column\" key=\"urlToCopy\" gap={1} paddingBottom={1}>\n <Box paddingX={1}>\n <Text dimColor>\n Browser didn&apos;t open? Use the url below to sign in:\n </Text>\n </Box>\n <Box width={1000}>\n <Text dimColor>{oauthStatus.url}</Text>\n </Box>\n </Box>\n )\n }\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Static \n items={Object.keys(staticItems)}\n children={(item: string) => staticItems[item]}\n />\n <Box paddingLeft={1} flexDirection=\"column\" gap={1}>\n {renderStatusMessage()}\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "AAAA,OAAO,SAAS,WAAW,UAAU,mBAAmB;AACxD,SAAS,QAAQ,KAAK,MAAM,gBAAgB;AAC5C,OAAO,eAAe;AACtB,SAAS,cAAc,4BAA4B;AACnD,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AAmBjC,MAAM,iBAAiB;AAEhB,SAAS,iBAAiB,EAAE,OAAO,GAA2B;AACnE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB;AAAA,IAC1D,OAAO;AAAA,EACT,CAAC;AACD,QAAM,QAAQ,SAAS;AAEvB,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,EAAE;AAC/C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAClD,QAAM,CAAC,YAAY,IAAI,SAAS,MAAM,IAAI,aAAa,CAAC;AAIxD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,KAAK;AAE5D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,QAAM,mBAAmB,gBAAgB,EAAE,UAAU,eAAe,SAAS;AAE7E,YAAU,MAAM;AACd,QAAI,YAAY;AACd,oBAAc;AACd,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAGf,YAAU,MAAM;AACd,QAAI,YAAY,UAAU,kBAAkB;AAC1C,oBAAc,IAAI;AAClB,iBAAW,MAAM;AACf,uBAAe,YAAY,SAAS;AAAA,MACtC,GAAG,GAAI;AAAA,IACT;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,WAAS,OAAO,GAAG,QAAQ;AACzB,QAAI,IAAI,QAAQ;AACd,UAAI,YAAY,UAAU,QAAQ;AAEhC,uBAAe,EAAE,OAAO,iBAAiB,CAAC;AAAA,MAC5C,WAAW,YAAY,UAAU,WAAW;AAE1C,cAAM,cAAc;AACpB,eAAO;AAAA,MACT,WAAW,YAAY,UAAU,WAAW,YAAY,SAAS;AAC/D,sBAAc,EAAE;AAChB,uBAAe;AAAA,UACb,OAAO;AAAA,UACP,WAAW,YAAY;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,iBAAe,iBAAiB,OAAe,KAAa;AAC1D,QAAI;AAEF,YAAM,CAAC,mBAAmB,KAAK,IAAI,MAAM,MAAM,GAAG;AAElD,UAAI,CAAC,qBAAqB,CAAC,OAAO;AAChC,uBAAe;AAAA,UACb,OAAO;AAAA,UACP,SAAS;AAAA,UACT,SAAS,EAAE,OAAO,qBAAqB,IAAI;AAAA,QAC7C,CAAC;AACD;AAAA,MACF;AAIA,mBAAa,gBAAgB;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,mBAAmB;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,eAAS,GAAG;AACZ,qBAAe;AAAA,QACb,OAAO;AAAA,QACP,SAAU,IAAc;AAAA,QACxB,SAAS,EAAE,OAAO,qBAAqB,IAAI;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,aAAa,YAAY,YAAY;AACzC,QAAI;AACF,YAAM,SAAS,MAAM,aAClB,eAAe,OAAM,QAAO;AAC3B,uBAAe,EAAE,OAAO,qBAAqB,IAAI,CAAC;AAClD,mBAAW,MAAM,mBAAmB,IAAI,GAAG,GAAI;AAAA,MACjD,CAAC,EACA,MAAM,SAAO;AAEZ,YAAI,IAAI,QAAQ,SAAS,uBAAuB,GAAG;AACjD,yBAAe;AAAA,YACb,OAAO;AAAA,YACP,SACE;AAAA,YACF,SAAS,EAAE,OAAO,iBAAiB;AAAA,UACrC,CAAC;AAAA,QAEH,OAAO;AAEL,yBAAe;AAAA,YACb,OAAO;AAAA,YACP,SAAS,IAAI;AAAA,YACb,SAAS,EAAE,OAAO,iBAAiB;AAAA,UACrC,CAAC;AAAA,QACH;AACA,cAAM;AAAA,MACR,CAAC;AAEH,qBAAe,EAAE,OAAO,mBAAmB,CAAC;AAE5C,YAAM,SAAS,MAAM,qBAAqB,OAAO,WAAW,EAAE;AAAA,QAC5D,SAAO;AACL,yBAAe;AAAA,YACb,OAAO;AAAA,YACP,SAAS,+BAA+B,IAAI;AAAA,YAC5C,SAAS,EAAE,OAAO,iBAAiB;AAAA,UACrC,CAAC;AAED,gBAAM;AAAA,QACR;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,uBAAe,EAAE,OAAO,WAAW,OAAO,CAAC;AAC3C,yBAAiB,EAAE,SAAS,yBAAyB,CAAC;AAAA,MACxD,OAAO;AACL,uBAAe;AAAA,UACb,OAAO;AAAA,UACP,SACE;AAAA,UACF,SAAS,EAAE,OAAO,iBAAiB;AAAA,QACrC,CAAC;AAAA,MAEH;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,eAAgB,IAAc;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,cAAc,kBAAkB,CAAC;AAErC,YAAU,MAAM;AACd,QAAI,YAAY,UAAU,kBAAkB;AAC1C,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,YAAY,OAAO,UAAU,CAAC;AAGlC,WAAS,sBAAuC;AAC9C,YAAQ,YAAY,OAAO;AAAA,MACzB,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B,oCAAC,QAAK,MAAI,QACP,cAAa,uEAEhB,GAEA,oCAAC,WACC,oCAAC,YAAK,6DAEN,CACF,GAEA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,cAAY,UACvB,oCAAC,QAAK,MAAI,QAAC,OAAK,GAAO,mDAE/B,CACF,CACF;AAAA,MAGJ,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC9B,CAAC,mBACA,oCAAC,WACC,oCAAC,mBAAc,GACf,oCAAC,YAAK,kCAA2B,CACnC,GAGD,mBACC,oCAAC,WACC,oCAAC,YAAM,cAAe,GACtB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU;AAAA,YACV,UAAU,CAAC,UACT,iBAAiB,OAAO,YAAY,GAAG;AAAA,YAEzC;AAAA,YACA,sBAAsB;AAAA,YACtB,SAAS;AAAA;AAAA,QACX,CACF,CAEJ;AAAA,MAGJ,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B,oCAAC,WACC,oCAAC,mBAAc,GACf,oCAAC,YAAK,kCAA2B,CACnC,CACF;AAAA,MAGJ,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B,oCAAC,QAAK,OAAO,MAAM,cAAY,gBAAS,CAC1C;AAAA,MAGJ,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B,oCAAC,QAAK,OAAO,MAAM,WAAS,4BACF,oCAAC,QAAK,MAAI,QAAC,OAAK,GAAO,oBACjD,CACF;AAAA,MAGJ,KAAK;AACH,eACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B,oCAAC,QAAK,OAAO,MAAM,SAAO,iBAAc,YAAY,OAAQ,GAE3D,YAAY,WACX,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,cAAY,UACvB,oCAAC,QAAK,MAAI,QAAC,OAAK,GAAO,YAC/B,CACF,CAEJ;AAAA,MAGJ;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAKA,QAAM,cAAiD,CAAC;AACxD,MAAI,CAAC,YAAY;AACf,gBAAY,SACV,oCAAC,OAAI,KAAI,UAAS,eAAc,UAAS,KAAK,KAC5C,oCAAC,gBAAW,GACZ,oCAAC,OAAI,eAAe,GAAG,aAAa,KAClC,oCAAC,eAAU,CACb,CACF;AAAA,EAEJ;AACA,MAAI,YAAY,UAAU,uBAAuB,iBAAiB;AAChE,gBAAY,YACV,oCAAC,OAAI,eAAc,UAAS,KAAI,aAAY,KAAK,GAAG,eAAe,KACjE,oCAAC,OAAI,UAAU,KACb,oCAAC,QAAK,UAAQ,QAAC,oDAEf,CACF,GACA,oCAAC,OAAI,OAAO,OACV,oCAAC,QAAK,UAAQ,QAAE,YAAY,GAAI,CAClC,CACF;AAAA,EAEJ;AACA,SACE,oCAAC,OAAI,eAAc,UAAS,KAAK,KAC/B;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,OAAO,KAAK,WAAW;AAAA,MAC9B,UAAU,CAAC,SAAiB,YAAY,IAAI;AAAA;AAAA,EAC9C,GACA,oCAAC,OAAI,aAAa,GAAG,eAAc,UAAS,KAAK,KAC9C,oBAAoB,CACvB,CACF;AAEJ;",
4
+ "sourcesContent": ["import React, { useEffect, useState, useCallback } from 'react'\nimport { Static, Box, Text, useInput } from 'ink'\nimport TextInput from './TextInput'\nimport { OAuthService, createAndStoreApiKey } from '@services/oauth'\nimport { getTheme } from '@utils/theme'\nimport { AsciiLogo } from './AsciiLogo'\nimport { useTerminalSize } from '@hooks/useTerminalSize'\nimport { logError } from '@utils/log'\nimport { clearTerminal } from '@utils/terminal'\nimport { SimpleSpinner } from './Spinner'\nimport { WelcomeBox } from './Onboarding'\nimport { PRODUCT_NAME } from '@constants/product'\nimport { sendNotification } from '@services/notifier'\n\ntype Props = {\n onDone(): void\n}\n\ntype OAuthStatus =\n | { state: 'idle' }\n | { state: 'ready_to_start' }\n | { state: 'waiting_for_login'; url: string }\n | { state: 'creating_api_key' }\n | { state: 'about_to_retry'; nextState: OAuthStatus }\n | { state: 'success'; apiKey: string }\n | {\n state: 'error'\n message: string\n toRetry?: OAuthStatus\n }\n\nconst PASTE_HERE_MSG = 'Paste code here if prompted > '\n\nexport function ConsoleOAuthFlow({ onDone }: Props): React.ReactNode {\n const [oauthStatus, setOAuthStatus] = useState<OAuthStatus>({\n state: 'idle',\n })\n const theme = getTheme()\n\n const [pastedCode, setPastedCode] = useState('')\n const [cursorOffset, setCursorOffset] = useState(0)\n const [oauthService] = useState(() => new OAuthService())\n // After a few seconds we suggest the user to copy/paste url if the\n // browser did not open automatically. In this flow we expect the user to\n // copy the code from the browser and paste it in the terminal\n const [showPastePrompt, setShowPastePrompt] = useState(false)\n // we need a special clearing state to correctly re-render Static elements\n const [isClearing, setIsClearing] = useState(false)\n\n const textInputColumns = useTerminalSize().columns - PASTE_HERE_MSG.length - 1\n\n useEffect(() => {\n if (isClearing) {\n clearTerminal()\n setIsClearing(false)\n }\n }, [isClearing])\n\n // Retry logic\n useEffect(() => {\n if (oauthStatus.state === 'about_to_retry') {\n setIsClearing(true)\n setTimeout(() => {\n setOAuthStatus(oauthStatus.nextState)\n }, 1000)\n }\n }, [oauthStatus])\n\n useInput(async (_, key) => {\n if (key.return) {\n if (oauthStatus.state === 'idle') {\n setOAuthStatus({ state: 'ready_to_start' })\n } else if (oauthStatus.state === 'success') {\n await clearTerminal() // needed to clear out Static components\n onDone()\n } else if (oauthStatus.state === 'error' && oauthStatus.toRetry) {\n setPastedCode('')\n setOAuthStatus({\n state: 'about_to_retry',\n nextState: oauthStatus.toRetry,\n })\n }\n }\n })\n\n async function handleSubmitCode(value: string, url: string) {\n try {\n // Expecting format \"authorizationCode#state\" from the authorization callback URL\n const [authorizationCode, state] = value.split('#')\n\n if (!authorizationCode || !state) {\n setOAuthStatus({\n state: 'error',\n message: 'Invalid code. Please make sure the full code was copied',\n toRetry: { state: 'waiting_for_login', url },\n })\n return\n }\n\n // Track which path the user is taking (manual code entry)\n\n oauthService.processCallback({\n authorizationCode,\n state,\n useManualRedirect: true,\n })\n } catch (err) {\n logError(err)\n setOAuthStatus({\n state: 'error',\n message: (err as Error).message,\n toRetry: { state: 'waiting_for_login', url },\n })\n }\n }\n\n const startOAuth = useCallback(async () => {\n try {\n const result = await oauthService\n .startOAuthFlow(async url => {\n setOAuthStatus({ state: 'waiting_for_login', url })\n setTimeout(() => setShowPastePrompt(true), 3000)\n })\n .catch(err => {\n // Handle token exchange errors specifically\n if (err.message.includes('Token exchange failed')) {\n setOAuthStatus({\n state: 'error',\n message:\n 'Failed to exchange authorization code for access token. Please try again.',\n toRetry: { state: 'ready_to_start' },\n })\n } else {\n // Handle other errors\n setOAuthStatus({\n state: 'error',\n message: err.message,\n toRetry: { state: 'ready_to_start' },\n })\n }\n throw err\n })\n\n setOAuthStatus({ state: 'creating_api_key' })\n\n const apiKey = await createAndStoreApiKey(result.accessToken).catch(\n err => {\n setOAuthStatus({\n state: 'error',\n message: 'Failed to create API key: ' + err.message,\n toRetry: { state: 'ready_to_start' },\n })\n\n throw err\n },\n )\n\n if (apiKey) {\n setOAuthStatus({ state: 'success', apiKey })\n sendNotification({ message: 'Minto login successful' })\n } else {\n setOAuthStatus({\n state: 'error',\n message:\n \"Unable to create API key. The server accepted the request but didn't return a key.\",\n toRetry: { state: 'ready_to_start' },\n })\n }\n } catch (err) {\n const errorMessage = (err as Error).message\n }\n }, [oauthService, setShowPastePrompt])\n\n useEffect(() => {\n if (oauthStatus.state === 'ready_to_start') {\n startOAuth()\n }\n }, [oauthStatus.state, startOAuth])\n\n // Helper function to render the appropriate status message\n function renderStatusMessage(): React.ReactNode {\n switch (oauthStatus.state) {\n case 'idle':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text bold>\n {PRODUCT_NAME} is billed based on API usage through your Anthropic\n Console account.\n </Text>\n\n <Box>\n <Text>\n Pricing may evolve as we move towards general availability.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={theme.permission}>\n Press <Text bold>Enter</Text> to login to your Anthropic Console\n account\u2026\n </Text>\n </Box>\n </Box>\n )\n\n case 'waiting_for_login':\n return (\n <Box flexDirection=\"column\" gap={1}>\n {!showPastePrompt && (\n <Box>\n <SimpleSpinner />\n <Text>Opening browser to sign in\u2026</Text>\n </Box>\n )}\n\n {showPastePrompt && (\n <Box>\n <Text>{PASTE_HERE_MSG}</Text>\n <TextInput\n value={pastedCode}\n onChange={setPastedCode}\n onSubmit={(value: string) =>\n handleSubmitCode(value, oauthStatus.url)\n }\n cursorOffset={cursorOffset}\n onChangeCursorOffset={setCursorOffset}\n columns={textInputColumns}\n />\n </Box>\n )}\n </Box>\n )\n\n case 'creating_api_key':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <SimpleSpinner />\n <Text>Creating API key for Minto\u2026</Text>\n </Box>\n </Box>\n )\n\n case 'about_to_retry':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.permission}>Retrying\u2026</Text>\n </Box>\n )\n\n case 'success':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.success}>\n Login successful. Press <Text bold>Enter</Text> to continue\u2026\n </Text>\n </Box>\n )\n\n case 'error':\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color={theme.error}>OAuth error: {oauthStatus.message}</Text>\n\n {oauthStatus.toRetry && (\n <Box marginTop={1}>\n <Text color={theme.permission}>\n Press <Text bold>Enter</Text> to retry.\n </Text>\n </Box>\n )}\n </Box>\n )\n\n default:\n return null\n }\n }\n\n // We need to render the copy-able URL statically to prevent Ink <Text> from inserting\n // newlines in the middle of the URL (this breaks Safari). Because <Static> components are\n // only rendered once top-to-bottom, we also need to make everything above the URL static.\n const staticItems: Record<string, React.JSX.Element> = {}\n if (!isClearing) {\n staticItems.header = (\n <Box key=\"header\" flexDirection=\"column\" gap={1}>\n <WelcomeBox />\n <Box paddingBottom={1} paddingLeft={1}>\n <AsciiLogo />\n </Box>\n </Box>\n )\n }\n if (oauthStatus.state === 'waiting_for_login' && showPastePrompt) {\n staticItems.urlToCopy = (\n <Box flexDirection=\"column\" key=\"urlToCopy\" gap={1} paddingBottom={1}>\n <Box paddingX={1}>\n <Text dimColor>\n Browser didn&apos;t open? Use the url below to sign in:\n </Text>\n </Box>\n <Box width={1000}>\n <Text dimColor>{oauthStatus.url}</Text>\n </Box>\n </Box>\n )\n }\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Static\n items={Object.keys(staticItems)}\n children={(item: string) => staticItems[item]}\n />\n <Box paddingLeft={1} flexDirection=\"column\" gap={1}>\n {renderStatusMessage()}\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,7 +18,10 @@ function SelectOption({
18
18
  focusIndicator: () => ({
19
19
  color: appTheme.minto
20
20
  }),
21
- label: ({ isFocused: isFocused2, isSelected: isSelected2 }) => ({
21
+ label: ({
22
+ isFocused: isFocused2,
23
+ isSelected: isSelected2
24
+ }) => ({
22
25
  color: isSelected2 ? appTheme.success : isFocused2 ? appTheme.minto : appTheme.text,
23
26
  bold: isSelected2
24
27
  }),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/CustomSelect/select-option.tsx"],
4
- "sourcesContent": ["import figures from 'figures'\nimport { Box, Text } from 'ink'\nimport React, { type ReactNode } from 'react'\nimport { type Theme } from './theme'\nimport { getTheme } from '@utils/theme'\n\nexport type SelectOptionProps = {\n /**\n * Determines if option is focused.\n */\n readonly isFocused: boolean\n\n /**\n * Determines if option is selected.\n */\n readonly isSelected: boolean\n\n /**\n * Determines if pointer is shown when selected\n */\n readonly smallPointer?: boolean\n\n /**\n * Option label.\n */\n readonly children: ReactNode\n\n /**\n * React key prop (handled internally by React)\n */\n readonly key?: React.Key\n}\n\nexport function SelectOption({\n isFocused,\n isSelected,\n smallPointer,\n children,\n ...props\n}: SelectOptionProps) {\n const appTheme = getTheme()\n const styles = {\n option: ({ isFocused }: { isFocused: boolean }) => ({\n paddingLeft: 2,\n paddingRight: 1,\n }),\n focusIndicator: () => ({\n color: appTheme.minto,\n }),\n label: ({ isFocused, isSelected }: { isFocused: boolean; isSelected: boolean }) => ({\n color: isSelected \n ? appTheme.success \n : isFocused \n ? appTheme.minto \n : appTheme.text,\n bold: isSelected,\n }),\n selectedIndicator: () => ({\n color: appTheme.success,\n }),\n }\n\n return (\n <Box {...styles.option({ isFocused })}>\n {isFocused && (\n <Text {...styles.focusIndicator()}>\n {smallPointer ? figures.triangleDownSmall : figures.pointer}\n </Text>\n )}\n\n <Text {...styles.label({ isFocused, isSelected })}>{children}</Text>\n\n {isSelected && (\n <Text {...styles.selectedIndicator()}>{figures.tick}</Text>\n )}\n </Box>\n )\n}\n"],
5
- "mappings": "AAAA,OAAO,aAAa;AACpB,SAAS,KAAK,YAAY;AAC1B,OAAO,WAA+B;AAEtC,SAAS,gBAAgB;AA6BlB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,WAAW,SAAS;AAC1B,QAAM,SAAS;AAAA,IACb,QAAQ,CAAC,EAAE,WAAAA,WAAU,OAA+B;AAAA,MAClD,aAAa;AAAA,MACb,cAAc;AAAA,IAChB;AAAA,IACA,gBAAgB,OAAO;AAAA,MACrB,OAAO,SAAS;AAAA,IAClB;AAAA,IACA,OAAO,CAAC,EAAE,WAAAA,YAAW,YAAAC,YAAW,OAAoD;AAAA,MAClF,OAAOA,cACH,SAAS,UACTD,aACE,SAAS,QACT,SAAS;AAAA,MACf,MAAMC;AAAA,IACR;AAAA,IACA,mBAAmB,OAAO;AAAA,MACxB,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAEA,SACE,oCAAC,OAAK,GAAG,OAAO,OAAO,EAAE,UAAU,CAAC,KACjC,aACC,oCAAC,QAAM,GAAG,OAAO,eAAe,KAC7B,eAAe,QAAQ,oBAAoB,QAAQ,OACtD,GAGF,oCAAC,QAAM,GAAG,OAAO,MAAM,EAAE,WAAW,WAAW,CAAC,KAAI,QAAS,GAE5D,cACC,oCAAC,QAAM,GAAG,OAAO,kBAAkB,KAAI,QAAQ,IAAK,CAExD;AAEJ;",
4
+ "sourcesContent": ["import figures from 'figures'\nimport { Box, Text } from 'ink'\nimport React, { type ReactNode } from 'react'\nimport { type Theme } from './theme'\nimport { getTheme } from '@utils/theme'\n\nexport type SelectOptionProps = {\n /**\n * Determines if option is focused.\n */\n readonly isFocused: boolean\n\n /**\n * Determines if option is selected.\n */\n readonly isSelected: boolean\n\n /**\n * Determines if pointer is shown when selected\n */\n readonly smallPointer?: boolean\n\n /**\n * Option label.\n */\n readonly children: ReactNode\n\n /**\n * React key prop (handled internally by React)\n */\n readonly key?: React.Key\n}\n\nexport function SelectOption({\n isFocused,\n isSelected,\n smallPointer,\n children,\n ...props\n}: SelectOptionProps) {\n const appTheme = getTheme()\n const styles = {\n option: ({ isFocused }: { isFocused: boolean }) => ({\n paddingLeft: 2,\n paddingRight: 1,\n }),\n focusIndicator: () => ({\n color: appTheme.minto,\n }),\n label: ({\n isFocused,\n isSelected,\n }: {\n isFocused: boolean\n isSelected: boolean\n }) => ({\n color: isSelected\n ? appTheme.success\n : isFocused\n ? appTheme.minto\n : appTheme.text,\n bold: isSelected,\n }),\n selectedIndicator: () => ({\n color: appTheme.success,\n }),\n }\n\n return (\n <Box {...styles.option({ isFocused })}>\n {isFocused && (\n <Text {...styles.focusIndicator()}>\n {smallPointer ? figures.triangleDownSmall : figures.pointer}\n </Text>\n )}\n\n <Text {...styles.label({ isFocused, isSelected })}>{children}</Text>\n\n {isSelected && (\n <Text {...styles.selectedIndicator()}>{figures.tick}</Text>\n )}\n </Box>\n )\n}\n"],
5
+ "mappings": "AAAA,OAAO,aAAa;AACpB,SAAS,KAAK,YAAY;AAC1B,OAAO,WAA+B;AAEtC,SAAS,gBAAgB;AA6BlB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,WAAW,SAAS;AAC1B,QAAM,SAAS;AAAA,IACb,QAAQ,CAAC,EAAE,WAAAA,WAAU,OAA+B;AAAA,MAClD,aAAa;AAAA,MACb,cAAc;AAAA,IAChB;AAAA,IACA,gBAAgB,OAAO;AAAA,MACrB,OAAO,SAAS;AAAA,IAClB;AAAA,IACA,OAAO,CAAC;AAAA,MACN,WAAAA;AAAA,MACA,YAAAC;AAAA,IACF,OAGO;AAAA,MACL,OAAOA,cACH,SAAS,UACTD,aACE,SAAS,QACT,SAAS;AAAA,MACf,MAAMC;AAAA,IACR;AAAA,IACA,mBAAmB,OAAO;AAAA,MACxB,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAEA,SACE,oCAAC,OAAK,GAAG,OAAO,OAAO,EAAE,UAAU,CAAC,KACjC,aACC,oCAAC,QAAM,GAAG,OAAO,eAAe,KAC7B,eAAe,QAAQ,oBAAoB,QAAQ,OACtD,GAGF,oCAAC,QAAM,GAAG,OAAO,MAAM,EAAE,WAAW,WAAW,CAAC,KAAI,QAAS,GAE5D,cACC,oCAAC,QAAM,GAAG,OAAO,kBAAkB,KAAI,QAAQ,IAAK,CAExD;AAEJ;",
6
6
  "names": ["isFocused", "isSelected"]
7
7
  }
@@ -19,13 +19,11 @@ function Help({
19
19
  ).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
20
20
  const customCommands = filteredCommands.filter(
21
21
  (cmd) => cmd.name.startsWith("project:") || cmd.name.startsWith("user:")
22
- ).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
23
- const pluginCommands = filteredCommands.filter(
24
- (cmd) => cmd.name.startsWith("plugin:")
25
- ).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
26
- const mcpCommands = filteredCommands.filter(
27
- (cmd) => cmd.name.startsWith("mcp:")
28
- ).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
22
+ ).sort(
23
+ (a, b) => a.userFacingName().localeCompare(b.userFacingName())
24
+ );
25
+ const pluginCommands = filteredCommands.filter((cmd) => cmd.name.startsWith("plugin:")).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
26
+ const mcpCommands = filteredCommands.filter((cmd) => cmd.name.startsWith("mcp:")).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
29
27
  const [count, setCount] = React.useState(0);
30
28
  React.useEffect(() => {
31
29
  const timer = setTimeout(() => {
@@ -36,7 +34,7 @@ function Help({
36
34
  return () => clearTimeout(timer);
37
35
  }, [count]);
38
36
  useInput((_, key) => {
39
- if (key.return) onClose();
37
+ if (key.return || key.escape) onClose();
40
38
  });
41
39
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `${PRODUCT_NAME} v${MACRO.VERSION}`), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, PRODUCT_NAME, " is a beta research preview. Always review", " ", PRODUCT_NAME, "'s responses, especially when running code.", " ", PRODUCT_NAME, " has read access to files in the current directory and can run commands and edit files with your permission.")), count >= 1 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Usage Modes:"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 REPL: ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND), " (interactive session)"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Non-interactive:", " ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND, ' -p "question"')), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Run ", /* @__PURE__ */ React.createElement(Text, { bold: true }, PRODUCT_COMMAND, " -h"), " for all command line options"))), count >= 2 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Common Tasks:"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Ask questions about your codebase", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> How does foo.py work?")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Edit files", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> Update bar.ts to...")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Fix errors", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> cargo build")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Run commands", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> /help")), /* @__PURE__ */ React.createElement(Text, null, "\u2022 Run bash commands", " ", /* @__PURE__ */ React.createElement(Text, { color: getTheme().secondaryText }, "> !ls"))), count >= 3 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Built-in Commands:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, builtInCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description)))), customCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Custom Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, customCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"), cmd.scope && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " [", cmd.scope, "]"))))), pluginCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Plugin Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, pluginCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), mcpCommands.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "MCP Commands:")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, mcpCommands.map((cmd, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, `/${cmd.name}`), /* @__PURE__ */ React.createElement(Text, null, " - ", cmd.description), cmd.aliases && cmd.aliases.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(aliases: ", cmd.aliases.join(", "), ")"))))), (hasCustomCommands() || customCommands.length > 0 || pluginCommands.length > 0 || mcpCommands.length > 0) && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Commands are loaded in priority order:"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "1. Built-in commands (highest priority, alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "2. Custom commands (user/project, alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "3. Plugin commands (alphabetically sorted)"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "4. MCP commands (alphabetically sorted)"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Use /refresh-commands to reload after changes")))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, moreHelp)), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(PressEnterToContinue, null)));
42
40
  }