@within-7/minto 0.1.6 → 0.2.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/cli.js +155 -37
- package/dist/Tool.js +38 -0
- package/dist/Tool.js.map +3 -3
- package/dist/commands/agents/AgentsCommand.js +52 -26
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +1 -1
- package/dist/commands/agents/constants.js.map +1 -1
- package/dist/commands/agents/index.js +1 -1
- package/dist/commands/bug.js +74 -7
- package/dist/commands/bug.js.map +3 -3
- package/dist/commands/clear.js +3 -0
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +37 -0
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/context.js +84 -0
- package/dist/commands/context.js.map +7 -0
- package/dist/commands/ctx_viz.js +18 -10
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/doctor.js.map +2 -2
- package/dist/commands/export.js +156 -0
- package/dist/commands/export.js.map +7 -0
- package/dist/commands/mcp-interactive.js +21 -12
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +6 -5
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +86 -0
- package/dist/commands/permissions.js.map +7 -0
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/sandbox.js +104 -0
- package/dist/commands/sandbox.js.map +7 -0
- package/dist/commands/status.js +58 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/tasks.js +108 -0
- package/dist/commands/tasks.js.map +7 -0
- package/dist/commands/todos.js +123 -0
- package/dist/commands/todos.js.map +7 -0
- package/dist/commands.js +20 -2
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +10 -18
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +78 -29
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/BashStreamingProgress.js +24 -0
- package/dist/components/BashStreamingProgress.js.map +7 -0
- package/dist/components/CollapsibleHint.js +14 -0
- package/dist/components/CollapsibleHint.js.map +7 -0
- package/dist/components/FileEditToolUpdatedMessage.js +1 -1
- package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +137 -0
- package/dist/components/HotkeyHelpPanel.js.map +7 -0
- package/dist/components/Logo.js +5 -5
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/Message.js +23 -7
- package/dist/components/Message.js.map +3 -3
- package/dist/components/ModelConfig.js +16 -3
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +3 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +1 -1
- package/dist/components/Onboarding.js +19 -14
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/ProgressBar.js +74 -0
- package/dist/components/ProgressBar.js.map +7 -0
- package/dist/components/PromptInput.js +156 -46
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RequestStatusIndicator.js +194 -0
- package/dist/components/RequestStatusIndicator.js.map +7 -0
- package/dist/components/Spinner.js +92 -27
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/SpinnerSymbol.js +21 -27
- package/dist/components/SpinnerSymbol.js.map +2 -2
- package/dist/components/StreamingBashOutput.js +9 -8
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/SubagentBlock.js +1 -1
- package/dist/components/SubagentBlock.js.map +1 -1
- package/dist/components/SubagentProgress.js +10 -11
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +16 -13
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TodoChangeBlock.js +1 -1
- package/dist/components/TodoChangeBlock.js.map +2 -2
- package/dist/components/TodoPanel.js +120 -29
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TokenCounter.js +74 -0
- package/dist/components/TokenCounter.js.map +7 -0
- package/dist/components/TokenWarning.js +2 -1
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/TreeConnector.js +25 -0
- package/dist/components/TreeConnector.js.map +7 -0
- package/dist/components/TurnCompletionIndicator.js +18 -0
- package/dist/components/TurnCompletionIndicator.js.map +7 -0
- package/dist/components/messages/AssistantTextMessage.js +5 -2
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantThinkingMessage.js +18 -3
- package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +11 -8
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +53 -0
- package/dist/components/messages/GroupRenderer.js.map +7 -0
- package/dist/components/messages/NestedTasksPreview.js +12 -0
- package/dist/components/messages/NestedTasksPreview.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +92 -0
- package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
- package/dist/components/messages/TaskInModuleView.js +198 -0
- package/dist/components/messages/TaskInModuleView.js.map +7 -0
- package/dist/components/messages/TaskOutputContent.js +53 -0
- package/dist/components/messages/TaskOutputContent.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +1 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
- package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
- package/dist/constants/colors.js +48 -0
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/formatRules.js +102 -0
- package/dist/constants/formatRules.js.map +7 -0
- package/dist/constants/prompts.js +12 -34
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/symbols.js +64 -6
- package/dist/constants/symbols.js.map +2 -2
- package/dist/constants/timing.js +5 -0
- package/dist/constants/timing.js.map +2 -2
- package/dist/core/config/defaults.js +84 -0
- package/dist/core/config/defaults.js.map +7 -0
- package/dist/core/config/index.js +111 -0
- package/dist/core/config/index.js.map +7 -0
- package/dist/core/config/loader.js +221 -0
- package/dist/core/config/loader.js.map +7 -0
- package/dist/core/config/migrations.js +128 -0
- package/dist/core/config/migrations.js.map +7 -0
- package/dist/core/config/schema.js +178 -0
- package/dist/core/config/schema.js.map +7 -0
- package/dist/core/costTracker.js +138 -0
- package/dist/core/costTracker.js.map +7 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +7 -0
- package/dist/core/permissions/auditLog.js +204 -0
- package/dist/core/permissions/auditLog.js.map +7 -0
- package/dist/core/permissions/engine/index.js +3 -0
- package/dist/core/permissions/engine/index.js.map +7 -0
- package/dist/core/permissions/engine/permissionEngine.js +106 -0
- package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
- package/dist/core/permissions/engine/types.js +1 -0
- package/dist/core/permissions/engine/types.js.map +7 -0
- package/dist/core/permissions/index.js +84 -0
- package/dist/core/permissions/index.js.map +7 -0
- package/dist/core/permissions/ruleEngine.js +259 -0
- package/dist/core/permissions/ruleEngine.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
- package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
- package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
- package/dist/core/permissions/rules/index.js +46 -0
- package/dist/core/permissions/rules/index.js.map +7 -0
- package/dist/core/permissions/rules/planModeRule.js +55 -0
- package/dist/core/permissions/rules/planModeRule.js.map +7 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
- package/dist/core/permissions/rules/safeModeRule.js +65 -0
- package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
- package/dist/core/permissions/types.js +127 -0
- package/dist/core/permissions/types.js.map +7 -0
- package/dist/core/tools/executor.js +143 -0
- package/dist/core/tools/executor.js.map +7 -0
- package/dist/core/tools/index.js +15 -0
- package/dist/core/tools/index.js.map +7 -0
- package/dist/core/tools/registry.js +183 -0
- package/dist/core/tools/registry.js.map +7 -0
- package/dist/core/tools/types.js +1 -0
- package/dist/core/tools/types.js.map +7 -0
- package/dist/cost-tracker.js +23 -15
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/cli.js +43 -43
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/entrypoints/mcp.js +12 -4
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/history.js +14 -3
- package/dist/history.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +116 -0
- package/dist/hooks/useAgentTranscripts.js.map +7 -0
- package/dist/hooks/useAnimationSync.js +53 -0
- package/dist/hooks/useAnimationSync.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +4 -2
- package/dist/hooks/useArrowKeyHistory.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +3 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useCancelRequest.js +4 -1
- package/dist/hooks/useCancelRequest.js.map +2 -2
- package/dist/hooks/useExitOnCtrlCD.js +9 -5
- package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
- package/dist/hooks/useHookStatus.js +40 -0
- package/dist/hooks/useHookStatus.js.map +7 -0
- package/dist/hooks/useLogMessages.js +17 -1
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/hooks/useMessageGroups.js +43 -0
- package/dist/hooks/useMessageGroups.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +62 -6
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +69 -0
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.js +347 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/index.js +7 -0
- package/dist/i18n/locales/index.js.map +7 -0
- package/dist/i18n/locales/zh-CN.js +347 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/query.js +175 -17
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +501 -192
- package/dist/screens/REPL.js.map +3 -3
- package/dist/services/adapters/chatCompletions.js +3 -1
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/messageNormalizer.js +354 -0
- package/dist/services/adapters/messageNormalizer.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +6 -3
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/checkpointManager.js +386 -0
- package/dist/services/checkpointManager.js.map +7 -0
- package/dist/services/claude.js +138 -11
- package/dist/services/claude.js.map +3 -3
- package/dist/services/compressionService.js +50 -1
- package/dist/services/compressionService.js.map +2 -2
- package/dist/services/contextMonitor.js +162 -0
- package/dist/services/contextMonitor.js.map +7 -0
- package/dist/services/customCommands.js +60 -41
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/hookExecutor.js +173 -1
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/intelligentCompactor.js +281 -0
- package/dist/services/intelligentCompactor.js.map +7 -0
- package/dist/services/lspConfig.js +109 -0
- package/dist/services/lspConfig.js.map +7 -0
- package/dist/services/mcpClient.js +273 -34
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/modelOrchestrator.js +310 -0
- package/dist/services/modelOrchestrator.js.map +7 -0
- package/dist/services/openai.js +8 -1
- package/dist/services/openai.js.map +2 -2
- package/dist/services/outputStyles.js +138 -0
- package/dist/services/outputStyles.js.map +7 -0
- package/dist/services/plugins/index.js +5 -0
- package/dist/services/plugins/index.js.map +7 -0
- package/dist/services/plugins/lspServers.js +188 -0
- package/dist/services/plugins/lspServers.js.map +7 -0
- package/dist/services/plugins/pluginRuntime.js +229 -0
- package/dist/services/plugins/pluginRuntime.js.map +7 -0
- package/dist/services/plugins/pluginValidation.js +219 -0
- package/dist/services/plugins/pluginValidation.js.map +7 -0
- package/dist/services/plugins/skillMarketplace.js +556 -0
- package/dist/services/plugins/skillMarketplace.js.map +7 -0
- package/dist/services/responseStateManager.js +37 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +300 -0
- package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
- package/dist/services/sandbox/index.js +14 -0
- package/dist/services/sandbox/index.js.map +7 -0
- package/dist/services/sandbox/networkProxy.js +293 -0
- package/dist/services/sandbox/networkProxy.js.map +7 -0
- package/dist/services/sandbox/sandboxController.js +574 -0
- package/dist/services/sandbox/sandboxController.js.map +7 -0
- package/dist/services/sandbox/types.js +50 -0
- package/dist/services/sandbox/types.js.map +7 -0
- package/dist/services/sessionMemory.js +266 -0
- package/dist/services/sessionMemory.js.map +7 -0
- package/dist/services/taskRouter.js +324 -0
- package/dist/services/taskRouter.js.map +7 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +10 -3
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +8 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BaseTool.js +72 -0
- package/dist/tools/BaseTool.js.map +7 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +60 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/OutputLine.js +54 -0
- package/dist/tools/BashTool/OutputLine.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +192 -3
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +29 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +23 -4
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +14 -3
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +41 -7
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
- package/dist/tools/LspTool/LspTool.js +664 -0
- package/dist/tools/LspTool/LspTool.js.map +7 -0
- package/dist/tools/LspTool/prompt.js +27 -0
- package/dist/tools/LspTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +11 -4
- package/dist/tools/MCPTool/MCPTool.js.map +2 -2
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js +8 -4
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/prompt.js +94 -0
- package/dist/tools/PlanModeTool/prompt.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
- package/dist/tools/SkillTool/SkillTool.js +14 -3
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
- package/dist/tools/SlashCommandTool/prompt.js +35 -0
- package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
- package/dist/tools/TaskOutputTool/prompt.js +15 -0
- package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +321 -146
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -73
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +7 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +55 -8
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js +6 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools.js +31 -2
- package/dist/tools.js.map +2 -2
- package/dist/types/hooks.js +4 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/messageGroup.js +36 -0
- package/dist/types/messageGroup.js.map +7 -0
- package/dist/types/plugin.js.map +2 -2
- package/dist/types/thinking.js +1 -0
- package/dist/types/thinking.js.map +7 -0
- package/dist/utils/BackgroundShellManager.js +136 -39
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/MessageBatchBuffer.js +102 -0
- package/dist/utils/MessageBatchBuffer.js.map +7 -0
- package/dist/utils/PersistentShell.js +151 -1
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/agentLoader.js +1 -23
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentTranscripts.js +641 -0
- package/dist/utils/agentTranscripts.js.map +7 -0
- package/dist/utils/animationManager.js +213 -0
- package/dist/utils/animationManager.js.map +7 -0
- package/dist/utils/animationSync.js +110 -0
- package/dist/utils/animationSync.js.map +7 -0
- package/dist/utils/asyncFile.js +215 -0
- package/dist/utils/asyncFile.js.map +7 -0
- package/dist/utils/backgroundAgentManager.js +231 -0
- package/dist/utils/backgroundAgentManager.js.map +7 -0
- package/dist/utils/config.js +63 -7
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/conversationRecovery.js +19 -0
- package/dist/utils/conversationRecovery.js.map +2 -2
- package/dist/utils/exit.js +73 -0
- package/dist/utils/exit.js.map +7 -0
- package/dist/utils/format.js +73 -5
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/generators.js +76 -6
- package/dist/utils/generators.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +149 -0
- package/dist/utils/globalErrorHandler.js.map +7 -0
- package/dist/utils/groupHandlers/index.js +8 -0
- package/dist/utils/groupHandlers/index.js.map +7 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
- package/dist/utils/groupHandlers/taskHandler.js +104 -0
- package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
- package/dist/utils/groupHandlers/types.js +1 -0
- package/dist/utils/groupHandlers/types.js.map +7 -0
- package/dist/utils/logRotation.js +224 -0
- package/dist/utils/logRotation.js.map +7 -0
- package/dist/utils/marketplaceManager.js +3 -5
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memSafety.js +264 -0
- package/dist/utils/memSafety.js.map +7 -0
- package/dist/utils/messageGroupManager.js +274 -0
- package/dist/utils/messageGroupManager.js.map +7 -0
- package/dist/utils/messages.js +13 -4
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +119 -15
- package/dist/utils/model.js.map +3 -3
- package/dist/utils/permissions/filesystem.js +157 -5
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/plan/planMode.js +143 -0
- package/dist/utils/plan/planMode.js.map +7 -0
- package/dist/utils/pluginLoader.js +17 -21
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/ripgrep.js +55 -2
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/sanitizeInput.js +32 -0
- package/dist/utils/sanitizeInput.js.map +7 -0
- package/dist/utils/secureKeyStorage.js +312 -0
- package/dist/utils/secureKeyStorage.js.map +7 -0
- package/dist/utils/session/sessionPlugins.js +67 -0
- package/dist/utils/session/sessionPlugins.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +257 -0
- package/dist/utils/taskDisplayUtils.js.map +7 -0
- package/dist/utils/teamConfig.js +2 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/todoStorage.js +92 -2
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/toolTimeout.js +136 -0
- package/dist/utils/toolTimeout.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +115 -0
- package/dist/utils/tooling/safeRender.js.map +7 -0
- package/dist/utils/userFriendlyError.js +346 -0
- package/dist/utils/userFriendlyError.js.map +7 -0
- package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +14 -4
- package/scripts/postinstall.js +128 -38
- package/dist/commands/agents.js +0 -2086
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/build.js +0 -74
- package/dist/commands/build.js.map +0 -7
- package/dist/commands/compression.js +0 -57
- package/dist/commands/compression.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -40
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/mcp_refresh.js +0 -40
- package/dist/commands/mcp_refresh.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/plugin-interactive.js +0 -446
- package/dist/commands/plugin-interactive.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -2062
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/entrypoints/cli-wrapper.js +0 -61
- package/dist/entrypoints/cli-wrapper.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
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 } from 'fs'\nimport { resolve, join } 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\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}\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\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 = 'main' | 'task' | 'reasoning' | 'quick'\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}\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 verbose: boolean\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}\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 },\n lastDismissedUpdateVersion: undefined,\n compressionMode: 'business', // Default to business consulting compression\n thinking: false, // Default to thinking mode off (Phase 4.2)\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] 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// \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 return migrateModelProfilesRemoveId(config)\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\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 writeFileSync(file, JSON.stringify(filteredConfig, null, 2), 'utf-8')\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 }\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\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 },\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// \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 } from 'fs'\nimport { resolve, join } 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 * 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\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}\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] 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 return migrateDisplayModeToVerbose(migratedConfig)\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\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 writeFileSync(file, JSON.stringify(filteredConfig, null, 2), 'utf-8')\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\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// \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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -10,9 +10,28 @@ async function loadMessagesFromLog(logPath, tools) {
|
|
|
10
10
|
throw new Error(`Failed to load messages from log: ${error}`);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
function deserializeProgressMessage(serialized, tools) {
|
|
14
|
+
return {
|
|
15
|
+
type: "progress",
|
|
16
|
+
uuid: serialized.uuid,
|
|
17
|
+
toolUseID: serialized.toolUseID,
|
|
18
|
+
// Convert Array back to Set
|
|
19
|
+
siblingToolUseIDs: new Set(serialized.siblingToolUseIDs || []),
|
|
20
|
+
// Restore content (AssistantMessage)
|
|
21
|
+
content: serialized.content,
|
|
22
|
+
// Restore tools reference - use current tools since saved tools may be stale
|
|
23
|
+
tools,
|
|
24
|
+
// normalizedMessages will be empty - they were not persisted to avoid circular refs
|
|
25
|
+
// This is OK because they're only used for live display, not for resume logic
|
|
26
|
+
normalizedMessages: []
|
|
27
|
+
};
|
|
28
|
+
}
|
|
13
29
|
function deserializeMessages(messages, tools) {
|
|
14
30
|
const toolMap = new Map(tools.map((tool) => [tool.name, tool]));
|
|
15
31
|
return messages.map((message) => {
|
|
32
|
+
if (message.type === "progress") {
|
|
33
|
+
return deserializeProgressMessage(message, tools);
|
|
34
|
+
}
|
|
16
35
|
const clonedMessage = JSON.parse(JSON.stringify(message));
|
|
17
36
|
if (clonedMessage.toolCalls) {
|
|
18
37
|
clonedMessage.toolCalls = clonedMessage.toolCalls.map((toolCall) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/conversationRecovery.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'fs/promises'\nimport { logError } from './log'\nimport { Tool } from '@tool'\n\n/**\n * Load messages from a log file\n * @param logPath Path to the log file\n * @param tools Available tools for deserializing tool usage\n * @returns Array of deserialized messages\n */\nexport async function loadMessagesFromLog(\n logPath: string,\n tools: Tool[],\n): Promise<any[]> {\n try {\n const content = await fs.readFile(logPath, 'utf-8')\n const messages = JSON.parse(content)\n return deserializeMessages(messages, tools)\n } catch (error) {\n logError(`Failed to load messages from ${logPath}: ${error}`)\n throw new Error(`Failed to load messages from log: ${error}`)\n }\n}\n\n/**\n * Deserialize messages from a saved format, reconnecting any tool references\n * @param messages The serialized message array\n * @param tools Available tools to reconnect\n * @returns Deserialized messages with reconnected tool references\n */\nexport function deserializeMessages(messages: any[], tools: Tool[]): any[] {\n // Map of tool names to actual tool instances for reconnection\n const toolMap = new Map(tools.map(tool => [tool.name, tool]))\n\n return messages.map(message => {\n // Deep clone the message to avoid mutation issues\n const clonedMessage = JSON.parse(JSON.stringify(message))\n\n // If the message has tool calls, reconnect them to actual tool instances\n if (clonedMessage.toolCalls) {\n clonedMessage.toolCalls = clonedMessage.toolCalls.map((toolCall: any) => {\n // Reconnect tool reference if it exists\n if (toolCall.tool && typeof toolCall.tool === 'string') {\n const actualTool = toolMap.get(toolCall.tool)\n if (actualTool) {\n toolCall.tool = actualTool\n }\n }\n return toolCall\n })\n }\n\n return clonedMessage\n })\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,SAAS,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import fs from 'fs/promises'\nimport { logError } from './log'\nimport { Tool } from '@tool'\nimport { ProgressMessage } from '@query'\n\n/**\n * Load messages from a log file\n * @param logPath Path to the log file\n * @param tools Available tools for deserializing tool usage\n * @returns Array of deserialized messages\n */\nexport async function loadMessagesFromLog(\n logPath: string,\n tools: Tool[],\n): Promise<any[]> {\n try {\n const content = await fs.readFile(logPath, 'utf-8')\n const messages = JSON.parse(content)\n return deserializeMessages(messages, tools)\n } catch (error) {\n logError(`Failed to load messages from ${logPath}: ${error}`)\n throw new Error(`Failed to load messages from log: ${error}`)\n }\n}\n\n/**\n * Deserialize a progress message from its serialized format.\n * Converts siblingToolUseIDs from Array back to Set, and reconnects tools.\n */\nfunction deserializeProgressMessage(\n serialized: any,\n tools: Tool[],\n): ProgressMessage {\n return {\n type: 'progress',\n uuid: serialized.uuid,\n toolUseID: serialized.toolUseID,\n // Convert Array back to Set\n siblingToolUseIDs: new Set(serialized.siblingToolUseIDs || []),\n // Restore content (AssistantMessage)\n content: serialized.content,\n // Restore tools reference - use current tools since saved tools may be stale\n tools: tools,\n // normalizedMessages will be empty - they were not persisted to avoid circular refs\n // This is OK because they're only used for live display, not for resume logic\n normalizedMessages: [],\n }\n}\n\n/**\n * Deserialize messages from a saved format, reconnecting any tool references\n * @param messages The serialized message array\n * @param tools Available tools to reconnect\n * @returns Deserialized messages with reconnected tool references\n */\nexport function deserializeMessages(messages: any[], tools: Tool[]): any[] {\n // Map of tool names to actual tool instances for reconnection\n const toolMap = new Map(tools.map(tool => [tool.name, tool]))\n\n return messages.map(message => {\n // Handle progress messages specially - they need Set reconstruction\n if (message.type === 'progress') {\n return deserializeProgressMessage(message, tools)\n }\n\n // Deep clone the message to avoid mutation issues\n const clonedMessage = JSON.parse(JSON.stringify(message))\n\n // If the message has tool calls, reconnect them to actual tool instances\n if (clonedMessage.toolCalls) {\n clonedMessage.toolCalls = clonedMessage.toolCalls.map((toolCall: any) => {\n // Reconnect tool reference if it exists\n if (toolCall.tool && typeof toolCall.tool === 'string') {\n const actualTool = toolMap.get(toolCall.tool)\n if (actualTool) {\n toolCall.tool = actualTool\n }\n }\n return toolCall\n })\n }\n\n return clonedMessage\n })\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,QAAQ;AACf,SAAS,gBAAgB;AAUzB,eAAsB,oBACpB,SACA,OACgB;AAChB,MAAI;AACF,UAAM,UAAU,MAAM,GAAG,SAAS,SAAS,OAAO;AAClD,UAAM,WAAW,KAAK,MAAM,OAAO;AACnC,WAAO,oBAAoB,UAAU,KAAK;AAAA,EAC5C,SAAS,OAAO;AACd,aAAS,gCAAgC,OAAO,KAAK,KAAK,EAAE;AAC5D,UAAM,IAAI,MAAM,qCAAqC,KAAK,EAAE;AAAA,EAC9D;AACF;AAMA,SAAS,2BACP,YACA,OACiB;AACjB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,WAAW;AAAA,IACjB,WAAW,WAAW;AAAA;AAAA,IAEtB,mBAAmB,IAAI,IAAI,WAAW,qBAAqB,CAAC,CAAC;AAAA;AAAA,IAE7D,SAAS,WAAW;AAAA;AAAA,IAEpB;AAAA;AAAA;AAAA,IAGA,oBAAoB,CAAC;AAAA,EACvB;AACF;AAQO,SAAS,oBAAoB,UAAiB,OAAsB;AAEzE,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,UAAQ,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;AAE5D,SAAO,SAAS,IAAI,aAAW;AAE7B,QAAI,QAAQ,SAAS,YAAY;AAC/B,aAAO,2BAA2B,SAAS,KAAK;AAAA,IAClD;AAGA,UAAM,gBAAgB,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC;AAGxD,QAAI,cAAc,WAAW;AAC3B,oBAAc,YAAY,cAAc,UAAU,IAAI,CAAC,aAAkB;AAEvE,YAAI,SAAS,QAAQ,OAAO,SAAS,SAAS,UAAU;AACtD,gBAAM,aAAa,QAAQ,IAAI,SAAS,IAAI;AAC5C,cAAI,YAAY;AACd,qBAAS,OAAO;AAAA,UAClB;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT,CAAC;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { PersistentShell } from "./PersistentShell.js";
|
|
2
|
+
import { shutdownMCPClients } from "../services/mcpClient.js";
|
|
3
|
+
let isShuttingDown = false;
|
|
4
|
+
function resetCursor() {
|
|
5
|
+
const cursorShow = "\x1B[?25h";
|
|
6
|
+
const terminal = process.stderr.isTTY ? process.stderr : process.stdout.isTTY ? process.stdout : void 0;
|
|
7
|
+
terminal?.write(`\x1B[?25h${cursorShow}`);
|
|
8
|
+
}
|
|
9
|
+
async function gracefulExit(code = 0) {
|
|
10
|
+
if (isShuttingDown) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
isShuttingDown = true;
|
|
14
|
+
try {
|
|
15
|
+
resetCursor();
|
|
16
|
+
} catch {
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
PersistentShell.getInstance().close();
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
await shutdownMCPClients();
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
process.exit(code);
|
|
27
|
+
}
|
|
28
|
+
function setupExitHandlers() {
|
|
29
|
+
process.on("SIGINT", () => {
|
|
30
|
+
gracefulExit(0);
|
|
31
|
+
});
|
|
32
|
+
process.on("SIGTERM", () => {
|
|
33
|
+
gracefulExit(0);
|
|
34
|
+
});
|
|
35
|
+
process.on("SIGBREAK", () => {
|
|
36
|
+
gracefulExit(0);
|
|
37
|
+
});
|
|
38
|
+
process.on("exit", () => {
|
|
39
|
+
try {
|
|
40
|
+
resetCursor();
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
PersistentShell.getInstance().close();
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
process.on("unhandledRejection", (err) => {
|
|
49
|
+
const isTimeoutError = err instanceof Error && (err.name === "TimeoutError" || err.message?.includes("timed out") || err.message?.includes("timeout"));
|
|
50
|
+
const isDOMTimeoutError = err && typeof err === "object" && "name" in err && err.name === "TimeoutError";
|
|
51
|
+
if (isTimeoutError || isDOMTimeoutError) {
|
|
52
|
+
console.error(
|
|
53
|
+
"\u26A0\uFE0F Operation timed out:",
|
|
54
|
+
err instanceof Error ? err.message : err
|
|
55
|
+
);
|
|
56
|
+
console.error(
|
|
57
|
+
" The operation will be retried or skipped. You can continue working."
|
|
58
|
+
);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.error("Unhandled rejection:", err);
|
|
62
|
+
gracefulExit(1);
|
|
63
|
+
});
|
|
64
|
+
process.on("uncaughtException", (err) => {
|
|
65
|
+
console.error("Uncaught exception:", err);
|
|
66
|
+
gracefulExit(1);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
gracefulExit,
|
|
71
|
+
setupExitHandlers
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=exit.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/exit.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Graceful exit utilities\n *\n * Provides a centralized way to exit the application gracefully,\n * ensuring resources are cleaned up properly.\n *\n * NOTE: Cost summary is now handled by useCostSummary() in cost-tracker.ts\n * which matches Kode-cli's implementation exactly.\n */\n\nimport { PersistentShell } from './PersistentShell'\nimport { shutdownMCPClients } from '../services/mcpClient'\n\n// Track if we're already shutting down to prevent multiple cleanup attempts\nlet isShuttingDown = false\n\n/**\n * Reset cursor visibility\n */\nfunction resetCursor() {\n const cursorShow = '\\x1B[?25h'\n const terminal = process.stderr.isTTY\n ? process.stderr\n : process.stdout.isTTY\n ? process.stdout\n : undefined\n terminal?.write(`\\u001B[?25h${cursorShow}`)\n}\n\n/**\n * Exit gracefully with proper cleanup\n *\n * NOTE: Cost summary is NOT printed here. It's handled by useCostSummary()\n * hook's process.on('exit') handler, matching Kode-cli's pattern.\n *\n * @param code Exit code (default: 0)\n */\nexport async function gracefulExit(code = 0): Promise<void> {\n if (isShuttingDown) {\n return\n }\n isShuttingDown = true\n\n try {\n resetCursor()\n } catch {}\n\n try {\n PersistentShell.getInstance().close()\n } catch {}\n\n try {\n await shutdownMCPClients()\n } catch {}\n\n process.exit(code)\n}\n\n/**\n * Setup exit handlers for various signals and events\n * Should be called once during application initialization\n *\n * NOTE: Cost summary output is handled by useCostSummary() in cost-tracker.ts,\n * NOT here. This matches Kode-cli's architecture.\n */\nexport function setupExitHandlers(): void {\n // Handle graceful shutdown signals\n process.on('SIGINT', () => {\n gracefulExit(0)\n })\n\n process.on('SIGTERM', () => {\n gracefulExit(0)\n })\n\n // Windows CTRL+BREAK\n process.on('SIGBREAK', () => {\n gracefulExit(0)\n })\n\n // Final cleanup on exit (cost summary handled by useCostSummary)\n process.on('exit', () => {\n try {\n resetCursor()\n } catch {}\n try {\n PersistentShell.getInstance().close()\n } catch {}\n })\n\n // Handle unhandled rejections\n process.on('unhandledRejection', err => {\n // Check if this is a timeout error that we can handle gracefully\n const isTimeoutError =\n err instanceof Error &&\n (err.name === 'TimeoutError' ||\n err.message?.includes('timed out') ||\n err.message?.includes('timeout'))\n\n const isDOMTimeoutError =\n err &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name: string }).name === 'TimeoutError'\n\n if (isTimeoutError || isDOMTimeoutError) {\n // Log timeout errors but don't exit - they're often recoverable\n console.error(\n '\u26A0\uFE0F Operation timed out:',\n err instanceof Error ? err.message : err,\n )\n console.error(\n ' The operation will be retried or skipped. You can continue working.',\n )\n return\n }\n\n // For other unhandled rejections, log and exit\n console.error('Unhandled rejection:', err)\n gracefulExit(1)\n })\n\n // Handle uncaught exceptions\n process.on('uncaughtException', err => {\n console.error('Uncaught exception:', err)\n gracefulExit(1)\n })\n}\n"],
|
|
5
|
+
"mappings": "AAUA,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAGnC,IAAI,iBAAiB;AAKrB,SAAS,cAAc;AACrB,QAAM,aAAa;AACnB,QAAM,WAAW,QAAQ,OAAO,QAC5B,QAAQ,SACR,QAAQ,OAAO,QACb,QAAQ,SACR;AACN,YAAU,MAAM,YAAc,UAAU,EAAE;AAC5C;AAUA,eAAsB,aAAa,OAAO,GAAkB;AAC1D,MAAI,gBAAgB;AAClB;AAAA,EACF;AACA,mBAAiB;AAEjB,MAAI;AACF,gBAAY;AAAA,EACd,QAAQ;AAAA,EAAC;AAET,MAAI;AACF,oBAAgB,YAAY,EAAE,MAAM;AAAA,EACtC,QAAQ;AAAA,EAAC;AAET,MAAI;AACF,UAAM,mBAAmB;AAAA,EAC3B,QAAQ;AAAA,EAAC;AAET,UAAQ,KAAK,IAAI;AACnB;AASO,SAAS,oBAA0B;AAExC,UAAQ,GAAG,UAAU,MAAM;AACzB,iBAAa,CAAC;AAAA,EAChB,CAAC;AAED,UAAQ,GAAG,WAAW,MAAM;AAC1B,iBAAa,CAAC;AAAA,EAChB,CAAC;AAGD,UAAQ,GAAG,YAAY,MAAM;AAC3B,iBAAa,CAAC;AAAA,EAChB,CAAC;AAGD,UAAQ,GAAG,QAAQ,MAAM;AACvB,QAAI;AACF,kBAAY;AAAA,IACd,QAAQ;AAAA,IAAC;AACT,QAAI;AACF,sBAAgB,YAAY,EAAE,MAAM;AAAA,IACtC,QAAQ;AAAA,IAAC;AAAA,EACX,CAAC;AAGD,UAAQ,GAAG,sBAAsB,SAAO;AAEtC,UAAM,iBACJ,eAAe,UACd,IAAI,SAAS,kBACZ,IAAI,SAAS,SAAS,WAAW,KACjC,IAAI,SAAS,SAAS,SAAS;AAEnC,UAAM,oBACJ,OACA,OAAO,QAAQ,YACf,UAAU,OACT,IAAyB,SAAS;AAErC,QAAI,kBAAkB,mBAAmB;AAEvC,cAAQ;AAAA,QACN;AAAA,QACA,eAAe,QAAQ,IAAI,UAAU;AAAA,MACvC;AACA,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAGA,YAAQ,MAAM,wBAAwB,GAAG;AACzC,iBAAa,CAAC;AAAA,EAChB,CAAC;AAGD,UAAQ,GAAG,qBAAqB,SAAO;AACrC,YAAQ,MAAM,uBAAuB,GAAG;AACxC,iBAAa,CAAC;AAAA,EAChB,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/utils/format.js
CHANGED
|
@@ -13,12 +13,13 @@ function wrapText(text, width) {
|
|
|
13
13
|
return lines;
|
|
14
14
|
}
|
|
15
15
|
function formatDuration(ms) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const totalSeconds = Math.floor(ms / 1e3);
|
|
17
|
+
if (totalSeconds < 60) {
|
|
18
|
+
return `${totalSeconds}s`;
|
|
18
19
|
}
|
|
19
|
-
const hours = Math.floor(
|
|
20
|
-
const minutes = Math.floor(
|
|
21
|
-
const seconds =
|
|
20
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
21
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
22
|
+
const seconds = totalSeconds % 60;
|
|
22
23
|
if (hours > 0) {
|
|
23
24
|
return `${hours}h ${minutes}m ${seconds}s`;
|
|
24
25
|
}
|
|
@@ -33,9 +34,76 @@ function formatNumber(number) {
|
|
|
33
34
|
maximumFractionDigits: 1
|
|
34
35
|
}).format(number).toLowerCase();
|
|
35
36
|
}
|
|
37
|
+
function formatTokens(tokens) {
|
|
38
|
+
if (tokens < 1e3) {
|
|
39
|
+
return `${tokens} tokens`;
|
|
40
|
+
}
|
|
41
|
+
return `${formatNumber(tokens)} tokens`;
|
|
42
|
+
}
|
|
43
|
+
function formatContextUsage(usedTokens, maxTokens) {
|
|
44
|
+
const percentage = usedTokens / maxTokens * 100;
|
|
45
|
+
const formatted = formatNumber(usedTokens);
|
|
46
|
+
if (percentage <= 50) {
|
|
47
|
+
return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}%)`;
|
|
48
|
+
} else if (percentage <= 80) {
|
|
49
|
+
return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}% \u26A0\uFE0F)`;
|
|
50
|
+
} else {
|
|
51
|
+
return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}% \u{1F534})`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function formatTimestamp(timestamp) {
|
|
55
|
+
const date = typeof timestamp === "number" ? new Date(timestamp) : timestamp;
|
|
56
|
+
return date.toLocaleTimeString("en-US", {
|
|
57
|
+
hour: "numeric",
|
|
58
|
+
minute: "2-digit",
|
|
59
|
+
hour12: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function formatUrl(url, maxLength = 60) {
|
|
63
|
+
try {
|
|
64
|
+
const decoded = decodeURIComponent(url);
|
|
65
|
+
if (decoded.length <= maxLength) {
|
|
66
|
+
return decoded;
|
|
67
|
+
}
|
|
68
|
+
const urlObj = new URL(decoded);
|
|
69
|
+
const host = urlObj.host;
|
|
70
|
+
const pathStart = urlObj.pathname.slice(0, 20);
|
|
71
|
+
const remaining = maxLength - host.length - pathStart.length - 6;
|
|
72
|
+
if (remaining > 10) {
|
|
73
|
+
const pathEnd = urlObj.pathname.slice(-remaining);
|
|
74
|
+
return `${host}${pathStart}...${pathEnd}`;
|
|
75
|
+
}
|
|
76
|
+
return decoded.slice(0, maxLength - 3) + "...";
|
|
77
|
+
} catch {
|
|
78
|
+
if (url.length <= maxLength) return url;
|
|
79
|
+
return url.slice(0, maxLength - 3) + "...";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function truncateText(text, maxLength = 80) {
|
|
83
|
+
if (!text) return "";
|
|
84
|
+
const trimmed = text.trim().replace(/\n+/g, " ").replace(/\s+/g, " ");
|
|
85
|
+
if (trimmed.length <= maxLength) return trimmed;
|
|
86
|
+
return trimmed.slice(0, maxLength - 3) + "...";
|
|
87
|
+
}
|
|
88
|
+
function formatTokenUsage(inputTokens, outputTokens) {
|
|
89
|
+
const parts = [];
|
|
90
|
+
if (inputTokens != null && inputTokens > 0) {
|
|
91
|
+
parts.push(`\u2191 ${formatNumber(inputTokens)}`);
|
|
92
|
+
}
|
|
93
|
+
if (outputTokens != null && outputTokens > 0) {
|
|
94
|
+
parts.push(`\u2193 ${formatNumber(outputTokens)}`);
|
|
95
|
+
}
|
|
96
|
+
return parts.join(" \xB7 ");
|
|
97
|
+
}
|
|
36
98
|
export {
|
|
99
|
+
formatContextUsage,
|
|
37
100
|
formatDuration,
|
|
38
101
|
formatNumber,
|
|
102
|
+
formatTimestamp,
|
|
103
|
+
formatTokenUsage,
|
|
104
|
+
formatTokens,
|
|
105
|
+
formatUrl,
|
|
106
|
+
truncateText,
|
|
39
107
|
wrapText
|
|
40
108
|
};
|
|
41
109
|
//# sourceMappingURL=format.js.map
|
package/dist/utils/format.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/format.tsx"],
|
|
4
|
-
"sourcesContent": ["export function wrapText(text: string, width: number): string[] {\n const lines: string[] = []\n let currentLine = ''\n\n for (const char of text) {\n // Important: we need the spread to properly count multi-plane UTF-8 characters (eg. \uD805\uDE96)\n if ([...currentLine].length < width) {\n currentLine += char\n } else {\n lines.push(currentLine)\n currentLine = char\n }\n }\n\n if (currentLine) lines.push(currentLine)\n return lines\n}\n\nexport function formatDuration(ms: number): string {\n
|
|
5
|
-
"mappings": "AAAO,SAAS,SAAS,MAAc,OAAyB;AAC9D,QAAM,QAAkB,CAAC;AACzB,MAAI,cAAc;AAElB,aAAW,QAAQ,MAAM;AAEvB,QAAI,CAAC,GAAG,WAAW,EAAE,SAAS,OAAO;AACnC,qBAAe;AAAA,IACjB,OAAO;AACL,YAAM,KAAK,WAAW;AACtB,oBAAc;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,YAAa,OAAM,KAAK,WAAW;AACvC,SAAO;AACT;AAEO,SAAS,eAAe,IAAoB;AACjD,
|
|
4
|
+
"sourcesContent": ["export function wrapText(text: string, width: number): string[] {\n const lines: string[] = []\n let currentLine = ''\n\n for (const char of text) {\n // Important: we need the spread to properly count multi-plane UTF-8 characters (eg. \uD805\uDE96)\n if ([...currentLine].length < width) {\n currentLine += char\n } else {\n lines.push(currentLine)\n currentLine = char\n }\n }\n\n if (currentLine) lines.push(currentLine)\n return lines\n}\n\nexport function formatDuration(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000)\n\n if (totalSeconds < 60) {\n return `${totalSeconds}s`\n }\n\n const hours = Math.floor(totalSeconds / 3600)\n const minutes = Math.floor((totalSeconds % 3600) / 60)\n const seconds = totalSeconds % 60\n\n if (hours > 0) {\n return `${hours}h ${minutes}m ${seconds}s`\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds}s`\n }\n return `${seconds}s`\n}\n\nexport function formatNumber(number: number): string {\n return new Intl.NumberFormat('en', {\n notation: 'compact',\n maximumFractionDigits: 1,\n })\n .format(number) // eg. \"1321\" => \"1.3K\"\n .toLowerCase() // eg. \"1.3K\" => \"1.3k\"\n}\n\n/**\n * Format token count for display (e.g., 42000 -> \"42k tokens\")\n * More descriptive than formatNumber for token-specific contexts\n */\nexport function formatTokens(tokens: number): string {\n if (tokens < 1000) {\n return `${tokens} tokens`\n }\n return `${formatNumber(tokens)} tokens`\n}\n\n/**\n * Format context usage as percentage with visual indicator\n */\nexport function formatContextUsage(\n usedTokens: number,\n maxTokens: number,\n): string {\n const percentage = (usedTokens / maxTokens) * 100\n const formatted = formatNumber(usedTokens)\n\n if (percentage <= 50) {\n return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}%)`\n } else if (percentage <= 80) {\n return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}% \u26A0\uFE0F)`\n } else {\n return `${formatted}/${formatNumber(maxTokens)} (${percentage.toFixed(0)}% \uD83D\uDD34)`\n }\n}\n\n/**\n * Format timestamp for display (e.g., \"12:20 AM\")\n * Uses 12-hour format with AM/PM indicator like Claude Code\n */\nexport function formatTimestamp(timestamp: number | Date): string {\n const date = typeof timestamp === 'number' ? new Date(timestamp) : timestamp\n return date.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n}\n\n/**\n * Format URL for display\n * - Decodes URL-encoded characters for readability\n * - Truncates to max length with ellipsis\n * - Shows host + path truncated\n */\nexport function formatUrl(url: string, maxLength: number = 60): string {\n try {\n // Decode URL-encoded characters\n const decoded = decodeURIComponent(url)\n\n // Truncate if too long\n if (decoded.length <= maxLength) {\n return decoded\n }\n\n // Try to preserve host and beginning of path\n const urlObj = new URL(decoded)\n const host = urlObj.host\n const pathStart = urlObj.pathname.slice(0, 20)\n\n // Format: host/path.../end\n const remaining = maxLength - host.length - pathStart.length - 6 // \"...\" x2\n if (remaining > 10) {\n const pathEnd = urlObj.pathname.slice(-remaining)\n return `${host}${pathStart}...${pathEnd}`\n }\n\n // Fallback: simple truncation\n return decoded.slice(0, maxLength - 3) + '...'\n } catch {\n // If URL parsing fails, just truncate\n if (url.length <= maxLength) return url\n return url.slice(0, maxLength - 3) + '...'\n }\n}\n\n/**\n * Truncate text to a maximum length with ellipsis\n */\nexport function truncateText(text: string, maxLength: number = 80): string {\n if (!text) return ''\n const trimmed = text.trim().replace(/\\n+/g, ' ').replace(/\\s+/g, ' ')\n if (trimmed.length <= maxLength) return trimmed\n return trimmed.slice(0, maxLength - 3) + '...'\n}\n\n/**\n * Format token usage with up/down arrows for input/output\n * e.g., \"\u2191 8.2k \u00B7 \u2193 1.2k\"\n */\nexport function formatTokenUsage(\n inputTokens?: number,\n outputTokens?: number,\n): string {\n const parts: string[] = []\n if (inputTokens != null && inputTokens > 0) {\n parts.push(`\u2191 ${formatNumber(inputTokens)}`)\n }\n if (outputTokens != null && outputTokens > 0) {\n parts.push(`\u2193 ${formatNumber(outputTokens)}`)\n }\n return parts.join(' \u00B7 ')\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/generators.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { debug } from "./debugLogger.js";
|
|
1
2
|
const NO_VALUE = Symbol("NO_VALUE");
|
|
2
3
|
async function lastX(as) {
|
|
3
4
|
let lastValue = NO_VALUE;
|
|
@@ -9,35 +10,104 @@ async function lastX(as) {
|
|
|
9
10
|
}
|
|
10
11
|
return lastValue;
|
|
11
12
|
}
|
|
12
|
-
async function* all(generators, concurrencyCap = Infinity) {
|
|
13
|
+
async function* all(generators, concurrencyCap = Infinity, abortSignal) {
|
|
14
|
+
let generatorIdCounter = 0;
|
|
15
|
+
const generatorIds = /* @__PURE__ */ new Map();
|
|
16
|
+
const activeGenerators = /* @__PURE__ */ new Set();
|
|
13
17
|
const next = (generator) => {
|
|
18
|
+
let id = generatorIds.get(generator);
|
|
19
|
+
if (id === void 0) {
|
|
20
|
+
id = generatorIdCounter++;
|
|
21
|
+
generatorIds.set(generator, id);
|
|
22
|
+
}
|
|
23
|
+
activeGenerators.add(generator);
|
|
14
24
|
const promise = generator.next().then(({ done, value }) => ({
|
|
15
25
|
done,
|
|
16
26
|
value,
|
|
17
27
|
generator,
|
|
18
|
-
promise
|
|
28
|
+
promise,
|
|
29
|
+
id
|
|
19
30
|
}));
|
|
20
31
|
return promise;
|
|
21
32
|
};
|
|
33
|
+
const terminateAll = async () => {
|
|
34
|
+
debug.flow("ALL_GENERATORS_ABORT", {
|
|
35
|
+
activeCount: activeGenerators.size
|
|
36
|
+
});
|
|
37
|
+
for (const gen of activeGenerators) {
|
|
38
|
+
try {
|
|
39
|
+
await gen.return(void 0);
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
activeGenerators.clear();
|
|
44
|
+
};
|
|
22
45
|
const waiting = [...generators];
|
|
23
46
|
const promises = /* @__PURE__ */ new Set();
|
|
47
|
+
debug.flow("ALL_GENERATORS_START", {
|
|
48
|
+
totalGenerators: generators.length,
|
|
49
|
+
concurrencyCap,
|
|
50
|
+
hasAbortSignal: !!abortSignal
|
|
51
|
+
});
|
|
52
|
+
if (abortSignal?.aborted) {
|
|
53
|
+
debug.flow("ALL_GENERATORS_ALREADY_ABORTED", {});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
24
56
|
while (promises.size < concurrencyCap && waiting.length > 0) {
|
|
25
57
|
const gen = waiting.shift();
|
|
26
58
|
promises.add(next(gen));
|
|
27
59
|
}
|
|
60
|
+
debug.flow("ALL_GENERATORS_INITIAL_BATCH", {
|
|
61
|
+
activeCount: promises.size,
|
|
62
|
+
waitingCount: waiting.length
|
|
63
|
+
});
|
|
64
|
+
let yieldCount = 0;
|
|
65
|
+
let completedCount = 0;
|
|
28
66
|
while (promises.size > 0) {
|
|
29
|
-
|
|
67
|
+
if (abortSignal?.aborted) {
|
|
68
|
+
debug.flow("ALL_GENERATORS_ABORT_DETECTED", {
|
|
69
|
+
completedCount,
|
|
70
|
+
remainingActive: promises.size
|
|
71
|
+
});
|
|
72
|
+
await terminateAll();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const { done, value, generator, promise, id } = await Promise.race(promises);
|
|
30
76
|
promises.delete(promise);
|
|
77
|
+
if (abortSignal?.aborted) {
|
|
78
|
+
debug.flow("ALL_GENERATORS_ABORT_AFTER_RACE", {
|
|
79
|
+
completedCount,
|
|
80
|
+
remainingActive: promises.size
|
|
81
|
+
});
|
|
82
|
+
await terminateAll();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
31
85
|
if (!done) {
|
|
32
86
|
promises.add(next(generator));
|
|
33
87
|
if (value !== void 0) {
|
|
88
|
+
yieldCount++;
|
|
34
89
|
yield value;
|
|
35
90
|
}
|
|
36
|
-
} else
|
|
37
|
-
|
|
38
|
-
|
|
91
|
+
} else {
|
|
92
|
+
completedCount++;
|
|
93
|
+
activeGenerators.delete(generator);
|
|
94
|
+
debug.flow("ALL_GENERATOR_COMPLETED", {
|
|
95
|
+
generatorId: id,
|
|
96
|
+
completedCount,
|
|
97
|
+
remainingActive: promises.size,
|
|
98
|
+
waitingCount: waiting.length
|
|
99
|
+
});
|
|
100
|
+
if (waiting.length > 0) {
|
|
101
|
+
const nextGen = waiting.shift();
|
|
102
|
+
promises.add(next(nextGen));
|
|
103
|
+
}
|
|
39
104
|
}
|
|
40
105
|
}
|
|
106
|
+
debug.flow("ALL_GENERATORS_DONE", {
|
|
107
|
+
totalGenerators: generators.length,
|
|
108
|
+
totalYields: yieldCount,
|
|
109
|
+
totalCompleted: completedCount
|
|
110
|
+
});
|
|
41
111
|
}
|
|
42
112
|
export {
|
|
43
113
|
all,
|