@within-7/minto 0.3.10 → 0.4.1
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/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +2 -2
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +19 -9
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/mcp-interactive.js +14 -8
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +45 -2
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +10 -1
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +8 -0
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +250 -143
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/PromptInput.js +21 -6
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +1 -1
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +2 -2
- package/dist/core/backupHook.js.map +2 -2
- package/dist/core/config/defaults.js +4 -1
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +7 -1
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -0
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/entrypoints/cli.js +65 -84
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +8 -9
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +8 -9
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +4 -1
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +350 -3
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +1 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +3 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +1 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +1 -1
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +75 -5
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +1 -1
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentLoader.js +25 -3
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/config.js +26 -128
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +34 -5
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +201 -32
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +59 -6
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +9 -3
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
package/dist/i18n/types.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/i18n/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * i18n Type Definitions\n *\n * Type-safe internationalization system for Minto CLI.\n */\n\n/**\n * Supported languages\n */\nexport type Language = 'en' | 'zh-CN'\n\n/**\n * Language display names\n */\nexport const LANGUAGE_NAMES: Record<Language, string> = {\n en: 'English',\n 'zh-CN': '\u7B80\u4F53\u4E2D\u6587',\n}\n\n/**\n * Translation namespace keys\n */\nexport type TranslationNamespace =\n | 'common'\n | 'ui'\n | 'commands'\n | 'tools'\n | 'errors'\n | 'help'\n | 'status'\n | 'prompts'\n\n/**\n * Translation key structure for type safety\n */\nexport interface TranslationKeys {\n // Common\n 'common.yes': string\n 'common.no': string\n 'common.ok': string\n 'common.cancel': string\n 'common.confirm': string\n 'common.save': string\n 'common.delete': string\n 'common.edit': string\n 'common.create': string\n 'common.loading': string\n 'common.error': string\n 'common.success': string\n 'common.warning': string\n 'common.info': string\n 'common.unknown': string\n 'common.none': string\n 'common.all': string\n 'common.selected': string\n 'common.default': string\n 'common.custom': string\n 'common.enabled': string\n 'common.disabled': string\n 'common.connected': string\n 'common.disconnected': string\n 'common.pending': string\n 'common.completed': string\n 'common.failed': string\n 'common.inProgress': string\n 'common.version': string\n 'common.help': string\n 'common.quit': string\n 'common.back': string\n 'common.next': string\n 'common.previous': string\n 'common.search': string\n 'common.filter': string\n 'common.sort': string\n 'common.refresh': string\n 'common.retry': string\n 'common.skip': string\n 'common.continue': string\n 'common.abort': string\n 'common.reset': string\n 'common.clear': string\n 'common.copy': string\n 'common.paste': string\n 'common.select': string\n 'common.deselect': string\n 'common.selectAll': string\n 'common.deselectAll': string\n\n // UI - Verbose mode\n 'ui.verbose.on': string\n 'ui.verbose.off': string\n 'ui.verbose.label': string\n 'ui.verbose.hint': string\n // Deprecated - kept for backward compatibility\n 'ui.displayMode.minimal': string\n 'ui.displayMode.compact': string\n 'ui.displayMode.detailed': string\n 'ui.displayMode.label': string\n 'ui.displayMode.hint': string\n\n // UI - Input\n 'ui.input.placeholder': string\n 'ui.input.thinking': string\n 'ui.input.processing': string\n 'ui.input.waiting': string\n 'ui.input.multilineHint': string\n 'ui.input.submitHint': string\n\n // UI - Panels\n 'ui.panel.todo': string\n 'ui.panel.tasks': string\n 'ui.panel.agents': string\n 'ui.panel.models': string\n 'ui.panel.help': string\n 'ui.panel.history': string\n 'ui.panel.settings': string\n\n // UI - Status\n 'ui.status.ready': string\n 'ui.status.busy': string\n 'ui.status.error': string\n 'ui.status.offline': string\n 'ui.status.connecting': string\n 'ui.status.streaming': string\n\n // UI - Welcome\n 'ui.welcome.title': string\n 'ui.welcome.subtitle': string\n 'ui.welcome.quickStart': string\n 'ui.welcome.tip1': string\n 'ui.welcome.tip2': string\n 'ui.welcome.tip3': string\n 'ui.welcome.tip4': string\n 'ui.welcome.cwd': string\n 'ui.welcome.mcpServers': string\n 'ui.welcome.taglinePart1': string\n 'ui.welcome.taglinePart2': string\n\n // UI - Update banner\n 'ui.update.newVersionAvailable': string\n 'ui.update.runCommand': string\n 'ui.update.sudoNote': string\n\n // UI - Hotkeys\n 'ui.hotkey.submit': string\n 'ui.hotkey.newline': string\n 'ui.hotkey.cancel': string\n 'ui.hotkey.toggleMode': string\n 'ui.hotkey.help': string\n 'ui.hotkey.quit': string\n 'ui.hotkey.history': string\n 'ui.hotkey.clear': string\n 'ui.hotkey.interrupt': string\n\n // UI - Hotkey hints (context-aware)\n 'ui.hints.command': string\n 'ui.hints.bash': string\n 'ui.hints.send': string\n 'ui.hints.complete': string\n 'ui.hints.rollback': string\n 'ui.hints.select': string\n 'ui.hints.confirm': string\n 'ui.hints.close': string\n 'ui.hints.browse': string\n 'ui.hints.execute': string\n 'ui.hints.completeCommand': string\n 'ui.hints.shortcuts': string\n 'ui.hints.pressEsc': string\n 'ui.hints.tip': string\n // UI - PromptInput mode hints\n 'ui.hints.executeCommand': string\n 'ui.hints.recordNote': string\n 'ui.hints.featureMenu': string\n 'ui.hints.forNewline': string\n 'ui.hints.forBashMode': string\n 'ui.hints.forMintoMd': string\n 'ui.hints.forCommands': string\n 'ui.hints.typeToQueue': string\n 'ui.hints.backgroundTasks': string\n 'ui.hints.queued': string\n 'ui.hints.willRunAfter': string\n 'ui.hints.toEdit': string\n // UI - Completion hints\n 'ui.hints.completion.navigate': string\n 'ui.hints.completion.enterDirectory': string\n 'ui.hints.completion.selectAgent': string\n 'ui.hints.completion.insertReference': string\n 'ui.hints.completion.moreAbove': string\n 'ui.hints.completion.moreBelow': string\n\n // UI - Todo panel\n 'ui.todo.tasksRemaining': string\n 'ui.todo.allDone': string\n 'ui.todo.updatedTaskList': string\n 'ui.todo.pending': string\n 'ui.todo.inProgress': string\n 'ui.todo.done': string\n\n // UI - Model display\n 'ui.model.fallbackName': string\n // UI - Model management\n 'ui.model.manageList': string\n 'ui.model.manageListDeleteMode': string\n 'ui.model.cannotDeleteLast': string\n 'ui.model.deleteConfirmPrompt': string\n 'ui.model.addNewModelPrompt': string\n 'ui.model.configureNewModel': string\n 'ui.model.navigateHint': string\n 'ui.model.deleteHint': string\n 'ui.model.activeLabel': string\n 'ui.model.availableLabel': string\n 'ui.model.spaceToCycle': string\n 'ui.model.enterToConfigure': string\n 'ui.model.notConfigured': string\n // UI - Model config\n 'ui.modelConfig.title': string\n 'ui.modelConfig.clearMode': string\n 'ui.modelConfig.clearAssignmentPrompt': string\n 'ui.modelConfig.noModelsConfigured': string\n 'ui.modelConfig.configureHint': string\n 'ui.modelConfig.navigateHint': string\n 'ui.modelConfig.clearModePrompt': string\n // UI - Model pointer descriptions\n 'ui.modelConfig.mainDescription': string\n 'ui.modelConfig.taskDescription': string\n 'ui.modelConfig.reasoningDescription': string\n 'ui.modelConfig.quickDescription': string\n 'ui.modelConfig.compactDescription': string\n 'ui.modelConfig.manageModelsDescription': string\n\n // UI - Sensitive file warning\n 'ui.sensitiveFile.title': string\n 'ui.sensitiveFile.operating': string\n 'ui.sensitiveFile.defaultReason': string\n 'ui.sensitiveFile.operation.read': string\n 'ui.sensitiveFile.operation.write': string\n 'ui.sensitiveFile.operation.delete': string\n\n // Commands - Undo\n 'commands.undo.description': string\n 'commands.undo.title': string\n 'commands.undo.selectFile': string\n 'commands.undo.noBackups': string\n 'commands.undo.smartModeHint': string\n 'commands.undo.smartModeCommand': string\n 'commands.undo.versions': string\n 'commands.undo.selectVersion': string\n 'commands.undo.file': string\n 'commands.undo.restoredTo': string\n 'commands.undo.fileRestored': string\n 'commands.undo.restoreFailed': string\n 'commands.undo.loading': string\n 'commands.undo.error': string\n 'commands.undo.pressAnyKey': string\n 'commands.undo.pressQOrEsc': string\n 'commands.undo.navHintsFile': string\n 'commands.undo.navHintsVersion': string\n // Time format\n 'commands.undo.justNow': string\n 'commands.undo.minutesAgo': string\n 'commands.undo.today': string\n 'commands.undo.weekday.sun': string\n 'commands.undo.weekday.mon': string\n 'commands.undo.weekday.tue': string\n 'commands.undo.weekday.wed': string\n 'commands.undo.weekday.thu': string\n 'commands.undo.weekday.fri': string\n 'commands.undo.weekday.sat': string\n\n // Commands\n 'commands.help.description': string\n 'commands.clear.description': string\n 'commands.compact.description': string\n 'commands.compact.success': string\n 'commands.compact.noMessages': string\n 'commands.model.description': string\n 'commands.model.current': string\n 'commands.model.switched': string\n 'commands.model.notFound': string\n 'commands.agents.description': string\n 'commands.agents.title': string\n 'commands.agents.empty': string\n 'commands.agents.loaded': string\n 'commands.tasks.description': string\n 'commands.config.description': string\n 'commands.bug.description': string\n 'commands.doctor.description': string\n 'commands.status.description': string\n 'commands.permissions.description': string\n 'commands.mcp.description': string\n 'commands.plugin.description': string\n // Plugin - Tabs\n 'commands.plugin.tabBrowse': string\n 'commands.plugin.tabInstalled': string\n 'commands.plugin.tabMarketplaces': string\n // Plugin - Add marketplace\n 'commands.plugin.addMarketplace': string\n 'commands.plugin.addMarketplacePlaceholder': string\n // Plugin - Footer hints\n 'commands.plugin.footerHint': string\n 'commands.plugin.addFooterHint': string\n // Plugin - Install/Update/Uninstall actions\n 'commands.plugin.install': string\n 'commands.plugin.installing': string\n 'commands.plugin.installSuccess': string\n 'commands.plugin.installFailed': string\n 'commands.plugin.update': string\n 'commands.plugin.updating': string\n 'commands.plugin.updateSuccess': string\n 'commands.plugin.updateFailed': string\n 'commands.plugin.uninstall': string\n 'commands.plugin.uninstalling': string\n 'commands.plugin.uninstallSuccess': string\n 'commands.plugin.uninstallFailed': string\n 'commands.plugin.enable': string\n 'commands.plugin.disable': string\n 'commands.plugin.toggleSuccess': string\n // Plugin - Marketplace actions\n 'commands.plugin.marketplaceUpdate': string\n 'commands.plugin.marketplaceUpdating': string\n 'commands.plugin.marketplaceUpdateSuccess': string\n 'commands.plugin.marketplaceUpdateFailed': string\n 'commands.plugin.marketplaceRemove': string\n 'commands.plugin.marketplaceRemoving': string\n 'commands.plugin.marketplaceRemoveSuccess': string\n 'commands.plugin.marketplaceAdd': string\n 'commands.plugin.marketplaceAdding': string\n 'commands.plugin.marketplaceAddSuccess': string\n 'commands.plugin.marketplaceAddFailed': string\n 'commands.plugin.browsePlugins': string\n 'commands.plugin.actions': string\n 'commands.plugin.back': string\n 'commands.plugin.local': string\n 'commands.plugin.sourceClaudeCode': string\n 'commands.plugin.syncDesc': string\n 'commands.plugin.syncStarting': string\n 'commands.plugin.syncScanning': string\n 'commands.plugin.syncInstalling': string\n 'commands.plugin.syncUpdating': string\n 'commands.plugin.syncComplete': string\n 'commands.plugin.syncNoChanges': string\n 'commands.plugin.syncFailed': string\n 'commands.plugin.syncNotFound': string\n 'commands.plugin.syncCleaned': string\n 'commands.plugin.syncSkippedManual': string\n 'commands.plugin.syncDryRun': string\n 'commands.plugin.syncMarketplacesRegistered': string\n 'commands.plugin.syncMarketplacesFailed': string\n 'commands.plugin.syncMarketplacesProgress': string\n // Plugin - Batch operations\n 'commands.plugin.batchInstallAction': string\n 'commands.plugin.batchUpdateAction': string\n 'commands.plugin.batchAction': string\n 'commands.plugin.batchInstalling': string\n 'commands.plugin.batchUpdating': string\n 'commands.plugin.batchInstalledCount': string\n 'commands.plugin.batchUpdatedCount': string\n 'commands.plugin.batchFailedCount': string\n 'commands.plugin.batchDeleteAction': string\n 'commands.plugin.batchEnableAction': string\n 'commands.plugin.batchDisableAction': string\n 'commands.plugin.batchUninstalling': string\n 'commands.plugin.batchUninstalledCount': string\n 'commands.plugin.batchEnabledCount': string\n 'commands.plugin.batchDisabledCount': string\n 'commands.plugin.batchActionPickerTitle': string\n 'commands.plugin.updateAvailable': string\n 'commands.plugin.batchAllAlreadyInstalled': string\n 'commands.plugin.batchNoUpdatable': string\n 'commands.plugin.footerHintMultiSelect': string\n 'commands.sandbox.description': string\n 'commands.thinking.description': string\n 'commands.thinking.enabled': string\n 'commands.thinking.disabled': string\n 'commands.language.description': string\n 'commands.language.title': string\n 'commands.language.current': string\n 'commands.language.select': string\n 'commands.language.changed': string\n 'commands.language.restart': string\n 'commands.language.alreadyUsing': string\n 'commands.language.navigate': string\n\n // Commands - Sessions\n 'commands.sessions.description': string\n 'commands.sessions.title': string\n 'commands.sessions.count': string\n 'commands.sessions.noSessions': string\n 'commands.sessions.headerDate': string\n 'commands.sessions.headerProject': string\n 'commands.sessions.headerPrompt': string\n 'commands.sessions.headerMsgs': string\n 'commands.sessions.headerTools': string\n 'commands.sessions.helpHint': string\n 'commands.sessions.today': string\n 'commands.sessions.yesterday': string\n 'commands.sessions.moreBelow': string\n 'commands.sessions.navigationHint': string\n\n // Commands - Resume\n 'commands.resume.description': string\n 'commands.resume.title': string\n 'commands.resume.noSessions': string\n 'commands.resume.navigationHint': string\n\n // Commands - New\n 'commands.new.description': string\n\n // Tools\n 'tools.bash.description': string\n 'tools.bash.executing': string\n 'tools.bash.completed': string\n 'tools.bash.failed': string\n 'tools.read.description': string\n 'tools.read.reading': string\n 'tools.write.description': string\n 'tools.write.writing': string\n 'tools.write.created': string\n 'tools.write.updated': string\n 'tools.edit.description': string\n 'tools.edit.editing': string\n 'tools.glob.description': string\n 'tools.grep.description': string\n 'tools.task.description': string\n 'tools.task.spawning': string\n 'tools.task.running': string\n 'tools.task.completed': string\n 'tools.todo.description': string\n\n // Errors\n 'errors.generic': string\n 'errors.network': string\n 'errors.timeout': string\n 'errors.auth': string\n 'errors.rateLimit': string\n 'errors.modelNotFound': string\n 'errors.apiKeyMissing': string\n 'errors.apiKeyInvalid': string\n 'errors.permissionDenied': string\n 'errors.fileNotFound': string\n 'errors.fileReadError': string\n 'errors.fileWriteError': string\n 'errors.configError': string\n 'errors.parseError': string\n 'errors.validationError': string\n 'errors.aborted': string\n 'errors.contextTooLong': string\n 'errors.serverError': string\n 'errors.connectionFailed': string\n\n // Help\n 'help.title': string\n 'help.usage': string\n 'help.commands': string\n 'help.options': string\n 'help.examples': string\n 'help.moreInfo': string\n 'help.reportBug': string\n 'help.documentation': string\n // Help - Usage modes\n 'help.usageModes': string\n 'help.nonInteractive': string\n 'help.runForOptions': string\n // Help - Common tasks\n 'help.commonTasks': string\n 'help.taskAskQuestions': string\n 'help.taskEditFiles': string\n 'help.taskFixErrors': string\n 'help.taskRunCommands': string\n 'help.taskRunBash': string\n // Help - Command categories\n 'help.builtInCommands': string\n 'help.customCommands': string\n 'help.pluginCommands': string\n 'help.mcpCommands': string\n // Help - Command loading\n 'help.commandPriority': string\n 'help.priorityBuiltIn': string\n 'help.priorityCustom': string\n 'help.priorityPlugin': string\n 'help.priorityMcp': string\n 'help.refreshCommandsHint': string\n // Help - Product description\n 'help.productDescription': string\n // Help - Mode Systems\n 'help.modeSystems': string\n 'help.safetyModes': string\n 'help.safetyModeYolo': string\n 'help.safetyModeSmart': string\n 'help.safetyModeStrict': string\n 'help.safetyModeFree': string\n 'help.permissionModes': string\n 'help.permissionModeDefault': string\n 'help.permissionModeAcceptEdits': string\n 'help.permissionModePlan': string\n 'help.permissionModeBypass': string\n 'help.modeInteraction': string\n\n // Status messages\n 'status.modelLoaded': string\n 'status.contextCompressed': string\n 'status.tokensUsed': string\n 'status.costEstimate': string\n 'status.apiLatency': string\n 'status.streaming': string\n 'status.thinking': string\n 'status.toolUse': string\n 'status.subagent': string\n\n // Prompts\n 'prompts.confirmDelete': string\n 'prompts.confirmOverwrite': string\n 'prompts.confirmExecute': string\n 'prompts.enterApiKey': string\n 'prompts.selectModel': string\n 'prompts.selectLanguage': string\n 'prompts.interruptedByUser': string\n 'prompts.interruptedCtrlC': string\n 'prompts.interruptedEscEsc': string\n 'prompts.inputCleared': string\n 'prompts.inputClearedCtrlD': string\n 'prompts.inputClearedEscEsc': string\n 'prompts.screenCleared': string\n 'prompts.todoPanelToggled': string\n 'prompts.typeCommandFirst': string\n 'prompts.executingBash': string\n 'prompts.exitingGracefully': string\n 'prompts.pressCtrlDToExit': string\n 'prompts.pressCtrlDAgain': string\n 'prompts.pressEscAgainClear': string\n 'prompts.pressEscAgainInterrupt': string\n 'prompts.thinkingModeEnabled': string\n 'prompts.thinkingModeDisabled': string\n 'prompts.limitedInputMode': string\n 'prompts.limitedInputModeDetail': string\n 'prompts.queuedMessage': string\n 'prompts.noModelsConfigured': string\n 'prompts.noActiveModels': string\n 'prompts.onlyOneActiveModel': string\n 'prompts.modelSwitchingFailed': string\n\n // Agent/Subagent\n 'agent.spawning': string\n 'agent.running': string\n 'agent.completed': string\n 'agent.failed': string\n 'agent.cancelled': string\n 'agent.waiting': string\n 'agent.thinking': string\n\n // Model\n 'model.selecting': string\n 'model.selected': string\n 'model.unavailable': string\n 'model.switching': string\n 'model.switched': string\n 'model.default': string\n 'model.custom': string\n\n // Permissions\n 'permission.required': string\n 'permission.granted': string\n 'permission.denied': string\n 'permission.allowOnce': string\n 'permission.allowAlways': string\n 'permission.denyOnce': string\n 'permission.denyAlways': string\n 'permission.sensitiveFile': string\n 'permission.externalPath': string\n 'permission.dangerousCommand': string\n\n // Dialog - Generic\n 'dialog.enterToConfirm': string\n 'dialog.escToCancel': string\n 'dialog.confirmCancelPrompt': string\n 'dialog.enterCustomResponse': string\n // Dialog - Message selector\n 'dialog.jumpToPreviousMessage': string\n 'dialog.forkConversation': string\n 'dialog.current': string\n 'dialog.emptyMessage': string\n 'dialog.selectConfirmCancelPrompt': string\n // Dialog - MCP server\n 'dialog.mcpServerDetected': string\n 'dialog.mcpServersDetected': string\n 'dialog.mcpApprovalRequired': string\n 'dialog.mcpSelectServers': string\n 'dialog.approveServer': string\n 'dialog.rejectServer': string\n 'dialog.confirmRejectPrompt': string\n 'dialog.selectConfirmRejectAllPrompt': string\n // Dialog - Trust\n 'dialog.trustTitle': string\n 'dialog.trustWarning1': string\n 'dialog.trustWarning2': string\n 'dialog.yesProceed': string\n 'dialog.noExit': string\n 'dialog.confirmExitPrompt': string\n\n // Config\n 'config.title': string\n 'config.modelConfiguration': string\n 'config.noModelsConfigured': string\n 'config.useModelCommand': string\n 'config.enterToSaveEscToCancel': string\n 'config.navigateChangeClose': string\n 'config.enterNewValue': string\n 'config.theme': string\n 'config.verboseMode': string\n 'config.streamResponses': string\n 'config.compressionMode': string\n 'config.backupEnabled': string\n 'config.backupEnabled.description': string\n\n // HotkeyHelpPanel\n 'hotkey.navigation': string\n 'hotkey.control': string\n 'hotkey.features': string\n 'hotkey.inputModes': string\n 'hotkey.browseHistory': string\n 'hotkey.searchHistory': string\n 'hotkey.autocomplete': string\n 'hotkey.rollbackResponse': string\n 'hotkey.cancelOperation': string\n 'hotkey.exitPressTwice': string\n 'hotkey.clearScreen': string\n 'hotkey.submitPrompt': string\n 'hotkey.toggleTodoPanel': string\n 'hotkey.cycleDisplayMode': string\n 'hotkey.executeAsBash': string\n 'hotkey.showHideHelp': string\n 'hotkey.startSlashCommand': string\n 'hotkey.executeBashCommand': string\n 'hotkey.addNoteToKoding': string\n 'hotkey.ctrlQuestionForShortcuts': string\n\n // User-Friendly Error Messages\n // Network & Connectivity\n 'friendlyError.networkConnection.title': string\n 'friendlyError.networkConnection.description': string\n 'friendlyError.networkConnection.suggestion1': string\n 'friendlyError.networkConnection.suggestion2': string\n 'friendlyError.networkConnection.suggestion3': string\n\n 'friendlyError.networkTimeout.title': string\n 'friendlyError.networkTimeout.description': string\n 'friendlyError.networkTimeout.suggestion1': string\n 'friendlyError.networkTimeout.suggestion2': string\n 'friendlyError.networkTimeout.suggestion3': string\n\n 'friendlyError.networkDns.title': string\n 'friendlyError.networkDns.description': string\n 'friendlyError.networkDns.suggestion1': string\n 'friendlyError.networkDns.suggestion2': string\n 'friendlyError.networkDns.suggestion3': string\n\n // API & Service\n 'friendlyError.apiRateLimit.title': string\n 'friendlyError.apiRateLimit.description': string\n 'friendlyError.apiRateLimit.suggestion1': string\n 'friendlyError.apiRateLimit.suggestion2': string\n 'friendlyError.apiRateLimit.suggestion3': string\n\n 'friendlyError.apiAuth.title': string\n 'friendlyError.apiAuth.description': string\n 'friendlyError.apiAuth.suggestion1': string\n 'friendlyError.apiAuth.suggestion2': string\n 'friendlyError.apiAuth.suggestion3': string\n\n 'friendlyError.apiQuota.title': string\n 'friendlyError.apiQuota.description': string\n 'friendlyError.apiQuota.suggestion1': string\n 'friendlyError.apiQuota.suggestion2': string\n 'friendlyError.apiQuota.suggestion3': string\n\n 'friendlyError.apiServerError.title': string\n 'friendlyError.apiServerError.description': string\n 'friendlyError.apiServerError.suggestion1': string\n 'friendlyError.apiServerError.suggestion2': string\n\n 'friendlyError.apiInvalidResponse.title': string\n 'friendlyError.apiInvalidResponse.description': string\n 'friendlyError.apiInvalidResponse.suggestion1': string\n 'friendlyError.apiInvalidResponse.suggestion2': string\n\n // File & Storage\n 'friendlyError.fileNotFound.title': string\n 'friendlyError.fileNotFound.description': string\n 'friendlyError.fileNotFound.suggestion1': string\n 'friendlyError.fileNotFound.suggestion2': string\n\n 'friendlyError.filePermission.title': string\n 'friendlyError.filePermission.description': string\n 'friendlyError.filePermission.suggestion1': string\n 'friendlyError.filePermission.suggestion2': string\n\n 'friendlyError.fileTooLarge.title': string\n 'friendlyError.fileTooLarge.description': string\n 'friendlyError.fileTooLarge.suggestion1': string\n 'friendlyError.fileTooLarge.suggestion2': string\n\n 'friendlyError.fileEncoding.title': string\n 'friendlyError.fileEncoding.description': string\n 'friendlyError.fileEncoding.suggestion1': string\n 'friendlyError.fileEncoding.suggestion2': string\n\n // Configuration\n 'friendlyError.configMissing.title': string\n 'friendlyError.configMissing.description': string\n 'friendlyError.configMissing.suggestion1': string\n 'friendlyError.configMissing.suggestion2': string\n\n 'friendlyError.configInvalid.title': string\n 'friendlyError.configInvalid.description': string\n 'friendlyError.configInvalid.suggestion1': string\n 'friendlyError.configInvalid.suggestion2': string\n\n 'friendlyError.configApiKey.title': string\n 'friendlyError.configApiKey.description': string\n 'friendlyError.configApiKey.suggestion1': string\n 'friendlyError.configApiKey.suggestion2': string\n\n // Model & AI\n 'friendlyError.modelUnavailable.title': string\n 'friendlyError.modelUnavailable.description': string\n 'friendlyError.modelUnavailable.suggestion1': string\n 'friendlyError.modelUnavailable.suggestion2': string\n 'friendlyError.modelUnavailable.suggestion3': string\n\n 'friendlyError.modelContextLength.title': string\n 'friendlyError.modelContextLength.description': string\n 'friendlyError.modelContextLength.suggestion1': string\n 'friendlyError.modelContextLength.suggestion2': string\n\n 'friendlyError.modelContentFilter.title': string\n 'friendlyError.modelContentFilter.description': string\n 'friendlyError.modelContentFilter.suggestion1': string\n 'friendlyError.modelContentFilter.suggestion2': string\n\n // System\n 'friendlyError.systemMemory.title': string\n 'friendlyError.systemMemory.description': string\n 'friendlyError.systemMemory.suggestion1': string\n 'friendlyError.systemMemory.suggestion2': string\n 'friendlyError.systemMemory.suggestion3': string\n\n 'friendlyError.systemProcess.title': string\n 'friendlyError.systemProcess.description': string\n 'friendlyError.systemProcess.suggestion1': string\n 'friendlyError.systemProcess.suggestion2': string\n\n // Unknown\n 'friendlyError.unknown.title': string\n 'friendlyError.unknown.description': string\n 'friendlyError.unknown.suggestion1': string\n 'friendlyError.unknown.suggestion2': string\n\n // Error display format\n 'friendlyError.suggestionLabel': string\n 'friendlyError.errorIdLabel': string\n 'friendlyError.technicalDetailsLabel': string\n\n // UI - TabbedListView\n 'ui.tabbedList.search': string\n 'ui.tabbedList.loading': string\n 'ui.tabbedList.noItems': string\n 'ui.tabbedList.moreAbove': string\n 'ui.tabbedList.moreBelow': string\n 'ui.tabbedList.tabCycleHint': string\n 'ui.tabbedList.navigationHint': string\n\n // UI - InfoPanel\n 'ui.infoPanel.continueHint': string\n 'ui.infoPanel.dismissHint': string\n\n // UI - SimpleSelector\n 'ui.simpleSelector.navigationHint': string\n 'ui.simpleSelector.dismissHint': string\n\n // Commands - Status\n 'commands.status.title': string\n 'commands.status.versionInfo': string\n 'commands.status.environment': string\n 'commands.status.modelConfiguration': string\n 'commands.status.apiConnection': string\n 'commands.status.connected': string\n 'commands.status.notConnected': string\n 'commands.status.notConfigured': string\n\n // Commands - Context\n 'commands.context.title': string\n 'commands.context.contextUsage': string\n 'commands.context.tokens': string\n 'commands.context.remaining': string\n 'commands.context.messages': string\n 'commands.context.estTurns': string\n 'commands.context.highUsage': string\n 'commands.context.criticalUsage': string\n\n // Commands - Model status\n 'commands.model.title': string\n 'commands.model.modelPointers': string\n 'commands.model.configure': string\n 'commands.model.error': string\n // Commands - Model (refactored phases)\n 'commands.model.selectModel': string\n 'commands.model.pointerUpdated': string\n 'commands.model.pointerCleared': string\n 'commands.model.modelLibrary': string\n 'commands.model.modelLibrarySubtitle': string\n 'commands.model.addNewModel': string\n 'commands.model.clearAssignment': string\n 'commands.model.modelActions': string\n 'commands.model.confirmDeleteTitle': string\n 'commands.model.confirmDeleteYes': string\n 'commands.model.confirmDeleteNo': string\n 'commands.model.modelDeleted': string\n 'commands.model.deleteFailed': string\n 'commands.model.actionsCategory': string\n 'commands.model.pointersCategory': string\n\n // Commands - Sandbox\n 'commands.sandbox.title': string\n 'commands.sandbox.statusSection': string\n 'commands.sandbox.implementation': string\n 'commands.sandbox.filesystemPolicy': string\n 'commands.sandbox.networkPolicy': string\n 'commands.sandbox.processPolicy': string\n 'commands.sandbox.helpSection': string\n 'commands.sandbox.toggle': string\n 'commands.sandbox.toggleHelp': string\n 'commands.sandbox.enabled': string\n 'commands.sandbox.disabled': string\n 'commands.sandbox.notAvailable': string\n\n // Commands - Help\n 'commands.help.title': string\n\n // Commands - MCP\n 'commands.mcp.title': string\n 'commands.mcp.noServers': string\n 'commands.mcp.addServer': string\n 'commands.mcp.refreshAll': string\n 'commands.mcp.enable': string\n 'commands.mcp.disable': string\n 'commands.mcp.deleteServer': string\n 'commands.mcp.confirmDeleteTitle': string\n 'commands.mcp.confirmYes': string\n 'commands.mcp.confirmNo': string\n // MCP - Tabs\n 'commands.mcp.tabAll': string\n 'commands.mcp.tabProject': string\n 'commands.mcp.tabGlobal': string\n // MCP - Add server\n 'commands.mcp.addNamePlaceholder': string\n 'commands.mcp.addCommandPlaceholder': string\n 'commands.mcp.addFooterHint': string\n 'commands.mcp.addCommandFooterHint': string\n // MCP - Status overlays\n 'commands.mcp.adding': string\n 'commands.mcp.addSuccess': string\n 'commands.mcp.addFailed': string\n 'commands.mcp.toggling': string\n 'commands.mcp.toggleSuccess': string\n 'commands.mcp.deleting': string\n 'commands.mcp.deleteSuccess': string\n 'commands.mcp.refreshing': string\n 'commands.mcp.refreshSuccess': string\n // MCP - Sub-phase labels\n 'commands.mcp.back': string\n 'commands.mcp.actions': string\n\n // Commands - Undo\n 'commands.undo.tabFiles': string\n 'commands.undo.tabVersions': string\n\n // Commands - Export\n 'commands.export.description': string\n 'commands.export.title': string\n 'commands.export.selectType': string\n 'commands.export.selectScope': string\n 'commands.export.typeRuntime': string\n 'commands.export.typeRuntimeDesc': string\n 'commands.export.typeTeam': string\n 'commands.export.typeTeamDesc': string\n 'commands.export.scopeUser': string\n 'commands.export.scopeUserDesc': string\n 'commands.export.scopeProject': string\n 'commands.export.scopeProjectDesc': string\n 'commands.export.typeConversation': string\n 'commands.export.typeConversationDesc': string\n 'commands.export.typeSummary': string\n 'commands.export.typeSummaryDesc': string\n 'commands.export.exporting': string\n 'commands.export.success': string\n 'commands.export.failed': string\n 'commands.export.noPlugins': string\n 'commands.export.noAgents': string\n 'commands.export.noHooks': string\n 'commands.export.navigationHint': string\n 'commands.export.sensitiveDataTitle': string\n 'commands.export.sensitiveDataQuestion': string\n 'commands.export.sensitiveInclude': string\n 'commands.export.sensitiveIncludeDesc': string\n 'commands.export.sensitivePlaceholder': string\n 'commands.export.sensitivePlaceholderDesc': string\n // Export - scope descriptions\n 'commands.export.scopeAll': string\n 'commands.export.scopeAllDesc': string\n // Export - flattened TabbedListView items\n 'commands.export.itemTeamUserInclude': string\n 'commands.export.itemTeamUserPlaceholder': string\n 'commands.export.itemTeamProjectInclude': string\n 'commands.export.itemTeamProjectPlaceholder': string\n 'commands.export.itemTeamAllInclude': string\n 'commands.export.itemTeamAllPlaceholder': string\n 'commands.export.itemRuntimeUser': string\n 'commands.export.itemRuntimeProject': string\n 'commands.export.itemRuntimeAll': string\n 'commands.export.itemConversation': string\n 'commands.export.itemSummary': string\n 'commands.export.footerHint': string\n\n // Commands - Setup\n 'commands.setup.description': string\n 'commands.setup.previewTitle': string\n 'commands.setup.tabOverview': string\n 'commands.setup.tabModels': string\n 'commands.setup.tabMcp': string\n 'commands.setup.tabPlugins': string\n 'commands.setup.tabAgents': string\n 'commands.setup.tabHooks': string\n 'commands.setup.tabSettings': string\n 'commands.setup.confirmHint': string\n 'commands.setup.applying': string\n 'commands.setup.tabSkills': string\n 'commands.setup.tabCommands': string\n 'commands.setup.installingPlugins': string\n 'commands.setup.installingProjectPlugins': string\n 'commands.setup.installingAgents': string\n 'commands.setup.installingHooks': string\n 'commands.setup.installingSkills': string\n 'commands.setup.installingCommands': string\n 'commands.setup.addingMarketplaces': string\n 'commands.setup.success': string\n 'commands.setup.failed': string\n 'commands.setup.loading': string\n 'commands.setup.errorMissingFrom': string\n 'commands.setup.errorUsage': string\n\n // Commands - Stats\n 'commands.stats.description': string\n 'commands.stats.title': string\n 'commands.stats.today': string\n 'commands.stats.thisWeek': string\n 'commands.stats.thisMonth': string\n 'commands.stats.lifetime': string\n 'commands.stats.messages': string\n 'commands.stats.sessions': string\n 'commands.stats.toolCalls': string\n 'commands.stats.tokens': string\n 'commands.stats.totalMessages': string\n 'commands.stats.totalSessions': string\n 'commands.stats.totalTools': string\n 'commands.stats.estCost': string\n 'commands.stats.modelUsage': string\n 'commands.stats.topTools': string\n 'commands.stats.calls': string\n 'commands.stats.noData': string\n 'commands.stats.vsYesterday': string\n 'commands.stats.firstUsed': string\n\n // ModelSelector Wizard\n 'modelSelector.providerSelection': string\n 'modelSelector.providerSelectionDesc': string\n 'modelSelector.providerSelectionHint': string\n 'modelSelector.anthropicSubMenu': string\n 'modelSelector.anthropicSubMenuDesc': string\n 'modelSelector.anthropicOfficial': string\n 'modelSelector.anthropicOfficialDesc': string\n 'modelSelector.anthropicBigdream': string\n 'modelSelector.anthropicBigdreamDesc': string\n 'modelSelector.anthropicOpendev': string\n 'modelSelector.anthropicOpendevDesc': string\n 'modelSelector.anthropicCustom': string\n 'modelSelector.anthropicCustomDesc': string\n 'modelSelector.baseUrlTitle': string\n 'modelSelector.baseUrlDesc': string\n 'modelSelector.baseUrlOllamaDesc': string\n 'modelSelector.customApiTitle': string\n 'modelSelector.customApiDesc': string\n 'modelSelector.apiKeyTitle': string\n 'modelSelector.apiKeyDesc': string\n 'modelSelector.apiKeyTabHintManual': string\n 'modelSelector.apiKeyTabHintSkip': string\n 'modelSelector.resourceNameTitle': string\n 'modelSelector.resourceNameDesc': string\n 'modelSelector.modelSelectionTitle': string\n 'modelSelector.modelSelectionDesc': string\n 'modelSelector.modelSearchPlaceholder': string\n 'modelSelector.modelInputTitle': string\n 'modelSelector.modelParamsTitle': string\n 'modelSelector.modelParamsDesc': string\n 'modelSelector.maxTokens': string\n 'modelSelector.reasoningEffort': string\n 'modelSelector.contextLengthTitle': string\n 'modelSelector.contextLengthDesc': string\n 'modelSelector.connectionTestTitle': string\n 'modelSelector.connectionTestDesc': string\n 'modelSelector.connectionTestStart': string\n 'modelSelector.connectionTestRunning': string\n 'modelSelector.connectionTestAutoProceeding': string\n 'modelSelector.connectionTestRetry': string\n 'modelSelector.confirmationTitle': string\n 'modelSelector.confirmationDesc': string\n 'modelSelector.confirmationSave': string\n 'modelSelector.configError': string\n 'modelSelector.footerEnterContinue': string\n 'modelSelector.footerEscBack': string\n 'modelSelector.footerNavSelectEsc': string\n 'modelSelector.footerTabNavigate': string\n 'modelSelector.showingModels': string\n 'modelSelector.noModelsMatch': string\n 'modelSelector.noModelsAvailable': string\n 'modelSelector.recommended': string\n 'modelSelector.continue': string\n}\n\n/**\n * Full translation object type\n */\nexport type Translations = TranslationKeys\n\n/**\n * Translation key type (string union of all keys)\n */\nexport type TranslationKey = keyof TranslationKeys\n\n/**\n * Partial translations for extending\n */\nexport type PartialTranslations = Partial<TranslationKeys>\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * i18n Type Definitions\n *\n * Type-safe internationalization system for Minto CLI.\n */\n\n/**\n * Supported languages\n */\nexport type Language = 'en' | 'zh-CN'\n\n/**\n * Language display names\n */\nexport const LANGUAGE_NAMES: Record<Language, string> = {\n en: 'English',\n 'zh-CN': '\u7B80\u4F53\u4E2D\u6587',\n}\n\n/**\n * Translation namespace keys\n */\nexport type TranslationNamespace =\n | 'common'\n | 'ui'\n | 'commands'\n | 'tools'\n | 'errors'\n | 'help'\n | 'status'\n | 'prompts'\n\n/**\n * Translation key structure for type safety\n */\nexport interface TranslationKeys {\n // Common\n 'common.yes': string\n 'common.no': string\n 'common.ok': string\n 'common.cancel': string\n 'common.confirm': string\n 'common.save': string\n 'common.delete': string\n 'common.edit': string\n 'common.create': string\n 'common.loading': string\n 'common.error': string\n 'common.success': string\n 'common.warning': string\n 'common.info': string\n 'common.unknown': string\n 'common.none': string\n 'common.all': string\n 'common.selected': string\n 'common.default': string\n 'common.custom': string\n 'common.enabled': string\n 'common.disabled': string\n 'common.connected': string\n 'common.disconnected': string\n 'common.pending': string\n 'common.completed': string\n 'common.failed': string\n 'common.inProgress': string\n 'common.version': string\n 'common.help': string\n 'common.quit': string\n 'common.back': string\n 'common.next': string\n 'common.previous': string\n 'common.search': string\n 'common.filter': string\n 'common.sort': string\n 'common.refresh': string\n 'common.retry': string\n 'common.skip': string\n 'common.continue': string\n 'common.abort': string\n 'common.reset': string\n 'common.clear': string\n 'common.copy': string\n 'common.paste': string\n 'common.select': string\n 'common.deselect': string\n 'common.selectAll': string\n 'common.deselectAll': string\n\n // UI - Verbose mode\n 'ui.verbose.on': string\n 'ui.verbose.off': string\n 'ui.verbose.label': string\n 'ui.verbose.hint': string\n // Deprecated - kept for backward compatibility\n 'ui.displayMode.minimal': string\n 'ui.displayMode.compact': string\n 'ui.displayMode.detailed': string\n 'ui.displayMode.label': string\n 'ui.displayMode.hint': string\n\n // UI - Input\n 'ui.input.placeholder': string\n 'ui.input.thinking': string\n 'ui.input.processing': string\n 'ui.input.waiting': string\n 'ui.input.multilineHint': string\n 'ui.input.submitHint': string\n\n // UI - Panels\n 'ui.panel.todo': string\n 'ui.panel.tasks': string\n 'ui.panel.agents': string\n 'ui.panel.models': string\n 'ui.panel.help': string\n 'ui.panel.history': string\n 'ui.panel.settings': string\n\n // UI - Status\n 'ui.status.ready': string\n 'ui.status.busy': string\n 'ui.status.error': string\n 'ui.status.offline': string\n 'ui.status.connecting': string\n 'ui.status.streaming': string\n\n // UI - Welcome\n 'ui.welcome.title': string\n 'ui.welcome.subtitle': string\n 'ui.welcome.quickStart': string\n 'ui.welcome.tip1': string\n 'ui.welcome.tip2': string\n 'ui.welcome.tip3': string\n 'ui.welcome.tip4': string\n 'ui.welcome.cwd': string\n 'ui.welcome.mcpServers': string\n 'ui.welcome.taglinePart1': string\n 'ui.welcome.taglinePart2': string\n\n // UI - Update banner\n 'ui.update.newVersionAvailable': string\n 'ui.update.runCommand': string\n 'ui.update.sudoNote': string\n\n // UI - Hotkeys\n 'ui.hotkey.submit': string\n 'ui.hotkey.newline': string\n 'ui.hotkey.cancel': string\n 'ui.hotkey.toggleMode': string\n 'ui.hotkey.help': string\n 'ui.hotkey.quit': string\n 'ui.hotkey.history': string\n 'ui.hotkey.clear': string\n 'ui.hotkey.interrupt': string\n\n // UI - Hotkey hints (context-aware)\n 'ui.hints.command': string\n 'ui.hints.bash': string\n 'ui.hints.send': string\n 'ui.hints.complete': string\n 'ui.hints.rollback': string\n 'ui.hints.select': string\n 'ui.hints.confirm': string\n 'ui.hints.close': string\n 'ui.hints.browse': string\n 'ui.hints.execute': string\n 'ui.hints.completeCommand': string\n 'ui.hints.shortcuts': string\n 'ui.hints.pressEsc': string\n 'ui.hints.tip': string\n // UI - PromptInput mode hints\n 'ui.hints.executeCommand': string\n 'ui.hints.recordNote': string\n 'ui.hints.featureMenu': string\n 'ui.hints.forNewline': string\n 'ui.hints.forBashMode': string\n 'ui.hints.forMintoMd': string\n 'ui.hints.forCommands': string\n 'ui.hints.typeToQueue': string\n 'ui.hints.backgroundTasks': string\n 'ui.hints.queued': string\n 'ui.hints.willRunAfter': string\n 'ui.hints.toEdit': string\n // UI - Completion hints\n 'ui.hints.completion.navigate': string\n 'ui.hints.completion.enterDirectory': string\n 'ui.hints.completion.selectAgent': string\n 'ui.hints.completion.insertReference': string\n 'ui.hints.completion.moreAbove': string\n 'ui.hints.completion.moreBelow': string\n\n // UI - Todo panel\n 'ui.todo.tasksRemaining': string\n 'ui.todo.allDone': string\n 'ui.todo.updatedTaskList': string\n 'ui.todo.pending': string\n 'ui.todo.inProgress': string\n 'ui.todo.done': string\n\n // UI - Model display\n 'ui.model.fallbackName': string\n // UI - Model management\n 'ui.model.manageList': string\n 'ui.model.manageListDeleteMode': string\n 'ui.model.cannotDeleteLast': string\n 'ui.model.deleteConfirmPrompt': string\n 'ui.model.addNewModelPrompt': string\n 'ui.model.configureNewModel': string\n 'ui.model.navigateHint': string\n 'ui.model.deleteHint': string\n 'ui.model.activeLabel': string\n 'ui.model.availableLabel': string\n 'ui.model.spaceToCycle': string\n 'ui.model.enterToConfigure': string\n 'ui.model.notConfigured': string\n // UI - Model config\n 'ui.modelConfig.title': string\n 'ui.modelConfig.clearMode': string\n 'ui.modelConfig.clearAssignmentPrompt': string\n 'ui.modelConfig.noModelsConfigured': string\n 'ui.modelConfig.configureHint': string\n 'ui.modelConfig.navigateHint': string\n 'ui.modelConfig.clearModePrompt': string\n // UI - Model pointer descriptions\n 'ui.modelConfig.mainDescription': string\n 'ui.modelConfig.taskDescription': string\n 'ui.modelConfig.reasoningDescription': string\n 'ui.modelConfig.quickDescription': string\n 'ui.modelConfig.compactDescription': string\n 'ui.modelConfig.manageModelsDescription': string\n\n // UI - Sensitive file warning\n 'ui.sensitiveFile.title': string\n 'ui.sensitiveFile.operating': string\n 'ui.sensitiveFile.defaultReason': string\n 'ui.sensitiveFile.operation.read': string\n 'ui.sensitiveFile.operation.write': string\n 'ui.sensitiveFile.operation.delete': string\n\n // Commands - Undo\n 'commands.undo.description': string\n 'commands.undo.title': string\n 'commands.undo.selectFile': string\n 'commands.undo.noBackups': string\n 'commands.undo.smartModeHint': string\n 'commands.undo.smartModeCommand': string\n 'commands.undo.versions': string\n 'commands.undo.selectVersion': string\n 'commands.undo.file': string\n 'commands.undo.restoredTo': string\n 'commands.undo.fileRestored': string\n 'commands.undo.restoreFailed': string\n 'commands.undo.loading': string\n 'commands.undo.error': string\n 'commands.undo.pressAnyKey': string\n 'commands.undo.pressQOrEsc': string\n 'commands.undo.navHintsFile': string\n 'commands.undo.navHintsVersion': string\n // Time format\n 'commands.undo.justNow': string\n 'commands.undo.minutesAgo': string\n 'commands.undo.today': string\n 'commands.undo.weekday.sun': string\n 'commands.undo.weekday.mon': string\n 'commands.undo.weekday.tue': string\n 'commands.undo.weekday.wed': string\n 'commands.undo.weekday.thu': string\n 'commands.undo.weekday.fri': string\n 'commands.undo.weekday.sat': string\n\n // Commands\n 'commands.help.description': string\n 'commands.clear.description': string\n 'commands.compact.description': string\n 'commands.compact.success': string\n 'commands.compact.noMessages': string\n 'commands.model.description': string\n 'commands.model.current': string\n 'commands.model.switched': string\n 'commands.model.notFound': string\n 'commands.agents.description': string\n 'commands.agents.title': string\n 'commands.agents.empty': string\n 'commands.agents.loaded': string\n 'commands.tasks.description': string\n 'commands.config.description': string\n 'commands.bug.description': string\n 'commands.doctor.description': string\n 'commands.status.description': string\n 'commands.permissions.description': string\n 'commands.mcp.description': string\n 'commands.plugin.description': string\n // Plugin - Tabs\n 'commands.plugin.tabBrowse': string\n 'commands.plugin.tabInstalled': string\n 'commands.plugin.tabMarketplaces': string\n // Plugin - Add marketplace\n 'commands.plugin.addMarketplace': string\n 'commands.plugin.addMarketplacePlaceholder': string\n // Plugin - Footer hints\n 'commands.plugin.footerHint': string\n 'commands.plugin.addFooterHint': string\n // Plugin - Install/Update/Uninstall actions\n 'commands.plugin.install': string\n 'commands.plugin.installing': string\n 'commands.plugin.installSuccess': string\n 'commands.plugin.installFailed': string\n 'commands.plugin.update': string\n 'commands.plugin.updating': string\n 'commands.plugin.updateSuccess': string\n 'commands.plugin.updateFailed': string\n 'commands.plugin.uninstall': string\n 'commands.plugin.uninstalling': string\n 'commands.plugin.uninstallSuccess': string\n 'commands.plugin.uninstallFailed': string\n 'commands.plugin.enable': string\n 'commands.plugin.disable': string\n 'commands.plugin.toggleSuccess': string\n // Plugin - Marketplace actions\n 'commands.plugin.marketplaceUpdate': string\n 'commands.plugin.marketplaceUpdating': string\n 'commands.plugin.marketplaceUpdateSuccess': string\n 'commands.plugin.marketplaceUpdateFailed': string\n 'commands.plugin.marketplaceRemove': string\n 'commands.plugin.marketplaceRemoving': string\n 'commands.plugin.marketplaceRemoveSuccess': string\n 'commands.plugin.marketplaceAdd': string\n 'commands.plugin.marketplaceAdding': string\n 'commands.plugin.marketplaceAddSuccess': string\n 'commands.plugin.marketplaceAddFailed': string\n 'commands.plugin.browsePlugins': string\n 'commands.plugin.actions': string\n 'commands.plugin.back': string\n 'commands.plugin.local': string\n 'commands.plugin.sourceClaudeCode': string\n 'commands.plugin.syncDesc': string\n 'commands.plugin.syncStarting': string\n 'commands.plugin.syncScanning': string\n 'commands.plugin.syncInstalling': string\n 'commands.plugin.syncUpdating': string\n 'commands.plugin.syncComplete': string\n 'commands.plugin.syncNoChanges': string\n 'commands.plugin.syncFailed': string\n 'commands.plugin.syncNotFound': string\n 'commands.plugin.syncCleaned': string\n 'commands.plugin.syncSkippedManual': string\n 'commands.plugin.syncDryRun': string\n 'commands.plugin.syncMarketplacesRegistered': string\n 'commands.plugin.syncMarketplacesFailed': string\n 'commands.plugin.syncMarketplacesProgress': string\n // Plugin - Batch operations\n 'commands.plugin.batchInstallAction': string\n 'commands.plugin.batchUpdateAction': string\n 'commands.plugin.batchAction': string\n 'commands.plugin.batchInstalling': string\n 'commands.plugin.batchUpdating': string\n 'commands.plugin.batchInstalledCount': string\n 'commands.plugin.batchUpdatedCount': string\n 'commands.plugin.batchFailedCount': string\n 'commands.plugin.batchDeleteAction': string\n 'commands.plugin.batchEnableAction': string\n 'commands.plugin.batchDisableAction': string\n 'commands.plugin.batchUninstalling': string\n 'commands.plugin.batchUninstalledCount': string\n 'commands.plugin.batchEnabledCount': string\n 'commands.plugin.batchDisabledCount': string\n 'commands.plugin.batchActionPickerTitle': string\n 'commands.plugin.updateAvailable': string\n 'commands.plugin.batchAllAlreadyInstalled': string\n 'commands.plugin.batchNoUpdatable': string\n 'commands.plugin.footerHintMultiSelect': string\n 'commands.sandbox.description': string\n 'commands.thinking.description': string\n 'commands.thinking.enabled': string\n 'commands.thinking.disabled': string\n 'commands.language.description': string\n 'commands.language.title': string\n 'commands.language.current': string\n 'commands.language.select': string\n 'commands.language.changed': string\n 'commands.language.restart': string\n 'commands.language.alreadyUsing': string\n 'commands.language.navigate': string\n\n // Commands - Sessions\n 'commands.sessions.description': string\n 'commands.sessions.title': string\n 'commands.sessions.count': string\n 'commands.sessions.noSessions': string\n 'commands.sessions.headerDate': string\n 'commands.sessions.headerProject': string\n 'commands.sessions.headerPrompt': string\n 'commands.sessions.headerMsgs': string\n 'commands.sessions.headerTools': string\n 'commands.sessions.helpHint': string\n 'commands.sessions.today': string\n 'commands.sessions.yesterday': string\n 'commands.sessions.moreBelow': string\n 'commands.sessions.navigationHint': string\n\n // Commands - Resume\n 'commands.resume.description': string\n 'commands.resume.title': string\n 'commands.resume.noSessions': string\n 'commands.resume.navigationHint': string\n\n // Commands - New\n 'commands.new.description': string\n\n // Tools\n 'tools.bash.description': string\n 'tools.bash.executing': string\n 'tools.bash.completed': string\n 'tools.bash.failed': string\n 'tools.read.description': string\n 'tools.read.reading': string\n 'tools.write.description': string\n 'tools.write.writing': string\n 'tools.write.created': string\n 'tools.write.updated': string\n 'tools.edit.description': string\n 'tools.edit.editing': string\n 'tools.glob.description': string\n 'tools.grep.description': string\n 'tools.task.description': string\n 'tools.task.spawning': string\n 'tools.task.running': string\n 'tools.task.completed': string\n 'tools.todo.description': string\n\n // Errors\n 'errors.generic': string\n 'errors.network': string\n 'errors.timeout': string\n 'errors.auth': string\n 'errors.rateLimit': string\n 'errors.modelNotFound': string\n 'errors.apiKeyMissing': string\n 'errors.apiKeyInvalid': string\n 'errors.permissionDenied': string\n 'errors.fileNotFound': string\n 'errors.fileReadError': string\n 'errors.fileWriteError': string\n 'errors.configError': string\n 'errors.parseError': string\n 'errors.validationError': string\n 'errors.aborted': string\n 'errors.contextTooLong': string\n 'errors.serverError': string\n 'errors.connectionFailed': string\n\n // Help\n 'help.title': string\n 'help.usage': string\n 'help.commands': string\n 'help.options': string\n 'help.examples': string\n 'help.moreInfo': string\n 'help.reportBug': string\n 'help.documentation': string\n // Help - Usage modes\n 'help.usageModes': string\n 'help.nonInteractive': string\n 'help.runForOptions': string\n // Help - Common tasks\n 'help.commonTasks': string\n 'help.taskAskQuestions': string\n 'help.taskEditFiles': string\n 'help.taskFixErrors': string\n 'help.taskRunCommands': string\n 'help.taskRunBash': string\n // Help - Command categories\n 'help.builtInCommands': string\n 'help.customCommands': string\n 'help.pluginCommands': string\n 'help.mcpCommands': string\n // Help - Command loading\n 'help.commandPriority': string\n 'help.priorityBuiltIn': string\n 'help.priorityCustom': string\n 'help.priorityPlugin': string\n 'help.priorityMcp': string\n 'help.refreshCommandsHint': string\n // Help - Product description\n 'help.productDescription': string\n // Help - Mode Systems\n 'help.modeSystems': string\n 'help.safetyModes': string\n 'help.safetyModeYolo': string\n 'help.safetyModeSmart': string\n 'help.safetyModeStrict': string\n 'help.safetyModeFree': string\n 'help.permissionModes': string\n 'help.permissionModeDefault': string\n 'help.permissionModeAcceptEdits': string\n 'help.permissionModePlan': string\n 'help.permissionModeBypass': string\n 'help.modeInteraction': string\n\n // Status messages\n 'status.modelLoaded': string\n 'status.contextCompressed': string\n 'status.tokensUsed': string\n 'status.costEstimate': string\n 'status.apiLatency': string\n 'status.streaming': string\n 'status.thinking': string\n 'status.toolUse': string\n 'status.subagent': string\n\n // Prompts\n 'prompts.confirmDelete': string\n 'prompts.confirmOverwrite': string\n 'prompts.confirmExecute': string\n 'prompts.enterApiKey': string\n 'prompts.selectModel': string\n 'prompts.selectLanguage': string\n 'prompts.interruptedByUser': string\n 'prompts.interruptedCtrlC': string\n 'prompts.interruptedEscEsc': string\n 'prompts.inputCleared': string\n 'prompts.inputClearedCtrlD': string\n 'prompts.inputClearedEscEsc': string\n 'prompts.screenCleared': string\n 'prompts.todoPanelToggled': string\n 'prompts.typeCommandFirst': string\n 'prompts.executingBash': string\n 'prompts.exitingGracefully': string\n 'prompts.pressCtrlDToExit': string\n 'prompts.pressCtrlDAgain': string\n 'prompts.pressEscAgainClear': string\n 'prompts.pressEscAgainInterrupt': string\n 'prompts.thinkingModeEnabled': string\n 'prompts.thinkingModeDisabled': string\n 'prompts.limitedInputMode': string\n 'prompts.limitedInputModeDetail': string\n 'prompts.queuedMessage': string\n 'prompts.noModelsConfigured': string\n 'prompts.noActiveModels': string\n 'prompts.onlyOneActiveModel': string\n 'prompts.modelSwitchingFailed': string\n\n // Agent/Subagent\n 'agent.spawning': string\n 'agent.running': string\n 'agent.completed': string\n 'agent.failed': string\n 'agent.cancelled': string\n 'agent.waiting': string\n 'agent.thinking': string\n\n // Model\n 'model.selecting': string\n 'model.selected': string\n 'model.unavailable': string\n 'model.switching': string\n 'model.switched': string\n 'model.default': string\n 'model.custom': string\n\n // Permissions\n 'permission.required': string\n 'permission.granted': string\n 'permission.denied': string\n 'permission.allowOnce': string\n 'permission.allowAlways': string\n 'permission.denyOnce': string\n 'permission.denyAlways': string\n 'permission.sensitiveFile': string\n 'permission.externalPath': string\n 'permission.dangerousCommand': string\n\n // Dialog - Generic\n 'dialog.enterToConfirm': string\n 'dialog.escToCancel': string\n 'dialog.confirmCancelPrompt': string\n 'dialog.enterCustomResponse': string\n // Dialog - Message selector\n 'dialog.jumpToPreviousMessage': string\n 'dialog.forkConversation': string\n 'dialog.current': string\n 'dialog.emptyMessage': string\n 'dialog.selectConfirmCancelPrompt': string\n // Dialog - MCP server\n 'dialog.mcpServerDetected': string\n 'dialog.mcpServersDetected': string\n 'dialog.mcpApprovalRequired': string\n 'dialog.mcpSelectServers': string\n 'dialog.approveServer': string\n 'dialog.rejectServer': string\n 'dialog.confirmRejectPrompt': string\n 'dialog.selectConfirmRejectAllPrompt': string\n // Dialog - Trust\n 'dialog.trustTitle': string\n 'dialog.trustWarning1': string\n 'dialog.trustWarning2': string\n 'dialog.yesProceed': string\n 'dialog.noExit': string\n 'dialog.confirmExitPrompt': string\n\n // Config\n 'config.title': string\n 'config.modelConfiguration': string\n 'config.noModelsConfigured': string\n 'config.useModelCommand': string\n 'config.enterToSaveEscToCancel': string\n 'config.navigateChangeClose': string\n 'config.enterNewValue': string\n 'config.theme': string\n 'config.verboseMode': string\n 'config.streamResponses': string\n 'config.compressionMode': string\n 'config.backupEnabled': string\n 'config.backupEnabled.description': string\n\n // HotkeyHelpPanel\n 'hotkey.navigation': string\n 'hotkey.control': string\n 'hotkey.features': string\n 'hotkey.inputModes': string\n 'hotkey.browseHistory': string\n 'hotkey.searchHistory': string\n 'hotkey.autocomplete': string\n 'hotkey.rollbackResponse': string\n 'hotkey.cancelOperation': string\n 'hotkey.exitPressTwice': string\n 'hotkey.clearScreen': string\n 'hotkey.submitPrompt': string\n 'hotkey.toggleTodoPanel': string\n 'hotkey.cycleDisplayMode': string\n 'hotkey.executeAsBash': string\n 'hotkey.showHideHelp': string\n 'hotkey.startSlashCommand': string\n 'hotkey.executeBashCommand': string\n 'hotkey.addNoteToKoding': string\n 'hotkey.ctrlQuestionForShortcuts': string\n\n // User-Friendly Error Messages\n // Network & Connectivity\n 'friendlyError.networkConnection.title': string\n 'friendlyError.networkConnection.description': string\n 'friendlyError.networkConnection.suggestion1': string\n 'friendlyError.networkConnection.suggestion2': string\n 'friendlyError.networkConnection.suggestion3': string\n\n 'friendlyError.networkTimeout.title': string\n 'friendlyError.networkTimeout.description': string\n 'friendlyError.networkTimeout.suggestion1': string\n 'friendlyError.networkTimeout.suggestion2': string\n 'friendlyError.networkTimeout.suggestion3': string\n\n 'friendlyError.networkDns.title': string\n 'friendlyError.networkDns.description': string\n 'friendlyError.networkDns.suggestion1': string\n 'friendlyError.networkDns.suggestion2': string\n 'friendlyError.networkDns.suggestion3': string\n\n // API & Service\n 'friendlyError.apiRateLimit.title': string\n 'friendlyError.apiRateLimit.description': string\n 'friendlyError.apiRateLimit.suggestion1': string\n 'friendlyError.apiRateLimit.suggestion2': string\n 'friendlyError.apiRateLimit.suggestion3': string\n\n 'friendlyError.apiAuth.title': string\n 'friendlyError.apiAuth.description': string\n 'friendlyError.apiAuth.suggestion1': string\n 'friendlyError.apiAuth.suggestion2': string\n 'friendlyError.apiAuth.suggestion3': string\n\n 'friendlyError.apiQuota.title': string\n 'friendlyError.apiQuota.description': string\n 'friendlyError.apiQuota.suggestion1': string\n 'friendlyError.apiQuota.suggestion2': string\n 'friendlyError.apiQuota.suggestion3': string\n\n 'friendlyError.apiServerError.title': string\n 'friendlyError.apiServerError.description': string\n 'friendlyError.apiServerError.suggestion1': string\n 'friendlyError.apiServerError.suggestion2': string\n\n 'friendlyError.apiInvalidResponse.title': string\n 'friendlyError.apiInvalidResponse.description': string\n 'friendlyError.apiInvalidResponse.suggestion1': string\n 'friendlyError.apiInvalidResponse.suggestion2': string\n\n // File & Storage\n 'friendlyError.fileNotFound.title': string\n 'friendlyError.fileNotFound.description': string\n 'friendlyError.fileNotFound.suggestion1': string\n 'friendlyError.fileNotFound.suggestion2': string\n\n 'friendlyError.filePermission.title': string\n 'friendlyError.filePermission.description': string\n 'friendlyError.filePermission.suggestion1': string\n 'friendlyError.filePermission.suggestion2': string\n\n 'friendlyError.fileTooLarge.title': string\n 'friendlyError.fileTooLarge.description': string\n 'friendlyError.fileTooLarge.suggestion1': string\n 'friendlyError.fileTooLarge.suggestion2': string\n\n 'friendlyError.fileEncoding.title': string\n 'friendlyError.fileEncoding.description': string\n 'friendlyError.fileEncoding.suggestion1': string\n 'friendlyError.fileEncoding.suggestion2': string\n\n // Configuration\n 'friendlyError.configMissing.title': string\n 'friendlyError.configMissing.description': string\n 'friendlyError.configMissing.suggestion1': string\n 'friendlyError.configMissing.suggestion2': string\n\n 'friendlyError.configInvalid.title': string\n 'friendlyError.configInvalid.description': string\n 'friendlyError.configInvalid.suggestion1': string\n 'friendlyError.configInvalid.suggestion2': string\n\n 'friendlyError.configApiKey.title': string\n 'friendlyError.configApiKey.description': string\n 'friendlyError.configApiKey.suggestion1': string\n 'friendlyError.configApiKey.suggestion2': string\n\n // Model & AI\n 'friendlyError.modelUnavailable.title': string\n 'friendlyError.modelUnavailable.description': string\n 'friendlyError.modelUnavailable.suggestion1': string\n 'friendlyError.modelUnavailable.suggestion2': string\n 'friendlyError.modelUnavailable.suggestion3': string\n\n 'friendlyError.modelContextLength.title': string\n 'friendlyError.modelContextLength.description': string\n 'friendlyError.modelContextLength.suggestion1': string\n 'friendlyError.modelContextLength.suggestion2': string\n\n 'friendlyError.modelContentFilter.title': string\n 'friendlyError.modelContentFilter.description': string\n 'friendlyError.modelContentFilter.suggestion1': string\n 'friendlyError.modelContentFilter.suggestion2': string\n\n // System\n 'friendlyError.systemMemory.title': string\n 'friendlyError.systemMemory.description': string\n 'friendlyError.systemMemory.suggestion1': string\n 'friendlyError.systemMemory.suggestion2': string\n 'friendlyError.systemMemory.suggestion3': string\n\n 'friendlyError.systemProcess.title': string\n 'friendlyError.systemProcess.description': string\n 'friendlyError.systemProcess.suggestion1': string\n 'friendlyError.systemProcess.suggestion2': string\n\n // Unknown\n 'friendlyError.unknown.title': string\n 'friendlyError.unknown.description': string\n 'friendlyError.unknown.suggestion1': string\n 'friendlyError.unknown.suggestion2': string\n\n // Error display format\n 'friendlyError.suggestionLabel': string\n 'friendlyError.errorIdLabel': string\n 'friendlyError.technicalDetailsLabel': string\n\n // UI - TabbedListView\n 'ui.tabbedList.search': string\n 'ui.tabbedList.loading': string\n 'ui.tabbedList.noItems': string\n 'ui.tabbedList.moreAbove': string\n 'ui.tabbedList.moreBelow': string\n 'ui.tabbedList.tabCycleHint': string\n 'ui.tabbedList.navigationHint': string\n\n // UI - InfoPanel\n 'ui.infoPanel.continueHint': string\n 'ui.infoPanel.dismissHint': string\n\n // UI - SimpleSelector\n 'ui.simpleSelector.navigationHint': string\n 'ui.simpleSelector.dismissHint': string\n\n // Commands - Status\n 'commands.status.title': string\n 'commands.status.versionInfo': string\n 'commands.status.environment': string\n 'commands.status.modelConfiguration': string\n 'commands.status.apiConnection': string\n 'commands.status.connected': string\n 'commands.status.notConnected': string\n 'commands.status.notConfigured': string\n\n // Commands - Context\n 'commands.context.title': string\n 'commands.context.contextUsage': string\n 'commands.context.tokens': string\n 'commands.context.remaining': string\n 'commands.context.messages': string\n 'commands.context.estTurns': string\n 'commands.context.highUsage': string\n 'commands.context.criticalUsage': string\n\n // Commands - Model status\n 'commands.model.title': string\n 'commands.model.modelPointers': string\n 'commands.model.configure': string\n 'commands.model.error': string\n // Commands - Model (refactored phases)\n 'commands.model.selectModel': string\n 'commands.model.pointerUpdated': string\n 'commands.model.pointerCleared': string\n 'commands.model.modelLibrary': string\n 'commands.model.modelLibrarySubtitle': string\n 'commands.model.addNewModel': string\n 'commands.model.clearAssignment': string\n 'commands.model.modelActions': string\n 'commands.model.confirmDeleteTitle': string\n 'commands.model.confirmDeleteYes': string\n 'commands.model.confirmDeleteNo': string\n 'commands.model.editModel': string\n 'commands.model.editTitle': string\n 'commands.model.modelDeleted': string\n 'commands.model.deleteFailed': string\n 'commands.model.actionsCategory': string\n 'commands.model.pointersCategory': string\n\n // Commands - Sandbox\n 'commands.sandbox.title': string\n 'commands.sandbox.statusSection': string\n 'commands.sandbox.implementation': string\n 'commands.sandbox.filesystemPolicy': string\n 'commands.sandbox.networkPolicy': string\n 'commands.sandbox.processPolicy': string\n 'commands.sandbox.helpSection': string\n 'commands.sandbox.toggle': string\n 'commands.sandbox.toggleHelp': string\n 'commands.sandbox.enabled': string\n 'commands.sandbox.disabled': string\n 'commands.sandbox.notAvailable': string\n\n // Commands - Help\n 'commands.help.title': string\n\n // Commands - MCP\n 'commands.mcp.title': string\n 'commands.mcp.noServers': string\n 'commands.mcp.addServer': string\n 'commands.mcp.refreshAll': string\n 'commands.mcp.enable': string\n 'commands.mcp.disable': string\n 'commands.mcp.deleteServer': string\n 'commands.mcp.confirmDeleteTitle': string\n 'commands.mcp.confirmYes': string\n 'commands.mcp.confirmNo': string\n // MCP - Tabs\n 'commands.mcp.tabAll': string\n 'commands.mcp.tabProject': string\n 'commands.mcp.tabGlobal': string\n // MCP - Add server\n 'commands.mcp.addNamePlaceholder': string\n 'commands.mcp.addCommandPlaceholder': string\n 'commands.mcp.addFooterHint': string\n 'commands.mcp.addCommandFooterHint': string\n // MCP - Status overlays\n 'commands.mcp.adding': string\n 'commands.mcp.addSuccess': string\n 'commands.mcp.addFailed': string\n 'commands.mcp.toggling': string\n 'commands.mcp.toggleSuccess': string\n 'commands.mcp.deleting': string\n 'commands.mcp.deleteSuccess': string\n 'commands.mcp.refreshing': string\n 'commands.mcp.refreshSuccess': string\n // MCP - Sub-phase labels\n 'commands.mcp.back': string\n 'commands.mcp.actions': string\n\n // Commands - Undo\n 'commands.undo.tabFiles': string\n 'commands.undo.tabVersions': string\n\n // Commands - Export\n 'commands.export.description': string\n 'commands.export.title': string\n 'commands.export.selectType': string\n 'commands.export.selectScope': string\n 'commands.export.typeRuntime': string\n 'commands.export.typeRuntimeDesc': string\n 'commands.export.typeTeam': string\n 'commands.export.typeTeamDesc': string\n 'commands.export.scopeUser': string\n 'commands.export.scopeUserDesc': string\n 'commands.export.scopeProject': string\n 'commands.export.scopeProjectDesc': string\n 'commands.export.typeConversation': string\n 'commands.export.typeConversationDesc': string\n 'commands.export.typeSummary': string\n 'commands.export.typeSummaryDesc': string\n 'commands.export.exporting': string\n 'commands.export.success': string\n 'commands.export.failed': string\n 'commands.export.noPlugins': string\n 'commands.export.noAgents': string\n 'commands.export.noHooks': string\n 'commands.export.navigationHint': string\n 'commands.export.sensitiveDataTitle': string\n 'commands.export.sensitiveDataQuestion': string\n 'commands.export.sensitiveInclude': string\n 'commands.export.sensitiveIncludeDesc': string\n 'commands.export.sensitivePlaceholder': string\n 'commands.export.sensitivePlaceholderDesc': string\n // Export - scope descriptions\n 'commands.export.scopeAll': string\n 'commands.export.scopeAllDesc': string\n // Export - flattened TabbedListView items\n 'commands.export.itemTeamUserInclude': string\n 'commands.export.itemTeamUserPlaceholder': string\n 'commands.export.itemTeamProjectInclude': string\n 'commands.export.itemTeamProjectPlaceholder': string\n 'commands.export.itemTeamAllInclude': string\n 'commands.export.itemTeamAllPlaceholder': string\n 'commands.export.itemRuntimeUser': string\n 'commands.export.itemRuntimeProject': string\n 'commands.export.itemRuntimeAll': string\n 'commands.export.itemConversation': string\n 'commands.export.itemSummary': string\n 'commands.export.footerHint': string\n\n // Commands - Setup\n 'commands.setup.description': string\n 'commands.setup.previewTitle': string\n 'commands.setup.tabOverview': string\n 'commands.setup.tabModels': string\n 'commands.setup.tabMcp': string\n 'commands.setup.tabPlugins': string\n 'commands.setup.tabAgents': string\n 'commands.setup.tabHooks': string\n 'commands.setup.tabSettings': string\n 'commands.setup.confirmHint': string\n 'commands.setup.applying': string\n 'commands.setup.tabSkills': string\n 'commands.setup.tabCommands': string\n 'commands.setup.installingPlugins': string\n 'commands.setup.installingProjectPlugins': string\n 'commands.setup.installingAgents': string\n 'commands.setup.installingHooks': string\n 'commands.setup.installingSkills': string\n 'commands.setup.installingCommands': string\n 'commands.setup.addingMarketplaces': string\n 'commands.setup.success': string\n 'commands.setup.failed': string\n 'commands.setup.loading': string\n 'commands.setup.errorMissingFrom': string\n 'commands.setup.errorUsage': string\n\n // Commands - Stats\n 'commands.stats.description': string\n 'commands.stats.title': string\n 'commands.stats.today': string\n 'commands.stats.thisWeek': string\n 'commands.stats.thisMonth': string\n 'commands.stats.lifetime': string\n 'commands.stats.messages': string\n 'commands.stats.sessions': string\n 'commands.stats.toolCalls': string\n 'commands.stats.tokens': string\n 'commands.stats.totalMessages': string\n 'commands.stats.totalSessions': string\n 'commands.stats.totalTools': string\n 'commands.stats.estCost': string\n 'commands.stats.modelUsage': string\n 'commands.stats.topTools': string\n 'commands.stats.calls': string\n 'commands.stats.noData': string\n 'commands.stats.vsYesterday': string\n 'commands.stats.firstUsed': string\n\n // ModelSelector Wizard\n 'modelSelector.providerSelection': string\n 'modelSelector.providerSelectionDesc': string\n 'modelSelector.providerSelectionHint': string\n 'modelSelector.anthropicSubMenu': string\n 'modelSelector.anthropicSubMenuDesc': string\n 'modelSelector.anthropicOfficial': string\n 'modelSelector.anthropicOfficialDesc': string\n 'modelSelector.anthropicBigdream': string\n 'modelSelector.anthropicBigdreamDesc': string\n 'modelSelector.anthropicOpendev': string\n 'modelSelector.anthropicOpendevDesc': string\n 'modelSelector.anthropicCustom': string\n 'modelSelector.anthropicCustomDesc': string\n 'modelSelector.baseUrlTitle': string\n 'modelSelector.baseUrlDesc': string\n 'modelSelector.baseUrlOllamaDesc': string\n 'modelSelector.customApiTitle': string\n 'modelSelector.customApiDesc': string\n 'modelSelector.apiKeyTitle': string\n 'modelSelector.apiKeyDesc': string\n 'modelSelector.apiKeyTabHintManual': string\n 'modelSelector.apiKeyTabHintSkip': string\n 'modelSelector.resourceNameTitle': string\n 'modelSelector.resourceNameDesc': string\n 'modelSelector.modelSelectionTitle': string\n 'modelSelector.modelSelectionDesc': string\n 'modelSelector.modelSearchPlaceholder': string\n 'modelSelector.modelInputTitle': string\n 'modelSelector.modelParamsTitle': string\n 'modelSelector.modelParamsDesc': string\n 'modelSelector.maxTokens': string\n 'modelSelector.reasoningEffort': string\n 'modelSelector.contextLengthTitle': string\n 'modelSelector.contextLengthDesc': string\n 'modelSelector.connectionTestRetry': string\n 'modelSelector.confirmationSave': string\n 'modelSelector.configError': string\n 'modelSelector.testAndSaveTitle': string\n 'modelSelector.testAndSaveDesc': string\n 'modelSelector.saveAnyway': string\n 'modelSelector.autoTesting': string\n 'modelSelector.footerEnterContinue': string\n 'modelSelector.footerEscBack': string\n 'modelSelector.footerNavSelectEsc': string\n 'modelSelector.footerTabNavigate': string\n 'modelSelector.showingModels': string\n 'modelSelector.noModelsMatch': string\n 'modelSelector.noModelsAvailable': string\n 'modelSelector.recommended': string\n 'modelSelector.continue': string\n}\n\n/**\n * Full translation object type\n */\nexport type Translations = TranslationKeys\n\n/**\n * Translation key type (string union of all keys)\n */\nexport type TranslationKey = keyof TranslationKeys\n\n/**\n * Partial translations for extending\n */\nexport type PartialTranslations = Partial<TranslationKeys>\n"],
|
|
5
5
|
"mappings": "AAcO,MAAM,iBAA2C;AAAA,EACtD,IAAI;AAAA,EACJ,SAAS;AACX;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/messages.js
CHANGED
|
@@ -1,39 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
class MessageBus {
|
|
2
|
+
messagesGetter = () => [];
|
|
3
|
+
messagesSetter = () => {
|
|
4
|
+
};
|
|
5
|
+
modelConfigChangeHandler = null;
|
|
6
|
+
languageChangeHandler = null;
|
|
7
|
+
registerMessagesGetter(getter) {
|
|
8
|
+
this.messagesGetter = getter;
|
|
9
|
+
}
|
|
10
|
+
getMessagesGetter() {
|
|
11
|
+
return this.messagesGetter;
|
|
12
|
+
}
|
|
13
|
+
registerMessagesSetter(setter) {
|
|
14
|
+
this.messagesSetter = setter;
|
|
15
|
+
}
|
|
16
|
+
getMessagesSetter() {
|
|
17
|
+
return this.messagesSetter;
|
|
18
|
+
}
|
|
19
|
+
setModelConfigChangeHandler(handler) {
|
|
20
|
+
this.modelConfigChangeHandler = handler;
|
|
21
|
+
}
|
|
22
|
+
triggerModelConfigChange() {
|
|
23
|
+
this.modelConfigChangeHandler?.();
|
|
24
|
+
}
|
|
25
|
+
setLanguageChangeHandler(handler) {
|
|
26
|
+
this.languageChangeHandler = handler;
|
|
27
|
+
}
|
|
28
|
+
async triggerLanguageChange() {
|
|
29
|
+
await this.languageChangeHandler?.();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const messageBus = new MessageBus();
|
|
4
33
|
function setMessagesGetter(getter) {
|
|
5
|
-
|
|
34
|
+
messageBus.registerMessagesGetter(getter);
|
|
6
35
|
}
|
|
7
36
|
function getMessagesGetter() {
|
|
8
|
-
return
|
|
37
|
+
return messageBus.getMessagesGetter();
|
|
9
38
|
}
|
|
10
39
|
function setMessagesSetter(setter) {
|
|
11
|
-
|
|
40
|
+
messageBus.registerMessagesSetter(setter);
|
|
12
41
|
}
|
|
13
42
|
function getMessagesSetter() {
|
|
14
|
-
return
|
|
43
|
+
return messageBus.getMessagesSetter();
|
|
15
44
|
}
|
|
16
|
-
let onModelConfigChange = null;
|
|
17
45
|
function setModelConfigChangeHandler(handler) {
|
|
18
|
-
|
|
46
|
+
messageBus.setModelConfigChangeHandler(handler);
|
|
19
47
|
}
|
|
20
48
|
function triggerModelConfigChange() {
|
|
21
|
-
|
|
22
|
-
onModelConfigChange();
|
|
23
|
-
}
|
|
49
|
+
messageBus.triggerModelConfigChange();
|
|
24
50
|
}
|
|
25
|
-
let onLanguageChange = null;
|
|
26
51
|
function setLanguageChangeHandler(handler) {
|
|
27
|
-
|
|
52
|
+
messageBus.setLanguageChangeHandler(handler);
|
|
28
53
|
}
|
|
29
54
|
async function triggerLanguageChange() {
|
|
30
|
-
|
|
31
|
-
await onLanguageChange();
|
|
32
|
-
}
|
|
55
|
+
await messageBus.triggerLanguageChange();
|
|
33
56
|
}
|
|
34
57
|
export {
|
|
35
58
|
getMessagesGetter,
|
|
36
59
|
getMessagesSetter,
|
|
60
|
+
messageBus,
|
|
37
61
|
setLanguageChangeHandler,
|
|
38
62
|
setMessagesGetter,
|
|
39
63
|
setMessagesSetter,
|
package/dist/messages.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/messages.ts"],
|
|
4
|
-
"sourcesContent": ["import React from 'react'\nimport type { Message } from './query'\n\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import React from 'react'\nimport type { Message } from './query'\n\n/**\n * MessageBus \u2014 encapsulates global message state and UI refresh handlers.\n *\n * Replaces loose module-level variables with a single owning object.\n * Provides getter/setter registration for React state binding,\n * plus event-style hooks for model config and language changes.\n */\nclass MessageBus {\n private messagesGetter: () => Message[] = () => []\n private messagesSetter: React.Dispatch<React.SetStateAction<Message[]>> =\n () => {}\n private modelConfigChangeHandler: (() => void) | null = null\n private languageChangeHandler: (() => Promise<void>) | null = null\n\n registerMessagesGetter(getter: () => Message[]): void {\n this.messagesGetter = getter\n }\n\n getMessagesGetter(): () => Message[] {\n return this.messagesGetter\n }\n\n registerMessagesSetter(\n setter: React.Dispatch<React.SetStateAction<Message[]>>,\n ): void {\n this.messagesSetter = setter\n }\n\n getMessagesSetter(): React.Dispatch<React.SetStateAction<Message[]>> {\n return this.messagesSetter\n }\n\n setModelConfigChangeHandler(handler: () => void): void {\n this.modelConfigChangeHandler = handler\n }\n\n triggerModelConfigChange(): void {\n this.modelConfigChangeHandler?.()\n }\n\n setLanguageChangeHandler(handler: () => Promise<void>): void {\n this.languageChangeHandler = handler\n }\n\n async triggerLanguageChange(): Promise<void> {\n await this.languageChangeHandler?.()\n }\n}\n\nexport const messageBus = new MessageBus()\n\n// Backward-compatible function exports (thin wrappers)\nexport function setMessagesGetter(getter: () => Message[]) {\n messageBus.registerMessagesGetter(getter)\n}\n\nexport function getMessagesGetter(): () => Message[] {\n return messageBus.getMessagesGetter()\n}\n\nexport function setMessagesSetter(\n setter: React.Dispatch<React.SetStateAction<Message[]>>,\n) {\n messageBus.registerMessagesSetter(setter)\n}\n\nexport function getMessagesSetter(): React.Dispatch<\n React.SetStateAction<Message[]>\n> {\n return messageBus.getMessagesSetter()\n}\n\nexport function setModelConfigChangeHandler(handler: () => void) {\n messageBus.setModelConfigChangeHandler(handler)\n}\n\nexport function triggerModelConfigChange() {\n messageBus.triggerModelConfigChange()\n}\n\nexport function setLanguageChangeHandler(handler: () => Promise<void>) {\n messageBus.setLanguageChangeHandler(handler)\n}\n\nexport async function triggerLanguageChange() {\n await messageBus.triggerLanguageChange()\n}\n"],
|
|
5
|
+
"mappings": "AAUA,MAAM,WAAW;AAAA,EACP,iBAAkC,MAAM,CAAC;AAAA,EACzC,iBACN,MAAM;AAAA,EAAC;AAAA,EACD,2BAAgD;AAAA,EAChD,wBAAsD;AAAA,EAE9D,uBAAuB,QAA+B;AACpD,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,oBAAqC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,uBACE,QACM;AACN,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,oBAAqE;AACnE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,4BAA4B,SAA2B;AACrD,SAAK,2BAA2B;AAAA,EAClC;AAAA,EAEA,2BAAiC;AAC/B,SAAK,2BAA2B;AAAA,EAClC;AAAA,EAEA,yBAAyB,SAAoC;AAC3D,SAAK,wBAAwB;AAAA,EAC/B;AAAA,EAEA,MAAM,wBAAuC;AAC3C,UAAM,KAAK,wBAAwB;AAAA,EACrC;AACF;AAEO,MAAM,aAAa,IAAI,WAAW;AAGlC,SAAS,kBAAkB,QAAyB;AACzD,aAAW,uBAAuB,MAAM;AAC1C;AAEO,SAAS,oBAAqC;AACnD,SAAO,WAAW,kBAAkB;AACtC;AAEO,SAAS,kBACd,QACA;AACA,aAAW,uBAAuB,MAAM;AAC1C;AAEO,SAAS,oBAEd;AACA,SAAO,WAAW,kBAAkB;AACtC;AAEO,SAAS,4BAA4B,SAAqB;AAC/D,aAAW,4BAA4B,OAAO;AAChD;AAEO,SAAS,2BAA2B;AACzC,aAAW,yBAAyB;AACtC;AAEO,SAAS,yBAAyB,SAA8B;AACrE,aAAW,yBAAyB,OAAO;AAC7C;AAEA,eAAsB,wBAAwB;AAC5C,QAAM,WAAW,sBAAsB;AACzC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/permissions.js
CHANGED
|
@@ -15,7 +15,11 @@ import { PRODUCT_NAME } from "./constants/product.js";
|
|
|
15
15
|
import {
|
|
16
16
|
getToolRiskLevel
|
|
17
17
|
} from "./utils/toolRiskClassification.js";
|
|
18
|
-
import { resolve, relative, isAbsolute } from "path";
|
|
18
|
+
import { resolve, relative, isAbsolute, join } from "path";
|
|
19
|
+
import { getHookManager } from "./utils/hookManager.js";
|
|
20
|
+
import { existsSync, readFileSync } from "fs";
|
|
21
|
+
import { homedir } from "os";
|
|
22
|
+
import { CONFIG_BASE_DIR } from "./constants/product.js";
|
|
19
23
|
const SAFE_COMMANDS = /* @__PURE__ */ new Set([
|
|
20
24
|
"git status",
|
|
21
25
|
"git diff",
|
|
@@ -241,7 +245,70 @@ function shouldAllowByRiskLevel(safetyMode, riskLevel, toolName, input) {
|
|
|
241
245
|
return false;
|
|
242
246
|
}
|
|
243
247
|
}
|
|
248
|
+
let settingsPermissionsCache = null;
|
|
249
|
+
function loadSettingsPermissions() {
|
|
250
|
+
if (settingsPermissionsCache) return settingsPermissionsCache;
|
|
251
|
+
const deny = [];
|
|
252
|
+
const allow = [];
|
|
253
|
+
const cwd = getCwd();
|
|
254
|
+
const home = homedir();
|
|
255
|
+
const settingsFiles = [
|
|
256
|
+
join(home, ".claude", "settings.json"),
|
|
257
|
+
join(home, CONFIG_BASE_DIR, "settings.json"),
|
|
258
|
+
join(cwd, ".claude", "settings.json"),
|
|
259
|
+
join(cwd, CONFIG_BASE_DIR, "settings.json")
|
|
260
|
+
];
|
|
261
|
+
for (const file of settingsFiles) {
|
|
262
|
+
if (!existsSync(file)) continue;
|
|
263
|
+
try {
|
|
264
|
+
const content = JSON.parse(readFileSync(file, "utf-8"));
|
|
265
|
+
if (content?.permissions?.deny && Array.isArray(content.permissions.deny)) {
|
|
266
|
+
deny.push(...content.permissions.deny);
|
|
267
|
+
}
|
|
268
|
+
if (content?.permissions?.allow && Array.isArray(content.permissions.allow)) {
|
|
269
|
+
allow.push(...content.permissions.allow);
|
|
270
|
+
}
|
|
271
|
+
} catch {
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
settingsPermissionsCache = { deny, allow };
|
|
275
|
+
return settingsPermissionsCache;
|
|
276
|
+
}
|
|
277
|
+
function matchesPermissionPattern(toolName, input, patterns) {
|
|
278
|
+
for (const pattern of patterns) {
|
|
279
|
+
if (pattern === toolName) return true;
|
|
280
|
+
if (toolName === "Bash" && pattern.startsWith("Bash(") && input?.command) {
|
|
281
|
+
const cmdPattern = pattern.slice(5, -1);
|
|
282
|
+
const command = String(input.command);
|
|
283
|
+
if (cmdPattern.endsWith(":*")) {
|
|
284
|
+
const prefix = cmdPattern.slice(0, -2);
|
|
285
|
+
if (command.startsWith(prefix)) return true;
|
|
286
|
+
} else if (command === cmdPattern) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
244
293
|
const hasPermissionsToUseTool = async (tool, input, context, _assistantMessage) => {
|
|
294
|
+
const settingsPerms = loadSettingsPermissions();
|
|
295
|
+
if (matchesPermissionPattern(
|
|
296
|
+
tool.name,
|
|
297
|
+
input,
|
|
298
|
+
settingsPerms.deny
|
|
299
|
+
)) {
|
|
300
|
+
return {
|
|
301
|
+
result: false,
|
|
302
|
+
message: `Tool "${tool.name}" is denied by settings configuration.`
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (matchesPermissionPattern(
|
|
306
|
+
tool.name,
|
|
307
|
+
input,
|
|
308
|
+
settingsPerms.allow
|
|
309
|
+
)) {
|
|
310
|
+
return { result: true };
|
|
311
|
+
}
|
|
245
312
|
const safetyMode = getEffectiveSafetyMode(context.options);
|
|
246
313
|
const riskLevel = getToolRiskLevel(
|
|
247
314
|
tool.name,
|
|
@@ -295,6 +362,13 @@ const hasPermissionsToUseTool = async (tool, input, context, _assistantMessage)
|
|
|
295
362
|
if (allowedTools.includes(permissionKey)) {
|
|
296
363
|
return { result: true };
|
|
297
364
|
}
|
|
365
|
+
const hookDecision = await firePermissionRequestHook(
|
|
366
|
+
tool.name,
|
|
367
|
+
input
|
|
368
|
+
);
|
|
369
|
+
if (hookDecision === "approve") {
|
|
370
|
+
return { result: true };
|
|
371
|
+
}
|
|
298
372
|
return {
|
|
299
373
|
result: false,
|
|
300
374
|
message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`
|
|
@@ -302,6 +376,25 @@ const hasPermissionsToUseTool = async (tool, input, context, _assistantMessage)
|
|
|
302
376
|
}
|
|
303
377
|
}
|
|
304
378
|
};
|
|
379
|
+
async function firePermissionRequestHook(toolName, toolInput) {
|
|
380
|
+
try {
|
|
381
|
+
const hookMgr = getHookManager();
|
|
382
|
+
if (!hookMgr) return "ask";
|
|
383
|
+
const result = await hookMgr.executePermissionRequest(
|
|
384
|
+
toolName,
|
|
385
|
+
toolInput,
|
|
386
|
+
"other"
|
|
387
|
+
);
|
|
388
|
+
if (!result.shouldContinue && !result.shouldAskUser) {
|
|
389
|
+
return "block";
|
|
390
|
+
}
|
|
391
|
+
if (result.shouldContinue && !result.shouldAskUser) {
|
|
392
|
+
if (result.reason) return "approve";
|
|
393
|
+
}
|
|
394
|
+
} catch {
|
|
395
|
+
}
|
|
396
|
+
return "ask";
|
|
397
|
+
}
|
|
305
398
|
async function savePermission(tool, input, prefix) {
|
|
306
399
|
const key = getPermissionKey(tool, input, prefix);
|
|
307
400
|
if (tool === FileEditTool || tool === FileWriteTool || tool === NotebookEditTool) {
|
package/dist/permissions.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/permissions.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CanUseToolFn } from './hooks/useCanUseTool'\nimport { Tool, ToolUseContext } from './Tool'\nimport { BashTool, inputSchema } from './tools/BashTool/BashTool'\nimport { FileEditTool } from './tools/FileEditTool/FileEditTool'\nimport { FileWriteTool } from './tools/FileWriteTool/FileWriteTool'\nimport { NotebookEditTool } from './tools/NotebookEditTool/NotebookEditTool'\nimport { getCommandSubcommandPrefix, splitCommand } from './utils/commands'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n type SafetyMode,\n} from '@utils/config'\nimport { AbortError } from './utils/errors'\nimport { logError } from './utils/log'\nimport { grantWritePermissionForOriginalDir } from './utils/permissions/filesystem'\nimport { getCwd } from './utils/state'\nimport { PRODUCT_NAME } from './constants/product'\nimport {\n getToolRiskLevel,\n type RiskLevel,\n} from './utils/toolRiskClassification'\nimport { resolve, relative, isAbsolute } from 'path'\n\n// Commands that are known to be safe for execution\nconst SAFE_COMMANDS = new Set([\n 'git status',\n 'git diff',\n 'git log',\n 'git branch',\n 'pwd',\n 'tree',\n 'date',\n 'which',\n])\n\nexport const bashToolCommandHasExactMatchPermission = (\n tool: Tool,\n command: string,\n allowedTools: string[],\n): boolean => {\n if (SAFE_COMMANDS.has(command)) {\n return true\n }\n // Check exact match first\n if (allowedTools.includes(getPermissionKey(tool, { command }, null))) {\n return true\n }\n // Check if command is an exact match with an approved prefix\n if (allowedTools.includes(getPermissionKey(tool, { command }, command))) {\n return true\n }\n return false\n}\n\nexport const bashToolCommandHasPermission = (\n tool: Tool,\n command: string,\n prefix: string | null,\n allowedTools: string[],\n): boolean => {\n // Check exact match first\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n return true\n }\n return allowedTools.includes(getPermissionKey(tool, { command }, prefix))\n}\n\nexport const bashToolHasPermission = async (\n tool: Tool,\n command: string,\n context: ToolUseContext,\n allowedTools: string[],\n getCommandSubcommandPrefixFn = getCommandSubcommandPrefix,\n): Promise<PermissionResult> => {\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n // This is an exact match for a command that is allowed, so we can skip the prefix check\n return { result: true }\n }\n\n const subCommands = splitCommand(command).filter(_ => {\n // Denim likes to add this, we strip it out so we don't need to prompt the user each time\n if (_ === `cd ${getCwd()}`) {\n return false\n }\n return true\n })\n const commandSubcommandPrefix = await getCommandSubcommandPrefixFn(\n command,\n context.abortController.signal,\n )\n if (context.abortController.signal.aborted) {\n throw new AbortError()\n }\n\n if (commandSubcommandPrefix === null) {\n // Fail closed and ask for user approval if the command prefix query failed (e.g. due to network error)\n // This is NOT the same as `fullCommandPrefix.commandPrefix === null`, which means no prefix was detected\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n\n if (commandSubcommandPrefix.commandInjectionDetected) {\n // Only allow exact matches for potential command injections\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n return { result: true }\n } else {\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n\n // After the commandInjectionDetected check above, TypeScript still sees the union type.\n // We know commandInjectionDetected is false here, so commandPrefix exists.\n // Use 'in' check for proper type narrowing\n const commandPrefix =\n 'commandPrefix' in commandSubcommandPrefix\n ? commandSubcommandPrefix.commandPrefix\n : null\n\n // If there is only one command, no need to process subCommands\n if (subCommands.length < 2) {\n if (\n bashToolCommandHasPermission(tool, command, commandPrefix, allowedTools)\n ) {\n return { result: true }\n } else {\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n if (\n subCommands.every(subCommand => {\n const prefixResult =\n commandSubcommandPrefix.subcommandPrefixes.get(subCommand)\n if (prefixResult === undefined || prefixResult.commandInjectionDetected) {\n // If prefix result is missing or command injection is detected, always ask for permission\n return false\n }\n // After the check above, we know commandInjectionDetected is false\n // Use 'in' check for proper type narrowing\n const subCommandPrefix =\n 'commandPrefix' in prefixResult ? prefixResult.commandPrefix : null\n const hasPermission = bashToolCommandHasPermission(\n tool,\n subCommand,\n subCommandPrefix,\n allowedTools,\n )\n return hasPermission\n })\n ) {\n return { result: true }\n }\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n}\n\ntype PermissionResult = { result: true } | { result: false; message: string }\n\n/**\n * Get effective safety mode from context options\n * Handles backward compatibility with legacy safeMode boolean\n */\nfunction getEffectiveSafetyMode(options: {\n safeMode?: boolean\n safetyMode?: SafetyMode\n}): SafetyMode {\n // New safetyMode takes precedence\n if (options.safetyMode) {\n return options.safetyMode\n }\n // Backward compatibility: convert legacy safeMode boolean\n // safeMode: true \u2192 'strict' (old behavior)\n // safeMode: false \u2192 'yolo' (permissive)\n if (options.safeMode === true) {\n return 'strict'\n }\n // Default to 'yolo' for non-technical users (zero interruption)\n return 'yolo'\n}\n\n/**\n * Check if a path is within the project directory\n * Used by Free mode to allow operations within project boundaries\n */\nfunction isPathWithinProject(targetPath: string, projectDir: string): boolean {\n // Resolve to absolute path\n const absolutePath = isAbsolute(targetPath)\n ? resolve(targetPath)\n : resolve(projectDir, targetPath)\n\n // Get relative path from project directory\n const relativePath = relative(projectDir, absolutePath)\n\n // Path is within project if:\n // 1. It doesn't start with '..' (not escaping project)\n // 2. It's not an absolute path (after relative calculation)\n return !relativePath.startsWith('..') && !isAbsolute(relativePath)\n}\n\n/**\n * System critical paths that should NEVER be auto-allowed, even in Free mode\n * These paths require explicit user confirmation regardless of safety mode\n */\nconst SYSTEM_CRITICAL_PATHS = [\n '/etc',\n '/bin',\n '/sbin',\n '/usr/bin',\n '/usr/sbin',\n '/var',\n '/System',\n '/Library',\n '/Applications',\n '/private',\n 'C:\\\\Windows',\n 'C:\\\\Program Files',\n 'C:\\\\Program Files (x86)',\n]\n\n/**\n * Check if a path is a system critical path\n */\nfunction isSystemCriticalPath(targetPath: string): boolean {\n const normalizedPath = resolve(targetPath).toLowerCase()\n return SYSTEM_CRITICAL_PATHS.some(criticalPath =>\n normalizedPath.startsWith(criticalPath.toLowerCase()),\n )\n}\n\n/**\n * Extract paths from tool input for boundary checking in Free mode\n */\nfunction extractPathsFromToolInput(\n toolName: string,\n input: { [k: string]: unknown },\n): string[] {\n const paths: string[] = []\n\n // File tools\n if (toolName === 'Read' || toolName === 'Write' || toolName === 'Edit') {\n if (typeof input.file_path === 'string') {\n paths.push(input.file_path)\n }\n }\n\n // Glob/Grep tools\n if (toolName === 'Glob' || toolName === 'Grep') {\n if (typeof input.path === 'string') {\n paths.push(input.path)\n }\n }\n\n // LS tool\n if (toolName === 'LS') {\n if (typeof input.path === 'string') {\n paths.push(input.path)\n }\n }\n\n // NotebookEdit\n if (toolName === 'NotebookEdit') {\n if (typeof input.notebook_path === 'string') {\n paths.push(input.notebook_path)\n }\n }\n\n return paths\n}\n\n/**\n * Extract paths from a Bash command for boundary checking\n * This is a simplified extraction - complex commands may need manual review\n */\nfunction extractPathsFromBashCommand(command: string): string[] {\n const paths: string[] = []\n\n // Extract quoted paths\n const quotedMatches = command.matchAll(/[\"']([^\"']+)[\"']/g)\n for (const match of quotedMatches) {\n if (match[1] && (match[1].includes('/') || match[1].startsWith('.'))) {\n paths.push(match[1])\n }\n }\n\n // Extract unquoted paths (starting with ./ or / or ../)\n const unquotedMatches = command.matchAll(\n /(?:^|\\s)((?:\\.\\/|\\/|\\.\\.\\/)[^\\s;&|>]+)/g,\n )\n for (const match of unquotedMatches) {\n if (match[1]) {\n paths.push(match[1])\n }\n }\n\n // Extract redirect targets\n const redirectMatches = command.matchAll(/>\\s*[\"']?([^\\s\"';&|]+)[\"']?/g)\n for (const match of redirectMatches) {\n if (match[1] && !match[1].startsWith('&')) {\n paths.push(match[1])\n }\n }\n\n return [...new Set(paths)] // Deduplicate\n}\n\n/**\n * Check if all paths in an operation are within the project directory\n * Used by Free mode for path-based permission decisions\n */\nfunction areAllPathsWithinProject(\n toolName: string,\n input: { [k: string]: unknown },\n projectDir: string,\n): { withinProject: boolean; outsidePaths: string[] } {\n let paths: string[] = []\n\n // For Bash tool, extract paths from command\n if (toolName === 'Bash' && typeof input.command === 'string') {\n paths = extractPathsFromBashCommand(input.command)\n } else {\n paths = extractPathsFromToolInput(toolName, input)\n }\n\n // If no paths detected, allow by default (e.g., pwd, date, etc.)\n if (paths.length === 0) {\n return { withinProject: true, outsidePaths: [] }\n }\n\n const outsidePaths: string[] = []\n for (const path of paths) {\n // Check system critical paths first\n if (isSystemCriticalPath(path)) {\n outsidePaths.push(path)\n continue\n }\n\n // Check if path is within project\n if (!isPathWithinProject(path, projectDir)) {\n outsidePaths.push(path)\n }\n }\n\n return {\n withinProject: outsidePaths.length === 0,\n outsidePaths,\n }\n}\n\n/**\n * Check if a tool should be allowed based on safety mode and risk level\n *\n * Safety Mode Matrix:\n * | Mode | Safe Tools | Monitored Tools | Dangerous Tools |\n * |--------|------------|-----------------|-----------------|\n * | yolo | \u2713 allow | \u2713 allow | \u2713 allow |\n * | smart | \u2713 allow | \u2713 allow | \u26A0 ask |\n * | strict | \u2713 allow | \u26A0 ask | \u26A0 ask |\n * | free | Path-based: within project = allow, outside = ask |\n */\nfunction shouldAllowByRiskLevel(\n safetyMode: SafetyMode,\n riskLevel: RiskLevel,\n toolName?: string,\n input?: { [k: string]: unknown },\n): boolean {\n switch (safetyMode) {\n case 'yolo':\n // YOLO mode: allow everything\n return true\n case 'smart':\n // Smart mode: allow safe and monitored, ask for dangerous\n return riskLevel === 'safe' || riskLevel === 'monitored'\n case 'strict':\n // Strict mode: only allow safe tools\n return riskLevel === 'safe'\n case 'free':\n // Free mode: path-based decision\n // Safe tools (read-only) are always allowed\n if (riskLevel === 'safe') {\n return true\n }\n // For tools with side effects, check path boundaries\n if (toolName && input) {\n const projectDir = getCwd()\n const { withinProject } = areAllPathsWithinProject(\n toolName,\n input,\n projectDir,\n )\n return withinProject\n }\n // If we can't determine paths, ask for confirmation\n return false\n }\n}\n\nexport const hasPermissionsToUseTool: CanUseToolFn = async (\n tool,\n input,\n context,\n _assistantMessage,\n): Promise<PermissionResult> => {\n const safetyMode = getEffectiveSafetyMode(context.options)\n\n // Get risk level for this tool (with command-specific classification for Bash)\n const riskLevel = getToolRiskLevel(\n tool.name,\n input as { command?: string } | undefined,\n )\n\n // Check if this tool should be auto-allowed based on safety mode and risk level\n // For Free mode, we also pass tool name and input for path-based decisions\n if (\n shouldAllowByRiskLevel(\n safetyMode,\n riskLevel,\n tool.name,\n input as { [k: string]: unknown },\n )\n ) {\n return { result: true }\n }\n\n if (context.abortController.signal.aborted) {\n throw new AbortError()\n }\n\n // Check if the tool needs permissions\n try {\n if (!tool.needsPermissions(input as never)) {\n return { result: true }\n }\n } catch (e) {\n logError(`Error checking permissions: ${e}`)\n return { result: false, message: 'Error checking permissions' }\n }\n\n const projectConfig = getCurrentProjectConfig()\n const allowedTools = projectConfig.allowedTools ?? []\n // Special case for BashTool to allow blanket commands without exposing them in the UI\n if (tool === BashTool && allowedTools.includes(BashTool.name)) {\n return { result: true }\n }\n\n // TODO: Move this into tool definitions (done for read tools!)\n switch (tool) {\n // For bash tool, check each sub-command's permissions separately\n case BashTool: {\n // The types have already been validated by the tool,\n // so we can safely parse the input (as opposed to safeParse).\n const { command } = inputSchema.parse(input)\n return await bashToolHasPermission(tool, command, context, allowedTools)\n }\n // For file editing tools, check session-only permissions\n case FileEditTool:\n case FileWriteTool:\n case NotebookEditTool: {\n // The types have already been validated by the tool,\n // so we can safely pass this in\n if (!tool.needsPermissions(input)) {\n return { result: true }\n }\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n // For other tools, check persistent permissions\n default: {\n const permissionKey = getPermissionKey(tool, input, null)\n if (allowedTools.includes(permissionKey)) {\n return { result: true }\n }\n\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n}\n\nexport async function savePermission(\n tool: Tool,\n input: { [k: string]: unknown },\n prefix: string | null,\n): Promise<void> {\n const key = getPermissionKey(tool, input, prefix)\n\n // For file editing tools, store write permissions only in memory\n if (\n tool === FileEditTool ||\n tool === FileWriteTool ||\n tool === NotebookEditTool\n ) {\n grantWritePermissionForOriginalDir()\n return\n }\n\n // For other tools, store permissions on disk\n const projectConfig = getCurrentProjectConfig()\n if (projectConfig.allowedTools.includes(key)) {\n return\n }\n\n projectConfig.allowedTools.push(key)\n projectConfig.allowedTools.sort()\n\n saveCurrentProjectConfig(projectConfig)\n}\n\nfunction getPermissionKey(\n tool: Tool,\n input: { [k: string]: unknown },\n prefix: string | null,\n): string {\n switch (tool) {\n case BashTool:\n if (prefix) {\n return `${BashTool.name}(${prefix}:*)`\n }\n return `${BashTool.name}(${BashTool.renderToolUseMessage(input as never)})`\n default:\n return tool.name\n }\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,UAAU,mBAAmB;AACtC,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,4BAA4B,oBAAoB;AACzD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,0CAA0C;AACnD,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,OAEK;AACP,SAAS,SAAS,UAAU,
|
|
4
|
+
"sourcesContent": ["import type { CanUseToolFn } from './hooks/useCanUseTool'\nimport { Tool, ToolUseContext } from './Tool'\nimport { BashTool, inputSchema } from './tools/BashTool/BashTool'\nimport { FileEditTool } from './tools/FileEditTool/FileEditTool'\nimport { FileWriteTool } from './tools/FileWriteTool/FileWriteTool'\nimport { NotebookEditTool } from './tools/NotebookEditTool/NotebookEditTool'\nimport { getCommandSubcommandPrefix, splitCommand } from './utils/commands'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n type SafetyMode,\n} from '@utils/config'\nimport { AbortError } from './utils/errors'\nimport { logError } from './utils/log'\nimport { grantWritePermissionForOriginalDir } from './utils/permissions/filesystem'\nimport { getCwd } from './utils/state'\nimport { PRODUCT_NAME } from './constants/product'\nimport {\n getToolRiskLevel,\n type RiskLevel,\n} from './utils/toolRiskClassification'\nimport { resolve, relative, isAbsolute, join } from 'path'\nimport { getHookManager } from './utils/hookManager'\nimport { existsSync, readFileSync } from 'fs'\nimport { homedir } from 'os'\nimport { CONFIG_BASE_DIR } from './constants/product'\n\n// Commands that are known to be safe for execution\nconst SAFE_COMMANDS = new Set([\n 'git status',\n 'git diff',\n 'git log',\n 'git branch',\n 'pwd',\n 'tree',\n 'date',\n 'which',\n])\n\nexport const bashToolCommandHasExactMatchPermission = (\n tool: Tool,\n command: string,\n allowedTools: string[],\n): boolean => {\n if (SAFE_COMMANDS.has(command)) {\n return true\n }\n // Check exact match first\n if (allowedTools.includes(getPermissionKey(tool, { command }, null))) {\n return true\n }\n // Check if command is an exact match with an approved prefix\n if (allowedTools.includes(getPermissionKey(tool, { command }, command))) {\n return true\n }\n return false\n}\n\nexport const bashToolCommandHasPermission = (\n tool: Tool,\n command: string,\n prefix: string | null,\n allowedTools: string[],\n): boolean => {\n // Check exact match first\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n return true\n }\n return allowedTools.includes(getPermissionKey(tool, { command }, prefix))\n}\n\nexport const bashToolHasPermission = async (\n tool: Tool,\n command: string,\n context: ToolUseContext,\n allowedTools: string[],\n getCommandSubcommandPrefixFn = getCommandSubcommandPrefix,\n): Promise<PermissionResult> => {\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n // This is an exact match for a command that is allowed, so we can skip the prefix check\n return { result: true }\n }\n\n const subCommands = splitCommand(command).filter(_ => {\n // Denim likes to add this, we strip it out so we don't need to prompt the user each time\n if (_ === `cd ${getCwd()}`) {\n return false\n }\n return true\n })\n const commandSubcommandPrefix = await getCommandSubcommandPrefixFn(\n command,\n context.abortController.signal,\n )\n if (context.abortController.signal.aborted) {\n throw new AbortError()\n }\n\n if (commandSubcommandPrefix === null) {\n // Fail closed and ask for user approval if the command prefix query failed (e.g. due to network error)\n // This is NOT the same as `fullCommandPrefix.commandPrefix === null`, which means no prefix was detected\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n\n if (commandSubcommandPrefix.commandInjectionDetected) {\n // Only allow exact matches for potential command injections\n if (bashToolCommandHasExactMatchPermission(tool, command, allowedTools)) {\n return { result: true }\n } else {\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n\n // After the commandInjectionDetected check above, TypeScript still sees the union type.\n // We know commandInjectionDetected is false here, so commandPrefix exists.\n // Use 'in' check for proper type narrowing\n const commandPrefix =\n 'commandPrefix' in commandSubcommandPrefix\n ? commandSubcommandPrefix.commandPrefix\n : null\n\n // If there is only one command, no need to process subCommands\n if (subCommands.length < 2) {\n if (\n bashToolCommandHasPermission(tool, command, commandPrefix, allowedTools)\n ) {\n return { result: true }\n } else {\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n if (\n subCommands.every(subCommand => {\n const prefixResult =\n commandSubcommandPrefix.subcommandPrefixes.get(subCommand)\n if (prefixResult === undefined || prefixResult.commandInjectionDetected) {\n // If prefix result is missing or command injection is detected, always ask for permission\n return false\n }\n // After the check above, we know commandInjectionDetected is false\n // Use 'in' check for proper type narrowing\n const subCommandPrefix =\n 'commandPrefix' in prefixResult ? prefixResult.commandPrefix : null\n const hasPermission = bashToolCommandHasPermission(\n tool,\n subCommand,\n subCommandPrefix,\n allowedTools,\n )\n return hasPermission\n })\n ) {\n return { result: true }\n }\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n}\n\ntype PermissionResult = { result: true } | { result: false; message: string }\n\n/**\n * Get effective safety mode from context options\n * Handles backward compatibility with legacy safeMode boolean\n */\nfunction getEffectiveSafetyMode(options: {\n safeMode?: boolean\n safetyMode?: SafetyMode\n}): SafetyMode {\n // New safetyMode takes precedence\n if (options.safetyMode) {\n return options.safetyMode\n }\n // Backward compatibility: convert legacy safeMode boolean\n // safeMode: true \u2192 'strict' (old behavior)\n // safeMode: false \u2192 'yolo' (permissive)\n if (options.safeMode === true) {\n return 'strict'\n }\n // Default to 'yolo' for non-technical users (zero interruption)\n return 'yolo'\n}\n\n/**\n * Check if a path is within the project directory\n * Used by Free mode to allow operations within project boundaries\n */\nfunction isPathWithinProject(targetPath: string, projectDir: string): boolean {\n // Resolve to absolute path\n const absolutePath = isAbsolute(targetPath)\n ? resolve(targetPath)\n : resolve(projectDir, targetPath)\n\n // Get relative path from project directory\n const relativePath = relative(projectDir, absolutePath)\n\n // Path is within project if:\n // 1. It doesn't start with '..' (not escaping project)\n // 2. It's not an absolute path (after relative calculation)\n return !relativePath.startsWith('..') && !isAbsolute(relativePath)\n}\n\n/**\n * System critical paths that should NEVER be auto-allowed, even in Free mode\n * These paths require explicit user confirmation regardless of safety mode\n */\nconst SYSTEM_CRITICAL_PATHS = [\n '/etc',\n '/bin',\n '/sbin',\n '/usr/bin',\n '/usr/sbin',\n '/var',\n '/System',\n '/Library',\n '/Applications',\n '/private',\n 'C:\\\\Windows',\n 'C:\\\\Program Files',\n 'C:\\\\Program Files (x86)',\n]\n\n/**\n * Check if a path is a system critical path\n */\nfunction isSystemCriticalPath(targetPath: string): boolean {\n const normalizedPath = resolve(targetPath).toLowerCase()\n return SYSTEM_CRITICAL_PATHS.some(criticalPath =>\n normalizedPath.startsWith(criticalPath.toLowerCase()),\n )\n}\n\n/**\n * Extract paths from tool input for boundary checking in Free mode\n */\nfunction extractPathsFromToolInput(\n toolName: string,\n input: { [k: string]: unknown },\n): string[] {\n const paths: string[] = []\n\n // File tools\n if (toolName === 'Read' || toolName === 'Write' || toolName === 'Edit') {\n if (typeof input.file_path === 'string') {\n paths.push(input.file_path)\n }\n }\n\n // Glob/Grep tools\n if (toolName === 'Glob' || toolName === 'Grep') {\n if (typeof input.path === 'string') {\n paths.push(input.path)\n }\n }\n\n // LS tool\n if (toolName === 'LS') {\n if (typeof input.path === 'string') {\n paths.push(input.path)\n }\n }\n\n // NotebookEdit\n if (toolName === 'NotebookEdit') {\n if (typeof input.notebook_path === 'string') {\n paths.push(input.notebook_path)\n }\n }\n\n return paths\n}\n\n/**\n * Extract paths from a Bash command for boundary checking\n * This is a simplified extraction - complex commands may need manual review\n */\nfunction extractPathsFromBashCommand(command: string): string[] {\n const paths: string[] = []\n\n // Extract quoted paths\n const quotedMatches = command.matchAll(/[\"']([^\"']+)[\"']/g)\n for (const match of quotedMatches) {\n if (match[1] && (match[1].includes('/') || match[1].startsWith('.'))) {\n paths.push(match[1])\n }\n }\n\n // Extract unquoted paths (starting with ./ or / or ../)\n const unquotedMatches = command.matchAll(\n /(?:^|\\s)((?:\\.\\/|\\/|\\.\\.\\/)[^\\s;&|>]+)/g,\n )\n for (const match of unquotedMatches) {\n if (match[1]) {\n paths.push(match[1])\n }\n }\n\n // Extract redirect targets\n const redirectMatches = command.matchAll(/>\\s*[\"']?([^\\s\"';&|]+)[\"']?/g)\n for (const match of redirectMatches) {\n if (match[1] && !match[1].startsWith('&')) {\n paths.push(match[1])\n }\n }\n\n return [...new Set(paths)] // Deduplicate\n}\n\n/**\n * Check if all paths in an operation are within the project directory\n * Used by Free mode for path-based permission decisions\n */\nfunction areAllPathsWithinProject(\n toolName: string,\n input: { [k: string]: unknown },\n projectDir: string,\n): { withinProject: boolean; outsidePaths: string[] } {\n let paths: string[] = []\n\n // For Bash tool, extract paths from command\n if (toolName === 'Bash' && typeof input.command === 'string') {\n paths = extractPathsFromBashCommand(input.command)\n } else {\n paths = extractPathsFromToolInput(toolName, input)\n }\n\n // If no paths detected, allow by default (e.g., pwd, date, etc.)\n if (paths.length === 0) {\n return { withinProject: true, outsidePaths: [] }\n }\n\n const outsidePaths: string[] = []\n for (const path of paths) {\n // Check system critical paths first\n if (isSystemCriticalPath(path)) {\n outsidePaths.push(path)\n continue\n }\n\n // Check if path is within project\n if (!isPathWithinProject(path, projectDir)) {\n outsidePaths.push(path)\n }\n }\n\n return {\n withinProject: outsidePaths.length === 0,\n outsidePaths,\n }\n}\n\n/**\n * Check if a tool should be allowed based on safety mode and risk level\n *\n * Safety Mode Matrix:\n * | Mode | Safe Tools | Monitored Tools | Dangerous Tools |\n * |--------|------------|-----------------|-----------------|\n * | yolo | \u2713 allow | \u2713 allow | \u2713 allow |\n * | smart | \u2713 allow | \u2713 allow | \u26A0 ask |\n * | strict | \u2713 allow | \u26A0 ask | \u26A0 ask |\n * | free | Path-based: within project = allow, outside = ask |\n */\nfunction shouldAllowByRiskLevel(\n safetyMode: SafetyMode,\n riskLevel: RiskLevel,\n toolName?: string,\n input?: { [k: string]: unknown },\n): boolean {\n switch (safetyMode) {\n case 'yolo':\n // YOLO mode: allow everything\n return true\n case 'smart':\n // Smart mode: allow safe and monitored, ask for dangerous\n return riskLevel === 'safe' || riskLevel === 'monitored'\n case 'strict':\n // Strict mode: only allow safe tools\n return riskLevel === 'safe'\n case 'free':\n // Free mode: path-based decision\n // Safe tools (read-only) are always allowed\n if (riskLevel === 'safe') {\n return true\n }\n // For tools with side effects, check path boundaries\n if (toolName && input) {\n const projectDir = getCwd()\n const { withinProject } = areAllPathsWithinProject(\n toolName,\n input,\n projectDir,\n )\n return withinProject\n }\n // If we can't determine paths, ask for confirmation\n return false\n }\n}\n\n/**\n * Load permission deny/allow rules from settings.json files.\n * Checks: .minto/settings.json, .claude/settings.json, ~/.minto/settings.json, ~/.claude/settings.json\n */\nlet settingsPermissionsCache: {\n deny: string[]\n allow: string[]\n} | null = null\n\nfunction loadSettingsPermissions(): { deny: string[]; allow: string[] } {\n if (settingsPermissionsCache) return settingsPermissionsCache\n\n const deny: string[] = []\n const allow: string[] = []\n\n const cwd = getCwd()\n const home = homedir()\n\n // Check settings files in priority order (later overrides earlier)\n const settingsFiles = [\n join(home, '.claude', 'settings.json'),\n join(home, CONFIG_BASE_DIR, 'settings.json'),\n join(cwd, '.claude', 'settings.json'),\n join(cwd, CONFIG_BASE_DIR, 'settings.json'),\n ]\n\n for (const file of settingsFiles) {\n if (!existsSync(file)) continue\n try {\n const content = JSON.parse(readFileSync(file, 'utf-8'))\n if (\n content?.permissions?.deny &&\n Array.isArray(content.permissions.deny)\n ) {\n deny.push(...content.permissions.deny)\n }\n if (\n content?.permissions?.allow &&\n Array.isArray(content.permissions.allow)\n ) {\n allow.push(...content.permissions.allow)\n }\n } catch {\n // Ignore malformed settings files\n }\n }\n\n settingsPermissionsCache = { deny, allow }\n return settingsPermissionsCache\n}\n\n/**\n * Check if tool matches any pattern in a permission list.\n * Patterns can be exact tool names or tool(pattern) for Bash commands.\n */\nfunction matchesPermissionPattern(\n toolName: string,\n input: { [k: string]: unknown } | undefined,\n patterns: string[],\n): boolean {\n for (const pattern of patterns) {\n // Exact tool name match\n if (pattern === toolName) return true\n\n // Bash command pattern: Bash(command:*)\n if (toolName === 'Bash' && pattern.startsWith('Bash(') && input?.command) {\n const cmdPattern = pattern.slice(5, -1) // Remove Bash( and )\n const command = String(input.command)\n if (cmdPattern.endsWith(':*')) {\n const prefix = cmdPattern.slice(0, -2)\n if (command.startsWith(prefix)) return true\n } else if (command === cmdPattern) {\n return true\n }\n }\n }\n return false\n}\n\nexport const hasPermissionsToUseTool: CanUseToolFn = async (\n tool,\n input,\n context,\n _assistantMessage,\n): Promise<PermissionResult> => {\n // Step 0: Check settings.json deny rules (highest priority - block immediately)\n const settingsPerms = loadSettingsPermissions()\n if (\n matchesPermissionPattern(\n tool.name,\n input as { [k: string]: unknown },\n settingsPerms.deny,\n )\n ) {\n return {\n result: false,\n message: `Tool \"${tool.name}\" is denied by settings configuration.`,\n }\n }\n\n // Step 0b: Check settings.json allow rules (explicit allow)\n if (\n matchesPermissionPattern(\n tool.name,\n input as { [k: string]: unknown },\n settingsPerms.allow,\n )\n ) {\n return { result: true }\n }\n\n const safetyMode = getEffectiveSafetyMode(context.options)\n\n // Get risk level for this tool (with command-specific classification for Bash)\n const riskLevel = getToolRiskLevel(\n tool.name,\n input as { command?: string } | undefined,\n )\n\n // Check if this tool should be auto-allowed based on safety mode and risk level\n // For Free mode, we also pass tool name and input for path-based decisions\n if (\n shouldAllowByRiskLevel(\n safetyMode,\n riskLevel,\n tool.name,\n input as { [k: string]: unknown },\n )\n ) {\n return { result: true }\n }\n\n if (context.abortController.signal.aborted) {\n throw new AbortError()\n }\n\n // Check if the tool needs permissions\n try {\n if (!tool.needsPermissions(input as never)) {\n return { result: true }\n }\n } catch (e) {\n logError(`Error checking permissions: ${e}`)\n return { result: false, message: 'Error checking permissions' }\n }\n\n const projectConfig = getCurrentProjectConfig()\n const allowedTools = projectConfig.allowedTools ?? []\n // Special case for BashTool to allow blanket commands without exposing them in the UI\n if (tool === BashTool && allowedTools.includes(BashTool.name)) {\n return { result: true }\n }\n\n // TODO: Move this into tool definitions (done for read tools!)\n switch (tool) {\n // For bash tool, check each sub-command's permissions separately\n case BashTool: {\n // The types have already been validated by the tool,\n // so we can safely parse the input (as opposed to safeParse).\n const { command } = inputSchema.parse(input)\n return await bashToolHasPermission(tool, command, context, allowedTools)\n }\n // For file editing tools, check session-only permissions\n case FileEditTool:\n case FileWriteTool:\n case NotebookEditTool: {\n // The types have already been validated by the tool,\n // so we can safely pass this in\n if (!tool.needsPermissions(input)) {\n return { result: true }\n }\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n // For other tools, check persistent permissions\n default: {\n const permissionKey = getPermissionKey(tool, input, null)\n if (allowedTools.includes(permissionKey)) {\n return { result: true }\n }\n\n // Fire PermissionRequest hook before denying\n const hookDecision = await firePermissionRequestHook(\n tool.name,\n input as Record<string, unknown>,\n )\n if (hookDecision === 'approve') {\n return { result: true }\n }\n\n return {\n result: false,\n message: `${PRODUCT_NAME} requested permissions to use ${tool.name}, but you haven't granted it yet.`,\n }\n }\n }\n}\n\n/**\n * Fire PermissionRequest hook when a tool needs permission\n * Returns 'approve' to auto-grant, 'block' to deny, or 'ask' to proceed normally\n */\nasync function firePermissionRequestHook(\n toolName: string,\n toolInput: Record<string, unknown>,\n): Promise<'approve' | 'block' | 'ask'> {\n try {\n const hookMgr = getHookManager()\n if (!hookMgr) return 'ask'\n\n const result = await hookMgr.executePermissionRequest(\n toolName,\n toolInput,\n 'other',\n )\n\n if (!result.shouldContinue && !result.shouldAskUser) {\n return 'block'\n }\n if (result.shouldContinue && !result.shouldAskUser) {\n // Check if hook explicitly approved (vs just no hooks matched)\n if (result.reason) return 'approve'\n }\n } catch {\n // Hook errors don't block permission flow\n }\n return 'ask'\n}\n\nexport async function savePermission(\n tool: Tool,\n input: { [k: string]: unknown },\n prefix: string | null,\n): Promise<void> {\n const key = getPermissionKey(tool, input, prefix)\n\n // For file editing tools, store write permissions only in memory\n if (\n tool === FileEditTool ||\n tool === FileWriteTool ||\n tool === NotebookEditTool\n ) {\n grantWritePermissionForOriginalDir()\n return\n }\n\n // For other tools, store permissions on disk\n const projectConfig = getCurrentProjectConfig()\n if (projectConfig.allowedTools.includes(key)) {\n return\n }\n\n projectConfig.allowedTools.push(key)\n projectConfig.allowedTools.sort()\n\n saveCurrentProjectConfig(projectConfig)\n}\n\nfunction getPermissionKey(\n tool: Tool,\n input: { [k: string]: unknown },\n prefix: string | null,\n): string {\n switch (tool) {\n case BashTool:\n if (prefix) {\n return `${BashTool.name}(${prefix}:*)`\n }\n return `${BashTool.name}(${BashTool.renderToolUseMessage(input as never)})`\n default:\n return tool.name\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|