@within-7/minto 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +461 -657
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/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 +684 -94
- 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/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +425 -217
- 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 +457 -65
- 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/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +891 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +146 -174
- 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/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +590 -565
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +26 -11
- 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/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/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/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.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 +123 -48
- 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 +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +11 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +21 -3
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -16
- 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/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +81 -68
- 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 +299 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +300 -2
- 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/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- 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/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +20 -9
- 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 +367 -9
- 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 +8 -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 +10 -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 +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/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 +84 -11
- 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 +3 -5
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +91 -15
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.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/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +27 -151
- 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/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- 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/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +68 -29
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +249 -57
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +77 -12
- 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/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +162 -16
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/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/utils/config.js
CHANGED
|
@@ -8,6 +8,7 @@ import { randomBytes } from "crypto";
|
|
|
8
8
|
import { safeParseJSON } from "./json.js";
|
|
9
9
|
import { ConfigParseError } from "./errors.js";
|
|
10
10
|
import { debug as debugLogger } from "./debugLogger.js";
|
|
11
|
+
import { safeValidateGlobalConfig } from "./configSchema.js";
|
|
11
12
|
const DEFAULT_PROJECT_CONFIG = {
|
|
12
13
|
allowedTools: [],
|
|
13
14
|
context: {},
|
|
@@ -40,23 +41,6 @@ function getVerboseLabel(verbose) {
|
|
|
40
41
|
return verbose ? "Verbose: On" : "Verbose: Off";
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
function getDisplayModeLabel(mode) {
|
|
44
|
-
return mode === "detailed" ? "Verbose: On" : "Verbose: Off";
|
|
45
|
-
}
|
|
46
|
-
const DISPLAY_MODE_LABELS = {
|
|
47
|
-
minimal: "Verbose: Off",
|
|
48
|
-
compact: "Verbose: Off",
|
|
49
|
-
detailed: "Verbose: On"
|
|
50
|
-
};
|
|
51
|
-
function getNextDisplayMode(current) {
|
|
52
|
-
return current === "detailed" ? "compact" : "detailed";
|
|
53
|
-
}
|
|
54
|
-
function displayModeToVerbose(mode) {
|
|
55
|
-
return mode === "detailed";
|
|
56
|
-
}
|
|
57
|
-
function verboseToDisplayMode(verbose) {
|
|
58
|
-
return verbose ? "detailed" : "compact";
|
|
59
|
-
}
|
|
60
44
|
const DEFAULT_GLOBAL_CONFIG = {
|
|
61
45
|
numStartups: 0,
|
|
62
46
|
autoUpdaterStatus: "not_configured",
|
|
@@ -87,8 +71,8 @@ const DEFAULT_GLOBAL_CONFIG = {
|
|
|
87
71
|
// Default to English
|
|
88
72
|
safeMode: false,
|
|
89
73
|
// Deprecated: use safetyMode instead
|
|
90
|
-
safetyMode: "
|
|
91
|
-
// Default to
|
|
74
|
+
safetyMode: "smart"
|
|
75
|
+
// Default to smart mode — safe tools auto-allowed, dangerous tools need confirmation
|
|
92
76
|
};
|
|
93
77
|
const GLOBAL_CONFIG_KEYS = [
|
|
94
78
|
"autoUpdaterStatus",
|
|
@@ -104,7 +88,10 @@ const GLOBAL_CONFIG_KEYS = [
|
|
|
104
88
|
"maxTokens",
|
|
105
89
|
"compressionMode",
|
|
106
90
|
"language",
|
|
107
|
-
"safetyMode"
|
|
91
|
+
"safetyMode",
|
|
92
|
+
"enableMemoryTools",
|
|
93
|
+
"outputStyle",
|
|
94
|
+
"autoMemory"
|
|
108
95
|
];
|
|
109
96
|
function isGlobalConfigKey(key) {
|
|
110
97
|
return GLOBAL_CONFIG_KEYS.includes(key);
|
|
@@ -144,6 +131,7 @@ function isProjectConfigKey(key) {
|
|
|
144
131
|
function saveGlobalConfig(config) {
|
|
145
132
|
if (process.env.NODE_ENV === "test") {
|
|
146
133
|
for (const key in config) {
|
|
134
|
+
;
|
|
147
135
|
TEST_GLOBAL_CONFIG_FOR_TESTING[key] = config[key];
|
|
148
136
|
}
|
|
149
137
|
return;
|
|
@@ -304,6 +292,15 @@ function getConfig(file, defaultConfig, throwOnInvalid) {
|
|
|
304
292
|
file,
|
|
305
293
|
parsedKeys: Object.keys(parsedConfig).join(", ")
|
|
306
294
|
});
|
|
295
|
+
if (file === GLOBAL_CONFIG_FILE) {
|
|
296
|
+
const validation = safeValidateGlobalConfig(parsedConfig);
|
|
297
|
+
if (!validation.success && validation.errors) {
|
|
298
|
+
debugLogger.warn("CONFIG_VALIDATION", {
|
|
299
|
+
file,
|
|
300
|
+
issues: validation.errors.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
307
304
|
const finalConfig = {
|
|
308
305
|
...cloneDeep(defaultConfig),
|
|
309
306
|
...parsedConfig
|
|
@@ -636,7 +633,8 @@ async function resolveApiKey(profile) {
|
|
|
636
633
|
return getApiKey(modelName);
|
|
637
634
|
} catch (error) {
|
|
638
635
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
639
|
-
|
|
636
|
+
debugLogger.warn(
|
|
637
|
+
"CREDENTIAL_RESOLVE",
|
|
640
638
|
`Failed to resolve encrypted API key for ${modelName}: ${errorMsg}`
|
|
641
639
|
);
|
|
642
640
|
return null;
|
|
@@ -644,133 +642,15 @@ async function resolveApiKey(profile) {
|
|
|
644
642
|
}
|
|
645
643
|
return profile.apiKey;
|
|
646
644
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
const now = Date.now();
|
|
655
|
-
const repairedProfile = { ...profile };
|
|
656
|
-
let wasRepaired = false;
|
|
657
|
-
if (isGPT5 !== profile.isGPT5) {
|
|
658
|
-
repairedProfile.isGPT5 = isGPT5;
|
|
659
|
-
wasRepaired = true;
|
|
660
|
-
}
|
|
661
|
-
if (isGPT5) {
|
|
662
|
-
const validReasoningEfforts = ["minimal", "low", "medium", "high"];
|
|
663
|
-
if (!profile.reasoningEffort || !validReasoningEfforts.includes(profile.reasoningEffort)) {
|
|
664
|
-
repairedProfile.reasoningEffort = "medium";
|
|
665
|
-
wasRepaired = true;
|
|
666
|
-
console.log(
|
|
667
|
-
`\u{1F527} GPT-5 Config: Set reasoning effort to 'medium' for ${profile.modelName}`
|
|
668
|
-
);
|
|
669
|
-
}
|
|
670
|
-
if (profile.contextLength < 128e3) {
|
|
671
|
-
repairedProfile.contextLength = 128e3;
|
|
672
|
-
wasRepaired = true;
|
|
673
|
-
console.log(
|
|
674
|
-
`\u{1F527} GPT-5 Config: Updated context length to 128k for ${profile.modelName}`
|
|
675
|
-
);
|
|
676
|
-
}
|
|
677
|
-
if (profile.maxTokens < 4e3) {
|
|
678
|
-
repairedProfile.maxTokens = 8192;
|
|
679
|
-
wasRepaired = true;
|
|
680
|
-
console.log(
|
|
681
|
-
`\u{1F527} GPT-5 Config: Updated max tokens to 8192 for ${profile.modelName}`
|
|
682
|
-
);
|
|
683
|
-
}
|
|
684
|
-
if (profile.provider !== "openai" && profile.provider !== "custom-openai" && profile.provider !== "azure") {
|
|
685
|
-
console.warn(
|
|
686
|
-
`\u26A0\uFE0F GPT-5 Config: Unexpected provider '${profile.provider}' for GPT-5 model ${profile.modelName}. Consider using 'openai' or 'custom-openai'.`
|
|
687
|
-
);
|
|
688
|
-
}
|
|
689
|
-
if (profile.modelName.includes("gpt-5") && !profile.baseURL) {
|
|
690
|
-
repairedProfile.baseURL = "https://api.openai.com/v1";
|
|
691
|
-
wasRepaired = true;
|
|
692
|
-
console.log(
|
|
693
|
-
`\u{1F527} GPT-5 Config: Set default base URL for ${profile.modelName}`
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
repairedProfile.validationStatus = wasRepaired ? "auto_repaired" : "valid";
|
|
698
|
-
repairedProfile.lastValidation = now;
|
|
699
|
-
if (wasRepaired) {
|
|
700
|
-
console.log(
|
|
701
|
-
`\u2705 GPT-5 Config: Auto-repaired configuration for ${profile.modelName}`
|
|
702
|
-
);
|
|
703
|
-
}
|
|
704
|
-
return repairedProfile;
|
|
705
|
-
}
|
|
706
|
-
function validateAndRepairAllGPT5Profiles() {
|
|
707
|
-
const config = getGlobalConfig();
|
|
708
|
-
if (!config.modelProfiles) {
|
|
709
|
-
return { repaired: 0, total: 0 };
|
|
710
|
-
}
|
|
711
|
-
let repairCount = 0;
|
|
712
|
-
const repairedProfiles = config.modelProfiles.map((profile) => {
|
|
713
|
-
const repairedProfile = validateAndRepairGPT5Profile(profile);
|
|
714
|
-
if (repairedProfile.validationStatus === "auto_repaired") {
|
|
715
|
-
repairCount++;
|
|
716
|
-
}
|
|
717
|
-
return repairedProfile;
|
|
718
|
-
});
|
|
719
|
-
if (repairCount > 0) {
|
|
720
|
-
const updatedConfig = {
|
|
721
|
-
...config,
|
|
722
|
-
modelProfiles: repairedProfiles
|
|
723
|
-
};
|
|
724
|
-
saveGlobalConfig(updatedConfig);
|
|
725
|
-
console.log(`\u{1F527} GPT-5 Config: Auto-repaired ${repairCount} model profiles`);
|
|
726
|
-
}
|
|
727
|
-
return { repaired: repairCount, total: config.modelProfiles.length };
|
|
728
|
-
}
|
|
729
|
-
function getGPT5ConfigRecommendations(modelName) {
|
|
730
|
-
if (!isGPT5ModelName(modelName)) {
|
|
731
|
-
return {};
|
|
732
|
-
}
|
|
733
|
-
const recommendations = {
|
|
734
|
-
contextLength: 128e3,
|
|
735
|
-
// GPT-5 standard context length
|
|
736
|
-
maxTokens: 8192,
|
|
737
|
-
// Good default for coding tasks
|
|
738
|
-
reasoningEffort: "medium",
|
|
739
|
-
// Balanced for most coding tasks
|
|
740
|
-
isGPT5: true
|
|
741
|
-
};
|
|
742
|
-
if (modelName.includes("gpt-5-mini")) {
|
|
743
|
-
recommendations.maxTokens = 4096;
|
|
744
|
-
recommendations.reasoningEffort = "low";
|
|
745
|
-
} else if (modelName.includes("gpt-5-nano")) {
|
|
746
|
-
recommendations.maxTokens = 2048;
|
|
747
|
-
recommendations.reasoningEffort = "minimal";
|
|
748
|
-
}
|
|
749
|
-
return recommendations;
|
|
750
|
-
}
|
|
751
|
-
function createGPT5ModelProfile(name, modelName, apiKey, baseURL, provider = "openai") {
|
|
752
|
-
const recommendations = getGPT5ConfigRecommendations(modelName);
|
|
753
|
-
const profile = {
|
|
754
|
-
name,
|
|
755
|
-
provider,
|
|
756
|
-
modelName,
|
|
757
|
-
baseURL: baseURL || "https://api.openai.com/v1",
|
|
758
|
-
apiKey,
|
|
759
|
-
maxTokens: recommendations.maxTokens || 8192,
|
|
760
|
-
contextLength: recommendations.contextLength || 128e3,
|
|
761
|
-
reasoningEffort: recommendations.reasoningEffort || "medium",
|
|
762
|
-
isActive: true,
|
|
763
|
-
createdAt: Date.now(),
|
|
764
|
-
isGPT5: true,
|
|
765
|
-
validationStatus: "valid",
|
|
766
|
-
lastValidation: Date.now()
|
|
767
|
-
};
|
|
768
|
-
console.log(`\u2705 Created GPT-5 model profile: ${name} (${modelName})`);
|
|
769
|
-
return profile;
|
|
770
|
-
}
|
|
645
|
+
import {
|
|
646
|
+
isGPT5ModelName,
|
|
647
|
+
validateAndRepairGPT5Profile,
|
|
648
|
+
validateAndRepairAllGPT5Profiles,
|
|
649
|
+
getGPT5ConfigRecommendations,
|
|
650
|
+
createGPT5ModelProfile
|
|
651
|
+
} from "./gpt5.js";
|
|
771
652
|
export {
|
|
772
653
|
DEFAULT_GLOBAL_CONFIG,
|
|
773
|
-
DISPLAY_MODE_LABELS,
|
|
774
654
|
GLOBAL_CONFIG_KEYS,
|
|
775
655
|
PROJECT_CONFIG_KEYS,
|
|
776
656
|
TEST_MCPRC_CONFIG_FOR_TESTING,
|
|
@@ -780,17 +660,14 @@ export {
|
|
|
780
660
|
createGPT5ModelProfile,
|
|
781
661
|
deduplicateModelProfiles,
|
|
782
662
|
deleteConfigForCLI,
|
|
783
|
-
displayModeToVerbose,
|
|
784
663
|
enableConfigs,
|
|
785
664
|
getAnthropicApiKey,
|
|
786
665
|
getConfigForCLI,
|
|
787
666
|
getCurrentProjectConfig,
|
|
788
667
|
getCustomApiKeyStatus,
|
|
789
|
-
getDisplayModeLabel,
|
|
790
668
|
getGPT5ConfigRecommendations,
|
|
791
669
|
getGlobalConfig,
|
|
792
670
|
getMcprcConfig,
|
|
793
|
-
getNextDisplayMode,
|
|
794
671
|
getOpenAIApiKey,
|
|
795
672
|
getOrCreateUserID,
|
|
796
673
|
getVerboseLabel,
|
|
@@ -809,7 +686,6 @@ export {
|
|
|
809
686
|
setConfigForCLI,
|
|
810
687
|
setModelPointer,
|
|
811
688
|
validateAndRepairAllGPT5Profiles,
|
|
812
|
-
validateAndRepairGPT5Profile
|
|
813
|
-
verboseToDisplayMode
|
|
689
|
+
validateAndRepairGPT5Profile
|
|
814
690
|
};
|
|
815
691
|
//# sourceMappingURL=config.js.map
|
package/dist/utils/config.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/config.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'fs'\nimport { resolve, join, dirname } from 'path'\nimport { cloneDeep, memoize, pick } from 'lodash-es'\nimport { homedir } from 'os'\nimport { GLOBAL_CONFIG_FILE } from './env'\nimport { getCwd } from './state'\nimport { randomBytes } from 'crypto'\nimport { safeParseJSON } from './json'\nimport { ConfigParseError } from './errors'\nimport type { ThemeNames } from './theme'\nimport { debug as debugLogger } from './debugLogger'\nimport { getSessionState, setSessionState } from './sessionState'\nimport type { CompressionMode } from '@constants/compressionPrompts'\n\nexport type McpStdioServerConfig = {\n type?: 'stdio' // Optional for backwards compatibility\n command: string\n args: string[]\n env?: Record<string, string>\n enabled?: boolean\n}\n\nexport type McpSSEServerConfig = {\n type: 'sse'\n url: string\n enabled?: boolean\n}\n\nexport type McpServerConfig = McpStdioServerConfig | McpSSEServerConfig\n\n/**\n * Sandbox configuration for project-level security settings\n */\nexport type SandboxConfigData = {\n /** Whether sandboxing is enabled */\n enabled: boolean\n /** Filesystem access policy */\n filesystem?: {\n writeAllowed?: string[]\n readAllowed?: string[]\n denied?: string[]\n }\n /** Network access policy */\n network?: {\n allowedDomains?: string[]\n promptForNewDomains?: boolean\n blockAll?: boolean\n }\n /** Process isolation policy */\n process?: {\n excludedCommands?: string[]\n maxExecutionTime?: number\n }\n}\n\nexport type ProjectConfig = {\n allowedTools: string[]\n context: Record<string, string>\n contextFiles?: string[]\n history: string[]\n dontCrawlDirectory?: boolean\n enableArchitectTool?: boolean\n mcpContextUris: string[]\n mcpServers?: Record<string, McpServerConfig>\n approvedMcprcServers?: string[]\n rejectedMcprcServers?: string[]\n lastAPIDuration?: number\n lastCost?: number\n lastDuration?: number\n lastSessionId?: string\n exampleFiles?: string[]\n exampleFilesGeneratedAt?: number\n hasTrustDialogAccepted?: boolean\n hasCompletedProjectOnboarding?: boolean\n /** Sandbox configuration for command execution isolation */\n sandbox?: SandboxConfigData\n}\n\nconst DEFAULT_PROJECT_CONFIG: ProjectConfig = {\n allowedTools: [],\n context: {},\n history: [],\n dontCrawlDirectory: false,\n enableArchitectTool: false,\n mcpContextUris: [],\n mcpServers: {},\n approvedMcprcServers: [],\n rejectedMcprcServers: [],\n hasTrustDialogAccepted: false,\n}\n\nfunction defaultConfigForProject(projectPath: string): ProjectConfig {\n const config = { ...DEFAULT_PROJECT_CONFIG }\n if (projectPath === homedir()) {\n config.dontCrawlDirectory = true\n }\n return config\n}\n\nexport type AutoUpdaterStatus =\n | 'disabled'\n | 'enabled'\n | 'no_permissions'\n | 'not_configured'\n\nexport function isAutoUpdaterStatus(value: string): value is AutoUpdaterStatus {\n return ['disabled', 'enabled', 'no_permissions', 'not_configured'].includes(\n value as AutoUpdaterStatus,\n )\n}\n\nexport type NotificationChannel =\n | 'iterm2'\n | 'terminal_bell'\n | 'iterm2_with_bell'\n | 'notifications_disabled'\n\n/**\n * @deprecated Use verbose boolean instead. Kept for backward compatibility migration.\n */\nexport type DisplayMode = 'minimal' | 'compact' | 'detailed'\n\n/**\n * Supported UI languages\n */\nexport type UILanguage = 'en' | 'zh-CN'\n\n/**\n * Safety mode for tool execution\n * - 'yolo': All tools allowed without confirmation (default for non-technical users)\n * - 'smart': Safe/monitored tools auto-allowed, dangerous tools need confirmation\n * - 'strict': Only safe tools auto-allowed, all others need confirmation\n * - 'free': Project directory operations auto-allowed, outside requires confirmation\n */\nexport type SafetyMode = 'yolo' | 'smart' | 'strict' | 'free'\n\n/**\n * Get verbose mode label (uses i18n)\n * Import dynamically to avoid circular dependency\n */\nexport function getVerboseLabel(verbose: boolean): string {\n // Dynamic import to avoid circular dependency at module load time\n try {\n const { t } = require('../i18n')\n return verbose ? t('ui.verbose.on') : t('ui.verbose.off')\n } catch {\n // Fallback if i18n not loaded yet\n return verbose ? 'Verbose: On' : 'Verbose: Off'\n }\n}\n\n/**\n * @deprecated Use getVerboseLabel() instead\n */\nexport function getDisplayModeLabel(mode: DisplayMode): string {\n return mode === 'detailed' ? 'Verbose: On' : 'Verbose: Off'\n}\n\n/**\n * @deprecated No longer needed - use verbose boolean directly\n */\nexport const DISPLAY_MODE_LABELS: Record<DisplayMode, string> = {\n minimal: 'Verbose: Off',\n compact: 'Verbose: Off',\n detailed: 'Verbose: On',\n}\n\n/**\n * @deprecated Use !verbose instead\n */\nexport function getNextDisplayMode(current: DisplayMode): DisplayMode {\n // Simply toggle between compact (off) and detailed (on)\n return current === 'detailed' ? 'compact' : 'detailed'\n}\n\n/**\n * Convert displayMode to verbose boolean for backward compatibility\n * @deprecated Components should use verbose directly\n */\nexport function displayModeToVerbose(mode: DisplayMode): boolean {\n return mode === 'detailed'\n}\n\n/**\n * Convert verbose boolean to displayMode for backward compatibility\n */\nexport function verboseToDisplayMode(verbose: boolean): DisplayMode {\n return verbose ? 'detailed' : 'compact'\n}\n\nexport type ProviderType =\n | 'anthropic'\n | 'openai'\n | 'mistral'\n | 'deepseek'\n | 'kimi'\n | 'qwen'\n | 'glm'\n | 'minimax'\n | 'baidu-qianfan'\n | 'siliconflow'\n | 'bigdream'\n | 'opendev'\n | 'xai'\n | 'groq'\n | 'gemini'\n | 'ollama'\n | 'azure'\n | 'custom'\n | 'custom-openai'\n\n// New model system types\nexport type ModelProfile = {\n name: string // User-friendly name\n provider: ProviderType // Provider type\n modelName: string // Primary key - actual model identifier\n baseURL?: string // Custom endpoint\n apiKey: string\n maxTokens: number // Output token limit (for GPT-5, this maps to max_completion_tokens)\n contextLength: number // Context window size\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal' | 'medium'\n isActive: boolean // Whether profile is enabled\n createdAt: number // Creation timestamp\n lastUsed?: number // Last usage timestamp\n // \uD83D\uDD25 GPT-5 specific metadata\n isGPT5?: boolean // Auto-detected GPT-5 model flag\n validationStatus?: 'valid' | 'needs_repair' | 'auto_repaired' // Configuration status\n lastValidation?: number // Last validation timestamp\n}\n\n// Legacy type for config migration - includes deprecated 'id' field\ntype LegacyModelProfile = ModelProfile & {\n id?: string\n}\n\n// Legacy global config fields for migration\ntype LegacyGlobalConfigFields = {\n defaultModelId?: string\n defaultModelName?: string\n currentSelectedModelId?: string\n mainAgentModelId?: string\n taskToolModelId?: string\n}\n\nexport type ModelPointerType =\n | 'main'\n | 'task'\n | 'reasoning'\n | 'quick'\n | 'compact'\n\nexport type ModelPointers = {\n main: string // Main dialog model ID\n task: string // Task tool model ID\n reasoning: string // Reasoning model ID\n quick: string // Quick model ID\n compact: string // Compact/summary model ID (for context compression)\n}\n\nexport type AccountInfo = {\n accountUuid: string\n emailAddress: string\n organizationUuid?: string\n}\n\nexport type GlobalConfig = {\n projects?: Record<string, ProjectConfig>\n numStartups: number\n autoUpdaterStatus?: AutoUpdaterStatus\n userID?: string\n theme: ThemeNames\n hasCompletedOnboarding?: boolean\n // Tracks the last version that reset onboarding, used with MIN_VERSION_REQUIRING_ONBOARDING_RESET\n lastOnboardingVersion?: string\n // Tracks the last version for which release notes were seen, used for managing release notes\n lastReleaseNotesSeen?: string\n mcpServers?: Record<string, McpServerConfig>\n preferredNotifChannel: NotificationChannel\n /**\n * Verbose mode: shows full parameters and complete outputs when enabled\n * - false: Concise output (default)\n * - true: Detailed/verbose output\n */\n verbose: boolean\n /**\n * @deprecated Use verbose boolean instead. Kept for backward compatibility migration.\n */\n displayMode?: DisplayMode\n customApiKeyResponses?: {\n approved?: string[]\n rejected?: string[]\n }\n primaryProvider?: ProviderType\n maxTokens?: number\n hasAcknowledgedCostThreshold?: boolean\n oauthAccount?: AccountInfo\n iterm2KeyBindingInstalled?: boolean // Legacy - keeping for backward compatibility\n shiftEnterKeyBindingInstalled?: boolean\n proxy?: string\n stream?: boolean\n\n // New model system\n modelProfiles?: ModelProfile[] // Model configuration list\n modelPointers?: ModelPointers // Model pointer system\n defaultModelName?: string // Default model\n // Update notifications\n lastDismissedUpdateVersion?: string\n // Compression mode\n compressionMode?: CompressionMode // Compression algorithm mode ('business' or 'code')\n // Thinking mode (Phase 4.2)\n thinking?: boolean // Whether thinking/extended reasoning mode is enabled\n // UI Language\n language?: UILanguage // UI language ('en' or 'zh-CN')\n /**\n * @deprecated Use safetyMode instead. Kept for backward compatibility.\n * Safe mode: when enabled, requires user confirmation for all tool executions\n */\n safeMode?: boolean\n /**\n * Safety mode for tool execution (4-tier system):\n * - 'yolo': All tools allowed without confirmation (default for non-technical users)\n * - 'smart': Safe/monitored tools auto-allowed, dangerous tools need confirmation\n * - 'strict': Only safe tools auto-allowed, all others need confirmation\n * - 'free': Project directory operations auto-allowed, outside requires confirmation\n */\n safetyMode?: SafetyMode\n}\n\nexport const DEFAULT_GLOBAL_CONFIG: GlobalConfig = {\n numStartups: 0,\n autoUpdaterStatus: 'not_configured',\n theme: 'dark' as ThemeNames,\n preferredNotifChannel: 'iterm2',\n verbose: false,\n primaryProvider: 'anthropic' as ProviderType,\n customApiKeyResponses: {\n approved: [],\n rejected: [],\n },\n stream: true,\n\n // New model system defaults\n modelProfiles: [],\n modelPointers: {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n },\n lastDismissedUpdateVersion: undefined,\n compressionMode: 'business', // Default to business consulting compression\n thinking: false, // Default to thinking mode off (Phase 4.2)\n language: 'en', // Default to English\n safeMode: false, // Deprecated: use safetyMode instead\n safetyMode: 'yolo', // Default to YOLO mode for non-technical users (zero interruption)\n}\n\nexport const GLOBAL_CONFIG_KEYS = [\n 'autoUpdaterStatus',\n 'theme',\n 'hasCompletedOnboarding',\n 'lastOnboardingVersion',\n 'lastReleaseNotesSeen',\n 'verbose',\n 'customApiKeyResponses',\n 'primaryProvider',\n 'preferredNotifChannel',\n 'shiftEnterKeyBindingInstalled',\n 'maxTokens',\n 'compressionMode',\n 'language',\n 'safetyMode',\n] as const\n\nexport type GlobalConfigKey = (typeof GLOBAL_CONFIG_KEYS)[number]\n\nexport function isGlobalConfigKey(key: string): key is GlobalConfigKey {\n return GLOBAL_CONFIG_KEYS.includes(key as GlobalConfigKey)\n}\n\nexport const PROJECT_CONFIG_KEYS = [\n 'dontCrawlDirectory',\n 'enableArchitectTool',\n 'hasTrustDialogAccepted',\n 'hasCompletedProjectOnboarding',\n] as const\n\nexport type ProjectConfigKey = (typeof PROJECT_CONFIG_KEYS)[number]\n\nexport function checkHasTrustDialogAccepted(): boolean {\n let currentPath = getCwd()\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n\n while (true) {\n const projectConfig = config.projects?.[currentPath]\n if (projectConfig?.hasTrustDialogAccepted) {\n return true\n }\n const parentPath = resolve(currentPath, '..')\n // Stop if we've reached the root (when parent is same as current)\n if (parentPath === currentPath) {\n break\n }\n currentPath = parentPath\n }\n\n return false\n}\n\n// We have to put this test code here because Jest doesn't support mocking ES modules :O\nconst TEST_GLOBAL_CONFIG_FOR_TESTING: GlobalConfig = {\n ...DEFAULT_GLOBAL_CONFIG,\n autoUpdaterStatus: 'disabled',\n}\nconst TEST_PROJECT_CONFIG_FOR_TESTING: ProjectConfig = {\n ...DEFAULT_PROJECT_CONFIG,\n}\n\nexport function isProjectConfigKey(key: string): key is ProjectConfigKey {\n return PROJECT_CONFIG_KEYS.includes(key as ProjectConfigKey)\n}\n\nexport function saveGlobalConfig(config: GlobalConfig): void {\n if (process.env.NODE_ENV === 'test') {\n for (const key in config) {\n TEST_GLOBAL_CONFIG_FOR_TESTING[key] = config[key]\n }\n return\n }\n\n // \u76F4\u63A5\u4FDD\u5B58\u914D\u7F6E\uFF08\u65E0\u9700\u6E05\u9664\u7F13\u5B58\uFF0C\u56E0\u4E3A\u5DF2\u79FB\u9664\u7F13\u5B58\uFF09\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...config,\n projects: getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG).projects,\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n}\n\n/**\n * Migrate legacy displayMode to verbose boolean\n */\nfunction migrateDisplayModeToVerbose(config: GlobalConfig): GlobalConfig {\n // If verbose is already set, no migration needed\n if (config.verbose !== undefined) {\n return config\n }\n\n // Check for legacy displayMode field\n const legacyConfig = config as GlobalConfig & { displayMode?: DisplayMode }\n if (legacyConfig.displayMode !== undefined) {\n const migratedConfig: GlobalConfig = {\n ...config,\n verbose: legacyConfig.displayMode === 'detailed',\n }\n // Remove legacy field\n delete (migratedConfig as any).displayMode\n return migratedConfig\n }\n\n // Default to false if no verbose or displayMode\n return {\n ...config,\n verbose: false,\n }\n}\n\n// \u4E34\u65F6\u79FB\u9664\u7F13\u5B58\uFF0C\u786E\u4FDD\u603B\u662F\u83B7\u53D6\u6700\u65B0\u914D\u7F6E\nexport function getGlobalConfig(): GlobalConfig {\n if (process.env.NODE_ENV === 'test') {\n return TEST_GLOBAL_CONFIG_FOR_TESTING\n }\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n const migratedConfig = migrateModelProfilesRemoveId(config)\n const displayMigratedConfig = migrateDisplayModeToVerbose(migratedConfig)\n\n // Apply model profile deduplication\n if (\n displayMigratedConfig.modelProfiles &&\n displayMigratedConfig.modelProfiles.length > 0\n ) {\n const originalCount = displayMigratedConfig.modelProfiles.length\n const deduplicatedProfiles = deduplicateModelProfiles(\n displayMigratedConfig.modelProfiles,\n )\n const deduplicatedCount = deduplicatedProfiles.length\n\n // If duplicates were found and removed, auto-save the deduplicated config\n if (deduplicatedCount < originalCount) {\n debugLogger.state('CONFIG_DEDUPLICATE_PROFILES', {\n originalCount: String(originalCount),\n deduplicatedCount: String(deduplicatedCount),\n removedCount: String(originalCount - deduplicatedCount),\n })\n const configToSave = {\n ...displayMigratedConfig,\n modelProfiles: deduplicatedProfiles,\n }\n // Save the deduplicated config (avoid recursion by using saveConfig directly)\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...configToSave,\n projects: config.projects,\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n return configToSave\n }\n\n return {\n ...displayMigratedConfig,\n modelProfiles: deduplicatedProfiles,\n }\n }\n\n return displayMigratedConfig\n}\n\nexport function getAnthropicApiKey(): null | string {\n return process.env.ANTHROPIC_API_KEY || null\n}\n\nexport function normalizeApiKeyForConfig(apiKey: string): string {\n return apiKey?.slice(-20) ?? ''\n}\n\nexport function getCustomApiKeyStatus(\n truncatedApiKey: string,\n): 'approved' | 'rejected' | 'new' {\n const config = getGlobalConfig()\n if (config.customApiKeyResponses?.approved?.includes(truncatedApiKey)) {\n return 'approved'\n }\n if (config.customApiKeyResponses?.rejected?.includes(truncatedApiKey)) {\n return 'rejected'\n }\n return 'new'\n}\n\n/**\n * Atomically write content to a file using temp file + rename pattern.\n * This prevents data corruption if writes are interrupted or multiple processes\n * attempt to write concurrently.\n *\n * @param filePath - The target file path to write to\n * @param content - The content to write\n * @throws {Error} If write or rename operation fails\n */\nfunction atomicWriteFileSync(filePath: string, content: string): void {\n const dir = dirname(filePath)\n const tempPath = join(\n dir,\n `.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,\n )\n\n try {\n // Write to temporary file\n writeFileSync(tempPath, content, 'utf-8')\n // Atomically rename temp to target (atomic on most filesystems)\n renameSync(tempPath, filePath)\n } catch (error) {\n // Clean up temporary file on failure\n try {\n rmSync(tempPath, { force: true })\n } catch {\n // Ignore cleanup errors\n }\n throw error\n }\n}\n\nfunction saveConfig<A extends object>(\n file: string,\n config: A,\n defaultConfig: A,\n): void {\n // Filter out any values that match the defaults\n const filteredConfig = Object.fromEntries(\n Object.entries(config).filter(\n ([key, value]) =>\n JSON.stringify(value) !== JSON.stringify(defaultConfig[key as keyof A]),\n ),\n )\n try {\n atomicWriteFileSync(file, JSON.stringify(filteredConfig, null, 2))\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (\n err?.code === 'EACCES' ||\n err?.code === 'EPERM' ||\n err?.code === 'EROFS'\n ) {\n debugLogger.state('CONFIG_SAVE_SKIPPED', {\n file,\n reason: String(err.code),\n })\n return\n }\n throw error\n }\n}\n\n// Flag to track if config reading is allowed\nlet configReadingAllowed = false\n\nexport function enableConfigs(): void {\n // Any reads to configuration before this flag is set show an console warning\n // to prevent us from adding config reading during module initialization\n configReadingAllowed = true\n // We only check the global config because currently all the configs share a file\n getConfig(\n GLOBAL_CONFIG_FILE,\n DEFAULT_GLOBAL_CONFIG,\n true /* throw on invalid */,\n )\n}\n\nfunction getConfig<A>(\n file: string,\n defaultConfig: A,\n throwOnInvalid?: boolean,\n): A {\n // \u7B80\u5316\u914D\u7F6E\u8BBF\u95EE\u903B\u8F91\uFF0C\u79FB\u9664\u590D\u6742\u7684\u65F6\u5E8F\u68C0\u67E5\n\n debugLogger.state('CONFIG_LOAD_START', {\n file,\n fileExists: String(existsSync(file)),\n throwOnInvalid: String(!!throwOnInvalid),\n })\n\n if (!existsSync(file)) {\n debugLogger.state('CONFIG_LOAD_DEFAULT', {\n file,\n reason: 'file_not_exists',\n defaultConfigKeys: Object.keys(defaultConfig as object).join(', '),\n })\n return cloneDeep(defaultConfig)\n }\n\n try {\n const fileContent = readFileSync(file, 'utf-8')\n debugLogger.state('CONFIG_FILE_READ', {\n file,\n contentLength: String(fileContent.length),\n contentPreview:\n fileContent.substring(0, 100) + (fileContent.length > 100 ? '...' : ''),\n })\n\n try {\n const parsedConfig = JSON.parse(fileContent)\n debugLogger.state('CONFIG_JSON_PARSED', {\n file,\n parsedKeys: Object.keys(parsedConfig).join(', '),\n })\n\n // Handle backward compatibility - remove logic for deleted fields\n const finalConfig = {\n ...cloneDeep(defaultConfig),\n ...parsedConfig,\n }\n\n debugLogger.state('CONFIG_LOAD_SUCCESS', {\n file,\n finalConfigKeys: Object.keys(finalConfig as object).join(', '),\n })\n\n return finalConfig\n } catch (error) {\n // Throw a ConfigParseError with the file path and default config\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n\n debugLogger.error('CONFIG_JSON_PARSE_ERROR', {\n file,\n errorMessage,\n errorType:\n error instanceof Error ? error.constructor.name : typeof error,\n contentLength: String(fileContent.length),\n })\n\n throw new ConfigParseError(errorMessage, file, defaultConfig)\n }\n } catch (error: unknown) {\n // Re-throw ConfigParseError if throwOnInvalid is true\n if (error instanceof ConfigParseError && throwOnInvalid) {\n debugLogger.error('CONFIG_PARSE_ERROR_RETHROWN', {\n file,\n throwOnInvalid: String(throwOnInvalid),\n errorMessage: error.message,\n })\n throw error\n }\n\n debugLogger.warn('CONFIG_FALLBACK_TO_DEFAULT', {\n file,\n errorType: error instanceof Error ? error.constructor.name : typeof error,\n errorMessage: error instanceof Error ? error.message : String(error),\n action: 'using_default_config',\n })\n\n return cloneDeep(defaultConfig)\n }\n}\n\nexport function getCurrentProjectConfig(): ProjectConfig {\n if (process.env.NODE_ENV === 'test') {\n return TEST_PROJECT_CONFIG_FOR_TESTING\n }\n\n const absolutePath = resolve(getCwd())\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n\n if (!config.projects) {\n return defaultConfigForProject(absolutePath)\n }\n\n const projectConfig =\n config.projects[absolutePath] ?? defaultConfigForProject(absolutePath)\n // Not sure how this became a string\n // TODO: Fix upstream\n if (typeof projectConfig.allowedTools === 'string') {\n projectConfig.allowedTools =\n (safeParseJSON(projectConfig.allowedTools) as string[]) ?? []\n }\n return projectConfig\n}\n\nexport function saveCurrentProjectConfig(projectConfig: ProjectConfig): void {\n if (process.env.NODE_ENV === 'test') {\n for (const key in projectConfig) {\n TEST_PROJECT_CONFIG_FOR_TESTING[key] = projectConfig[key]\n }\n return\n }\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...config,\n projects: {\n ...config.projects,\n [resolve(getCwd())]: projectConfig,\n },\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n}\n\nexport async function isAutoUpdaterDisabled(): Promise<boolean> {\n return getGlobalConfig().autoUpdaterStatus === 'disabled'\n}\n\nexport const TEST_MCPRC_CONFIG_FOR_TESTING: Record<string, McpServerConfig> = {}\n\nexport function clearMcprcConfigForTesting(): void {\n if (process.env.NODE_ENV === 'test') {\n Object.keys(TEST_MCPRC_CONFIG_FOR_TESTING).forEach(key => {\n delete TEST_MCPRC_CONFIG_FOR_TESTING[key]\n })\n }\n}\n\nexport function addMcprcServerForTesting(\n name: string,\n server: McpServerConfig,\n): void {\n if (process.env.NODE_ENV === 'test') {\n TEST_MCPRC_CONFIG_FOR_TESTING[name] = server\n }\n}\n\nexport function removeMcprcServerForTesting(name: string): void {\n if (process.env.NODE_ENV === 'test') {\n if (!TEST_MCPRC_CONFIG_FOR_TESTING[name]) {\n throw new Error(`No MCP server found with name: ${name} in .mcprc`)\n }\n delete TEST_MCPRC_CONFIG_FOR_TESTING[name]\n }\n}\n\nexport const getMcprcConfig = memoize(\n (): Record<string, McpServerConfig> => {\n if (process.env.NODE_ENV === 'test') {\n return TEST_MCPRC_CONFIG_FOR_TESTING\n }\n\n const mcprcPath = join(getCwd(), '.mcprc')\n if (!existsSync(mcprcPath)) {\n return {}\n }\n\n try {\n const mcprcContent = readFileSync(mcprcPath, 'utf-8')\n const config = safeParseJSON(mcprcContent)\n if (config && typeof config === 'object') {\n // Logging removed\n return config as Record<string, McpServerConfig>\n }\n } catch {\n // Ignore errors reading/parsing .mcprc (they're logged in safeParseJSON)\n }\n return {}\n },\n // This function returns the same value as long as the cwd and mcprc file content remain the same\n () => {\n const cwd = getCwd()\n const mcprcPath = join(cwd, '.mcprc')\n if (existsSync(mcprcPath)) {\n try {\n const stat = readFileSync(mcprcPath, 'utf-8')\n return `${cwd}:${stat}`\n } catch {\n return cwd\n }\n }\n return cwd\n },\n)\n\nexport function getOrCreateUserID(): string {\n const config = getGlobalConfig()\n if (config.userID) {\n return config.userID\n }\n\n const userID = randomBytes(32).toString('hex')\n saveGlobalConfig({ ...config, userID })\n return userID\n}\n\nexport function getConfigForCLI(key: string, global: boolean): unknown {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: '${key}' is not a valid config key. Valid keys are: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n return getGlobalConfig()[key]\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: '${key}' is not a valid config key. Valid keys are: ${PROJECT_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n return getCurrentProjectConfig()[key]\n }\n}\n\nexport function setConfigForCLI(\n key: string,\n value: unknown,\n global: boolean,\n): void {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: Cannot set '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n\n if (key === 'autoUpdaterStatus' && !isAutoUpdaterStatus(value as string)) {\n console.error(\n `Error: Invalid value for autoUpdaterStatus. Must be one of: disabled, enabled, no_permissions, not_configured`,\n )\n process.exit(1)\n }\n\n const currentConfig = getGlobalConfig()\n saveGlobalConfig({\n ...currentConfig,\n [key]: value,\n })\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: Cannot set '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\n )\n process.exit(1)\n }\n const currentConfig = getCurrentProjectConfig()\n saveCurrentProjectConfig({\n ...currentConfig,\n [key]: value,\n })\n }\n // Wait for the output to be flushed, to avoid clearing the screen.\n setTimeout(() => {\n // Without this we hang indefinitely.\n process.exit(0)\n }, 100)\n}\n\nexport function deleteConfigForCLI(key: string, global: boolean): void {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n const currentConfig = getGlobalConfig()\n delete currentConfig[key]\n saveGlobalConfig(currentConfig)\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\n )\n process.exit(1)\n }\n const currentConfig = getCurrentProjectConfig()\n delete currentConfig[key]\n saveCurrentProjectConfig(currentConfig)\n }\n}\n\nexport function listConfigForCLI(global: true): GlobalConfig\nexport function listConfigForCLI(global: false): ProjectConfig\nexport function listConfigForCLI(global: boolean): object {\n if (global) {\n const currentConfig = pick(getGlobalConfig(), GLOBAL_CONFIG_KEYS)\n return currentConfig\n } else {\n return pick(getCurrentProjectConfig(), PROJECT_CONFIG_KEYS)\n }\n}\n\nexport function getOpenAIApiKey(): string | undefined {\n return process.env.OPENAI_API_KEY\n}\n\n// Configuration migration utility functions\nfunction migrateModelProfilesRemoveId(config: GlobalConfig): GlobalConfig {\n if (!config.modelProfiles) return config\n\n // Cast to legacy type for migration - config may have old fields\n const legacyConfig = config as GlobalConfig & LegacyGlobalConfigFields\n\n // 1. Remove id field from ModelProfile objects and build ID to modelName mapping\n const idToModelNameMap = new Map<string, string>()\n const migratedProfiles = config.modelProfiles.map(profile => {\n // Cast to legacy type that includes optional id field\n const legacyProfile = profile as LegacyModelProfile\n // Build mapping before removing id field\n if (legacyProfile.id && profile.modelName) {\n idToModelNameMap.set(legacyProfile.id, profile.modelName)\n }\n\n // Remove id field, keep everything else\n const { id, ...profileWithoutId } = legacyProfile\n return profileWithoutId as ModelProfile\n })\n\n // 2. Migrate ModelPointers from IDs to modelNames\n const migratedPointers: ModelPointers = {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n }\n\n if (config.modelPointers) {\n Object.entries(config.modelPointers).forEach(([pointer, value]) => {\n if (value) {\n // If value looks like an old ID (model_xxx), map it to modelName\n const modelName = idToModelNameMap.get(value) || value\n migratedPointers[pointer as ModelPointerType] = modelName\n }\n })\n }\n\n // 3. Migrate legacy config fields\n let defaultModelName: string | undefined\n if (legacyConfig.defaultModelId) {\n defaultModelName =\n idToModelNameMap.get(legacyConfig.defaultModelId) ||\n legacyConfig.defaultModelId\n } else if (legacyConfig.defaultModelName) {\n defaultModelName = legacyConfig.defaultModelName\n }\n\n // 4. Remove legacy fields and return migrated config\n const migratedConfig: GlobalConfig & Partial<LegacyGlobalConfigFields> = {\n ...config,\n }\n delete migratedConfig.defaultModelId\n delete migratedConfig.currentSelectedModelId\n delete migratedConfig.mainAgentModelId\n delete migratedConfig.taskToolModelId\n\n return {\n ...migratedConfig,\n modelProfiles: migratedProfiles,\n modelPointers: migratedPointers,\n defaultModelName,\n }\n}\n\n// New model system utility functions\n\n/**\n * Deduplicate model profiles by modelName, keeping the one with the latest createdAt timestamp.\n *\n * @param profiles - Array of model profiles to deduplicate\n * @returns Deduplicated array of model profiles\n */\nexport function deduplicateModelProfiles(\n profiles: ModelProfile[],\n): ModelProfile[] {\n if (!profiles || profiles.length === 0) {\n return []\n }\n\n // Use Map to track the latest profile for each modelName\n const profileMap = new Map<string, ModelProfile>()\n\n for (const profile of profiles) {\n const existing = profileMap.get(profile.modelName)\n\n if (!existing) {\n // First occurrence of this modelName\n profileMap.set(profile.modelName, profile)\n } else {\n // Keep the one with the latest createdAt timestamp\n if (profile.createdAt > existing.createdAt) {\n profileMap.set(profile.modelName, profile)\n }\n }\n }\n\n // Return as array, preserving insertion order (which follows original array order for first occurrences)\n return Array.from(profileMap.values())\n}\n\nexport function setAllPointersToModel(modelName: string): void {\n const config = getGlobalConfig()\n const updatedConfig = {\n ...config,\n modelPointers: {\n main: modelName,\n task: modelName,\n reasoning: modelName,\n quick: modelName,\n compact: modelName,\n },\n defaultModelName: modelName,\n }\n saveGlobalConfig(updatedConfig)\n}\n\nexport function setModelPointer(\n pointer: ModelPointerType,\n modelName: string,\n): void {\n const config = getGlobalConfig()\n const updatedConfig = {\n ...config,\n modelPointers: {\n ...config.modelPointers,\n [pointer]: modelName,\n },\n }\n saveGlobalConfig(updatedConfig)\n\n // \uD83D\uDD27 Fix: Force ModelManager reload after config change\n // Import here to avoid circular dependency\n import('./model').then(({ reloadModelManager }) => {\n reloadModelManager()\n })\n}\n\n// Credential resolution functions for secure API key management\n\n/**\n * Resolve an API key for a ModelProfile.\n * Supports both plaintext keys (backward compatibility) and encrypted references.\n *\n * For plaintext keys (legacy):\n * Returns the key directly from the profile\n *\n * For encrypted references (encrypted:modelName):\n * Retrieves the key from the encrypted credential store\n *\n * @param profile The model profile to resolve the API key for\n * @returns The resolved API key, or null if not found\n * @throws Error if credential store access fails\n */\nexport async function resolveApiKey(\n profile: ModelProfile,\n): Promise<string | null> {\n if (!profile.apiKey) {\n return null\n }\n\n // Check if this is an encrypted reference\n if (profile.apiKey.startsWith('encrypted:')) {\n // Extract model name from the encrypted reference\n const modelName = profile.apiKey.slice('encrypted:'.length)\n\n // Import dynamically to avoid circular dependencies\n try {\n const { getApiKey } = await import('./credentials')\n return getApiKey(modelName)\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n console.warn(\n `Failed to resolve encrypted API key for ${modelName}: ${errorMsg}`,\n )\n return null\n }\n }\n\n // Return plaintext key for backward compatibility\n return profile.apiKey\n}\n\n// \uD83D\uDD25 GPT-5 Configuration Validation and Auto-Repair Functions\n\n/**\n * Check if a model name represents a GPT-5 model\n */\nexport function isGPT5ModelName(modelName: string): boolean {\n if (!modelName || typeof modelName !== 'string') return false\n const lowerName = modelName.toLowerCase()\n return lowerName.startsWith('gpt-5') || lowerName.includes('gpt-5')\n}\n\n/**\n * Validate and auto-repair GPT-5 model configuration\n */\nexport function validateAndRepairGPT5Profile(\n profile: ModelProfile,\n): ModelProfile {\n const isGPT5 = isGPT5ModelName(profile.modelName)\n const now = Date.now()\n\n // Create a working copy\n const repairedProfile: ModelProfile = { ...profile }\n let wasRepaired = false\n\n // \uD83D\uDD27 Set GPT-5 detection flag\n if (isGPT5 !== profile.isGPT5) {\n repairedProfile.isGPT5 = isGPT5\n wasRepaired = true\n }\n\n if (isGPT5) {\n // \uD83D\uDD27 GPT-5 Parameter Validation and Repair\n\n // 1. Reasoning effort validation\n const validReasoningEfforts = ['minimal', 'low', 'medium', 'high']\n if (\n !profile.reasoningEffort ||\n !validReasoningEfforts.includes(profile.reasoningEffort)\n ) {\n repairedProfile.reasoningEffort = 'medium' // Default for coding tasks\n wasRepaired = true\n console.log(\n `\uD83D\uDD27 GPT-5 Config: Set reasoning effort to 'medium' for ${profile.modelName}`,\n )\n }\n\n // 2. Context length validation (GPT-5 models typically have 128k context)\n if (profile.contextLength < 128000) {\n repairedProfile.contextLength = 128000\n wasRepaired = true\n console.log(\n `\uD83D\uDD27 GPT-5 Config: Updated context length to 128k for ${profile.modelName}`,\n )\n }\n\n // 3. Output tokens validation (reasonable defaults for GPT-5)\n if (profile.maxTokens < 4000) {\n repairedProfile.maxTokens = 8192 // Good default for coding tasks\n wasRepaired = true\n console.log(\n `\uD83D\uDD27 GPT-5 Config: Updated max tokens to 8192 for ${profile.modelName}`,\n )\n }\n\n // 4. Provider validation\n if (\n profile.provider !== 'openai' &&\n profile.provider !== 'custom-openai' &&\n profile.provider !== 'azure'\n ) {\n console.warn(\n `\u26A0\uFE0F GPT-5 Config: Unexpected provider '${profile.provider}' for GPT-5 model ${profile.modelName}. Consider using 'openai' or 'custom-openai'.`,\n )\n }\n\n // 5. Base URL validation for official models\n if (profile.modelName.includes('gpt-5') && !profile.baseURL) {\n repairedProfile.baseURL = 'https://api.openai.com/v1'\n wasRepaired = true\n console.log(\n `\uD83D\uDD27 GPT-5 Config: Set default base URL for ${profile.modelName}`,\n )\n }\n }\n\n // Update validation metadata\n repairedProfile.validationStatus = wasRepaired ? 'auto_repaired' : 'valid'\n repairedProfile.lastValidation = now\n\n if (wasRepaired) {\n console.log(\n `\u2705 GPT-5 Config: Auto-repaired configuration for ${profile.modelName}`,\n )\n }\n\n return repairedProfile\n}\n\n/**\n * Validate and repair all GPT-5 profiles in the global configuration\n */\nexport function validateAndRepairAllGPT5Profiles(): {\n repaired: number\n total: number\n} {\n const config = getGlobalConfig()\n if (!config.modelProfiles) {\n return { repaired: 0, total: 0 }\n }\n\n let repairCount = 0\n const repairedProfiles = config.modelProfiles.map(profile => {\n const repairedProfile = validateAndRepairGPT5Profile(profile)\n if (repairedProfile.validationStatus === 'auto_repaired') {\n repairCount++\n }\n return repairedProfile\n })\n\n // Save the repaired configuration\n if (repairCount > 0) {\n const updatedConfig = {\n ...config,\n modelProfiles: repairedProfiles,\n }\n saveGlobalConfig(updatedConfig)\n console.log(`\uD83D\uDD27 GPT-5 Config: Auto-repaired ${repairCount} model profiles`)\n }\n\n return { repaired: repairCount, total: config.modelProfiles.length }\n}\n\n/**\n * Get GPT-5 configuration recommendations for a specific model\n */\nexport function getGPT5ConfigRecommendations(\n modelName: string,\n): Partial<ModelProfile> {\n if (!isGPT5ModelName(modelName)) {\n return {}\n }\n\n const recommendations: Partial<ModelProfile> = {\n contextLength: 128000, // GPT-5 standard context length\n maxTokens: 8192, // Good default for coding tasks\n reasoningEffort: 'medium', // Balanced for most coding tasks\n isGPT5: true,\n }\n\n // Model-specific optimizations\n if (modelName.includes('gpt-5-mini')) {\n recommendations.maxTokens = 4096 // Smaller default for mini\n recommendations.reasoningEffort = 'low' // Faster for simple tasks\n } else if (modelName.includes('gpt-5-nano')) {\n recommendations.maxTokens = 2048 // Even smaller for nano\n recommendations.reasoningEffort = 'minimal' // Fastest option\n }\n\n return recommendations\n}\n\n/**\n * Create a properly configured GPT-5 model profile\n */\nexport function createGPT5ModelProfile(\n name: string,\n modelName: string,\n apiKey: string,\n baseURL?: string,\n provider: ProviderType = 'openai',\n): ModelProfile {\n const recommendations = getGPT5ConfigRecommendations(modelName)\n\n const profile: ModelProfile = {\n name,\n provider,\n modelName,\n baseURL: baseURL || 'https://api.openai.com/v1',\n apiKey,\n maxTokens: recommendations.maxTokens || 8192,\n contextLength: recommendations.contextLength || 128000,\n reasoningEffort: recommendations.reasoningEffort || 'medium',\n isActive: true,\n createdAt: Date.now(),\n isGPT5: true,\n validationStatus: 'valid',\n lastValidation: Date.now(),\n }\n\n console.log(`\u2705 Created GPT-5 model profile: ${name} (${modelName})`)\n return profile\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'fs'\nimport { resolve, join, dirname } from 'path'\nimport { cloneDeep, memoize, pick } from 'lodash-es'\nimport { homedir } from 'os'\nimport { GLOBAL_CONFIG_FILE } from './env'\nimport { getCwd } from './state'\nimport { randomBytes } from 'crypto'\nimport { safeParseJSON } from './json'\nimport { ConfigParseError } from './errors'\nimport type { ThemeNames } from './theme'\nimport { debug as debugLogger } from './debugLogger'\nimport { safeValidateGlobalConfig } from './configSchema'\n\n// Re-export canonical types derived from Zod schemas (single source of truth)\nexport type {\n McpStdioServerConfig,\n McpSSEServerConfig,\n McpHTTPServerConfig,\n McpServerConfig,\n AutoUpdaterStatus,\n NotificationChannel,\n ProviderType,\n UILanguage,\n SafetyMode,\n ReasoningEffort,\n ModelProfile,\n ModelPointerType,\n ModelPointers,\n AccountInfo,\n SandboxConfigData,\n CompressionMode,\n} from './configSchema'\n\n// Import types locally for use in this file\nimport type {\n McpServerConfig,\n AutoUpdaterStatus,\n NotificationChannel,\n ProviderType,\n UILanguage,\n SafetyMode,\n ModelProfile,\n ModelPointerType,\n ModelPointers,\n AccountInfo,\n SandboxConfigData,\n CompressionMode,\n} from './configSchema'\nimport { getSessionState, setSessionState } from './sessionState'\n// CompressionMode now re-exported from configSchema.ts\n\n// Types McpStdioServerConfig, McpSSEServerConfig, McpHTTPServerConfig,\n// McpServerConfig, SandboxConfigData are now derived from Zod schemas\n// and re-exported from configSchema.ts above.\n\n// ProjectConfig uses Zod-derived sub-types but keeps manual definition\n// due to .passthrough() in Zod schema generating incompatible index signatures.\nexport type ProjectConfig = {\n allowedTools: string[]\n context: Record<string, string>\n contextFiles?: string[]\n history: string[]\n dontCrawlDirectory?: boolean\n enableArchitectTool?: boolean\n mcpContextUris: string[]\n mcpServers?: Record<string, McpServerConfig>\n approvedMcprcServers?: string[]\n rejectedMcprcServers?: string[]\n lastAPIDuration?: number\n lastCost?: number\n lastDuration?: number\n lastSessionId?: string\n exampleFiles?: string[]\n exampleFilesGeneratedAt?: number\n hasTrustDialogAccepted?: boolean\n hasCompletedProjectOnboarding?: boolean\n sandbox?: SandboxConfigData\n [key: string]: unknown\n}\n\nconst DEFAULT_PROJECT_CONFIG: ProjectConfig = {\n allowedTools: [],\n context: {},\n history: [],\n dontCrawlDirectory: false,\n enableArchitectTool: false,\n mcpContextUris: [],\n mcpServers: {},\n approvedMcprcServers: [],\n rejectedMcprcServers: [],\n hasTrustDialogAccepted: false,\n}\n\nfunction defaultConfigForProject(projectPath: string): ProjectConfig {\n const config = { ...DEFAULT_PROJECT_CONFIG }\n if (projectPath === homedir()) {\n config.dontCrawlDirectory = true\n }\n return config\n}\n\n// AutoUpdaterStatus now derived from Zod schema in configSchema.ts\n\nexport function isAutoUpdaterStatus(value: string): value is AutoUpdaterStatus {\n return ['disabled', 'enabled', 'no_permissions', 'not_configured'].includes(\n value as AutoUpdaterStatus,\n )\n}\n\n// NotificationChannel now derived from Zod schema in configSchema.ts\n\n/**\n * @deprecated Use verbose boolean instead. Kept for backward compatibility migration.\n */\nexport type DisplayMode = 'minimal' | 'compact' | 'detailed'\n\n// UILanguage now derived from Zod schema in configSchema.ts\n\n// SafetyMode now derived from Zod schema in configSchema.ts\n\n/**\n * Get verbose mode label (uses i18n)\n * Import dynamically to avoid circular dependency\n */\nexport function getVerboseLabel(verbose: boolean): string {\n // Dynamic import to avoid circular dependency at module load time\n try {\n const { t } = require('../i18n')\n return verbose ? t('ui.verbose.on') : t('ui.verbose.off')\n } catch {\n // Fallback if i18n not loaded yet\n return verbose ? 'Verbose: On' : 'Verbose: Off'\n }\n}\n\n// ProviderType now derived from Zod schema in configSchema.ts\n\n// ModelProfile now derived from Zod schema in configSchema.ts\n\n// Legacy type for config migration - includes deprecated 'id' field\ntype LegacyModelProfile = ModelProfile & {\n id?: string\n}\n\n// Legacy global config fields for migration\ntype LegacyGlobalConfigFields = {\n defaultModelId?: string\n defaultModelName?: string\n currentSelectedModelId?: string\n mainAgentModelId?: string\n taskToolModelId?: string\n}\n\n// ModelPointerType, ModelPointers, AccountInfo now derived from Zod schema in configSchema.ts\n\nexport type GlobalConfig = {\n projects?: Record<string, ProjectConfig>\n numStartups: number\n autoUpdaterStatus?: AutoUpdaterStatus\n userID?: string\n theme: ThemeNames\n hasCompletedOnboarding?: boolean\n // Tracks the last version that reset onboarding, used with MIN_VERSION_REQUIRING_ONBOARDING_RESET\n lastOnboardingVersion?: string\n // Tracks the last version for which release notes were seen, used for managing release notes\n lastReleaseNotesSeen?: string\n mcpServers?: Record<string, McpServerConfig>\n preferredNotifChannel: NotificationChannel\n /**\n * Verbose mode: shows full parameters and complete outputs when enabled\n * - false: Concise output (default)\n * - true: Detailed/verbose output\n */\n verbose: boolean\n /**\n * @deprecated Use verbose boolean instead. Kept for backward compatibility migration.\n */\n displayMode?: DisplayMode\n customApiKeyResponses?: {\n approved?: string[]\n rejected?: string[]\n }\n primaryProvider?: ProviderType\n maxTokens?: number\n hasAcknowledgedCostThreshold?: boolean\n oauthAccount?: AccountInfo\n iterm2KeyBindingInstalled?: boolean // Legacy - keeping for backward compatibility\n shiftEnterKeyBindingInstalled?: boolean\n proxy?: string\n stream?: boolean\n\n // New model system\n modelProfiles?: ModelProfile[] // Model configuration list\n modelPointers?: ModelPointers // Model pointer system\n defaultModelName?: string // Default model\n // Update notifications\n lastDismissedUpdateVersion?: string\n // Compression mode\n compressionMode?: CompressionMode // Compression algorithm mode ('business' or 'code')\n // Thinking mode (Phase 4.2)\n thinking?: boolean // Whether thinking/extended reasoning mode is enabled\n // UI Language\n language?: UILanguage // UI language ('en' or 'zh-CN')\n /**\n * @deprecated Use safetyMode instead. Kept for backward compatibility.\n * Safe mode: when enabled, requires user confirmation for all tool executions\n */\n safeMode?: boolean\n /**\n * Safety mode for tool execution (4-tier system):\n * - 'yolo': All tools allowed without confirmation (default for non-technical users)\n * - 'smart': Safe/monitored tools auto-allowed, dangerous tools need confirmation\n * - 'strict': Only safe tools auto-allowed, all others need confirmation\n * - 'free': Project directory operations auto-allowed, outside requires confirmation\n */\n safetyMode?: SafetyMode\n // Claude Code plugin auto-sync\n autoSyncClaudeCode?: boolean\n // Enable experimental memory tools (read/write persistent agent memory)\n enableMemoryTools?: boolean\n // Output style selection (CC compat)\n outputStyle?: string\n // Auto-memory: extract key decisions during auto-compact\n autoMemory?: boolean\n // File backup for /undo\n backupEnabled?: boolean\n}\n\nexport const DEFAULT_GLOBAL_CONFIG: GlobalConfig = {\n numStartups: 0,\n autoUpdaterStatus: 'not_configured',\n theme: 'dark',\n preferredNotifChannel: 'iterm2',\n verbose: false,\n primaryProvider: 'anthropic',\n customApiKeyResponses: {\n approved: [],\n rejected: [],\n },\n stream: true,\n\n // New model system defaults\n modelProfiles: [],\n modelPointers: {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n },\n lastDismissedUpdateVersion: undefined,\n compressionMode: 'business', // Default to business consulting compression\n thinking: false, // Default to thinking mode off (Phase 4.2)\n language: 'en', // Default to English\n safeMode: false, // Deprecated: use safetyMode instead\n safetyMode: 'smart', // Default to smart mode \u2014 safe tools auto-allowed, dangerous tools need confirmation\n}\n\nexport const GLOBAL_CONFIG_KEYS = [\n 'autoUpdaterStatus',\n 'theme',\n 'hasCompletedOnboarding',\n 'lastOnboardingVersion',\n 'lastReleaseNotesSeen',\n 'verbose',\n 'customApiKeyResponses',\n 'primaryProvider',\n 'preferredNotifChannel',\n 'shiftEnterKeyBindingInstalled',\n 'maxTokens',\n 'compressionMode',\n 'language',\n 'safetyMode',\n 'enableMemoryTools',\n 'outputStyle',\n 'autoMemory',\n] as const\n\nexport type GlobalConfigKey = (typeof GLOBAL_CONFIG_KEYS)[number]\n\nexport function isGlobalConfigKey(key: string): key is GlobalConfigKey {\n return GLOBAL_CONFIG_KEYS.includes(key as GlobalConfigKey)\n}\n\nexport const PROJECT_CONFIG_KEYS = [\n 'dontCrawlDirectory',\n 'enableArchitectTool',\n 'hasTrustDialogAccepted',\n 'hasCompletedProjectOnboarding',\n] as const\n\nexport type ProjectConfigKey = (typeof PROJECT_CONFIG_KEYS)[number]\n\nexport function checkHasTrustDialogAccepted(): boolean {\n let currentPath = getCwd()\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n\n while (true) {\n const projectConfig = config.projects?.[currentPath]\n if (projectConfig?.hasTrustDialogAccepted) {\n return true\n }\n const parentPath = resolve(currentPath, '..')\n // Stop if we've reached the root (when parent is same as current)\n if (parentPath === currentPath) {\n break\n }\n currentPath = parentPath\n }\n\n return false\n}\n\n// We have to put this test code here because Jest doesn't support mocking ES modules :O\nconst TEST_GLOBAL_CONFIG_FOR_TESTING: GlobalConfig = {\n ...DEFAULT_GLOBAL_CONFIG,\n autoUpdaterStatus: 'disabled',\n}\nconst TEST_PROJECT_CONFIG_FOR_TESTING: ProjectConfig = {\n ...DEFAULT_PROJECT_CONFIG,\n}\n\nexport function isProjectConfigKey(key: string): key is ProjectConfigKey {\n return PROJECT_CONFIG_KEYS.includes(key as ProjectConfigKey)\n}\n\nexport function saveGlobalConfig(config: GlobalConfig): void {\n if (process.env.NODE_ENV === 'test') {\n for (const key in config) {\n ;(TEST_GLOBAL_CONFIG_FOR_TESTING as Record<string, unknown>)[key] = (\n config as Record<string, unknown>\n )[key]\n }\n return\n }\n\n // \u76F4\u63A5\u4FDD\u5B58\u914D\u7F6E\uFF08\u65E0\u9700\u6E05\u9664\u7F13\u5B58\uFF0C\u56E0\u4E3A\u5DF2\u79FB\u9664\u7F13\u5B58\uFF09\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...config,\n projects: getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG).projects,\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n}\n\n/**\n * Migrate legacy displayMode to verbose boolean\n */\nfunction migrateDisplayModeToVerbose(config: GlobalConfig): GlobalConfig {\n // If verbose is already set, no migration needed\n if (config.verbose !== undefined) {\n return config\n }\n\n // Check for legacy displayMode field\n const legacyConfig = config as GlobalConfig & { displayMode?: DisplayMode }\n if (legacyConfig.displayMode !== undefined) {\n const migratedConfig: GlobalConfig = {\n ...config,\n verbose: legacyConfig.displayMode === 'detailed',\n }\n // Remove legacy field\n delete (migratedConfig as Record<string, unknown>).displayMode\n return migratedConfig\n }\n\n // Default to false if no verbose or displayMode\n return {\n ...config,\n verbose: false,\n }\n}\n\n// \u4E34\u65F6\u79FB\u9664\u7F13\u5B58\uFF0C\u786E\u4FDD\u603B\u662F\u83B7\u53D6\u6700\u65B0\u914D\u7F6E\nexport function getGlobalConfig(): GlobalConfig {\n if (process.env.NODE_ENV === 'test') {\n return TEST_GLOBAL_CONFIG_FOR_TESTING\n }\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n const migratedConfig = migrateModelProfilesRemoveId(config)\n const displayMigratedConfig = migrateDisplayModeToVerbose(migratedConfig)\n\n // Apply model profile deduplication\n if (\n displayMigratedConfig.modelProfiles &&\n displayMigratedConfig.modelProfiles.length > 0\n ) {\n const originalCount = displayMigratedConfig.modelProfiles.length\n const deduplicatedProfiles = deduplicateModelProfiles(\n displayMigratedConfig.modelProfiles,\n )\n const deduplicatedCount = deduplicatedProfiles.length\n\n // If duplicates were found and removed, auto-save the deduplicated config\n if (deduplicatedCount < originalCount) {\n debugLogger.state('CONFIG_DEDUPLICATE_PROFILES', {\n originalCount: String(originalCount),\n deduplicatedCount: String(deduplicatedCount),\n removedCount: String(originalCount - deduplicatedCount),\n })\n const configToSave = {\n ...displayMigratedConfig,\n modelProfiles: deduplicatedProfiles,\n }\n // Save the deduplicated config (avoid recursion by using saveConfig directly)\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...configToSave,\n projects: config.projects,\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n return configToSave\n }\n\n return {\n ...displayMigratedConfig,\n modelProfiles: deduplicatedProfiles,\n }\n }\n\n return displayMigratedConfig\n}\n\nexport function getAnthropicApiKey(): null | string {\n return process.env.ANTHROPIC_API_KEY || null\n}\n\nexport function normalizeApiKeyForConfig(apiKey: string): string {\n return apiKey?.slice(-20) ?? ''\n}\n\nexport function getCustomApiKeyStatus(\n truncatedApiKey: string,\n): 'approved' | 'rejected' | 'new' {\n const config = getGlobalConfig()\n if (config.customApiKeyResponses?.approved?.includes(truncatedApiKey)) {\n return 'approved'\n }\n if (config.customApiKeyResponses?.rejected?.includes(truncatedApiKey)) {\n return 'rejected'\n }\n return 'new'\n}\n\n/**\n * Atomically write content to a file using temp file + rename pattern.\n * This prevents data corruption if writes are interrupted or multiple processes\n * attempt to write concurrently.\n *\n * @param filePath - The target file path to write to\n * @param content - The content to write\n * @throws {Error} If write or rename operation fails\n */\nfunction atomicWriteFileSync(filePath: string, content: string): void {\n const dir = dirname(filePath)\n const tempPath = join(\n dir,\n `.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,\n )\n\n try {\n // Write to temporary file\n writeFileSync(tempPath, content, 'utf-8')\n // Atomically rename temp to target (atomic on most filesystems)\n renameSync(tempPath, filePath)\n } catch (error) {\n // Clean up temporary file on failure\n try {\n rmSync(tempPath, { force: true })\n } catch {\n // Ignore cleanup errors\n }\n throw error\n }\n}\n\nfunction saveConfig<A extends object>(\n file: string,\n config: A,\n defaultConfig: A,\n): void {\n // Filter out any values that match the defaults\n const filteredConfig = Object.fromEntries(\n Object.entries(config).filter(\n ([key, value]) =>\n JSON.stringify(value) !== JSON.stringify(defaultConfig[key as keyof A]),\n ),\n )\n try {\n atomicWriteFileSync(file, JSON.stringify(filteredConfig, null, 2))\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (\n err?.code === 'EACCES' ||\n err?.code === 'EPERM' ||\n err?.code === 'EROFS'\n ) {\n debugLogger.state('CONFIG_SAVE_SKIPPED', {\n file,\n reason: String(err.code),\n })\n return\n }\n throw error\n }\n}\n\n// Flag to track if config reading is allowed\nlet configReadingAllowed = false\n\nexport function enableConfigs(): void {\n // Any reads to configuration before this flag is set show an console warning\n // to prevent us from adding config reading during module initialization\n configReadingAllowed = true\n // We only check the global config because currently all the configs share a file\n getConfig(\n GLOBAL_CONFIG_FILE,\n DEFAULT_GLOBAL_CONFIG,\n true /* throw on invalid */,\n )\n}\n\nfunction getConfig<A>(\n file: string,\n defaultConfig: A,\n throwOnInvalid?: boolean,\n): A {\n // \u7B80\u5316\u914D\u7F6E\u8BBF\u95EE\u903B\u8F91\uFF0C\u79FB\u9664\u590D\u6742\u7684\u65F6\u5E8F\u68C0\u67E5\n\n debugLogger.state('CONFIG_LOAD_START', {\n file,\n fileExists: String(existsSync(file)),\n throwOnInvalid: String(!!throwOnInvalid),\n })\n\n if (!existsSync(file)) {\n debugLogger.state('CONFIG_LOAD_DEFAULT', {\n file,\n reason: 'file_not_exists',\n defaultConfigKeys: Object.keys(defaultConfig as object).join(', '),\n })\n return cloneDeep(defaultConfig)\n }\n\n try {\n const fileContent = readFileSync(file, 'utf-8')\n debugLogger.state('CONFIG_FILE_READ', {\n file,\n contentLength: String(fileContent.length),\n contentPreview:\n fileContent.substring(0, 100) + (fileContent.length > 100 ? '...' : ''),\n })\n\n try {\n const parsedConfig = JSON.parse(fileContent)\n debugLogger.state('CONFIG_JSON_PARSED', {\n file,\n parsedKeys: Object.keys(parsedConfig).join(', '),\n })\n\n // Zod validation \u2014 monitor mode (log only, never reject)\n if (file === GLOBAL_CONFIG_FILE) {\n const validation = safeValidateGlobalConfig(parsedConfig)\n if (!validation.success && validation.errors) {\n debugLogger.warn('CONFIG_VALIDATION', {\n file,\n issues: validation.errors.issues\n .map(i => `${i.path.join('.')}: ${i.message}`)\n .join('; '),\n })\n }\n }\n\n // Handle backward compatibility - remove logic for deleted fields\n const finalConfig = {\n ...cloneDeep(defaultConfig),\n ...parsedConfig,\n }\n\n debugLogger.state('CONFIG_LOAD_SUCCESS', {\n file,\n finalConfigKeys: Object.keys(finalConfig as object).join(', '),\n })\n\n return finalConfig\n } catch (error) {\n // Throw a ConfigParseError with the file path and default config\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n\n debugLogger.error('CONFIG_JSON_PARSE_ERROR', {\n file,\n errorMessage,\n errorType:\n error instanceof Error ? error.constructor.name : typeof error,\n contentLength: String(fileContent.length),\n })\n\n throw new ConfigParseError(errorMessage, file, defaultConfig)\n }\n } catch (error: unknown) {\n // Re-throw ConfigParseError if throwOnInvalid is true\n if (error instanceof ConfigParseError && throwOnInvalid) {\n debugLogger.error('CONFIG_PARSE_ERROR_RETHROWN', {\n file,\n throwOnInvalid: String(throwOnInvalid),\n errorMessage: error.message,\n })\n throw error\n }\n\n debugLogger.warn('CONFIG_FALLBACK_TO_DEFAULT', {\n file,\n errorType: error instanceof Error ? error.constructor.name : typeof error,\n errorMessage: error instanceof Error ? error.message : String(error),\n action: 'using_default_config',\n })\n\n return cloneDeep(defaultConfig)\n }\n}\n\nexport function getCurrentProjectConfig(): ProjectConfig {\n if (process.env.NODE_ENV === 'test') {\n return TEST_PROJECT_CONFIG_FOR_TESTING\n }\n\n const absolutePath = resolve(getCwd())\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n\n if (!config.projects) {\n return defaultConfigForProject(absolutePath)\n }\n\n const projectConfig =\n config.projects[absolutePath] ?? defaultConfigForProject(absolutePath)\n // Guard: allowedTools may be serialized as a JSON string in some config paths\n if (typeof projectConfig.allowedTools === 'string') {\n projectConfig.allowedTools =\n (safeParseJSON(projectConfig.allowedTools) as string[]) ?? []\n }\n return projectConfig\n}\n\nexport function saveCurrentProjectConfig(projectConfig: ProjectConfig): void {\n if (process.env.NODE_ENV === 'test') {\n for (const key in projectConfig) {\n TEST_PROJECT_CONFIG_FOR_TESTING[key] = projectConfig[key]\n }\n return\n }\n const config = getConfig(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG)\n saveConfig(\n GLOBAL_CONFIG_FILE,\n {\n ...config,\n projects: {\n ...config.projects,\n [resolve(getCwd())]: projectConfig,\n },\n },\n DEFAULT_GLOBAL_CONFIG,\n )\n}\n\nexport async function isAutoUpdaterDisabled(): Promise<boolean> {\n return getGlobalConfig().autoUpdaterStatus === 'disabled'\n}\n\nexport const TEST_MCPRC_CONFIG_FOR_TESTING: Record<string, McpServerConfig> = {}\n\nexport function clearMcprcConfigForTesting(): void {\n if (process.env.NODE_ENV === 'test') {\n Object.keys(TEST_MCPRC_CONFIG_FOR_TESTING).forEach(key => {\n delete TEST_MCPRC_CONFIG_FOR_TESTING[key]\n })\n }\n}\n\nexport function addMcprcServerForTesting(\n name: string,\n server: McpServerConfig,\n): void {\n if (process.env.NODE_ENV === 'test') {\n TEST_MCPRC_CONFIG_FOR_TESTING[name] = server\n }\n}\n\nexport function removeMcprcServerForTesting(name: string): void {\n if (process.env.NODE_ENV === 'test') {\n if (!TEST_MCPRC_CONFIG_FOR_TESTING[name]) {\n throw new Error(`No MCP server found with name: ${name} in .mcprc`)\n }\n delete TEST_MCPRC_CONFIG_FOR_TESTING[name]\n }\n}\n\nexport const getMcprcConfig = memoize(\n (): Record<string, McpServerConfig> => {\n if (process.env.NODE_ENV === 'test') {\n return TEST_MCPRC_CONFIG_FOR_TESTING\n }\n\n const mcprcPath = join(getCwd(), '.mcprc')\n if (!existsSync(mcprcPath)) {\n return {}\n }\n\n try {\n const mcprcContent = readFileSync(mcprcPath, 'utf-8')\n const config = safeParseJSON(mcprcContent)\n if (config && typeof config === 'object') {\n // Logging removed\n return config as Record<string, McpServerConfig>\n }\n } catch {\n // Ignore errors reading/parsing .mcprc (they're logged in safeParseJSON)\n }\n return {}\n },\n // This function returns the same value as long as the cwd and mcprc file content remain the same\n () => {\n const cwd = getCwd()\n const mcprcPath = join(cwd, '.mcprc')\n if (existsSync(mcprcPath)) {\n try {\n const stat = readFileSync(mcprcPath, 'utf-8')\n return `${cwd}:${stat}`\n } catch {\n return cwd\n }\n }\n return cwd\n },\n)\n\nexport function getOrCreateUserID(): string {\n const config = getGlobalConfig()\n if (config.userID) {\n return config.userID\n }\n\n const userID = randomBytes(32).toString('hex')\n saveGlobalConfig({ ...config, userID })\n return userID\n}\n\nexport function getConfigForCLI(key: string, global: boolean): unknown {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: '${key}' is not a valid config key. Valid keys are: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n return getGlobalConfig()[key]\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: '${key}' is not a valid config key. Valid keys are: ${PROJECT_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n return getCurrentProjectConfig()[key]\n }\n}\n\nexport function setConfigForCLI(\n key: string,\n value: unknown,\n global: boolean,\n): void {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: Cannot set '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n\n if (key === 'autoUpdaterStatus' && !isAutoUpdaterStatus(value as string)) {\n console.error(\n `Error: Invalid value for autoUpdaterStatus. Must be one of: disabled, enabled, no_permissions, not_configured`,\n )\n process.exit(1)\n }\n\n const currentConfig = getGlobalConfig()\n saveGlobalConfig({\n ...currentConfig,\n [key]: value,\n })\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: Cannot set '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\n )\n process.exit(1)\n }\n const currentConfig = getCurrentProjectConfig()\n saveCurrentProjectConfig({\n ...currentConfig,\n [key]: value,\n })\n }\n // Wait for the output to be flushed, to avoid clearing the screen.\n setTimeout(() => {\n // Without this we hang indefinitely.\n process.exit(0)\n }, 100)\n}\n\nexport function deleteConfigForCLI(key: string, global: boolean): void {\n if (global) {\n if (!isGlobalConfigKey(key)) {\n console.error(\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\n )\n process.exit(1)\n }\n const currentConfig = getGlobalConfig()\n delete currentConfig[key]\n saveGlobalConfig(currentConfig)\n } else {\n if (!isProjectConfigKey(key)) {\n console.error(\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\n )\n process.exit(1)\n }\n const currentConfig = getCurrentProjectConfig()\n delete currentConfig[key]\n saveCurrentProjectConfig(currentConfig)\n }\n}\n\nexport function listConfigForCLI(global: true): GlobalConfig\nexport function listConfigForCLI(global: false): ProjectConfig\nexport function listConfigForCLI(global: boolean): object {\n if (global) {\n const currentConfig = pick(getGlobalConfig(), GLOBAL_CONFIG_KEYS)\n return currentConfig\n } else {\n return pick(getCurrentProjectConfig(), PROJECT_CONFIG_KEYS)\n }\n}\n\nexport function getOpenAIApiKey(): string | undefined {\n return process.env.OPENAI_API_KEY\n}\n\n// Configuration migration utility functions\nfunction migrateModelProfilesRemoveId(config: GlobalConfig): GlobalConfig {\n if (!config.modelProfiles) return config\n\n // Cast to legacy type for migration - config may have old fields\n const legacyConfig = config as GlobalConfig & LegacyGlobalConfigFields\n\n // 1. Remove id field from ModelProfile objects and build ID to modelName mapping\n const idToModelNameMap = new Map<string, string>()\n const migratedProfiles = config.modelProfiles.map(profile => {\n // Cast to legacy type that includes optional id field\n const legacyProfile = profile as LegacyModelProfile\n // Build mapping before removing id field\n if (legacyProfile.id && profile.modelName) {\n idToModelNameMap.set(legacyProfile.id, profile.modelName)\n }\n\n // Remove id field, keep everything else\n const { id, ...profileWithoutId } = legacyProfile\n return profileWithoutId as ModelProfile\n })\n\n // 2. Migrate ModelPointers from IDs to modelNames\n const migratedPointers: ModelPointers = {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n }\n\n if (config.modelPointers) {\n Object.entries(config.modelPointers).forEach(([pointer, value]) => {\n if (value) {\n // If value looks like an old ID (model_xxx), map it to modelName\n const modelName = idToModelNameMap.get(value) || value\n migratedPointers[pointer as ModelPointerType] = modelName\n }\n })\n }\n\n // 3. Migrate legacy config fields\n let defaultModelName: string | undefined\n if (legacyConfig.defaultModelId) {\n defaultModelName =\n idToModelNameMap.get(legacyConfig.defaultModelId) ||\n legacyConfig.defaultModelId\n } else if (legacyConfig.defaultModelName) {\n defaultModelName = legacyConfig.defaultModelName\n }\n\n // 4. Remove legacy fields and return migrated config\n const migratedConfig: GlobalConfig & Partial<LegacyGlobalConfigFields> = {\n ...config,\n }\n delete migratedConfig.defaultModelId\n delete migratedConfig.currentSelectedModelId\n delete migratedConfig.mainAgentModelId\n delete migratedConfig.taskToolModelId\n\n return {\n ...migratedConfig,\n modelProfiles: migratedProfiles,\n modelPointers: migratedPointers,\n defaultModelName,\n }\n}\n\n// New model system utility functions\n\n/**\n * Deduplicate model profiles by modelName, keeping the one with the latest createdAt timestamp.\n *\n * @param profiles - Array of model profiles to deduplicate\n * @returns Deduplicated array of model profiles\n */\nexport function deduplicateModelProfiles(\n profiles: ModelProfile[],\n): ModelProfile[] {\n if (!profiles || profiles.length === 0) {\n return []\n }\n\n // Use Map to track the latest profile for each modelName\n const profileMap = new Map<string, ModelProfile>()\n\n for (const profile of profiles) {\n const existing = profileMap.get(profile.modelName)\n\n if (!existing) {\n // First occurrence of this modelName\n profileMap.set(profile.modelName, profile)\n } else {\n // Keep the one with the latest createdAt timestamp\n if (profile.createdAt > existing.createdAt) {\n profileMap.set(profile.modelName, profile)\n }\n }\n }\n\n // Return as array, preserving insertion order (which follows original array order for first occurrences)\n return Array.from(profileMap.values())\n}\n\nexport function setAllPointersToModel(modelName: string): void {\n const config = getGlobalConfig()\n const updatedConfig = {\n ...config,\n modelPointers: {\n main: modelName,\n task: modelName,\n reasoning: modelName,\n quick: modelName,\n compact: modelName,\n },\n defaultModelName: modelName,\n }\n saveGlobalConfig(updatedConfig)\n}\n\nexport function setModelPointer(\n pointer: ModelPointerType,\n modelName: string,\n): void {\n const config = getGlobalConfig()\n const updatedConfig = {\n ...config,\n modelPointers: {\n ...config.modelPointers,\n [pointer]: modelName,\n },\n }\n saveGlobalConfig(updatedConfig)\n\n // \uD83D\uDD27 Fix: Force ModelManager reload after config change\n // Import here to avoid circular dependency\n import('./model').then(({ reloadModelManager }) => {\n reloadModelManager()\n })\n}\n\n// Credential resolution functions for secure API key management\n\n/**\n * Resolve an API key for a ModelProfile.\n * Supports both plaintext keys (backward compatibility) and encrypted references.\n *\n * For plaintext keys (legacy):\n * Returns the key directly from the profile\n *\n * For encrypted references (encrypted:modelName):\n * Retrieves the key from the encrypted credential store\n *\n * @param profile The model profile to resolve the API key for\n * @returns The resolved API key, or null if not found\n * @throws Error if credential store access fails\n */\nexport async function resolveApiKey(\n profile: ModelProfile,\n): Promise<string | null> {\n if (!profile.apiKey) {\n return null\n }\n\n // Check if this is an encrypted reference\n if (profile.apiKey.startsWith('encrypted:')) {\n // Extract model name from the encrypted reference\n const modelName = profile.apiKey.slice('encrypted:'.length)\n\n // Import dynamically to avoid circular dependencies\n try {\n const { getApiKey } = await import('./credentials')\n return getApiKey(modelName)\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n debugLogger.warn(\n 'CREDENTIAL_RESOLVE',\n `Failed to resolve encrypted API key for ${modelName}: ${errorMsg}`,\n )\n return null\n }\n }\n\n // Return plaintext key for backward compatibility\n return profile.apiKey\n}\n\n// GPT-5 functions extracted to src/utils/gpt5.ts \u2014 re-exported for backward compatibility\nexport {\n isGPT5ModelName,\n validateAndRepairGPT5Profile,\n validateAndRepairAllGPT5Profiles,\n getGPT5ConfigRecommendations,\n createGPT5ModelProfile,\n} from './gpt5'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|