@within-7/minto 0.1.7 → 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 +7 -1
- 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.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/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +4 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +36 -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 +9 -1
- 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.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 +6 -1
- 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 +302 -104
- 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 -77
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -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.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/model.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/model.ts"],
|
|
4
|
-
"sourcesContent": ["import { memoize } from 'lodash-es'\n\nimport { logError } from './log'\nimport {\n getGlobalConfig,\n ModelProfile,\n ModelPointerType,\n saveGlobalConfig,\n} from './config'\n\nexport const USE_BEDROCK = !!process.env.CLAUDE_CODE_USE_BEDROCK\nexport const USE_VERTEX = !!process.env.CLAUDE_CODE_USE_VERTEX\n\nexport interface ModelConfig {\n bedrock: string\n vertex: string\n firstParty: string\n}\n\nconst DEFAULT_MODEL_CONFIG: ModelConfig = {\n bedrock: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',\n vertex: 'claude-3-7-sonnet@20250219',\n firstParty: 'claude-sonnet-4-20250514',\n}\n\n/**\n * Helper to get the model config from defaults.\n */\nasync function getModelConfig(): Promise<ModelConfig> {\n return DEFAULT_MODEL_CONFIG\n}\n\nexport const getSlowAndCapableModel = memoize(async (): Promise<string> => {\n const config = await getGlobalConfig()\n\n // Use ModelManager for proper model resolution\n const modelManager = new ModelManager(config)\n const model = modelManager.getMainAgentModel()\n\n if (model) {\n return model\n }\n\n // Final fallback to default model\n const modelConfig = await getModelConfig()\n if (USE_BEDROCK) return modelConfig.bedrock\n if (USE_VERTEX) return modelConfig.vertex\n return modelConfig.firstParty\n})\n\n/**\n * Get context length for a model pointer type\n */\nexport function getModelContextLength(\n pointerType: ModelPointerType = 'main',\n): number {\n const config = getGlobalConfig()\n const modelManager = new ModelManager(config)\n\n // Get the model name based on pointer type\n let modelName: string | null = null\n switch (pointerType) {\n case 'main':\n modelName = modelManager.getMainAgentModel()\n break\n case 'task':\n modelName = modelManager.getTaskToolModel()\n break\n default:\n modelName = modelManager.getMainAgentModel()\n }\n\n // Find the profile for this model\n if (modelName) {\n const profile = config.modelProfiles?.find(\n (p: ModelProfile) => p.modelName === modelName && p.isActive,\n )\n if (profile && profile.contextLength) {\n return profile.contextLength\n }\n }\n\n // Default fallback (Claude Sonnet context length)\n return 200000\n}\n\nexport async function isDefaultSlowAndCapableModel(): Promise<boolean> {\n return (\n !process.env.ANTHROPIC_MODEL ||\n process.env.ANTHROPIC_MODEL === (await getSlowAndCapableModel())\n )\n}\n\n/**\n * Get the region for a specific Vertex model\n * Checks for hardcoded model-specific environment variables first,\n * then falls back to CLOUD_ML_REGION env var or default region\n */\nexport function getVertexRegionForModel(\n model: string | undefined,\n): string | undefined {\n if (model?.startsWith('claude-3-5-haiku')) {\n return process.env.VERTEX_REGION_CLAUDE_3_5_HAIKU\n } else if (model?.startsWith('claude-3-5-sonnet')) {\n return process.env.VERTEX_REGION_CLAUDE_3_5_SONNET\n } else if (model?.startsWith('claude-3-7-sonnet')) {\n return process.env.VERTEX_REGION_CLAUDE_3_7_SONNET\n }\n}\n\n/**\n * Comprehensive ModelManager class for centralized model selection and management.\n * Provides a clean interface for model selection across the application.\n */\nexport class ModelManager {\n private config: any // Using any to handle legacy properties\n private modelProfiles: ModelProfile[]\n\n constructor(config: any) {\n this.config = config\n this.modelProfiles = config.modelProfiles || []\n }\n\n /**\n * Get the current terminal model (for interactive CLI sessions)\n */\n getCurrentModel(): string | null {\n // Use main pointer from new ModelProfile system\n const mainModelName = this.config.modelPointers?.main\n if (mainModelName) {\n const profile = this.findModelProfile(mainModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to main agent model\n return this.getMainAgentModel()\n }\n\n /**\n * Get the main agent default model (for non-terminal mode and MCP calls)\n */\n getMainAgentModel(): string | null {\n // Use main pointer from new ModelProfile system\n const mainModelName = this.config.modelPointers?.main\n if (mainModelName) {\n const profile = this.findModelProfile(mainModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to first active profile\n const activeProfile = this.modelProfiles.find(p => p.isActive)\n if (activeProfile) {\n return activeProfile.modelName\n }\n\n return null\n }\n\n /**\n * Get the task tool default model (for Task tool sub-agents)\n */\n getTaskToolModel(): string | null {\n // Use task pointer from new ModelProfile system\n const taskModelName = this.config.modelPointers?.task\n if (taskModelName) {\n const profile = this.findModelProfile(taskModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to main agent model\n return this.getMainAgentModel()\n }\n\n /**\n * Switch to the next available model with simple context overflow handling\n * If target model can't handle current context, shows warning and reverts after delay\n *\n * @param currentContextTokens - Current conversation token count for validation\n * @returns Object with model name and context status information\n */\n switchToNextModelWithContextCheck(currentContextTokens: number = 0): {\n success: boolean\n modelName: string | null\n previousModelName: string | null\n contextOverflow: boolean\n usagePercentage: number\n } {\n // Use ALL configured models, not just active ones\n const allProfiles = this.getAllConfiguredModels()\n if (allProfiles.length === 0) {\n return {\n success: false,\n modelName: null,\n previousModelName: null,\n contextOverflow: false,\n usagePercentage: 0,\n }\n }\n\n // Sort by createdAt for consistent cycling order (don't use lastUsed)\n // Using lastUsed causes the order to change each time, preventing proper cycling\n allProfiles.sort((a, b) => {\n return a.createdAt - b.createdAt // Oldest first for consistent order\n })\n\n const currentMainModelName = this.config.modelPointers?.main\n const currentModel = currentMainModelName\n ? this.findModelProfile(currentMainModelName)\n : null\n const previousModelName = currentModel?.name || null\n\n if (!currentMainModelName) {\n // No current main model, select first available (activate if needed)\n const firstModel = allProfiles[0]\n if (!firstModel.isActive) {\n firstModel.isActive = true\n }\n this.setPointer('main', firstModel.modelName)\n this.updateLastUsed(firstModel.modelName)\n\n const analysis = this.analyzeContextCompatibility(\n firstModel,\n currentContextTokens,\n )\n return {\n success: true,\n modelName: firstModel.name,\n previousModelName: null,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n }\n }\n\n // Find current model index in ALL models\n const currentIndex = allProfiles.findIndex(\n p => p.modelName === currentMainModelName,\n )\n if (currentIndex === -1) {\n // Current model not found, select first available (activate if needed)\n const firstModel = allProfiles[0]\n if (!firstModel.isActive) {\n firstModel.isActive = true\n }\n this.setPointer('main', firstModel.modelName)\n this.updateLastUsed(firstModel.modelName)\n\n const analysis = this.analyzeContextCompatibility(\n firstModel,\n currentContextTokens,\n )\n return {\n success: true,\n modelName: firstModel.name,\n previousModelName,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n }\n }\n\n // Check if only one model is available\n if (allProfiles.length === 1) {\n return {\n success: false,\n modelName: null,\n previousModelName,\n contextOverflow: false,\n usagePercentage: 0,\n }\n }\n\n // Get next model in cycle (from ALL models)\n const nextIndex = (currentIndex + 1) % allProfiles.length\n const nextModel = allProfiles[nextIndex]\n\n // Activate the model if it's not already active\n const wasInactive = !nextModel.isActive\n if (!nextModel.isActive) {\n nextModel.isActive = true\n }\n\n // Analyze context compatibility for next model\n const analysis = this.analyzeContextCompatibility(\n nextModel,\n currentContextTokens,\n )\n\n // Always switch to next model, but return context status\n this.setPointer('main', nextModel.modelName)\n this.updateLastUsed(nextModel.modelName)\n\n // Save configuration if we activated a new model\n if (wasInactive) {\n this.saveConfig()\n }\n\n return {\n success: true,\n modelName: nextModel.name,\n previousModelName,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n }\n }\n\n /**\n * Simple model switching for UI components (compatible interface)\n * @param currentContextTokens - Current conversation token count for validation\n * @returns Compatible interface for PromptInput component\n */\n switchToNextModel(currentContextTokens: number = 0): {\n success: boolean\n modelName: string | null\n blocked?: boolean\n message?: string\n } {\n // Use the enhanced context check method for consistency\n const result = this.switchToNextModelWithContextCheck(currentContextTokens)\n\n if (!result.success) {\n const allModels = this.getAllConfiguredModels()\n if (allModels.length === 0) {\n return {\n success: false,\n modelName: null,\n blocked: false,\n message: '\u274C No models configured. Use /model to add models.',\n }\n } else if (allModels.length === 1) {\n return {\n success: false,\n modelName: null,\n blocked: false,\n message: `\u26A0\uFE0F Only one model configured (${allModels[0].modelName}). Use /model to add more models for switching.`,\n }\n }\n }\n\n // Convert the detailed result to the simple interface\n const currentModel = this.findModelProfile(this.config.modelPointers?.main)\n const allModels = this.getAllConfiguredModels()\n const currentIndex = allModels.findIndex(\n m => m.modelName === currentModel?.modelName,\n )\n const totalModels = allModels.length\n\n return {\n success: result.success,\n modelName: result.modelName,\n blocked: result.contextOverflow,\n message: result.success\n ? result.contextOverflow\n ? `\u26A0\uFE0F Context usage: ${result.usagePercentage.toFixed(1)}% - ${result.modelName}`\n : `\u2705 Switched to ${result.modelName} (${currentIndex + 1}/${totalModels})${currentModel?.provider ? ` [${currentModel.provider}]` : ''}`\n : `\u274C Failed to switch models`,\n }\n }\n\n /**\n * Revert to previous model (used when context overflow requires rollback)\n */\n revertToPreviousModel(previousModelName: string): boolean {\n const previousModel = this.modelProfiles.find(\n p => p.name === previousModelName && p.isActive,\n )\n if (!previousModel) {\n return false\n }\n\n this.setPointer('main', previousModel.modelName)\n this.updateLastUsed(previousModel.modelName)\n return true\n }\n\n /**\n * Enhanced context validation with different severity levels\n */\n analyzeContextCompatibility(\n model: ModelProfile,\n contextTokens: number,\n ): {\n compatible: boolean\n severity: 'safe' | 'warning' | 'critical'\n usagePercentage: number\n recommendation: string\n } {\n const usableContext = Math.floor(model.contextLength * 0.8) // Reserve 20% for output\n const usagePercentage = (contextTokens / usableContext) * 100\n\n if (usagePercentage <= 70) {\n return {\n compatible: true,\n severity: 'safe',\n usagePercentage,\n recommendation: 'Full context preserved',\n }\n } else if (usagePercentage <= 90) {\n return {\n compatible: true,\n severity: 'warning',\n usagePercentage,\n recommendation: 'Context usage high, consider compression',\n }\n } else {\n return {\n compatible: false,\n severity: 'critical',\n usagePercentage,\n recommendation: 'Auto-compression or message truncation required',\n }\n }\n }\n\n /**\n * Switch to next model with enhanced context analysis\n */\n switchToNextModelWithAnalysis(currentContextTokens: number = 0): {\n modelName: string | null\n contextAnalysis: ReturnType<typeof this.analyzeContextCompatibility> | null\n requiresCompression: boolean\n estimatedTokensAfterSwitch: number\n } {\n const result = this.switchToNextModel(currentContextTokens)\n\n if (!result.success || !result.modelName) {\n return {\n modelName: null,\n contextAnalysis: null,\n requiresCompression: false,\n estimatedTokensAfterSwitch: 0,\n }\n }\n\n const newModel = this.getModel('main')\n if (!newModel) {\n return {\n modelName: result.modelName,\n contextAnalysis: null,\n requiresCompression: false,\n estimatedTokensAfterSwitch: currentContextTokens,\n }\n }\n\n const analysis = this.analyzeContextCompatibility(\n newModel,\n currentContextTokens,\n )\n\n return {\n modelName: result.modelName,\n contextAnalysis: analysis,\n requiresCompression: analysis.severity === 'critical',\n estimatedTokensAfterSwitch: currentContextTokens,\n }\n }\n\n /**\n * Check if a model can handle the given context size (legacy method)\n */\n canModelHandleContext(model: ModelProfile, contextTokens: number): boolean {\n const analysis = this.analyzeContextCompatibility(model, contextTokens)\n return analysis.compatible\n }\n\n /**\n * Find the first model that can handle the given context size\n */\n findModelWithSufficientContext(\n models: ModelProfile[],\n contextTokens: number,\n ): ModelProfile | null {\n return (\n models.find(model => this.canModelHandleContext(model, contextTokens)) ||\n null\n )\n }\n\n /**\n * Unified model getter for different contexts\n */\n getModelForContext(\n contextType: 'terminal' | 'main-agent' | 'task-tool',\n ): string | null {\n switch (contextType) {\n case 'terminal':\n return this.getCurrentModel()\n case 'main-agent':\n return this.getMainAgentModel()\n case 'task-tool':\n return this.getTaskToolModel()\n default:\n return this.getMainAgentModel()\n }\n }\n\n /**\n * Get all active model profiles\n */\n getActiveModelProfiles(): ModelProfile[] {\n return this.modelProfiles.filter(p => p.isActive)\n }\n\n /**\n * Check if any models are configured\n */\n hasConfiguredModels(): boolean {\n return this.getActiveModelProfiles().length > 0\n }\n\n // New model pointer system methods\n\n /**\n * Get model by pointer type (main, task, reasoning, quick)\n */\n getModel(pointer: ModelPointerType): ModelProfile | null {\n const pointerId = this.config.modelPointers?.[pointer]\n if (!pointerId) {\n return this.getDefaultModel()\n }\n\n const profile = this.findModelProfile(pointerId)\n return profile && profile.isActive ? profile : this.getDefaultModel()\n }\n\n /**\n * Get model name by pointer type\n */\n getModelName(pointer: ModelPointerType): string | null {\n const profile = this.getModel(pointer)\n return profile ? profile.modelName : null\n }\n\n /**\n * Get reasoning model (with fallback)\n */\n getReasoningModel(): string | null {\n return this.getModelName('reasoning') || this.getModelName('main')\n }\n\n /**\n * Get quick model (with fallback)\n */\n getQuickModel(): string | null {\n return (\n this.getModelName('quick') ||\n this.getModelName('task') ||\n this.getModelName('main')\n )\n }\n\n /**\n * Add a new model profile with duplicate validation\n */\n async addModel(\n config: Omit<ModelProfile, 'createdAt' | 'isActive'>,\n ): Promise<string> {\n // Check for duplicate modelName (actual model identifier)\n const existingByModelName = this.modelProfiles.find(\n p => p.modelName === config.modelName,\n )\n if (existingByModelName) {\n throw new Error(\n `Model with modelName '${config.modelName}' already exists: ${existingByModelName.name}`,\n )\n }\n\n // Check for duplicate friendly name\n const existingByName = this.modelProfiles.find(p => p.name === config.name)\n if (existingByName) {\n throw new Error(`Model with name '${config.name}' already exists`)\n }\n\n const newModel: ModelProfile = {\n ...config,\n createdAt: Date.now(),\n isActive: true,\n }\n\n this.modelProfiles.push(newModel)\n\n // If this is the first model, set all pointers to it\n if (this.modelProfiles.length === 1) {\n this.config.modelPointers = {\n main: config.modelName,\n task: config.modelName,\n reasoning: config.modelName,\n quick: config.modelName,\n }\n this.config.defaultModelName = config.modelName\n }\n\n this.saveConfig()\n return config.modelName\n }\n\n /**\n * Set model pointer assignment\n */\n setPointer(pointer: ModelPointerType, modelName: string): void {\n if (!this.findModelProfile(modelName)) {\n throw new Error(`Model '${modelName}' not found`)\n }\n\n if (!this.config.modelPointers) {\n this.config.modelPointers = {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n }\n }\n\n this.config.modelPointers[pointer] = modelName\n this.saveConfig()\n }\n\n /**\n * Get all active models for pointer assignment\n */\n getAvailableModels(): ModelProfile[] {\n return this.modelProfiles.filter(p => p.isActive)\n }\n\n /**\n * Get all configured models (both active and inactive) for switching\n */\n getAllConfiguredModels(): ModelProfile[] {\n return this.modelProfiles\n }\n\n /**\n * Get all available model names (modelName field) - active only\n */\n getAllAvailableModelNames(): string[] {\n return this.getAvailableModels().map(p => p.modelName)\n }\n\n /**\n * Get all configured model names (both active and inactive)\n */\n getAllConfiguredModelNames(): string[] {\n return this.getAllConfiguredModels().map(p => p.modelName)\n }\n\n /**\n * Debug method to get detailed model switching information\n */\n getModelSwitchingDebugInfo(): {\n totalModels: number\n activeModels: number\n inactiveModels: number\n currentMainModel: string | null\n availableModels: Array<{\n name: string\n modelName: string\n provider: string\n isActive: boolean\n lastUsed?: number\n }>\n modelPointers: Record<string, string | undefined>\n } {\n const availableModels = this.getAvailableModels()\n const currentMainModelName = this.config.modelPointers?.main\n\n return {\n totalModels: this.modelProfiles.length,\n activeModels: availableModels.length,\n inactiveModels: this.modelProfiles.length - availableModels.length,\n currentMainModel: currentMainModelName || null,\n availableModels: this.modelProfiles.map(p => ({\n name: p.name,\n modelName: p.modelName,\n provider: p.provider,\n isActive: p.isActive,\n lastUsed: p.lastUsed,\n })),\n modelPointers: this.config.modelPointers || {},\n }\n }\n\n /**\n * Remove a model profile\n */\n removeModel(modelName: string): void {\n this.modelProfiles = this.modelProfiles.filter(\n p => p.modelName !== modelName,\n )\n\n // Clean up pointers that reference deleted model\n if (this.config.modelPointers) {\n Object.keys(this.config.modelPointers).forEach(pointer => {\n if (\n this.config.modelPointers[pointer as ModelPointerType] === modelName\n ) {\n this.config.modelPointers[pointer as ModelPointerType] =\n this.config.defaultModelName || ''\n }\n })\n }\n\n this.saveConfig()\n }\n\n /**\n * Get default model profile\n */\n private getDefaultModel(): ModelProfile | null {\n if (this.config.defaultModelId) {\n const profile = this.findModelProfile(this.config.defaultModelId)\n if (profile && profile.isActive) {\n return profile\n }\n }\n return this.modelProfiles.find(p => p.isActive) || null\n }\n\n /**\n * Save configuration changes\n */\n private saveConfig(): void {\n const updatedConfig = {\n ...this.config,\n modelProfiles: this.modelProfiles,\n }\n saveGlobalConfig(updatedConfig)\n }\n\n /**\n * Get a fallback model when no specific model is configured\n */\n async getFallbackModel(): Promise<string> {\n const modelConfig = await getModelConfig()\n if (USE_BEDROCK) return modelConfig.bedrock\n if (USE_VERTEX) return modelConfig.vertex\n return modelConfig.firstParty\n }\n\n /**\n * \u7EDF\u4E00\u7684\u6A21\u578B\u89E3\u6790\u65B9\u6CD5\uFF1A\u652F\u6301\u6307\u9488\u3001model ID \u548C\u771F\u5B9E\u6A21\u578B\u540D\u79F0\n * @param modelParam - \u53EF\u4EE5\u662F\u6A21\u578B\u6307\u9488 ('main', 'task', etc.)\u3001\u5185\u90E8model ID \u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0 ('gpt-4o', 'claude-3-5-sonnet')\n * @returns ModelProfile \u6216 null\n */\n resolveModel(modelParam: string | ModelPointerType): ModelProfile | null {\n // \u9996\u5148\u68C0\u67E5\u662F\u5426\u662F\u6A21\u578B\u6307\u9488\n if (['main', 'task', 'reasoning', 'quick'].includes(modelParam)) {\n const pointerId =\n this.config.modelPointers?.[modelParam as ModelPointerType]\n if (pointerId) {\n // pointerId \u53EF\u80FD\u662F\u5185\u90E8ID\u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0\uFF0C\u5C1D\u8BD5\u4E24\u79CD\u67E5\u627E\u65B9\u5F0F\n let profile = this.findModelProfile(pointerId) // \u6309\u5185\u90E8ID\u67E5\u627E\n if (!profile) {\n profile = this.findModelProfileByModelName(pointerId) // \u6309\u771F\u5B9E\u6A21\u578B\u540D\u67E5\u627E\n }\n if (profile && profile.isActive) {\n return profile\n }\n }\n // \u6307\u9488\u65E0\u6548\u65F6\uFF0C\u5C1D\u8BD5 fallback \u5230\u9ED8\u8BA4\u6A21\u578B\n return this.getDefaultModel()\n }\n\n // \u4E0D\u662F\u6307\u9488\uFF0C\u5C1D\u8BD5\u591A\u79CD\u67E5\u627E\u65B9\u5F0F\n // 1. \u5C1D\u8BD5\u6309\u5185\u90E8 model ID \u67E5\u627E\n let profile = this.findModelProfile(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // 2. \u5C1D\u8BD5\u6309\u771F\u5B9E\u6A21\u578B\u540D\u79F0\u67E5\u627E\n profile = this.findModelProfileByModelName(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // 3. \u5C1D\u8BD5\u6309\u53CB\u597D\u540D\u79F0\u67E5\u627E\n profile = this.findModelProfileByName(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // \u6240\u6709\u67E5\u627E\u65B9\u5F0F\u90FD\u5931\u8D25\uFF0C\u5C1D\u8BD5 fallback \u5230\u9ED8\u8BA4\u6A21\u578B\n return this.getDefaultModel()\n }\n\n /**\n * \u89E3\u6790\u6A21\u578B\u53C2\u6570\u5E76\u8FD4\u56DE\u5B8C\u6574\u4FE1\u606F\n */\n resolveModelWithInfo(modelParam: string | ModelPointerType): {\n success: boolean\n profile: ModelProfile | null\n error?: string\n } {\n const isPointer = ['main', 'task', 'reasoning', 'quick'].includes(\n modelParam,\n )\n\n if (isPointer) {\n const pointerId =\n this.config.modelPointers?.[modelParam as ModelPointerType]\n if (!pointerId) {\n return {\n success: false,\n profile: null,\n error: `Model pointer '${modelParam}' is not configured. Use /model to set up models.`,\n }\n }\n\n // pointerId \u53EF\u80FD\u662F\u5185\u90E8ID\u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0\n let profile = this.findModelProfile(pointerId)\n if (!profile) {\n profile = this.findModelProfileByModelName(pointerId)\n }\n\n if (!profile) {\n return {\n success: false,\n profile: null,\n error: `Model pointer '${modelParam}' points to invalid model '${pointerId}'. Use /model to reconfigure.`,\n }\n }\n\n if (!profile.isActive) {\n return {\n success: false,\n profile: null,\n error: `Model '${profile.name}' (pointed by '${modelParam}') is inactive. Use /model to activate it.`,\n }\n }\n\n return {\n success: true,\n profile,\n }\n } else {\n // \u76F4\u63A5\u7684 model ID \u6216\u6A21\u578B\u540D\u79F0\uFF0C\u5C1D\u8BD5\u591A\u79CD\u67E5\u627E\u65B9\u5F0F\n let profile = this.findModelProfile(modelParam)\n if (!profile) {\n profile = this.findModelProfileByModelName(modelParam)\n }\n if (!profile) {\n profile = this.findModelProfileByName(modelParam)\n }\n\n if (!profile) {\n return {\n success: false,\n profile: null,\n error: `Model '${modelParam}' not found. Use /model to add models.`,\n }\n }\n\n if (!profile.isActive) {\n return {\n success: false,\n profile: null,\n error: `Model '${profile.name}' is inactive. Use /model to activate it.`,\n }\n }\n\n return {\n success: true,\n profile,\n }\n }\n }\n\n // Private helper methods\n private findModelProfile(modelName: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.modelName === modelName) || null\n }\n\n private findModelProfileByModelName(modelName: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.modelName === modelName) || null\n }\n\n private findModelProfileByName(name: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.name === name) || null\n }\n\n private updateLastUsed(modelName: string): void {\n const profile = this.findModelProfile(modelName)\n if (profile) {\n profile.lastUsed = Date.now()\n }\n }\n}\n\n// Global ModelManager instance to avoid config read/write race conditions\nlet globalModelManager: ModelManager | null = null\n\n/**\n * Get the global ModelManager instance (singleton pattern to fix race conditions)\n */\nexport const getModelManager = (): ModelManager => {\n try {\n if (!globalModelManager) {\n const config = getGlobalConfig()\n if (!config) {\n console.warn(\n 'No global config available, creating ModelManager with empty config',\n )\n globalModelManager = new ModelManager({\n modelProfiles: [],\n modelPointers: { main: '', task: '', reasoning: '', quick: '' },\n })\n } else {\n globalModelManager = new ModelManager(config)\n }\n }\n return globalModelManager\n } catch (error) {\n console.error('Error creating ModelManager:', error)\n // Return a fallback ModelManager with empty configuration\n return new ModelManager({\n modelProfiles: [],\n modelPointers: { main: '', task: '', reasoning: '', quick: '' },\n })\n }\n}\n\n/**\n * Force reload of the global ModelManager instance\n * Used when configuration changes to ensure fresh data\n */\nexport const reloadModelManager = (): void => {\n globalModelManager = null\n // Force creation of new instance with fresh config\n getModelManager()\n}\n\n/**\n * Get the quick model for fast operations\n */\nexport const getQuickModel = (): string => {\n const manager = getModelManager()\n const quickModel = manager.getModel('quick')\n return quickModel?.modelName || 'quick' // Return pointer if model not resolved\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["analysis", "allModels", "profile"]
|
|
4
|
+
"sourcesContent": ["import { memoize } from 'lodash-es'\n\nimport { logError } from './log'\nimport {\n getGlobalConfig,\n ModelProfile,\n ModelPointerType,\n saveGlobalConfig,\n} from './config'\n\nexport const USE_BEDROCK = !!process.env.CLAUDE_CODE_USE_BEDROCK\nexport const USE_VERTEX = !!process.env.CLAUDE_CODE_USE_VERTEX\n\nexport interface ModelConfig {\n bedrock: string\n vertex: string\n firstParty: string\n}\n\nconst DEFAULT_MODEL_CONFIG: ModelConfig = {\n bedrock: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',\n vertex: 'claude-3-7-sonnet@20250219',\n firstParty: 'claude-sonnet-4-20250514',\n}\n\n/**\n * Helper to get the model config from defaults.\n */\nasync function getModelConfig(): Promise<ModelConfig> {\n return DEFAULT_MODEL_CONFIG\n}\n\nexport const getSlowAndCapableModel = memoize(async (): Promise<string> => {\n const config = await getGlobalConfig()\n\n // Use ModelManager for proper model resolution\n const modelManager = new ModelManager(config)\n const model = modelManager.getMainAgentModel()\n\n if (model) {\n return model\n }\n\n // Final fallback to default model\n const modelConfig = await getModelConfig()\n if (USE_BEDROCK) return modelConfig.bedrock\n if (USE_VERTEX) return modelConfig.vertex\n return modelConfig.firstParty\n})\n\n/**\n * Get context length for a model pointer type\n */\nexport function getModelContextLength(\n pointerType: ModelPointerType = 'main',\n): number {\n const config = getGlobalConfig()\n const modelManager = new ModelManager(config)\n\n // Get the model name based on pointer type\n let modelName: string | null = null\n switch (pointerType) {\n case 'main':\n modelName = modelManager.getMainAgentModel()\n break\n case 'task':\n modelName = modelManager.getTaskToolModel()\n break\n default:\n modelName = modelManager.getMainAgentModel()\n }\n\n // Find the profile for this model\n if (modelName) {\n const profile = config.modelProfiles?.find(\n (p: ModelProfile) => p.modelName === modelName && p.isActive,\n )\n if (profile && profile.contextLength) {\n return profile.contextLength\n }\n }\n\n // Default fallback (Claude Sonnet context length)\n return 200000\n}\n\nexport async function isDefaultSlowAndCapableModel(): Promise<boolean> {\n return (\n !process.env.ANTHROPIC_MODEL ||\n process.env.ANTHROPIC_MODEL === (await getSlowAndCapableModel())\n )\n}\n\n/**\n * Get the region for a specific Vertex model\n * Checks for hardcoded model-specific environment variables first,\n * then falls back to CLOUD_ML_REGION env var or default region\n */\nexport function getVertexRegionForModel(\n model: string | undefined,\n): string | undefined {\n if (model?.startsWith('claude-3-5-haiku')) {\n return process.env.VERTEX_REGION_CLAUDE_3_5_HAIKU\n } else if (model?.startsWith('claude-3-5-sonnet')) {\n return process.env.VERTEX_REGION_CLAUDE_3_5_SONNET\n } else if (model?.startsWith('claude-3-7-sonnet')) {\n return process.env.VERTEX_REGION_CLAUDE_3_7_SONNET\n }\n}\n\n/**\n * Comprehensive ModelManager class for centralized model selection and management.\n * Provides a clean interface for model selection across the application.\n */\nexport class ModelManager {\n private config: any // Using any to handle legacy properties\n private modelProfiles: ModelProfile[]\n\n constructor(config: any) {\n this.config = config\n this.modelProfiles = config.modelProfiles || []\n }\n\n /**\n * Get the current terminal model (for interactive CLI sessions)\n */\n getCurrentModel(): string | null {\n // Use main pointer from new ModelProfile system\n const mainModelName = this.config.modelPointers?.main\n if (mainModelName) {\n const profile = this.findModelProfile(mainModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to main agent model\n return this.getMainAgentModel()\n }\n\n /**\n * Get the main agent default model (for non-terminal mode and MCP calls)\n */\n getMainAgentModel(): string | null {\n // Use main pointer from new ModelProfile system\n const mainModelName = this.config.modelPointers?.main\n if (mainModelName) {\n const profile = this.findModelProfile(mainModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to first active profile\n const activeProfile = this.modelProfiles.find(p => p.isActive)\n if (activeProfile) {\n return activeProfile.modelName\n }\n\n return null\n }\n\n /**\n * Get the task tool default model (for Task tool sub-agents)\n */\n getTaskToolModel(): string | null {\n // Use task pointer from new ModelProfile system\n const taskModelName = this.config.modelPointers?.task\n if (taskModelName) {\n const profile = this.findModelProfile(taskModelName)\n if (profile && profile.isActive) {\n return profile.modelName\n }\n }\n\n // Fallback to main agent model\n return this.getMainAgentModel()\n }\n\n /**\n * Switch to the next available model with enhanced context overflow handling\n * If target model can't handle current context, shows warning and reverts after delay\n *\n * @param currentContextTokens - Current conversation token count for validation\n * @returns Object with detailed model name and context status information\n */\n switchToNextModelWithContextCheck(currentContextTokens: number = 0): {\n success: boolean\n modelName: string | null\n previousModelName: string | null\n contextOverflow: boolean\n usagePercentage: number\n // Enhanced feedback fields\n currentContextTokens: number\n targetContextLimit: number\n skippedModels: Array<{ name: string; reason: string }>\n totalAvailableModels: number\n } {\n // Use ALL configured models, not just active ones\n const allProfiles = this.getAllConfiguredModels()\n if (allProfiles.length === 0) {\n return {\n success: false,\n modelName: null,\n previousModelName: null,\n contextOverflow: false,\n usagePercentage: 0,\n currentContextTokens,\n targetContextLimit: 0,\n skippedModels: [],\n totalAvailableModels: 0,\n }\n }\n\n // Sort by createdAt for consistent cycling order (don't use lastUsed)\n // Using lastUsed causes the order to change each time, preventing proper cycling\n allProfiles.sort((a, b) => {\n return a.createdAt - b.createdAt // Oldest first for consistent order\n })\n\n const currentMainModelName = this.config.modelPointers?.main\n const currentModel = currentMainModelName\n ? this.findModelProfile(currentMainModelName)\n : null\n const previousModelName = currentModel?.name || null\n\n if (!currentMainModelName) {\n // No current main model, select first available (activate if needed)\n const firstModel = allProfiles[0]\n if (!firstModel.isActive) {\n firstModel.isActive = true\n }\n this.setPointer('main', firstModel.modelName)\n this.updateLastUsed(firstModel.modelName)\n\n const analysis = this.analyzeContextCompatibility(\n firstModel,\n currentContextTokens,\n )\n return {\n success: true,\n modelName: firstModel.name,\n previousModelName: null,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n currentContextTokens,\n targetContextLimit: firstModel.contextLength,\n skippedModels: [],\n totalAvailableModels: allProfiles.length,\n }\n }\n\n // Find current model index in ALL models\n const currentIndex = allProfiles.findIndex(\n p => p.modelName === currentMainModelName,\n )\n if (currentIndex === -1) {\n // Current model not found, select first available (activate if needed)\n const firstModel = allProfiles[0]\n if (!firstModel.isActive) {\n firstModel.isActive = true\n }\n this.setPointer('main', firstModel.modelName)\n this.updateLastUsed(firstModel.modelName)\n\n const analysis = this.analyzeContextCompatibility(\n firstModel,\n currentContextTokens,\n )\n return {\n success: true,\n modelName: firstModel.name,\n previousModelName,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n currentContextTokens,\n targetContextLimit: firstModel.contextLength,\n skippedModels: [],\n totalAvailableModels: allProfiles.length,\n }\n }\n\n // Check if only one model is available\n if (allProfiles.length === 1) {\n const currentModel = allProfiles[0]\n return {\n success: false,\n modelName: null,\n previousModelName,\n contextOverflow: false,\n usagePercentage: 0,\n currentContextTokens,\n targetContextLimit: currentModel?.contextLength || 0,\n skippedModels: [],\n totalAvailableModels: 1,\n }\n }\n\n // Get next model in cycle (from ALL models)\n const nextIndex = (currentIndex + 1) % allProfiles.length\n const nextModel = allProfiles[nextIndex]\n\n // Activate the model if it's not already active\n const wasInactive = !nextModel.isActive\n if (!nextModel.isActive) {\n nextModel.isActive = true\n }\n\n // Analyze context compatibility for next model\n const analysis = this.analyzeContextCompatibility(\n nextModel,\n currentContextTokens,\n )\n\n // Always switch to next model, but return context status\n this.setPointer('main', nextModel.modelName)\n this.updateLastUsed(nextModel.modelName)\n\n // Save configuration if we activated a new model\n if (wasInactive) {\n this.saveConfig()\n }\n\n return {\n success: true,\n modelName: nextModel.name,\n previousModelName,\n contextOverflow: !analysis.compatible,\n usagePercentage: analysis.usagePercentage,\n currentContextTokens,\n targetContextLimit: nextModel.contextLength,\n skippedModels: [], // In simple round-robin, no models are skipped\n totalAvailableModels: allProfiles.length,\n }\n }\n\n /**\n * Simple model switching for UI components (compatible interface)\n * @param currentContextTokens - Current conversation token count for validation\n * @returns Compatible interface for PromptInput component\n */\n switchToNextModel(currentContextTokens: number = 0): {\n success: boolean\n modelName: string | null\n blocked?: boolean\n message?: string\n } {\n // Use the enhanced context check method for consistency\n const result = this.switchToNextModelWithContextCheck(currentContextTokens)\n\n if (!result.success) {\n const allModels = this.getAllConfiguredModels()\n if (allModels.length === 0) {\n return {\n success: false,\n modelName: null,\n blocked: false,\n message: '\u274C No models configured. Use /model to add models.',\n }\n } else if (allModels.length === 1) {\n return {\n success: false,\n modelName: null,\n blocked: false,\n message: `\u26A0\uFE0F Only one model configured (${allModels[0].modelName}). Use /model to add more models for switching.`,\n }\n }\n }\n\n // Convert the detailed result to the simple interface\n const currentModel = this.findModelProfile(this.config.modelPointers?.main)\n const allModels = this.getAllConfiguredModels()\n const currentIndex = allModels.findIndex(\n m => m.modelName === currentModel?.modelName,\n )\n const totalModels = allModels.length\n\n return {\n success: result.success,\n modelName: result.modelName,\n blocked: result.contextOverflow,\n message: result.success\n ? result.contextOverflow\n ? `\u26A0\uFE0F Context usage: ${result.usagePercentage.toFixed(1)}% - ${result.modelName}`\n : `\u2705 Switched to ${result.modelName} (${currentIndex + 1}/${totalModels})${currentModel?.provider ? ` [${currentModel.provider}]` : ''}`\n : `\u274C Failed to switch models`,\n }\n }\n\n /**\n * Revert to previous model (used when context overflow requires rollback)\n */\n revertToPreviousModel(previousModelName: string): boolean {\n const previousModel = this.modelProfiles.find(\n p => p.name === previousModelName && p.isActive,\n )\n if (!previousModel) {\n return false\n }\n\n this.setPointer('main', previousModel.modelName)\n this.updateLastUsed(previousModel.modelName)\n return true\n }\n\n /**\n * Enhanced context validation with different severity levels\n */\n analyzeContextCompatibility(\n model: ModelProfile,\n contextTokens: number,\n ): {\n compatible: boolean\n severity: 'safe' | 'warning' | 'critical'\n usagePercentage: number\n recommendation: string\n } {\n const usableContext = Math.floor(model.contextLength * 0.8) // Reserve 20% for output\n const usagePercentage = (contextTokens / usableContext) * 100\n\n if (usagePercentage <= 70) {\n return {\n compatible: true,\n severity: 'safe',\n usagePercentage,\n recommendation: 'Full context preserved',\n }\n } else if (usagePercentage <= 90) {\n return {\n compatible: true,\n severity: 'warning',\n usagePercentage,\n recommendation: 'Context usage high, consider compression',\n }\n } else {\n return {\n compatible: false,\n severity: 'critical',\n usagePercentage,\n recommendation: 'Auto-compression or message truncation required',\n }\n }\n }\n\n /**\n * Switch to next model with enhanced context analysis\n */\n switchToNextModelWithAnalysis(currentContextTokens: number = 0): {\n modelName: string | null\n contextAnalysis: ReturnType<typeof this.analyzeContextCompatibility> | null\n requiresCompression: boolean\n estimatedTokensAfterSwitch: number\n } {\n const result = this.switchToNextModel(currentContextTokens)\n\n if (!result.success || !result.modelName) {\n return {\n modelName: null,\n contextAnalysis: null,\n requiresCompression: false,\n estimatedTokensAfterSwitch: 0,\n }\n }\n\n const newModel = this.getModel('main')\n if (!newModel) {\n return {\n modelName: result.modelName,\n contextAnalysis: null,\n requiresCompression: false,\n estimatedTokensAfterSwitch: currentContextTokens,\n }\n }\n\n const analysis = this.analyzeContextCompatibility(\n newModel,\n currentContextTokens,\n )\n\n return {\n modelName: result.modelName,\n contextAnalysis: analysis,\n requiresCompression: analysis.severity === 'critical',\n estimatedTokensAfterSwitch: currentContextTokens,\n }\n }\n\n /**\n * Check if a model can handle the given context size (legacy method)\n */\n canModelHandleContext(model: ModelProfile, contextTokens: number): boolean {\n const analysis = this.analyzeContextCompatibility(model, contextTokens)\n return analysis.compatible\n }\n\n /**\n * Find the first model that can handle the given context size\n */\n findModelWithSufficientContext(\n models: ModelProfile[],\n contextTokens: number,\n ): ModelProfile | null {\n return (\n models.find(model => this.canModelHandleContext(model, contextTokens)) ||\n null\n )\n }\n\n /**\n * Unified model getter for different contexts\n */\n getModelForContext(\n contextType: 'terminal' | 'main-agent' | 'task-tool',\n ): string | null {\n switch (contextType) {\n case 'terminal':\n return this.getCurrentModel()\n case 'main-agent':\n return this.getMainAgentModel()\n case 'task-tool':\n return this.getTaskToolModel()\n default:\n return this.getMainAgentModel()\n }\n }\n\n /**\n * Get all active model profiles\n */\n getActiveModelProfiles(): ModelProfile[] {\n return this.modelProfiles.filter(p => p.isActive)\n }\n\n /**\n * Check if any models are configured\n */\n hasConfiguredModels(): boolean {\n return this.getActiveModelProfiles().length > 0\n }\n\n // New model pointer system methods\n\n /**\n * Get model by pointer type (main, task, reasoning, quick)\n */\n getModel(pointer: ModelPointerType): ModelProfile | null {\n const pointerId = this.config.modelPointers?.[pointer]\n if (!pointerId) {\n return this.getDefaultModel()\n }\n\n const profile = this.findModelProfile(pointerId)\n return profile && profile.isActive ? profile : this.getDefaultModel()\n }\n\n /**\n * Get model name by pointer type\n */\n getModelName(pointer: ModelPointerType): string | null {\n const profile = this.getModel(pointer)\n return profile ? profile.modelName : null\n }\n\n /**\n * Get reasoning model (with fallback)\n */\n getReasoningModel(): string | null {\n return this.getModelName('reasoning') || this.getModelName('main')\n }\n\n /**\n * Get quick model (with fallback)\n */\n getQuickModel(): string | null {\n return (\n this.getModelName('quick') ||\n this.getModelName('task') ||\n this.getModelName('main')\n )\n }\n\n /**\n * Get compact model for context compression/summarization (with fallback)\n * Fallback chain: compact -> quick -> task -> main\n */\n getCompactModel(): string | null {\n return (\n this.getModelName('compact') ||\n this.getModelName('quick') ||\n this.getModelName('task') ||\n this.getModelName('main')\n )\n }\n\n /**\n * Add a new model profile with duplicate validation\n */\n async addModel(\n config: Omit<ModelProfile, 'createdAt' | 'isActive'>,\n ): Promise<string> {\n // Check for duplicate modelName (actual model identifier)\n const existingByModelName = this.modelProfiles.find(\n p => p.modelName === config.modelName,\n )\n if (existingByModelName) {\n throw new Error(\n `Model with modelName '${config.modelName}' already exists: ${existingByModelName.name}`,\n )\n }\n\n // Check for duplicate friendly name\n const existingByName = this.modelProfiles.find(p => p.name === config.name)\n if (existingByName) {\n throw new Error(`Model with name '${config.name}' already exists`)\n }\n\n const newModel: ModelProfile = {\n ...config,\n createdAt: Date.now(),\n isActive: true,\n }\n\n this.modelProfiles.push(newModel)\n\n // If this is the first model, set all pointers to it\n if (this.modelProfiles.length === 1) {\n this.config.modelPointers = {\n main: config.modelName,\n task: config.modelName,\n reasoning: config.modelName,\n quick: config.modelName,\n compact: config.modelName,\n }\n this.config.defaultModelName = config.modelName\n }\n\n this.saveConfig()\n return config.modelName\n }\n\n /**\n * Set model pointer assignment\n */\n setPointer(pointer: ModelPointerType, modelName: string): void {\n if (!this.findModelProfile(modelName)) {\n throw new Error(`Model '${modelName}' not found`)\n }\n\n if (!this.config.modelPointers) {\n this.config.modelPointers = {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n }\n }\n\n this.config.modelPointers[pointer] = modelName\n this.saveConfig()\n }\n\n /**\n * Get all active models for pointer assignment\n */\n getAvailableModels(): ModelProfile[] {\n return this.modelProfiles.filter(p => p.isActive)\n }\n\n /**\n * Get all configured models (both active and inactive) for switching\n */\n getAllConfiguredModels(): ModelProfile[] {\n return this.modelProfiles\n }\n\n /**\n * Get all available model names (modelName field) - active only\n */\n getAllAvailableModelNames(): string[] {\n return this.getAvailableModels().map(p => p.modelName)\n }\n\n /**\n * Get all configured model names (both active and inactive)\n */\n getAllConfiguredModelNames(): string[] {\n return this.getAllConfiguredModels().map(p => p.modelName)\n }\n\n /**\n * Debug method to get detailed model switching information\n */\n getModelSwitchingDebugInfo(): {\n totalModels: number\n activeModels: number\n inactiveModels: number\n currentMainModel: string | null\n availableModels: Array<{\n name: string\n modelName: string\n provider: string\n isActive: boolean\n lastUsed?: number\n }>\n modelPointers: Record<string, string | undefined>\n } {\n const availableModels = this.getAvailableModels()\n const currentMainModelName = this.config.modelPointers?.main\n\n return {\n totalModels: this.modelProfiles.length,\n activeModels: availableModels.length,\n inactiveModels: this.modelProfiles.length - availableModels.length,\n currentMainModel: currentMainModelName || null,\n availableModels: this.modelProfiles.map(p => ({\n name: p.name,\n modelName: p.modelName,\n provider: p.provider,\n isActive: p.isActive,\n lastUsed: p.lastUsed,\n })),\n modelPointers: this.config.modelPointers || {},\n }\n }\n\n /**\n * Remove a model profile\n */\n removeModel(modelName: string): void {\n this.modelProfiles = this.modelProfiles.filter(\n p => p.modelName !== modelName,\n )\n\n // Clean up pointers that reference deleted model\n if (this.config.modelPointers) {\n Object.keys(this.config.modelPointers).forEach(pointer => {\n if (\n this.config.modelPointers[pointer as ModelPointerType] === modelName\n ) {\n this.config.modelPointers[pointer as ModelPointerType] =\n this.config.defaultModelName || ''\n }\n })\n }\n\n this.saveConfig()\n }\n\n /**\n * Get default model profile\n */\n private getDefaultModel(): ModelProfile | null {\n if (this.config.defaultModelId) {\n const profile = this.findModelProfile(this.config.defaultModelId)\n if (profile && profile.isActive) {\n return profile\n }\n }\n return this.modelProfiles.find(p => p.isActive) || null\n }\n\n /**\n * Save configuration changes\n * Note: This updates the global config file. The singleton instance\n * is automatically refreshed to avoid stale data issues.\n */\n private saveConfig(): void {\n const updatedConfig = {\n ...this.config,\n modelProfiles: this.modelProfiles,\n }\n saveGlobalConfig(updatedConfig)\n\n // Refresh the global singleton to avoid stale data race conditions\n // This ensures any subsequent getModelManager() calls get fresh data\n refreshGlobalModelManagerInstance(this)\n }\n\n /**\n * Get a fallback model when no specific model is configured\n */\n async getFallbackModel(): Promise<string> {\n const modelConfig = await getModelConfig()\n if (USE_BEDROCK) return modelConfig.bedrock\n if (USE_VERTEX) return modelConfig.vertex\n return modelConfig.firstParty\n }\n\n /**\n * \u7EDF\u4E00\u7684\u6A21\u578B\u89E3\u6790\u65B9\u6CD5\uFF1A\u652F\u6301\u6307\u9488\u3001model ID \u548C\u771F\u5B9E\u6A21\u578B\u540D\u79F0\n * @param modelParam - \u53EF\u4EE5\u662F\u6A21\u578B\u6307\u9488 ('main', 'task', etc.)\u3001\u5185\u90E8model ID \u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0 ('gpt-4o', 'claude-3-5-sonnet')\n * @returns ModelProfile \u6216 null\n */\n resolveModel(modelParam: string | ModelPointerType): ModelProfile | null {\n // \u9996\u5148\u68C0\u67E5\u662F\u5426\u662F\u6A21\u578B\u6307\u9488\n if (\n ['main', 'task', 'reasoning', 'quick', 'compact'].includes(modelParam)\n ) {\n const pointerId =\n this.config.modelPointers?.[modelParam as ModelPointerType]\n if (pointerId) {\n // pointerId \u53EF\u80FD\u662F\u5185\u90E8ID\u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0\uFF0C\u5C1D\u8BD5\u4E24\u79CD\u67E5\u627E\u65B9\u5F0F\n let profile = this.findModelProfile(pointerId) // \u6309\u5185\u90E8ID\u67E5\u627E\n if (!profile) {\n profile = this.findModelProfileByModelName(pointerId) // \u6309\u771F\u5B9E\u6A21\u578B\u540D\u67E5\u627E\n }\n if (profile && profile.isActive) {\n return profile\n }\n }\n // \u6307\u9488\u65E0\u6548\u65F6\uFF0C\u5C1D\u8BD5 fallback \u5230\u9ED8\u8BA4\u6A21\u578B\n return this.getDefaultModel()\n }\n\n // \u4E0D\u662F\u6307\u9488\uFF0C\u5C1D\u8BD5\u591A\u79CD\u67E5\u627E\u65B9\u5F0F\n // 1. \u5C1D\u8BD5\u6309\u5185\u90E8 model ID \u67E5\u627E\n let profile = this.findModelProfile(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // 2. \u5C1D\u8BD5\u6309\u771F\u5B9E\u6A21\u578B\u540D\u79F0\u67E5\u627E\n profile = this.findModelProfileByModelName(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // 3. \u5C1D\u8BD5\u6309\u53CB\u597D\u540D\u79F0\u67E5\u627E\n profile = this.findModelProfileByName(modelParam)\n if (profile && profile.isActive) {\n return profile\n }\n\n // \u6240\u6709\u67E5\u627E\u65B9\u5F0F\u90FD\u5931\u8D25\uFF0C\u5C1D\u8BD5 fallback \u5230\u9ED8\u8BA4\u6A21\u578B\n return this.getDefaultModel()\n }\n\n /**\n * \u89E3\u6790\u6A21\u578B\u53C2\u6570\u5E76\u8FD4\u56DE\u5B8C\u6574\u4FE1\u606F\n */\n resolveModelWithInfo(modelParam: string | ModelPointerType): {\n success: boolean\n profile: ModelProfile | null\n error?: string\n } {\n const isPointer = [\n 'main',\n 'task',\n 'reasoning',\n 'quick',\n 'compact',\n ].includes(modelParam)\n\n if (isPointer) {\n const pointerId =\n this.config.modelPointers?.[modelParam as ModelPointerType]\n if (!pointerId) {\n return {\n success: false,\n profile: null,\n error: `Model pointer '${modelParam}' is not configured. Use /model to set up models.`,\n }\n }\n\n // pointerId \u53EF\u80FD\u662F\u5185\u90E8ID\u6216\u771F\u5B9E\u6A21\u578B\u540D\u79F0\n let profile = this.findModelProfile(pointerId)\n if (!profile) {\n profile = this.findModelProfileByModelName(pointerId)\n }\n\n if (!profile) {\n return {\n success: false,\n profile: null,\n error: `Model pointer '${modelParam}' points to invalid model '${pointerId}'. Use /model to reconfigure.`,\n }\n }\n\n if (!profile.isActive) {\n return {\n success: false,\n profile: null,\n error: `Model '${profile.name}' (pointed by '${modelParam}') is inactive. Use /model to activate it.`,\n }\n }\n\n return {\n success: true,\n profile,\n }\n } else {\n // \u76F4\u63A5\u7684 model ID \u6216\u6A21\u578B\u540D\u79F0\uFF0C\u5C1D\u8BD5\u591A\u79CD\u67E5\u627E\u65B9\u5F0F\n let profile = this.findModelProfile(modelParam)\n if (!profile) {\n profile = this.findModelProfileByModelName(modelParam)\n }\n if (!profile) {\n profile = this.findModelProfileByName(modelParam)\n }\n\n if (!profile) {\n return {\n success: false,\n profile: null,\n error: `Model '${modelParam}' not found. Use /model to add models.`,\n }\n }\n\n if (!profile.isActive) {\n return {\n success: false,\n profile: null,\n error: `Model '${profile.name}' is inactive. Use /model to activate it.`,\n }\n }\n\n return {\n success: true,\n profile,\n }\n }\n }\n\n // Private helper methods\n private findModelProfile(modelName: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.modelName === modelName) || null\n }\n\n private findModelProfileByModelName(modelName: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.modelName === modelName) || null\n }\n\n private findModelProfileByName(name: string): ModelProfile | null {\n return this.modelProfiles.find(p => p.name === name) || null\n }\n\n private updateLastUsed(modelName: string): void {\n const profile = this.findModelProfile(modelName)\n if (profile) {\n profile.lastUsed = Date.now()\n }\n }\n\n /**\n * Find model profile by provider-qualified name (e.g., \"openai:gpt-4o\", \"anthropic:claude-3-5-sonnet\")\n * @param qualifiedName - Format: \"provider:modelName\" or just \"modelName\"\n * @returns ModelProfile or null\n */\n findModelByProviderQualified(qualifiedName: string): ModelProfile | null {\n // Check if it's a provider-qualified name\n if (qualifiedName.includes(':')) {\n const [provider, modelName] = qualifiedName.split(':', 2)\n // Find model matching both provider and modelName\n return (\n this.modelProfiles.find(\n p =>\n p.provider.toLowerCase() === provider.toLowerCase() &&\n (p.modelName === modelName ||\n p.modelName.toLowerCase() === modelName.toLowerCase() ||\n p.name.toLowerCase() === modelName.toLowerCase()),\n ) || null\n )\n }\n\n // Not provider-qualified, fall back to regular lookup\n return (\n this.findModelProfile(qualifiedName) ||\n this.findModelProfileByName(qualifiedName)\n )\n }\n\n /**\n * Enhanced model resolution supporting provider:model format\n * @param modelParam - Can be pointer, provider:model, modelName, or friendly name\n * @returns ModelProfile or null\n */\n resolveProviderQualifiedModel(modelParam: string): {\n profile: ModelProfile | null\n provider?: string\n modelId?: string\n } {\n // Check for provider:model format first\n if (\n modelParam.includes(':') &&\n !['main', 'task', 'reasoning', 'quick', 'compact'].includes(\n modelParam.split(':')[0],\n )\n ) {\n const [provider, modelId] = modelParam.split(':', 2)\n const profile = this.findModelByProviderQualified(modelParam)\n return { profile, provider, modelId }\n }\n\n // Fall back to regular resolve\n const profile = this.resolveModel(modelParam)\n return { profile }\n }\n\n /**\n * Get all models from a specific provider\n */\n getModelsByProvider(provider: string): ModelProfile[] {\n return this.modelProfiles.filter(\n p => p.provider.toLowerCase() === provider.toLowerCase(),\n )\n }\n\n /**\n * Get list of unique providers\n */\n getUniqueProviders(): string[] {\n const providers = new Set(this.modelProfiles.map(p => p.provider))\n return Array.from(providers)\n }\n}\n\n// Global ModelManager instance to avoid config read/write race conditions\nlet globalModelManager: ModelManager | null = null\n\n/**\n * Internal function to refresh the global singleton with an updated instance\n * This is called by ModelManager.saveConfig() to avoid stale data\n */\nfunction refreshGlobalModelManagerInstance(instance: ModelManager): void {\n globalModelManager = instance\n}\n\n/**\n * Get the global ModelManager instance (singleton pattern to fix race conditions)\n */\nexport const getModelManager = (): ModelManager => {\n try {\n if (!globalModelManager) {\n const config = getGlobalConfig()\n if (!config) {\n console.warn(\n 'No global config available, creating ModelManager with empty config',\n )\n globalModelManager = new ModelManager({\n modelProfiles: [],\n modelPointers: {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n },\n })\n } else {\n globalModelManager = new ModelManager(config)\n }\n }\n return globalModelManager\n } catch (error) {\n console.error('Error creating ModelManager:', error)\n // Return a fallback ModelManager with empty configuration\n return new ModelManager({\n modelProfiles: [],\n modelPointers: {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n },\n })\n }\n}\n\n/**\n * Force reload of the global ModelManager instance\n * Used when configuration changes to ensure fresh data\n */\nexport const reloadModelManager = (): void => {\n globalModelManager = null\n // Force creation of new instance with fresh config\n getModelManager()\n}\n\n/**\n * Get the quick model for fast operations\n */\nexport const getQuickModel = (): string => {\n const manager = getModelManager()\n const quickModel = manager.getModel('quick')\n return quickModel?.modelName || 'quick' // Return pointer if model not resolved\n}\n\n/**\n * Get the compact model for context compression/summarization\n */\nexport const getCompactModel = (): string => {\n const manager = getModelManager()\n const compactModel = manager.getCompactModel()\n return compactModel || 'compact' // Return pointer if model not resolved\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["analysis", "currentModel", "allModels", "profile"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { isAbsolute, resolve, relative } from "path";
|
|
1
|
+
import { isAbsolute, resolve, relative, dirname } from "path";
|
|
2
2
|
import { getCwd, getOriginalCwd } from "../state.js";
|
|
3
|
+
import {
|
|
4
|
+
getCurrentProjectConfig,
|
|
5
|
+
saveCurrentProjectConfig
|
|
6
|
+
} from "../config.js";
|
|
3
7
|
const readFileAllowedDirectories = /* @__PURE__ */ new Set();
|
|
4
8
|
const writeFileAllowedDirectories = /* @__PURE__ */ new Set();
|
|
9
|
+
let persistentReadPermissions = [];
|
|
10
|
+
let persistentWritePermissions = [];
|
|
11
|
+
let persistentPermissionsLoaded = false;
|
|
5
12
|
function toAbsolutePath(path) {
|
|
6
13
|
const abs = isAbsolute(path) ? resolve(path) : resolve(getCwd(), path);
|
|
7
14
|
return normalizeForCompare(abs);
|
|
@@ -22,21 +29,68 @@ function pathInOriginalCwd(path) {
|
|
|
22
29
|
const base = toAbsolutePath(getOriginalCwd());
|
|
23
30
|
return isSubpath(base, absolutePath);
|
|
24
31
|
}
|
|
32
|
+
function loadPersistentPermissions() {
|
|
33
|
+
if (persistentPermissionsLoaded) return;
|
|
34
|
+
try {
|
|
35
|
+
const config = getCurrentProjectConfig();
|
|
36
|
+
const filePermissions = config.filePermissions;
|
|
37
|
+
if (filePermissions) {
|
|
38
|
+
const now = Date.now();
|
|
39
|
+
persistentReadPermissions = (filePermissions.read || []).filter(
|
|
40
|
+
(p) => !p.expiresAt || p.expiresAt > now
|
|
41
|
+
);
|
|
42
|
+
persistentWritePermissions = (filePermissions.write || []).filter(
|
|
43
|
+
(p) => !p.expiresAt || p.expiresAt > now
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
persistentPermissionsLoaded = true;
|
|
47
|
+
} catch {
|
|
48
|
+
persistentPermissionsLoaded = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function savePersistentPermissions() {
|
|
52
|
+
try {
|
|
53
|
+
const config = getCurrentProjectConfig();
|
|
54
|
+
if (persistentReadPermissions.length > 0 || persistentWritePermissions.length > 0) {
|
|
55
|
+
;
|
|
56
|
+
config.filePermissions = {
|
|
57
|
+
read: persistentReadPermissions,
|
|
58
|
+
write: persistentWritePermissions
|
|
59
|
+
};
|
|
60
|
+
saveCurrentProjectConfig(config);
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
64
|
+
}
|
|
25
65
|
function hasReadPermission(directory) {
|
|
66
|
+
loadPersistentPermissions();
|
|
26
67
|
const absolutePath = toAbsolutePath(directory);
|
|
27
68
|
for (const allowedPath of readFileAllowedDirectories) {
|
|
28
69
|
if (isSubpath(allowedPath, absolutePath)) return true;
|
|
29
70
|
}
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
for (const entry of persistentReadPermissions) {
|
|
73
|
+
if (entry.expiresAt && entry.expiresAt < now) continue;
|
|
74
|
+
const normalizedEntry = toAbsolutePath(entry.path);
|
|
75
|
+
if (isSubpath(normalizedEntry, absolutePath)) return true;
|
|
76
|
+
}
|
|
30
77
|
return false;
|
|
31
78
|
}
|
|
32
79
|
function hasWritePermission(directory) {
|
|
80
|
+
loadPersistentPermissions();
|
|
33
81
|
const absolutePath = toAbsolutePath(directory);
|
|
34
82
|
for (const allowedPath of writeFileAllowedDirectories) {
|
|
35
83
|
if (isSubpath(allowedPath, absolutePath)) return true;
|
|
36
84
|
}
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
for (const entry of persistentWritePermissions) {
|
|
87
|
+
if (entry.expiresAt && entry.expiresAt < now) continue;
|
|
88
|
+
const normalizedEntry = toAbsolutePath(entry.path);
|
|
89
|
+
if (isSubpath(normalizedEntry, absolutePath)) return true;
|
|
90
|
+
}
|
|
37
91
|
return false;
|
|
38
92
|
}
|
|
39
|
-
function saveReadPermission(directory) {
|
|
93
|
+
function saveReadPermission(directory, persist = false, expiresIn, reason) {
|
|
40
94
|
const absolutePath = toAbsolutePath(directory);
|
|
41
95
|
for (const allowedPath of Array.from(readFileAllowedDirectories)) {
|
|
42
96
|
if (isSubpath(absolutePath, allowedPath)) {
|
|
@@ -44,13 +98,28 @@ function saveReadPermission(directory) {
|
|
|
44
98
|
}
|
|
45
99
|
}
|
|
46
100
|
readFileAllowedDirectories.add(absolutePath);
|
|
101
|
+
if (persist) {
|
|
102
|
+
loadPersistentPermissions();
|
|
103
|
+
const entry = {
|
|
104
|
+
path: absolutePath,
|
|
105
|
+
type: "read",
|
|
106
|
+
grantedAt: Date.now(),
|
|
107
|
+
expiresAt: expiresIn ? Date.now() + expiresIn : void 0,
|
|
108
|
+
reason
|
|
109
|
+
};
|
|
110
|
+
persistentReadPermissions = persistentReadPermissions.filter(
|
|
111
|
+
(p) => toAbsolutePath(p.path) !== absolutePath
|
|
112
|
+
);
|
|
113
|
+
persistentReadPermissions.push(entry);
|
|
114
|
+
savePersistentPermissions();
|
|
115
|
+
}
|
|
47
116
|
}
|
|
48
117
|
const saveReadPermissionForTest = saveReadPermission;
|
|
49
118
|
function grantReadPermissionForOriginalDir() {
|
|
50
119
|
const originalProjectDir = getOriginalCwd();
|
|
51
|
-
saveReadPermission(originalProjectDir);
|
|
120
|
+
saveReadPermission(originalProjectDir, false);
|
|
52
121
|
}
|
|
53
|
-
function saveWritePermission(directory) {
|
|
122
|
+
function saveWritePermission(directory, persist = false, expiresIn, reason) {
|
|
54
123
|
const absolutePath = toAbsolutePath(directory);
|
|
55
124
|
for (const allowedPath of Array.from(writeFileAllowedDirectories)) {
|
|
56
125
|
if (isSubpath(absolutePath, allowedPath)) {
|
|
@@ -58,23 +127,106 @@ function saveWritePermission(directory) {
|
|
|
58
127
|
}
|
|
59
128
|
}
|
|
60
129
|
writeFileAllowedDirectories.add(absolutePath);
|
|
130
|
+
if (persist) {
|
|
131
|
+
loadPersistentPermissions();
|
|
132
|
+
const entry = {
|
|
133
|
+
path: absolutePath,
|
|
134
|
+
type: "write",
|
|
135
|
+
grantedAt: Date.now(),
|
|
136
|
+
expiresAt: expiresIn ? Date.now() + expiresIn : void 0,
|
|
137
|
+
reason
|
|
138
|
+
};
|
|
139
|
+
persistentWritePermissions = persistentWritePermissions.filter(
|
|
140
|
+
(p) => toAbsolutePath(p.path) !== absolutePath
|
|
141
|
+
);
|
|
142
|
+
persistentWritePermissions.push(entry);
|
|
143
|
+
savePersistentPermissions();
|
|
144
|
+
}
|
|
61
145
|
}
|
|
62
146
|
function grantWritePermissionForOriginalDir() {
|
|
63
147
|
const originalProjectDir = getOriginalCwd();
|
|
64
|
-
saveWritePermission(originalProjectDir);
|
|
148
|
+
saveWritePermission(originalProjectDir, false);
|
|
149
|
+
}
|
|
150
|
+
function grantFilePermission(filePath, type, persist = false, expiresIn, reason) {
|
|
151
|
+
const dir = dirname(toAbsolutePath(filePath));
|
|
152
|
+
if (type === "read") {
|
|
153
|
+
saveReadPermission(dir, persist, expiresIn, reason);
|
|
154
|
+
} else {
|
|
155
|
+
saveWritePermission(dir, persist, expiresIn, reason);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function revokePersistentPermission(path, type) {
|
|
159
|
+
loadPersistentPermissions();
|
|
160
|
+
const absolutePath = toAbsolutePath(path);
|
|
161
|
+
let found = false;
|
|
162
|
+
if (type === "read") {
|
|
163
|
+
const before = persistentReadPermissions.length;
|
|
164
|
+
persistentReadPermissions = persistentReadPermissions.filter(
|
|
165
|
+
(p) => toAbsolutePath(p.path) !== absolutePath
|
|
166
|
+
);
|
|
167
|
+
found = persistentReadPermissions.length < before;
|
|
168
|
+
} else {
|
|
169
|
+
const before = persistentWritePermissions.length;
|
|
170
|
+
persistentWritePermissions = persistentWritePermissions.filter(
|
|
171
|
+
(p) => toAbsolutePath(p.path) !== absolutePath
|
|
172
|
+
);
|
|
173
|
+
found = persistentWritePermissions.length < before;
|
|
174
|
+
}
|
|
175
|
+
if (found) {
|
|
176
|
+
savePersistentPermissions();
|
|
177
|
+
}
|
|
178
|
+
return found;
|
|
179
|
+
}
|
|
180
|
+
function getPersistentPermissions() {
|
|
181
|
+
loadPersistentPermissions();
|
|
182
|
+
return {
|
|
183
|
+
read: [...persistentReadPermissions],
|
|
184
|
+
write: [...persistentWritePermissions]
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function clearExpiredPermissions() {
|
|
188
|
+
loadPersistentPermissions();
|
|
189
|
+
const now = Date.now();
|
|
190
|
+
const beforeRead = persistentReadPermissions.length;
|
|
191
|
+
const beforeWrite = persistentWritePermissions.length;
|
|
192
|
+
persistentReadPermissions = persistentReadPermissions.filter(
|
|
193
|
+
(p) => !p.expiresAt || p.expiresAt > now
|
|
194
|
+
);
|
|
195
|
+
persistentWritePermissions = persistentWritePermissions.filter(
|
|
196
|
+
(p) => !p.expiresAt || p.expiresAt > now
|
|
197
|
+
);
|
|
198
|
+
const cleared = beforeRead - persistentReadPermissions.length + (beforeWrite - persistentWritePermissions.length);
|
|
199
|
+
if (cleared > 0) {
|
|
200
|
+
savePersistentPermissions();
|
|
201
|
+
}
|
|
202
|
+
return cleared;
|
|
65
203
|
}
|
|
66
204
|
function clearFilePermissions() {
|
|
67
205
|
readFileAllowedDirectories.clear();
|
|
68
206
|
writeFileAllowedDirectories.clear();
|
|
207
|
+
persistentReadPermissions = [];
|
|
208
|
+
persistentWritePermissions = [];
|
|
209
|
+
persistentPermissionsLoaded = false;
|
|
210
|
+
}
|
|
211
|
+
function reloadPersistentPermissions() {
|
|
212
|
+
persistentPermissionsLoaded = false;
|
|
213
|
+
loadPersistentPermissions();
|
|
69
214
|
}
|
|
70
215
|
export {
|
|
216
|
+
clearExpiredPermissions,
|
|
71
217
|
clearFilePermissions,
|
|
218
|
+
getPersistentPermissions,
|
|
219
|
+
grantFilePermission,
|
|
72
220
|
grantReadPermissionForOriginalDir,
|
|
73
221
|
grantWritePermissionForOriginalDir,
|
|
74
222
|
hasReadPermission,
|
|
75
223
|
hasWritePermission,
|
|
76
224
|
pathInOriginalCwd,
|
|
225
|
+
reloadPersistentPermissions,
|
|
226
|
+
revokePersistentPermission,
|
|
227
|
+
saveReadPermission,
|
|
77
228
|
saveReadPermissionForTest,
|
|
229
|
+
saveWritePermission,
|
|
78
230
|
toAbsolutePath
|
|
79
231
|
};
|
|
80
232
|
//# sourceMappingURL=filesystem.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/utils/permissions/filesystem.ts"],
|
|
4
|
-
"sourcesContent": ["import { isAbsolute, resolve, relative, sep } from 'path'\nimport { getCwd, getOriginalCwd } from '@utils/state'\n\n// In-memory storage for file permissions that resets each session\n// Sets of allowed directories for read and write operations\nconst readFileAllowedDirectories: Set<string> = new Set()\nconst writeFileAllowedDirectories: Set<string> = new Set()\n\n/**\n * Ensures a path is absolute by resolving it relative to cwd if necessary\n * @param path The path to normalize\n * @returns Absolute path\n */\nexport function toAbsolutePath(path: string): string {\n const abs = isAbsolute(path) ? resolve(path) : resolve(getCwd(), path)\n return normalizeForCompare(abs)\n}\n\nfunction normalizeForCompare(p: string): string {\n // Normalize separators and resolve .. and . segments\n const norm = resolve(p)\n // On Windows, comparisons should be case-insensitive\n return process.platform === 'win32' ? norm.toLowerCase() : norm\n}\n\nfunction isSubpath(base: string, target: string): boolean {\n const rel = relative(base, target)\n // If different drive letters on Windows, relative returns the target path\n if (!rel || rel === '') return true\n // Not a subpath if it goes up to parent\n if (rel.startsWith('..')) return false\n // Not a subpath if absolute\n if (isAbsolute(rel)) return false\n return true\n}\n\n/**\n * Ensures a path is in the original cwd path\n * @param directory The directory path to normalize\n * @returns Absolute path\n */\nexport function pathInOriginalCwd(path: string): boolean {\n const absolutePath = toAbsolutePath(path)\n const base = toAbsolutePath(getOriginalCwd())\n return isSubpath(base, absolutePath)\n}\n\n/**\n * Check if read permission exists for the specified directory\n * @param directory The directory to check permission for\n * @returns true if read permission exists, false otherwise\n */\nexport function hasReadPermission(directory: string): boolean {\n const absolutePath = toAbsolutePath(directory)\n for (const allowedPath of readFileAllowedDirectories) {\n if (isSubpath(allowedPath, absolutePath)) return true\n }\n return false\n}\n\n/**\n * Check if write permission exists for the specified directory\n * @param directory The directory to check permission for\n * @returns true if write permission exists, false otherwise\n */\nexport function hasWritePermission(directory: string): boolean {\n const absolutePath = toAbsolutePath(directory)\n for (const allowedPath of writeFileAllowedDirectories) {\n if (isSubpath(allowedPath, absolutePath)) return true\n }\n return false\n}\n\n/**\n * Save read permission for a directory\n * @param directory The directory to grant read permission for\n */\nfunction saveReadPermission(directory: string): void {\n const absolutePath = toAbsolutePath(directory)\n // Remove any existing subpaths contained by this new path\n for (const allowedPath of Array.from(readFileAllowedDirectories)) {\n if (isSubpath(absolutePath, allowedPath)) {\n readFileAllowedDirectories.delete(allowedPath)\n }\n }\n readFileAllowedDirectories.add(absolutePath)\n}\n\nexport const saveReadPermissionForTest = saveReadPermission\n\n/**\n * Grants read permission for the original project directory.\n * This is useful for initializing read access to the project root.\n */\nexport function grantReadPermissionForOriginalDir(): void {\n const originalProjectDir = getOriginalCwd()\n saveReadPermission(originalProjectDir)\n}\n\n/**\n * Save write permission for a directory\n * @param directory The directory to grant write permission for\n */\nfunction saveWritePermission(directory: string): void {\n const absolutePath = toAbsolutePath(directory)\n for (const allowedPath of Array.from(writeFileAllowedDirectories)) {\n if (isSubpath(absolutePath, allowedPath)) {\n writeFileAllowedDirectories.delete(allowedPath)\n }\n }\n writeFileAllowedDirectories.add(absolutePath)\n}\n\n/**\n * Grants write permission for the original project directory.\n * This is useful for initializing write access to the project root.\n */\nexport function grantWritePermissionForOriginalDir(): void {\n const originalProjectDir = getOriginalCwd()\n saveWritePermission(originalProjectDir)\n}\n\n// For testing purposes\nexport function clearFilePermissions(): void {\n readFileAllowedDirectories.clear()\n writeFileAllowedDirectories.clear()\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY,SAAS,
|
|
4
|
+
"sourcesContent": ["import { isAbsolute, resolve, relative, dirname } from 'path'\nimport { getCwd, getOriginalCwd } from '@utils/state'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\n\n/**\n * Permission persistence mode\n */\nexport type PermissionPersistenceMode = 'session' | 'project' | 'global'\n\n/**\n * File permission entry for persistent storage\n */\nexport interface FilePermissionEntry {\n /** Path that was granted permission */\n path: string\n /** Type of permission */\n type: 'read' | 'write'\n /** When the permission was granted */\n grantedAt: number\n /** Expiration timestamp (optional) */\n expiresAt?: number\n /** Reason for granting (for audit purposes) */\n reason?: string\n}\n\n// In-memory storage for file permissions that resets each session\n// Sets of allowed directories for read and write operations\nconst readFileAllowedDirectories: Set<string> = new Set()\nconst writeFileAllowedDirectories: Set<string> = new Set()\n\n// Persistent permission entries (loaded from config)\nlet persistentReadPermissions: FilePermissionEntry[] = []\nlet persistentWritePermissions: FilePermissionEntry[] = []\nlet persistentPermissionsLoaded = false\n\n/**\n * Ensures a path is absolute by resolving it relative to cwd if necessary\n * @param path The path to normalize\n * @returns Absolute path\n */\nexport function toAbsolutePath(path: string): string {\n const abs = isAbsolute(path) ? resolve(path) : resolve(getCwd(), path)\n return normalizeForCompare(abs)\n}\n\nfunction normalizeForCompare(p: string): string {\n // Normalize separators and resolve .. and . segments\n const norm = resolve(p)\n // On Windows, comparisons should be case-insensitive\n return process.platform === 'win32' ? norm.toLowerCase() : norm\n}\n\nfunction isSubpath(base: string, target: string): boolean {\n const rel = relative(base, target)\n // If different drive letters on Windows, relative returns the target path\n if (!rel || rel === '') return true\n // Not a subpath if it goes up to parent\n if (rel.startsWith('..')) return false\n // Not a subpath if absolute\n if (isAbsolute(rel)) return false\n return true\n}\n\n/**\n * Ensures a path is in the original cwd path\n * @param directory The directory path to normalize\n * @returns Absolute path\n */\nexport function pathInOriginalCwd(path: string): boolean {\n const absolutePath = toAbsolutePath(path)\n const base = toAbsolutePath(getOriginalCwd())\n return isSubpath(base, absolutePath)\n}\n\n/**\n * Load persistent permissions from project config\n */\nfunction loadPersistentPermissions(): void {\n if (persistentPermissionsLoaded) return\n\n try {\n const config = getCurrentProjectConfig()\n const filePermissions = (config as any).filePermissions as\n | { read?: FilePermissionEntry[]; write?: FilePermissionEntry[] }\n | undefined\n\n if (filePermissions) {\n const now = Date.now()\n\n // Load read permissions (filter out expired)\n persistentReadPermissions = (filePermissions.read || []).filter(\n p => !p.expiresAt || p.expiresAt > now,\n )\n\n // Load write permissions (filter out expired)\n persistentWritePermissions = (filePermissions.write || []).filter(\n p => !p.expiresAt || p.expiresAt > now,\n )\n }\n\n persistentPermissionsLoaded = true\n } catch {\n // Silently fail - use session-only permissions\n persistentPermissionsLoaded = true\n }\n}\n\n/**\n * Save persistent permissions to project config\n */\nfunction savePersistentPermissions(): void {\n try {\n const config = getCurrentProjectConfig()\n\n // Only save if there are permissions to save\n if (\n persistentReadPermissions.length > 0 ||\n persistentWritePermissions.length > 0\n ) {\n ;(config as any).filePermissions = {\n read: persistentReadPermissions,\n write: persistentWritePermissions,\n }\n saveCurrentProjectConfig(config)\n }\n } catch {\n // Silently fail - permissions will work for session only\n }\n}\n\n/**\n * Check if read permission exists for the specified directory\n * @param directory The directory to check permission for\n * @returns true if read permission exists, false otherwise\n */\nexport function hasReadPermission(directory: string): boolean {\n loadPersistentPermissions()\n\n const absolutePath = toAbsolutePath(directory)\n\n // Check session permissions\n for (const allowedPath of readFileAllowedDirectories) {\n if (isSubpath(allowedPath, absolutePath)) return true\n }\n\n // Check persistent permissions\n const now = Date.now()\n for (const entry of persistentReadPermissions) {\n if (entry.expiresAt && entry.expiresAt < now) continue\n const normalizedEntry = toAbsolutePath(entry.path)\n if (isSubpath(normalizedEntry, absolutePath)) return true\n }\n\n return false\n}\n\n/**\n * Check if write permission exists for the specified directory\n * @param directory The directory to check permission for\n * @returns true if write permission exists, false otherwise\n */\nexport function hasWritePermission(directory: string): boolean {\n loadPersistentPermissions()\n\n const absolutePath = toAbsolutePath(directory)\n\n // Check session permissions\n for (const allowedPath of writeFileAllowedDirectories) {\n if (isSubpath(allowedPath, absolutePath)) return true\n }\n\n // Check persistent permissions\n const now = Date.now()\n for (const entry of persistentWritePermissions) {\n if (entry.expiresAt && entry.expiresAt < now) continue\n const normalizedEntry = toAbsolutePath(entry.path)\n if (isSubpath(normalizedEntry, absolutePath)) return true\n }\n\n return false\n}\n\n/**\n * Save read permission for a directory\n * @param directory The directory to grant read permission for\n * @param persist Whether to persist the permission (default: session only)\n * @param expiresIn Optional expiration time in milliseconds\n * @param reason Optional reason for granting permission\n */\nexport function saveReadPermission(\n directory: string,\n persist: boolean = false,\n expiresIn?: number,\n reason?: string,\n): void {\n const absolutePath = toAbsolutePath(directory)\n\n // Remove any existing subpaths contained by this new path\n for (const allowedPath of Array.from(readFileAllowedDirectories)) {\n if (isSubpath(absolutePath, allowedPath)) {\n readFileAllowedDirectories.delete(allowedPath)\n }\n }\n readFileAllowedDirectories.add(absolutePath)\n\n // Handle persistence\n if (persist) {\n loadPersistentPermissions()\n\n const entry: FilePermissionEntry = {\n path: absolutePath,\n type: 'read',\n grantedAt: Date.now(),\n expiresAt: expiresIn ? Date.now() + expiresIn : undefined,\n reason,\n }\n\n // Remove existing entry for same path\n persistentReadPermissions = persistentReadPermissions.filter(\n p => toAbsolutePath(p.path) !== absolutePath,\n )\n persistentReadPermissions.push(entry)\n savePersistentPermissions()\n }\n}\n\nexport const saveReadPermissionForTest = saveReadPermission\n\n/**\n * Grants read permission for the original project directory.\n * This is useful for initializing read access to the project root.\n */\nexport function grantReadPermissionForOriginalDir(): void {\n const originalProjectDir = getOriginalCwd()\n saveReadPermission(originalProjectDir, false)\n}\n\n/**\n * Save write permission for a directory\n * @param directory The directory to grant write permission for\n * @param persist Whether to persist the permission (default: session only)\n * @param expiresIn Optional expiration time in milliseconds\n * @param reason Optional reason for granting permission\n */\nexport function saveWritePermission(\n directory: string,\n persist: boolean = false,\n expiresIn?: number,\n reason?: string,\n): void {\n const absolutePath = toAbsolutePath(directory)\n\n for (const allowedPath of Array.from(writeFileAllowedDirectories)) {\n if (isSubpath(absolutePath, allowedPath)) {\n writeFileAllowedDirectories.delete(allowedPath)\n }\n }\n writeFileAllowedDirectories.add(absolutePath)\n\n // Handle persistence\n if (persist) {\n loadPersistentPermissions()\n\n const entry: FilePermissionEntry = {\n path: absolutePath,\n type: 'write',\n grantedAt: Date.now(),\n expiresAt: expiresIn ? Date.now() + expiresIn : undefined,\n reason,\n }\n\n // Remove existing entry for same path\n persistentWritePermissions = persistentWritePermissions.filter(\n p => toAbsolutePath(p.path) !== absolutePath,\n )\n persistentWritePermissions.push(entry)\n savePersistentPermissions()\n }\n}\n\n/**\n * Grants write permission for the original project directory.\n * This is useful for initializing write access to the project root.\n */\nexport function grantWritePermissionForOriginalDir(): void {\n const originalProjectDir = getOriginalCwd()\n saveWritePermission(originalProjectDir, false)\n}\n\n/**\n * Grant permission for a specific file path\n * @param filePath The file path to grant permission for\n * @param type Permission type (read or write)\n * @param persist Whether to persist the permission\n * @param expiresIn Optional expiration time in milliseconds\n * @param reason Optional reason for granting permission\n */\nexport function grantFilePermission(\n filePath: string,\n type: 'read' | 'write',\n persist: boolean = false,\n expiresIn?: number,\n reason?: string,\n): void {\n // Grant permission to the file's directory\n const dir = dirname(toAbsolutePath(filePath))\n\n if (type === 'read') {\n saveReadPermission(dir, persist, expiresIn, reason)\n } else {\n saveWritePermission(dir, persist, expiresIn, reason)\n }\n}\n\n/**\n * Revoke a specific persistent permission\n * @param path The path to revoke permission for\n * @param type Permission type (read or write)\n */\nexport function revokePersistentPermission(\n path: string,\n type: 'read' | 'write',\n): boolean {\n loadPersistentPermissions()\n\n const absolutePath = toAbsolutePath(path)\n let found = false\n\n if (type === 'read') {\n const before = persistentReadPermissions.length\n persistentReadPermissions = persistentReadPermissions.filter(\n p => toAbsolutePath(p.path) !== absolutePath,\n )\n found = persistentReadPermissions.length < before\n } else {\n const before = persistentWritePermissions.length\n persistentWritePermissions = persistentWritePermissions.filter(\n p => toAbsolutePath(p.path) !== absolutePath,\n )\n found = persistentWritePermissions.length < before\n }\n\n if (found) {\n savePersistentPermissions()\n }\n\n return found\n}\n\n/**\n * Get all persistent permissions\n */\nexport function getPersistentPermissions(): {\n read: FilePermissionEntry[]\n write: FilePermissionEntry[]\n} {\n loadPersistentPermissions()\n return {\n read: [...persistentReadPermissions],\n write: [...persistentWritePermissions],\n }\n}\n\n/**\n * Clear all expired persistent permissions\n */\nexport function clearExpiredPermissions(): number {\n loadPersistentPermissions()\n\n const now = Date.now()\n const beforeRead = persistentReadPermissions.length\n const beforeWrite = persistentWritePermissions.length\n\n persistentReadPermissions = persistentReadPermissions.filter(\n p => !p.expiresAt || p.expiresAt > now,\n )\n persistentWritePermissions = persistentWritePermissions.filter(\n p => !p.expiresAt || p.expiresAt > now,\n )\n\n const cleared =\n beforeRead -\n persistentReadPermissions.length +\n (beforeWrite - persistentWritePermissions.length)\n\n if (cleared > 0) {\n savePersistentPermissions()\n }\n\n return cleared\n}\n\n// For testing purposes\nexport function clearFilePermissions(): void {\n readFileAllowedDirectories.clear()\n writeFileAllowedDirectories.clear()\n persistentReadPermissions = []\n persistentWritePermissions = []\n persistentPermissionsLoaded = false\n}\n\n/**\n * Reload persistent permissions (useful after config changes)\n */\nexport function reloadPersistentPermissions(): void {\n persistentPermissionsLoaded = false\n loadPersistentPermissions()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync } from "fs";
|
|
2
|
+
import { randomBytes } from "crypto";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
const DEFAULT_CONVERSATION_KEY = "default";
|
|
6
|
+
const MAX_SLUG_ATTEMPTS = 10;
|
|
7
|
+
const PLAN_SLUG_ADJECTIVES = [
|
|
8
|
+
"agile",
|
|
9
|
+
"bold",
|
|
10
|
+
"calm",
|
|
11
|
+
"deft",
|
|
12
|
+
"eager",
|
|
13
|
+
"fast",
|
|
14
|
+
"grand",
|
|
15
|
+
"keen",
|
|
16
|
+
"neat",
|
|
17
|
+
"prime",
|
|
18
|
+
"quick",
|
|
19
|
+
"sharp",
|
|
20
|
+
"swift",
|
|
21
|
+
"vast",
|
|
22
|
+
"wise"
|
|
23
|
+
];
|
|
24
|
+
const PLAN_SLUG_VERBS = [
|
|
25
|
+
"build",
|
|
26
|
+
"craft",
|
|
27
|
+
"design",
|
|
28
|
+
"draft",
|
|
29
|
+
"forge",
|
|
30
|
+
"guide",
|
|
31
|
+
"map",
|
|
32
|
+
"plan",
|
|
33
|
+
"plot",
|
|
34
|
+
"shape",
|
|
35
|
+
"sketch",
|
|
36
|
+
"trace",
|
|
37
|
+
"weave"
|
|
38
|
+
];
|
|
39
|
+
const PLAN_SLUG_NOUNS = [
|
|
40
|
+
"arch",
|
|
41
|
+
"code",
|
|
42
|
+
"flow",
|
|
43
|
+
"form",
|
|
44
|
+
"grid",
|
|
45
|
+
"path",
|
|
46
|
+
"plan",
|
|
47
|
+
"route",
|
|
48
|
+
"scheme",
|
|
49
|
+
"scope",
|
|
50
|
+
"shape",
|
|
51
|
+
"sketch",
|
|
52
|
+
"spec"
|
|
53
|
+
];
|
|
54
|
+
const planModeEnabledByConversationKey = /* @__PURE__ */ new Map();
|
|
55
|
+
const planSlugCache = /* @__PURE__ */ new Map();
|
|
56
|
+
function getConversationKey(context) {
|
|
57
|
+
const messageLogName = context?.options?.messageLogName ?? DEFAULT_CONVERSATION_KEY;
|
|
58
|
+
const forkNumber = context?.options?.forkNumber ?? 0;
|
|
59
|
+
return `${messageLogName}:${forkNumber}`;
|
|
60
|
+
}
|
|
61
|
+
function getPlanConversationKey(context) {
|
|
62
|
+
return getConversationKey(context);
|
|
63
|
+
}
|
|
64
|
+
function pickIndex(length) {
|
|
65
|
+
return randomBytes(4).readUInt32BE(0) % length;
|
|
66
|
+
}
|
|
67
|
+
function pickWord(words) {
|
|
68
|
+
return words[pickIndex(words.length)];
|
|
69
|
+
}
|
|
70
|
+
function generateSlug() {
|
|
71
|
+
const adjective = pickWord(PLAN_SLUG_ADJECTIVES);
|
|
72
|
+
const verb = pickWord(PLAN_SLUG_VERBS);
|
|
73
|
+
const noun = pickWord(PLAN_SLUG_NOUNS);
|
|
74
|
+
return `${adjective}-${verb}-${noun}`;
|
|
75
|
+
}
|
|
76
|
+
function getOrCreatePlanSlug(conversationKey) {
|
|
77
|
+
const existing = planSlugCache.get(conversationKey);
|
|
78
|
+
if (existing) return existing;
|
|
79
|
+
const dir = getPlanDirectory();
|
|
80
|
+
let slug = null;
|
|
81
|
+
for (let attempt = 0; attempt < MAX_SLUG_ATTEMPTS; attempt++) {
|
|
82
|
+
slug = generateSlug();
|
|
83
|
+
const path = join(dir, `${slug}.md`);
|
|
84
|
+
if (!existsSync(path)) break;
|
|
85
|
+
}
|
|
86
|
+
if (!slug) slug = generateSlug();
|
|
87
|
+
planSlugCache.set(conversationKey, slug);
|
|
88
|
+
return slug;
|
|
89
|
+
}
|
|
90
|
+
function getPlanDirectory() {
|
|
91
|
+
const dir = join(homedir(), ".minto", "plans");
|
|
92
|
+
if (!existsSync(dir)) {
|
|
93
|
+
mkdirSync(dir, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
return dir;
|
|
96
|
+
}
|
|
97
|
+
function getPlanFilePath(agentId, conversationKey) {
|
|
98
|
+
const dir = getPlanDirectory();
|
|
99
|
+
const key = conversationKey ?? DEFAULT_CONVERSATION_KEY;
|
|
100
|
+
const slug = getOrCreatePlanSlug(key);
|
|
101
|
+
if (!agentId) return join(dir, `${slug}.md`);
|
|
102
|
+
return join(dir, `${slug}-agent-${agentId}.md`);
|
|
103
|
+
}
|
|
104
|
+
function isPlanModeEnabled(context) {
|
|
105
|
+
const key = getConversationKey(context);
|
|
106
|
+
return planModeEnabledByConversationKey.get(key) ?? false;
|
|
107
|
+
}
|
|
108
|
+
function enterPlanMode(context) {
|
|
109
|
+
const key = getConversationKey(context);
|
|
110
|
+
planModeEnabledByConversationKey.set(key, true);
|
|
111
|
+
return { planFilePath: getPlanFilePath(context?.agentId, key) };
|
|
112
|
+
}
|
|
113
|
+
function exitPlanMode(context) {
|
|
114
|
+
const key = getConversationKey(context);
|
|
115
|
+
planModeEnabledByConversationKey.set(key, false);
|
|
116
|
+
return { planFilePath: getPlanFilePath(context?.agentId, key) };
|
|
117
|
+
}
|
|
118
|
+
function readPlanFile(agentId, conversationKey) {
|
|
119
|
+
const planFilePath = getPlanFilePath(agentId, conversationKey);
|
|
120
|
+
if (!existsSync(planFilePath)) {
|
|
121
|
+
return { content: "", exists: false, planFilePath };
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
content: readFileSync(planFilePath, "utf8"),
|
|
125
|
+
exists: true,
|
|
126
|
+
planFilePath
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function __resetPlanModeForTests() {
|
|
130
|
+
planModeEnabledByConversationKey.clear();
|
|
131
|
+
planSlugCache.clear();
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
__resetPlanModeForTests,
|
|
135
|
+
enterPlanMode,
|
|
136
|
+
exitPlanMode,
|
|
137
|
+
getPlanConversationKey,
|
|
138
|
+
getPlanDirectory,
|
|
139
|
+
getPlanFilePath,
|
|
140
|
+
isPlanModeEnabled,
|
|
141
|
+
readPlanFile
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=planMode.js.map
|