@within-7/minto 0.3.6 → 0.3.10
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.
- package/{cli.js → cli.cjs} +25 -23
- package/dist/commands/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +110 -0
- package/dist/commands/language.js.map +7 -0
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/new.js +56 -0
- package/dist/commands/new.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +251 -16
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +7 -0
- package/dist/commands/setup.js +596 -109
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +292 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/status.js +75 -7
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +154 -180
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js +6 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/Config.js +9 -8
- package/dist/components/Config.js.map +2 -2
- package/dist/components/HeaderBar.js +2 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +166 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +46 -44
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/Logo.js +5 -2
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +6 -5
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +5 -4
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModelConfig.js +13 -12
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +77 -44
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +12 -8
- package/dist/components/SensitiveFileWarning.js.map +2 -2
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +117 -0
- package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
- package/dist/components/TabbedListView/SearchInput.js +23 -0
- package/dist/components/TabbedListView/SearchInput.js.map +7 -0
- package/dist/components/TabbedListView/TabBar.js +20 -0
- package/dist/components/TabbedListView/TabBar.js.map +7 -0
- package/dist/components/TabbedListView/TabbedListView.js +246 -0
- package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
- package/dist/components/TabbedListView/index.js +11 -0
- package/dist/components/TabbedListView/index.js.map +7 -0
- package/dist/components/TabbedListView/types.js +1 -0
- package/dist/components/TabbedListView/types.js.map +7 -0
- package/dist/components/TodoChangeBlock.js +6 -5
- package/dist/components/TodoChangeBlock.js.map +3 -3
- package/dist/components/TodoPanel.js +6 -3
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TrustDialog.js +6 -5
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
- package/dist/constants/macros.js +1 -1
- package/dist/constants/macros.js.map +1 -1
- package/dist/constants/product.js +2 -2
- package/dist/constants/product.js.map +1 -1
- package/dist/constants/prompts.js +17 -0
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/toolInputExamples.js +5 -1
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/tokenStatsManager.js +5 -0
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +56 -0
- package/dist/entrypoints/bootstrap.js.map +7 -0
- package/dist/entrypoints/cli.js +164 -23
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/history.js +75 -15
- package/dist/history.js.map +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/i18n/locales/en.js +582 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +582 -1
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/messages.js +11 -0
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +9 -0
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +45 -7
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/customCommands.js +44 -16
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +179 -1
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/prompt.js +21 -0
- package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +14 -9
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +12 -6
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/types/PermissionMode.js +30 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/plugin.js +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +103 -0
- package/dist/utils/agentHookExecutor.js.map +7 -0
- package/dist/utils/agentLoader.js +272 -32
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js +134 -0
- package/dist/utils/agentMemory.js.map +7 -0
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +52 -24
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configPaths.js +199 -0
- package/dist/utils/configPaths.js.map +7 -0
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/historyManager.js +234 -0
- package/dist/utils/historyManager.js.map +7 -0
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messages.js +13 -8
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/migration/index.js +37 -0
- package/dist/utils/migration/index.js.map +7 -0
- package/dist/utils/migration/migrateHistory.js +273 -0
- package/dist/utils/migration/migrateHistory.js.map +7 -0
- package/dist/utils/migration/migrateTodos.js +323 -0
- package/dist/utils/migration/migrateTodos.js.map +7 -0
- package/dist/utils/pasteCache.js +309 -0
- package/dist/utils/pasteCache.js.map +7 -0
- package/dist/utils/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +54 -28
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/sessionIndex.js +192 -0
- package/dist/utils/sessionIndex.js.map +7 -0
- package/dist/utils/sessionTracker.js +170 -0
- package/dist/utils/sessionTracker.js.map +7 -0
- package/dist/utils/skillLoader.js +103 -5
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stats.js +417 -0
- package/dist/utils/stats.js.map +7 -0
- package/dist/utils/stringSubstitution.js +106 -0
- package/dist/utils/stringSubstitution.js.map +7 -0
- package/dist/utils/teamConfig.js +156 -14
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/todoStorage.js +51 -19
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +71 -28
- package/scripts/{postinstall.js → postinstall.cjs} +1 -1
package/dist/commands.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/commands.ts"],
|
|
4
|
-
"sourcesContent": ["import React from 'react'\nimport clear from './commands/clear'\nimport compact from './commands/compact'\nimport config from './commands/config'\nimport context from './commands/context'\nimport cost from './commands/cost'\nimport ctx_viz from './commands/ctx_viz'\nimport exportCmd from './commands/export'\nimport help from './commands/help'\nimport init from './commands/init'\nimport mcp from './commands/mcp-interactive'\nimport model from './commands/model'\nimport permissions from './commands/permissions'\nimport refreshCommands from './commands/refreshCommands'\nimport sandbox from './commands/sandbox'\nimport setup from './commands/setup'\nimport status from './commands/status'\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 undo from './commands/undo'\nimport { quit } from './commands/quit'\n// Phase 4: Diagnostic and task management commands\nimport doctor from './commands/doctor'\nimport bug from './commands/bug'\nimport tasks from './commands/tasks'\nimport todos from './commands/todos'\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 bug,\n clear,\n compact,\n config,\n context,\n cost,\n doctor,\n exportCmd,\n help,\n init,\n mcp,\n model,\n permissions,\n plugin,\n quit,\n resume,\n sandbox,\n setup,\n status,\n tasks,\n todos,\n undo,\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,aAAa;AACpB,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,OAAO,eAAe;AACtB,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,SAAS;AAChB,OAAO,WAAW;AAClB,OAAO,iBAAiB;AACxB,OAAO,qBAAqB;AAC5B,OAAO,aAAa;AACpB,OAAO,WAAW;AAClB,OAAO,YAAY;AACnB,OAAO,mBAAmB;AAE1B,OAAO,YAAY;AACnB,OAAO,YAAY;AACnB,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,YAAY;
|
|
4
|
+
"sourcesContent": ["import React from 'react'\nimport clear from './commands/clear'\nimport compact from './commands/compact'\nimport config from './commands/config'\nimport context from './commands/context'\nimport cost from './commands/cost'\nimport ctx_viz from './commands/ctx_viz'\nimport exportCmd from './commands/export'\nimport help from './commands/help'\nimport init from './commands/init'\nimport mcp from './commands/mcp-interactive'\nimport model from './commands/model'\nimport permissions from './commands/permissions'\nimport refreshCommands from './commands/refreshCommands'\nimport sandbox from './commands/sandbox'\nimport setup from './commands/setup'\nimport status from './commands/status'\nimport terminalSetup from './commands/terminalSetup'\nimport { Tool, ToolUseContext } from './Tool'\nimport resume from './commands/resume'\nimport newCmd from './commands/new'\nimport agents from './commands/agents'\nimport plugin from './commands/plugin'\nimport undo from './commands/undo'\nimport language from './commands/language'\nimport { quit } from './commands/quit'\nimport stats from './commands/stats'\n// Phase 4: Diagnostic and task management commands\nimport doctor from './commands/doctor'\nimport bug from './commands/bug'\nimport tasks from './commands/tasks'\nimport todos from './commands/todos'\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 /** Unmount current REPL (for commands that need to replace the entire UI) */\n unmount?: () => void\n },\n args?: string,\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 /** When true, the command's JSX replaces the PromptInput instead of rendering below it */\n hidePromptInput?: boolean\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 bug,\n clear,\n compact,\n config,\n context,\n cost,\n doctor,\n exportCmd,\n help,\n init,\n language,\n mcp,\n model,\n newCmd,\n permissions,\n plugin,\n quit,\n resume,\n sandbox,\n setup,\n stats,\n status,\n tasks,\n todos,\n undo,\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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -6,6 +6,7 @@ import { useNotifyAfterTimeout } from "../../hooks/useNotifyAfterTimeout.js";
|
|
|
6
6
|
import { PRODUCT_NAME } from "../../constants/product.js";
|
|
7
7
|
import TextInput from "ink-text-input";
|
|
8
8
|
import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../../constants/colors.js";
|
|
9
|
+
import { t } from "../../i18n/index.js";
|
|
9
10
|
function AskUserQuestionDialog({
|
|
10
11
|
context,
|
|
11
12
|
onDone
|
|
@@ -114,14 +115,14 @@ function AskUserQuestionDialog({
|
|
|
114
115
|
resolve
|
|
115
116
|
]
|
|
116
117
|
);
|
|
117
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingY: 1 }, isCustomInputMode ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 2 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "
|
|
118
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingY: 1 }, isCustomInputMode ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 2 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, t("dialog.enterCustomResponse"))), /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: BRAND_GRADIENT.START }, "> "), /* @__PURE__ */ React.createElement(
|
|
118
119
|
TextInput,
|
|
119
120
|
{
|
|
120
121
|
value: customInput,
|
|
121
122
|
onChange: setCustomInput,
|
|
122
123
|
onSubmit: handleConfirm
|
|
123
124
|
}
|
|
124
|
-
)), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "
|
|
125
|
+
)), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, t("dialog.confirmCancelPrompt")))) : (
|
|
125
126
|
/* Normal question view */
|
|
126
127
|
/* @__PURE__ */ React.createElement(
|
|
127
128
|
QuestionView,
|
|
@@ -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 {\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'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\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>
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,UAAU,mBAAmB;AAKtC,SAAS,oBAAoB;AAC7B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,OAAO,eAAe;AACtB,SAAS,gBAAgB,uBAAuB;
|
|
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'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport { t } from '@i18n'\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>{t('dialog.enterCustomResponse')}</Text>\n </Box>\n <Box marginBottom={1}>\n <Text color={BRAND_GRADIENT.START}>> </Text>\n <TextInput\n value={customInput}\n onChange={setCustomInput}\n onSubmit={handleConfirm}\n />\n </Box>\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>\n {t('dialog.confirmCancelPrompt')}\n </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
|
}
|
|
@@ -8,6 +8,7 @@ import { useExitOnCtrlCD } from "../hooks/useExitOnCtrlCD.js";
|
|
|
8
8
|
import { getModelManager } from "../utils/model.js";
|
|
9
9
|
import { getCompressionMode, setCompressionMode } from "../utils/compressionMode.js";
|
|
10
10
|
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
11
|
+
import { t } from "../i18n/index.js";
|
|
11
12
|
function Config({ onClose }) {
|
|
12
13
|
const [globalConfig, setGlobalConfig] = useState(getGlobalConfig());
|
|
13
14
|
const initialConfig = React.useRef(getGlobalConfig());
|
|
@@ -22,7 +23,7 @@ function Config({ onClose }) {
|
|
|
22
23
|
// Global settings
|
|
23
24
|
{
|
|
24
25
|
id: "theme",
|
|
25
|
-
label: "
|
|
26
|
+
label: t("config.theme"),
|
|
26
27
|
value: globalConfig.theme ?? "dark",
|
|
27
28
|
options: ["dark", "light"],
|
|
28
29
|
onChange(theme2) {
|
|
@@ -34,7 +35,7 @@ function Config({ onClose }) {
|
|
|
34
35
|
},
|
|
35
36
|
{
|
|
36
37
|
id: "verbose",
|
|
37
|
-
label: "
|
|
38
|
+
label: t("config.verboseMode"),
|
|
38
39
|
value: globalConfig.verbose ?? false,
|
|
39
40
|
onChange(verbose) {
|
|
40
41
|
const config = { ...getGlobalConfig(), verbose };
|
|
@@ -45,7 +46,7 @@ function Config({ onClose }) {
|
|
|
45
46
|
},
|
|
46
47
|
{
|
|
47
48
|
id: "stream",
|
|
48
|
-
label: "
|
|
49
|
+
label: t("config.streamResponses"),
|
|
49
50
|
value: globalConfig.stream ?? true,
|
|
50
51
|
onChange(stream) {
|
|
51
52
|
const config = { ...getGlobalConfig(), stream };
|
|
@@ -56,7 +57,7 @@ function Config({ onClose }) {
|
|
|
56
57
|
},
|
|
57
58
|
{
|
|
58
59
|
id: "compressionMode",
|
|
59
|
-
label: "
|
|
60
|
+
label: t("config.compressionMode"),
|
|
60
61
|
value: getCompressionMode(),
|
|
61
62
|
options: ["business", "code"],
|
|
62
63
|
onChange(mode) {
|
|
@@ -154,8 +155,8 @@ function Config({ onClose }) {
|
|
|
154
155
|
paddingY: 1,
|
|
155
156
|
gap: 1
|
|
156
157
|
},
|
|
157
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "
|
|
158
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, "
|
|
158
|
+
/* @__PURE__ */ React.createElement(Text, { bold: true }, t("config.title"), " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
159
|
+
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, t("config.modelConfiguration")), activeProfiles.length === 0 ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, t("config.noModelsConfigured")) : /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, activeProfiles.map((profile) => /* @__PURE__ */ React.createElement(React.Fragment, { key: profile.modelName }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "\u2022 ", profile.name, " (", profile.provider, ")"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, t("config.useModelCommand"))))),
|
|
159
160
|
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, settings.map((setting, index) => /* @__PURE__ */ React.createElement(Box, { key: setting.id, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
160
161
|
Text,
|
|
161
162
|
{
|
|
@@ -170,8 +171,8 @@ function Config({ onClose }) {
|
|
|
170
171
|
color: setting.disabled ? theme.secondaryText : theme.suggestion
|
|
171
172
|
},
|
|
172
173
|
setting.type === "boolean" ? setting.value ? "enabled" : "disabled" : setting.type === "enum" ? setting.value : String(setting.value)
|
|
173
|
-
)), index === selectedIndex && editingString && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "
|
|
174
|
-
/* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, editingString ? "
|
|
174
|
+
)), index === selectedIndex && editingString && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, t("config.enterNewValue"), " ", currentInput), inputError && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, inputError))))),
|
|
175
|
+
/* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, editingString ? t("config.enterToSaveEscToCancel") : /* @__PURE__ */ React.createElement(React.Fragment, null, t("config.navigateChangeClose"), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, " ", "\xB7 ", t("config.useModelCommand")))))
|
|
175
176
|
));
|
|
176
177
|
}
|
|
177
178
|
export {
|
|
@@ -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 { 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'\nimport { SEMANTIC_COLORS } from '@constants/colors'\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: '
|
|
5
|
-
"mappings": "AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,YAAY,WAAW;AACvB,SAAS,gBAAgB;AACzB,OAAO,aAAa;AACpB,SAAS,gBAAgB;AACzB,SAAuB,kBAAkB,uBAAuB;AAEhE,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,oBAAoB,0BAA0B;AAEvD,SAAS,uBAAuB;
|
|
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'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { t } from '@i18n'\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: t('config.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: t('config.verboseMode'),\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: t('config.streamResponses'),\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: t('config.compressionMode'),\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 {t('config.title')}{' '}\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 {t('config.modelConfiguration')}\n </Text>\n {activeProfiles.length === 0 ? (\n <Text color={theme.secondaryText}>\n {t('config.noModelsConfigured')}\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 {t('config.useModelCommand')}\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 {t('config.enterNewValue')} {currentInput}\n </Text>\n {inputError && (\n <Text color={SEMANTIC_COLORS.error}>{inputError}</Text>\n )}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n {editingString ? (\n t('config.enterToSaveEscToCancel')\n ) : (\n <>\n {t('config.navigateChangeClose')}\n <Text color={theme.suggestion}>\n {' '}\n \u00B7 {t('config.useModelCommand')}\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
|
}
|
|
@@ -4,6 +4,7 @@ import { getTheme } from "../utils/theme.js";
|
|
|
4
4
|
import { getCwd } from "../utils/state.js";
|
|
5
5
|
import { getModelManager } from "../utils/model.js";
|
|
6
6
|
import { BRAND_GRADIENT, SEMANTIC_COLORS } from "../constants/colors.js";
|
|
7
|
+
import { t } from "../i18n/index.js";
|
|
7
8
|
function HeaderBar({
|
|
8
9
|
tokenUsage = 0,
|
|
9
10
|
mcpClients = [],
|
|
@@ -16,7 +17,7 @@ function HeaderBar({
|
|
|
16
17
|
const contextPercentage = currentModel ? Math.round(tokenUsage / currentModel.contextLength * 100) : 0;
|
|
17
18
|
const formatTokens = (tokens) => `${Math.round(tokens / 1e3)}k`;
|
|
18
19
|
const getDisplayModelName = (modelName) => {
|
|
19
|
-
if (!modelName) return "
|
|
20
|
+
if (!modelName) return t("ui.model.fallbackName");
|
|
20
21
|
const simplified = modelName.replace(/^(claude-|gpt-|glm-)/, "").replace(/-\d+.*$/, "").replace(/-latest$/, "");
|
|
21
22
|
return simplified.charAt(0).toUpperCase() + simplified.slice(1);
|
|
22
23
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/HeaderBar.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * HeaderBar - Minto \u54C1\u724C\u9875\u7709\u7EC4\u4EF6\n *\n * \u8BBE\u8BA1\u539F\u5219\uFF1A\n * 1. **\u54C1\u724C\u8BC6\u522B** - \u7D2B\u84DD\u2192\u73CA\u745A\u6E10\u53D8\uFF0C\u4F20\u9012\u4E13\u4E1A\u4E0E\u70ED\u60C5\n * 2. **\u4FE1\u606F\u6E05\u6670** - \u663E\u793A\u5173\u952E\u4FE1\u606F\uFF08\u9879\u76EE\u4F4D\u7F6E\u3001AI \u6A21\u578B\u3001\u4F7F\u7528\u91CF\uFF09\n * 3. **\u5546\u52A1\u53CB\u597D** - \u6E29\u6696\u3001\u4E13\u4E1A\u3001\u6613\u4E8E\u7406\u89E3\n * 4. **\u89C6\u89C9\u7CBE\u7B80** - \u4E0D\u5360\u7528\u8FC7\u591A\u5782\u76F4\u7A7A\u95F4\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { getCwd } from '@utils/state'\nimport { getModelManager } from '@utils/model'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport type { WrappedClient } from '@services/mcpClient'\n\ninterface Props {\n /** \u5F53\u524D Token \u4F7F\u7528\u91CF */\n tokenUsage?: number\n\n /** MCP \u5BA2\u6237\u7AEF (\u53EF\u9009) */\n mcpClients?: WrappedClient[]\n\n /** \u662F\u5426\u662F\u9ED8\u8BA4\u6A21\u578B */\n isDefaultModel?: boolean\n}\n\n/**\n * HeaderBar - \u54C1\u724C\u9875\u7709\u72B6\u6001\u680F\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\n * \u2502 \u25C6 Minto \u00B7 /path/to/project AI Model \u00B7 50k/200k\u2502\n * \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n * ```\n */\nexport function HeaderBar({\n tokenUsage = 0,\n mcpClients = [],\n isDefaultModel = true,\n}: Props): React.ReactNode {\n const theme = getTheme()\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n // \u8BA1\u7B97\u4E0A\u4E0B\u6587\u4F7F\u7528\u767E\u5206\u6BD4\n const contextPercentage = currentModel\n ? Math.round((tokenUsage / currentModel.contextLength) * 100)\n : 0\n\n // \u683C\u5F0F\u5316 Token \u6570\u91CF (k \u4E3A\u5355\u4F4D)\n const formatTokens = (tokens: number) => `${Math.round(tokens / 1000)}k`\n\n // \
|
|
5
|
-
"mappings": "AAUA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAC1B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB,uBAAuB;
|
|
4
|
+
"sourcesContent": ["/**\n * HeaderBar - Minto \u54C1\u724C\u9875\u7709\u7EC4\u4EF6\n *\n * \u8BBE\u8BA1\u539F\u5219\uFF1A\n * 1. **\u54C1\u724C\u8BC6\u522B** - \u7D2B\u84DD\u2192\u73CA\u745A\u6E10\u53D8\uFF0C\u4F20\u9012\u4E13\u4E1A\u4E0E\u70ED\u60C5\n * 2. **\u4FE1\u606F\u6E05\u6670** - \u663E\u793A\u5173\u952E\u4FE1\u606F\uFF08\u9879\u76EE\u4F4D\u7F6E\u3001AI \u6A21\u578B\u3001\u4F7F\u7528\u91CF\uFF09\n * 3. **\u5546\u52A1\u53CB\u597D** - \u6E29\u6696\u3001\u4E13\u4E1A\u3001\u6613\u4E8E\u7406\u89E3\n * 4. **\u89C6\u89C9\u7CBE\u7B80** - \u4E0D\u5360\u7528\u8FC7\u591A\u5782\u76F4\u7A7A\u95F4\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport { getTheme } from '@utils/theme'\nimport { getCwd } from '@utils/state'\nimport { getModelManager } from '@utils/model'\nimport { BRAND_GRADIENT, SEMANTIC_COLORS } from '@constants/colors'\nimport type { WrappedClient } from '@services/mcpClient'\nimport { t } from '@i18n'\n\ninterface Props {\n /** \u5F53\u524D Token \u4F7F\u7528\u91CF */\n tokenUsage?: number\n\n /** MCP \u5BA2\u6237\u7AEF (\u53EF\u9009) */\n mcpClients?: WrappedClient[]\n\n /** \u662F\u5426\u662F\u9ED8\u8BA4\u6A21\u578B */\n isDefaultModel?: boolean\n}\n\n/**\n * HeaderBar - \u54C1\u724C\u9875\u7709\u72B6\u6001\u680F\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\n * \u2502 \u25C6 Minto \u00B7 /path/to/project AI Model \u00B7 50k/200k\u2502\n * \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n * ```\n */\nexport function HeaderBar({\n tokenUsage = 0,\n mcpClients = [],\n isDefaultModel = true,\n}: Props): React.ReactNode {\n const theme = getTheme()\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n // \u8BA1\u7B97\u4E0A\u4E0B\u6587\u4F7F\u7528\u767E\u5206\u6BD4\n const contextPercentage = currentModel\n ? Math.round((tokenUsage / currentModel.contextLength) * 100)\n : 0\n\n // \u683C\u5F0F\u5316 Token \u6570\u91CF (k \u4E3A\u5355\u4F4D)\n const formatTokens = (tokens: number) => `${Math.round(tokens / 1000)}k`\n\n // Get simplified model display name (more friendly for non-technical users)\n const getDisplayModelName = (modelName: string | undefined) => {\n if (!modelName) return t('ui.model.fallbackName')\n // Extract model short name, remove version numbers and technical details\n const simplified = modelName\n .replace(/^(claude-|gpt-|glm-)/, '')\n .replace(/-\\d+.*$/, '')\n .replace(/-latest$/, '')\n return simplified.charAt(0).toUpperCase() + simplified.slice(1)\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderColor={BRAND_GRADIENT.START}\n borderStyle=\"round\"\n paddingX={1}\n marginBottom={1}\n >\n {/* \u4E3B\u4FE1\u606F\u884C */}\n <Box flexDirection=\"row\" justifyContent=\"space-between\">\n {/* \u5DE6\u4FA7\uFF1A\u54C1\u724C\u6807\u8BC6 + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* \u53F3\u4FA7\uFF1AAI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n <Box flexDirection=\"row\">\n <Text color={SEMANTIC_COLORS.dim}>\n {getDisplayModelName(currentModel?.modelName)}\n </Text>\n {currentModel && (\n <>\n <Text color={SEMANTIC_COLORS.muted}> \u00B7 </Text>\n <Text\n color={\n contextPercentage > 80\n ? SEMANTIC_COLORS.error\n : contextPercentage > 60\n ? SEMANTIC_COLORS.running\n : SEMANTIC_COLORS.muted\n }\n >\n {formatTokens(tokenUsage)}/\n {formatTokens(currentModel.contextLength)}\n </Text>\n </>\n )}\n </Box>\n </Box>\n\n {/* \u6269\u5C55\u670D\u52A1\u72B6\u6001 (\u5982\u679C\u6709) */}\n {mcpClients.length > 0 && (\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={SEMANTIC_COLORS.muted}>MCP: </Text>\n {mcpClients.map((client, idx) => (\n <React.Fragment key={idx}>\n <Text\n color={\n client.type === 'connected'\n ? SEMANTIC_COLORS.success\n : SEMANTIC_COLORS.error\n }\n >\n {client.name}\n </Text>\n {idx < mcpClients.length - 1 && (\n <Text color={SEMANTIC_COLORS.muted}>, </Text>\n )}\n </React.Fragment>\n ))}\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * \u6781\u7B80\u7248\u9875\u7709 (\u53EA\u663E\u793A\u57FA\u672C\u4FE1\u606F)\n */\nexport function MinimalHeaderBar({\n tokenUsage = 0,\n}: {\n tokenUsage?: number\n}): React.ReactNode {\n const modelManager = getModelManager()\n const currentModel = modelManager.getModel('main')\n const cwd = getCwd()\n\n return (\n <Box flexDirection=\"row\" justifyContent=\"space-between\" paddingX={2}>\n {/* \u54C1\u724C + \u9879\u76EE\u4F4D\u7F6E */}\n <Box flexDirection=\"row\">\n <Text color={BRAND_GRADIENT.START}>\u25C6</Text>\n <Text> </Text>\n <Text color={BRAND_GRADIENT.START} bold>\n Min\n </Text>\n <Text color={BRAND_GRADIENT.END} bold>\n to\n </Text>\n <Text color={SEMANTIC_COLORS.dim}> \u00B7 </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{cwd}</Text>\n </Box>\n\n {/* AI \u6A21\u578B + \u4F7F\u7528\u91CF */}\n {currentModel && (\n <Text color={SEMANTIC_COLORS.dim}>\n {Math.round(tokenUsage / 1000)}k/\n {Math.round(currentModel.contextLength / 1000)}k\n </Text>\n )}\n </Box>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAUA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAC1B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB,uBAAuB;AAEhD,SAAS,SAAS;AAuBX,SAAS,UAAU;AAAA,EACxB,aAAa;AAAA,EACb,aAAa,CAAC;AAAA,EACd,iBAAiB;AACnB,GAA2B;AACzB,QAAM,QAAQ,SAAS;AACvB,QAAM,eAAe,gBAAgB;AACrC,QAAM,eAAe,aAAa,SAAS,MAAM;AACjD,QAAM,MAAM,OAAO;AAGnB,QAAM,oBAAoB,eACtB,KAAK,MAAO,aAAa,aAAa,gBAAiB,GAAG,IAC1D;AAGJ,QAAM,eAAe,CAAC,WAAmB,GAAG,KAAK,MAAM,SAAS,GAAI,CAAC;AAGrE,QAAM,sBAAsB,CAAC,cAAkC;AAC7D,QAAI,CAAC,UAAW,QAAO,EAAE,uBAAuB;AAEhD,UAAM,aAAa,UAChB,QAAQ,wBAAwB,EAAE,EAClC,QAAQ,WAAW,EAAE,EACrB,QAAQ,YAAY,EAAE;AACzB,WAAO,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AAAA,EAChE;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,aAAa,eAAe;AAAA,MAC5B,aAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA;AAAA,IAGd,oCAAC,OAAI,eAAc,OAAM,gBAAe,mBAEtC,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAO,eAAe,SAAO,QAAC,GACpC,oCAAC,YAAK,GAAC,GACP,oCAAC,QAAK,OAAO,eAAe,OAAO,MAAI,QAAC,KAExC,GACA,oCAAC,QAAK,OAAO,eAAe,KAAK,MAAI,QAAC,IAEtC,GACA,oCAAC,QAAK,OAAO,gBAAgB,OAAK,QAAG,GACrC,oCAAC,QAAK,OAAO,gBAAgB,aAAY,GAAI,CAC/C,GAGA,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,oBAAoB,cAAc,SAAS,CAC9C,GACC,gBACC,0DACE,oCAAC,QAAK,OAAO,gBAAgB,SAAO,QAAG,GACvC;AAAA,MAAC;AAAA;AAAA,QACC,OACE,oBAAoB,KAChB,gBAAgB,QAChB,oBAAoB,KAClB,gBAAgB,UAChB,gBAAgB;AAAA;AAAA,MAGvB,aAAa,UAAU;AAAA,MAAE;AAAA,MACzB,aAAa,aAAa,aAAa;AAAA,IAC1C,CACF,CAEJ,CACF;AAAA,IAGC,WAAW,SAAS,KACnB,oCAAC,OAAI,eAAc,OAAM,WAAW,KAClC,oCAAC,QAAK,OAAO,gBAAgB,SAAO,OAAK,GACxC,WAAW,IAAI,CAAC,QAAQ,QACvB,oCAAC,MAAM,UAAN,EAAe,KAAK,OACnB;AAAA,MAAC;AAAA;AAAA,QACC,OACE,OAAO,SAAS,cACZ,gBAAgB,UAChB,gBAAgB;AAAA;AAAA,MAGrB,OAAO;AAAA,IACV,GACC,MAAM,WAAW,SAAS,KACzB,oCAAC,QAAK,OAAO,gBAAgB,SAAO,IAAE,CAE1C,CACD,CACH;AAAA,EAEJ;AAEJ;AAKO,SAAS,iBAAiB;AAAA,EAC/B,aAAa;AACf,GAEoB;AAClB,QAAM,eAAe,gBAAgB;AACrC,QAAM,eAAe,aAAa,SAAS,MAAM;AACjD,QAAM,MAAM,OAAO;AAEnB,SACE,oCAAC,OAAI,eAAc,OAAM,gBAAe,iBAAgB,UAAU,KAEhE,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAO,eAAe,SAAO,QAAC,GACpC,oCAAC,YAAK,GAAC,GACP,oCAAC,QAAK,OAAO,eAAe,OAAO,MAAI,QAAC,KAExC,GACA,oCAAC,QAAK,OAAO,eAAe,KAAK,MAAI,QAAC,IAEtC,GACA,oCAAC,QAAK,OAAO,gBAAgB,OAAK,QAAG,GACrC,oCAAC,QAAK,OAAO,gBAAgB,aAAY,GAAI,CAC/C,GAGC,gBACC,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,KAAK,MAAM,aAAa,GAAI,GAAE,MAC9B,KAAK,MAAM,aAAa,gBAAgB,GAAI,GAAE,GACjD,CAEJ;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/components/Help.js
CHANGED
|
@@ -1,42 +1,176 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { hasCustomCommands } from "../services/customCommands.js";
|
|
1
3
|
import { PRODUCT_COMMAND, PRODUCT_NAME } from "../constants/product.js";
|
|
2
|
-
import {
|
|
3
|
-
hasCustomCommands
|
|
4
|
-
} from "../services/customCommands.js";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
import { Box, Text, useInput } from "ink";
|
|
7
|
-
import { getTheme } from "../utils/theme.js";
|
|
8
|
-
import { PressEnterToContinue } from "./PressEnterToContinue.js";
|
|
9
4
|
import { MACRO } from "../constants/macros.js";
|
|
5
|
+
import { SEMANTIC_COLORS } from "../constants/colors.js";
|
|
6
|
+
import { InfoPanel } from "./InfoPanel/index.js";
|
|
7
|
+
import { t } from "../i18n/index.js";
|
|
8
|
+
function buildUsageSection() {
|
|
9
|
+
return {
|
|
10
|
+
title: t("help.usageModes"),
|
|
11
|
+
items: [
|
|
12
|
+
{ label: "REPL", value: `${PRODUCT_COMMAND} (interactive session)` },
|
|
13
|
+
{
|
|
14
|
+
label: t("help.nonInteractive"),
|
|
15
|
+
value: `${PRODUCT_COMMAND} -p "question"`
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: t("help.options"),
|
|
19
|
+
value: t("help.runForOptions", { command: PRODUCT_COMMAND }),
|
|
20
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function buildCommonTasksSection() {
|
|
26
|
+
return {
|
|
27
|
+
title: t("help.commonTasks"),
|
|
28
|
+
items: [
|
|
29
|
+
{
|
|
30
|
+
label: "\u2022 Ask questions",
|
|
31
|
+
value: "How does foo.py work?",
|
|
32
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: "\u2022 Edit files",
|
|
36
|
+
value: "Update bar.ts to...",
|
|
37
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "\u2022 Fix errors",
|
|
41
|
+
value: "cargo build",
|
|
42
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
label: "\u2022 Run commands",
|
|
46
|
+
value: "/help",
|
|
47
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: "\u2022 Run bash",
|
|
51
|
+
value: "!ls",
|
|
52
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function buildModeSystemsSection() {
|
|
58
|
+
return {
|
|
59
|
+
title: t("help.modeSystems"),
|
|
60
|
+
items: [
|
|
61
|
+
{
|
|
62
|
+
label: "",
|
|
63
|
+
value: t("help.safetyModes"),
|
|
64
|
+
valueColor: SEMANTIC_COLORS.secondary
|
|
65
|
+
},
|
|
66
|
+
{ label: " --yolo", value: "Skip all confirmations" },
|
|
67
|
+
{ label: " --smart", value: "Dangerous tools require confirmation" },
|
|
68
|
+
{ label: " --strict", value: "All tools require confirmation" },
|
|
69
|
+
{ label: " --free", value: "Free mode (no restrictions)" },
|
|
70
|
+
{
|
|
71
|
+
label: "",
|
|
72
|
+
value: t("help.permissionModes"),
|
|
73
|
+
valueColor: SEMANTIC_COLORS.secondary
|
|
74
|
+
},
|
|
75
|
+
{ label: " default", value: "Standard confirmation flow" },
|
|
76
|
+
{ label: " acceptEdits", value: "Auto-approve file edits" },
|
|
77
|
+
{ label: " plan", value: "Plan mode (no modifications)" },
|
|
78
|
+
{ label: " bypass", value: "Skip all permission checks" }
|
|
79
|
+
]
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function buildBuiltInSection(commands) {
|
|
83
|
+
const builtInCommands = commands.filter(
|
|
84
|
+
(cmd) => !cmd.isHidden && !cmd.name.startsWith("project:") && !cmd.name.startsWith("user:") && !cmd.name.startsWith("plugin:") && !cmd.name.startsWith("mcp:")
|
|
85
|
+
).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
|
|
86
|
+
const items = builtInCommands.map((cmd) => ({
|
|
87
|
+
label: `/${cmd.name}`,
|
|
88
|
+
value: cmd.description
|
|
89
|
+
}));
|
|
90
|
+
return { title: t("help.builtInCommands"), items };
|
|
91
|
+
}
|
|
92
|
+
function buildCustomSection(commands) {
|
|
93
|
+
const customCommands = commands.filter(
|
|
94
|
+
(cmd) => !cmd.isHidden && (cmd.name.startsWith("project:") || cmd.name.startsWith("user:"))
|
|
95
|
+
).sort(
|
|
96
|
+
(a, b) => a.userFacingName().localeCompare(b.userFacingName())
|
|
97
|
+
);
|
|
98
|
+
if (customCommands.length === 0) return null;
|
|
99
|
+
const items = customCommands.map((cmd) => ({
|
|
100
|
+
label: `/${cmd.name}`,
|
|
101
|
+
value: `${cmd.description}${cmd.scope ? ` [${cmd.scope}]` : ""}`
|
|
102
|
+
}));
|
|
103
|
+
return { title: t("help.customCommands"), items };
|
|
104
|
+
}
|
|
105
|
+
function buildPluginSection(commands) {
|
|
106
|
+
const pluginCommands = commands.filter((cmd) => !cmd.isHidden && cmd.name.startsWith("plugin:")).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
|
|
107
|
+
if (pluginCommands.length === 0) return null;
|
|
108
|
+
const items = pluginCommands.map((cmd) => ({
|
|
109
|
+
label: `/${cmd.name}`,
|
|
110
|
+
value: cmd.description
|
|
111
|
+
}));
|
|
112
|
+
return { title: t("help.pluginCommands"), items };
|
|
113
|
+
}
|
|
114
|
+
function buildMcpSection(commands) {
|
|
115
|
+
const mcpCommands = commands.filter((cmd) => !cmd.isHidden && cmd.name.startsWith("mcp:")).sort((a, b) => a.userFacingName().localeCompare(b.userFacingName()));
|
|
116
|
+
if (mcpCommands.length === 0) return null;
|
|
117
|
+
const items = mcpCommands.map((cmd) => ({
|
|
118
|
+
label: `/${cmd.name}`,
|
|
119
|
+
value: cmd.description
|
|
120
|
+
}));
|
|
121
|
+
return { title: t("help.mcpCommands"), items };
|
|
122
|
+
}
|
|
123
|
+
function buildPrioritySection() {
|
|
124
|
+
return {
|
|
125
|
+
title: t("help.commandPriority"),
|
|
126
|
+
items: [
|
|
127
|
+
{
|
|
128
|
+
label: "1.",
|
|
129
|
+
value: "Built-in commands",
|
|
130
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
label: "2.",
|
|
134
|
+
value: "Custom commands (project: / user:)",
|
|
135
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
label: "3.",
|
|
139
|
+
value: "Plugin commands",
|
|
140
|
+
valueColor: SEMANTIC_COLORS.dim
|
|
141
|
+
},
|
|
142
|
+
{ label: "4.", value: "MCP commands", valueColor: SEMANTIC_COLORS.dim }
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
}
|
|
10
146
|
function Help({
|
|
11
147
|
commands,
|
|
12
148
|
onClose
|
|
13
149
|
}) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
).
|
|
23
|
-
|
|
150
|
+
const sections = [];
|
|
151
|
+
sections.push(buildUsageSection());
|
|
152
|
+
sections.push(buildCommonTasksSection());
|
|
153
|
+
sections.push(buildModeSystemsSection());
|
|
154
|
+
sections.push(buildBuiltInSection(commands));
|
|
155
|
+
const customSection = buildCustomSection(commands);
|
|
156
|
+
if (customSection) sections.push(customSection);
|
|
157
|
+
const pluginSection = buildPluginSection(commands);
|
|
158
|
+
if (pluginSection) sections.push(pluginSection);
|
|
159
|
+
const mcpSection = buildMcpSection(commands);
|
|
160
|
+
if (mcpSection) sections.push(mcpSection);
|
|
161
|
+
const hasExtended = hasCustomCommands() || customSection || pluginSection || mcpSection;
|
|
162
|
+
if (hasExtended) {
|
|
163
|
+
sections.push(buildPrioritySection());
|
|
164
|
+
}
|
|
165
|
+
return /* @__PURE__ */ React.createElement(
|
|
166
|
+
InfoPanel,
|
|
167
|
+
{
|
|
168
|
+
title: t("commands.help.title"),
|
|
169
|
+
subtitle: `${PRODUCT_NAME} v${MACRO.VERSION}`,
|
|
170
|
+
sections,
|
|
171
|
+
onClose
|
|
172
|
+
}
|
|
24
173
|
);
|
|
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()));
|
|
27
|
-
const [count, setCount] = React.useState(0);
|
|
28
|
-
React.useEffect(() => {
|
|
29
|
-
const timer = setTimeout(() => {
|
|
30
|
-
if (count < 3) {
|
|
31
|
-
setCount(count + 1);
|
|
32
|
-
}
|
|
33
|
-
}, 250);
|
|
34
|
-
return () => clearTimeout(timer);
|
|
35
|
-
}, [count]);
|
|
36
|
-
useInput((_, key) => {
|
|
37
|
-
if (key.return || key.escape) onClose();
|
|
38
|
-
});
|
|
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)));
|
|
40
174
|
}
|
|
41
175
|
export {
|
|
42
176
|
Help
|