@within-7/minto 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Tool.js +7 -0
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +1 -1
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +2 -2
- package/dist/commands/agents/constants.js.map +2 -2
- package/dist/commands/clear.js +4 -3
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +2 -2
- package/dist/commands/compact.js.map +1 -1
- package/dist/commands/context.js +3 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/memory.js +33 -82
- package/dist/commands/memory.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/resume.js +39 -239
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/tasks.js +1 -1
- package/dist/commands/tasks.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -2
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentDetailView.js +126 -0
- package/dist/components/AgentDetailView.js.map +7 -0
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AgentViewBanner.js +22 -0
- package/dist/components/AgentViewBanner.js.map +7 -0
- package/dist/components/HeaderBar.js +1 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +8 -1
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +26 -8
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/IdleNotificationBar.js +10 -0
- package/dist/components/IdleNotificationBar.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +55 -20
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/PromptInput.js +186 -115
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RewindPanel.js +272 -0
- package/dist/components/RewindPanel.js.map +7 -0
- package/dist/components/Spinner.js +10 -21
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StreamingTextPreview.js +29 -0
- package/dist/components/StreamingTextPreview.js.map +7 -0
- package/dist/components/SubagentBlock.js +3 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +4 -4
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TabbedListView/SearchInput.js +1 -1
- package/dist/components/TabbedListView/SearchInput.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +87 -41
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TaskCard.js +4 -4
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TeamMemberPanel.js +107 -0
- package/dist/components/TeamMemberPanel.js.map +7 -0
- package/dist/components/ThinkingSelector.js +84 -0
- package/dist/components/ThinkingSelector.js.map +7 -0
- package/dist/components/TitledDivider.js +26 -0
- package/dist/components/TitledDivider.js.map +7 -0
- package/dist/components/TodoPanel.js +31 -30
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/TokenWarning.js +28 -7
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +5 -2
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +9 -1
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/DefaultToolResultFallback.js +11 -0
- package/dist/components/messages/DefaultToolResultFallback.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +14 -6
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +27 -27
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/UserGuidanceMessage.js +26 -0
- package/dist/components/messages/UserGuidanceMessage.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserTeamNotificationMessage.js +91 -0
- package/dist/components/messages/UserTeamNotificationMessage.js.map +7 -0
- package/dist/components/messages/UserTextMessage.js +8 -0
- package/dist/components/messages/UserTextMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +4 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +18 -1
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +12 -1
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/PermissionRequest.js +4 -0
- package/dist/components/permissions/PermissionRequest.js.map +2 -2
- package/dist/components/permissions/PlanApprovalRequest.js +164 -0
- package/dist/components/permissions/PlanApprovalRequest.js.map +7 -0
- package/dist/constants/agentTeams.js +17 -0
- package/dist/constants/agentTeams.js.map +7 -0
- package/dist/constants/macros.js +2 -1
- package/dist/constants/macros.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +1 -0
- package/dist/constants/prompts/agentPrompt.js.map +2 -2
- package/dist/constants/prompts/autoMemory.js +39 -0
- package/dist/constants/prompts/autoMemory.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +1 -13
- package/dist/constants/prompts/codeConventions.js.map +2 -2
- package/dist/constants/prompts/doingTasks.js +21 -2
- package/dist/constants/prompts/doingTasks.js.map +2 -2
- package/dist/constants/prompts/envInfo.js +6 -7
- package/dist/constants/prompts/envInfo.js.map +2 -2
- package/dist/constants/prompts/index.js +27 -5
- package/dist/constants/prompts/index.js.map +2 -2
- package/dist/constants/prompts/taskManagement.js +2 -43
- package/dist/constants/prompts/taskManagement.js.map +2 -2
- package/dist/constants/prompts/teamOverlays.js +50 -0
- package/dist/constants/prompts/teamOverlays.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +4 -29
- package/dist/constants/prompts/toneAndStyle.js.map +2 -2
- package/dist/constants/prompts/toolUsagePolicy.js +7 -22
- package/dist/constants/prompts/toolUsagePolicy.js.map +2 -2
- package/dist/constants/toolInputExamples.js +2 -2
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/context.js +39 -6
- package/dist/context.js.map +2 -2
- package/dist/core/backupManager.js +1 -1
- package/dist/core/backupManager.js.map +2 -2
- package/dist/core/permissions/rules/planModeRule.js +1 -1
- package/dist/core/permissions/rules/planModeRule.js.map +1 -1
- package/dist/core/permissions/rules/safeModeRule.js +1 -1
- package/dist/core/permissions/rules/safeModeRule.js.map +1 -1
- package/dist/engine/AgentEngine.js +902 -0
- package/dist/engine/AgentEngine.js.map +7 -0
- package/dist/engine/EngineRegistry.js +89 -0
- package/dist/engine/EngineRegistry.js.map +7 -0
- package/dist/engine/foregroundAdapter.js +191 -0
- package/dist/engine/foregroundAdapter.js.map +7 -0
- package/dist/engine/index.js +15 -0
- package/dist/engine/index.js.map +7 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/types.js.map +7 -0
- package/dist/entrypoints/cli.js +410 -79
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/hooks/useAgentEngine.js +129 -0
- package/dist/hooks/useAgentEngine.js.map +7 -0
- package/dist/hooks/useAgentTokenStats.js +0 -16
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +47 -2
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +4 -1
- package/dist/hooks/useDeferredLoading.js.map +2 -2
- package/dist/hooks/useIdleNotifications.js +66 -0
- package/dist/hooks/useIdleNotifications.js.map +7 -0
- package/dist/hooks/useSessionTracking.js +9 -7
- package/dist/hooks/useSessionTracking.js.map +2 -2
- package/dist/hooks/useTeamMembers.js +51 -0
- package/dist/hooks/useTeamMembers.js.map +7 -0
- package/dist/i18n/locales/en.js +77 -12
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +77 -12
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +113 -7
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +135 -37
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +504 -361
- package/dist/screens/REPL.js.map +3 -3
- package/dist/screens/ResumeConversation.js +199 -14
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/adapters/base.js.map +1 -1
- package/dist/services/agentTeams/backends/headless.js +108 -0
- package/dist/services/agentTeams/backends/headless.js.map +7 -0
- package/dist/services/agentTeams/backends/inProcess.js +102 -0
- package/dist/services/agentTeams/backends/inProcess.js.map +7 -0
- package/dist/services/agentTeams/backends/resolver.js +18 -0
- package/dist/services/agentTeams/backends/resolver.js.map +7 -0
- package/dist/services/agentTeams/backends/tmux.js +168 -0
- package/dist/services/agentTeams/backends/tmux.js.map +7 -0
- package/dist/services/agentTeams/backends/types.js +1 -0
- package/dist/services/agentTeams/backends/types.js.map +7 -0
- package/dist/services/agentTeams/heartbeat.js +88 -0
- package/dist/services/agentTeams/heartbeat.js.map +7 -0
- package/dist/services/agentTeams/index.js +42 -2
- package/dist/services/agentTeams/index.js.map +2 -2
- package/dist/services/agentTeams/injectionChannel.js +105 -0
- package/dist/services/agentTeams/injectionChannel.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +410 -30
- package/dist/services/agentTeams/mailbox.js.map +2 -2
- package/dist/services/agentTeams/messageFormatter.js +80 -0
- package/dist/services/agentTeams/messageFormatter.js.map +7 -0
- package/dist/services/agentTeams/permissionDelegation.js +71 -0
- package/dist/services/agentTeams/permissionDelegation.js.map +7 -0
- package/dist/services/agentTeams/teamEvents.js +45 -0
- package/dist/services/agentTeams/teamEvents.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +251 -34
- package/dist/services/agentTeams/teamManager.js.map +2 -2
- package/dist/services/agentTeams/teamTaskStore.js +290 -61
- package/dist/services/agentTeams/teamTaskStore.js.map +2 -2
- package/dist/services/agentTeams/teammateSpawner.js +99 -18
- package/dist/services/agentTeams/teammateSpawner.js.map +2 -2
- package/dist/services/hookExecutor.js +51 -8
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +56 -59
- package/dist/services/llm/anthropicProvider.js.map +2 -2
- package/dist/services/llm/dispatch.js +24 -5
- package/dist/services/llm/dispatch.js.map +2 -2
- package/dist/services/llm/openaiProvider.js +115 -136
- package/dist/services/llm/openaiProvider.js.map +3 -3
- package/dist/services/llm/types.js +89 -15
- package/dist/services/llm/types.js.map +2 -2
- package/dist/services/mcpClient.js +80 -4
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/mintoAuth.js +299 -0
- package/dist/services/mintoAuth.js.map +7 -0
- package/dist/services/oauth.js +3 -3
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +91 -20
- package/dist/services/openai.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +11 -5
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +4 -2
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/sandbox/sandboxController.js +11 -3
- package/dist/services/sandbox/sandboxController.js.map +2 -2
- package/dist/services/sessionMemoryInjector.js +77 -0
- package/dist/services/sessionMemoryInjector.js.map +7 -0
- package/dist/services/systemReminder.js +130 -8
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +199 -8
- package/dist/services/taskStore.js.map +3 -3
- package/dist/services/topicDetector.js +169 -0
- package/dist/services/topicDetector.js.map +7 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +0 -13
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +51 -28
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +95 -118
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/BashTool/utils.js +39 -1
- package/dist/tools/BashTool/utils.js.map +2 -2
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js +121 -0
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js.map +7 -0
- package/dist/tools/EnterWorktreeTool/prompt.js +22 -0
- package/dist/tools/EnterWorktreeTool/prompt.js.map +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js +9 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +3 -7
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +125 -3
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileReadTool/prompt.js +1 -2
- package/dist/tools/FileReadTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +3 -5
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +3 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +16 -5
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/MCPSearchTool/MCPSearchTool.js +172 -0
- package/dist/tools/MCPSearchTool/MCPSearchTool.js.map +7 -0
- package/dist/tools/MCPSearchTool/prompt.js +77 -0
- package/dist/tools/MCPSearchTool/prompt.js.map +7 -0
- package/dist/tools/MultiEditTool/prompt.js +4 -7
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +12 -8
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +54 -1
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +23 -74
- package/dist/tools/PlanModeTool/prompt.js.map +2 -2
- package/dist/tools/SendMessageTool/SendMessageTool.js +341 -0
- package/dist/tools/SendMessageTool/SendMessageTool.js.map +7 -0
- package/dist/tools/SendMessageTool/prompt.js +44 -0
- package/dist/tools/SendMessageTool/prompt.js.map +7 -0
- package/dist/tools/TaskCreateTool/prompt.js +15 -4
- package/dist/tools/TaskCreateTool/prompt.js.map +2 -2
- package/dist/tools/TaskListTool/prompt.js +18 -3
- package/dist/tools/TaskListTool/prompt.js.map +2 -2
- package/dist/tools/TaskOutputTool/prompt.js +4 -3
- package/dist/tools/TaskOutputTool/prompt.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +762 -98
- package/dist/tools/TaskTool/TaskTool.js.map +3 -3
- package/dist/tools/TaskTool/constants.js +8 -2
- package/dist/tools/TaskTool/constants.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +74 -70
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js +15 -1
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +2 -2
- package/dist/tools/TeamCreateTool/TeamCreateTool.js +129 -0
- package/dist/tools/TeamCreateTool/TeamCreateTool.js.map +7 -0
- package/dist/tools/TeamCreateTool/prompt.js +58 -0
- package/dist/tools/TeamCreateTool/prompt.js.map +7 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js +151 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js.map +7 -0
- package/dist/tools/TeamDeleteTool/prompt.js +16 -0
- package/dist/tools/TeamDeleteTool/prompt.js.map +7 -0
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +106 -15
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +3 -2
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js +2 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +5 -4
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/tools.js +100 -20
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +35 -6
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/hooks.js +2 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +2 -0
- package/dist/types/plugin.js.map +3 -3
- package/dist/utils/CircuitBreaker.js +15 -9
- package/dist/utils/CircuitBreaker.js.map +2 -2
- package/dist/utils/agentLoader.js +249 -112
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/animationManager.js +40 -3
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +7 -6
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/atomicWrite.js +23 -0
- package/dist/utils/atomicWrite.js.map +7 -0
- package/dist/utils/autoCompactCore.js +73 -56
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/autoMemoryPaths.js +89 -0
- package/dist/utils/autoMemoryPaths.js.map +7 -0
- package/dist/utils/config.js +63 -38
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +13 -8
- package/dist/utils/configSchema.js.map +2 -2
- package/dist/utils/credentials/index.js +14 -0
- package/dist/utils/credentials/index.js.map +2 -2
- package/dist/utils/dualPath.js +24 -0
- package/dist/utils/dualPath.js.map +7 -0
- package/dist/utils/exit.js +66 -7
- package/dist/utils/exit.js.map +2 -2
- package/dist/utils/externalEditor.js +155 -0
- package/dist/utils/externalEditor.js.map +7 -0
- package/dist/utils/fileLock.js +67 -0
- package/dist/utils/fileLock.js.map +7 -0
- package/dist/utils/format.js +24 -14
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +5 -96
- package/dist/utils/globalErrorHandler.js.map +3 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js +5 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +2 -2
- package/dist/utils/groupHandlers/taskHandler.js +2 -2
- package/dist/utils/groupHandlers/taskHandler.js.map +2 -2
- package/dist/utils/hookManager.js +64 -6
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/log.js +6 -2
- package/dist/utils/log.js.map +2 -2
- package/dist/utils/markdown.js +237 -19
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/messageContextManager.js +18 -5
- package/dist/utils/messageContextManager.js.map +2 -2
- package/dist/utils/messageGroupManager.js +1 -1
- package/dist/utils/messageGroupManager.js.map +2 -2
- package/dist/utils/messages.js +104 -46
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +2 -2
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pasteCache.js +8 -4
- package/dist/utils/pasteCache.js.map +2 -2
- package/dist/utils/pluginLoader.js +18 -0
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/secureKeyStorage.js +36 -7
- package/dist/utils/secureKeyStorage.js.map +2 -2
- package/dist/utils/simpleMode.js +7 -0
- package/dist/utils/simpleMode.js.map +7 -0
- package/dist/utils/streamingState.js +11 -1
- package/dist/utils/streamingState.js.map +2 -2
- package/dist/utils/taskDisplayUtils.js +2 -1
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/teamConfig.js +2 -2
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/thinking.js +6 -2
- package/dist/utils/thinking.js.map +3 -3
- package/dist/utils/tokenProgress.js +55 -0
- package/dist/utils/tokenProgress.js.map +7 -0
- package/dist/utils/toolRiskClassification.js +26 -17
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/utils/tooling/toolError.js +12 -0
- package/dist/utils/tooling/toolError.js.map +7 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +10 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/taskDisplayUtils.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Task Display Utilities\n *\n * Utilities for computing task display content with truncation rules.\n * Implements V3's intermediate state display logic.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { AgentTranscript } from './agentTranscripts'\nimport type {\n DisplayConfig,\n TaskDisplayContent,\n} from '@minto-types/messageGroup'\nimport { getAgentTranscript, getAgentIdByToolUseId } from './agentTranscripts'\nimport { SEMANTIC_COLORS, SYMBOL_COLORS } from '@constants/colors'\nimport { SYMBOLS } from '@constants/symbols'\n\n/**\n * Get the latest text output from a transcript\n */\nexport function getLatestOutput(transcript: AgentTranscript): string {\n const messages = transcript.messages\n\n // Search from the end for the most recent text output\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n const textBlock = content.find(b => b.type === 'text')\n if (textBlock && 'text' in textBlock) {\n return textBlock.text\n }\n }\n }\n\n return ''\n}\n\n/**\n * Get all nested Task transcripts from a parent transcript\n */\nexport function getNestedTasks(transcript: AgentTranscript): AgentTranscript[] {\n const nested: AgentTranscript[] = []\n\n for (const msg of transcript.messages) {\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'Task') {\n const toolUse = block as ToolUseBlockParam\n const nestedAgentId = getAgentIdByToolUseId(toolUse.id)\n if (nestedAgentId) {\n const nestedTranscript = getAgentTranscript(nestedAgentId)\n if (nestedTranscript) {\n nested.push(nestedTranscript)\n }\n }\n }\n }\n }\n }\n\n return nested\n}\n\n/**\n * Truncate text to specified length with ellipsis\n */\nexport function truncate(text: string, maxLength: number): string {\n if (!text) return ''\n // Clean up whitespace\n const cleaned = text.trim().replace(/\\n+/g, ' ').replace(/\\s+/g, ' ')\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength - 3) + '...'\n}\n\n/**\n * Get task display content with truncation rules (from V3)\n */\nexport function getTaskDisplayContent(\n transcript: AgentTranscript,\n config: DisplayConfig,\n): TaskDisplayContent {\n const nestedTasks = getNestedTasks(transcript)\n\n if (nestedTasks.length === 0) {\n // No children: show latest output, truncated\n const latestOutput = getLatestOutput(transcript)\n return {\n type: 'simple',\n content: truncate(latestOutput, config.maxCharsWithoutChildren),\n }\n }\n\n // Has children: show recent children based on config\n const tasksToShow = config.showAllChildren\n ? nestedTasks\n : nestedTasks.slice(-config.maxRecentChildren)\n\n const children = tasksToShow.map(task => ({\n description: task.description,\n status: task.status,\n content: truncate(getLatestOutput(task), config.maxCharsPerChild),\n }))\n\n return {\n type: 'nested',\n children,\n hiddenCount: nestedTasks.length - tasksToShow.length,\n }\n}\n\n/**\n * Get status icon for a task status\n * \u9075\u5FAA REPL \u89C4\u8303\uFF1A\n * - pending: \u25CB (\u7A7A\u5FC3\u5706)\n * - running: \u25D0 (\u534A\u5706\uFF0CTOOL_RUNNING)\n * - completed: \u2713 (\u52FE\uFF0CTOOL_SUCCESS)\n * - failed: \u2717 (\u53C9\uFF0CTOOL_ERROR)\n */\nexport function getStatusIcon(status: string): string {\n switch (status) {\n case 'pending':\n return '\u25CB' // \u7A7A\u5FC3\u5706 - pending\n case 'running':\n return SYMBOLS.TOOL_RUNNING // \u25D0 \u534A\u5706 - in progress\n case 'completed':\n return SYMBOLS.TOOL_SUCCESS // \u2713 \u52FE - completed\n case 'failed':\n return SYMBOLS.TOOL_ERROR // \u2717 - failed\n case 'interrupted':\n return '\u2298'\n default:\n return '\u25CB'\n }\n}\n\n/**\n * Get status color for a task status\n * \u4F7F\u7528 SYMBOL_COLORS \u4E0E Logo \u54C1\u724C\u914D\u8272\u4FDD\u6301\u4E00\u81F4\n */\nexport function getStatusColor(status: string): string {\n switch (status) {\n case 'pending':\n return SYMBOL_COLORS.pending\n case 'running':\n return SYMBOL_COLORS.running\n case 'completed':\n return SYMBOL_COLORS.success\n case 'failed':\n return SYMBOL_COLORS.error\n case 'interrupted':\n return SYMBOL_COLORS.pending\n default:\n return SYMBOL_COLORS.pending\n }\n}\n\n// ============================================================================\n// \u5143\u4FE1\u606F\u683C\u5F0F\u5316 (Meta Info Formatting)\n// \u57FA\u4E8E REPL \u663E\u793A\u89C4\u8303\uFF1A\u8017\u65F6 \u00B7 \u6A21\u578B \u00B7 \u65F6\u95F4\n// ============================================================================\n\n/**\n * \u5143\u4FE1\u606F\u6570\u636E\u7ED3\u6784\n */\nexport interface MetaInfo {\n /** \u8017\u65F6\uFF08\u6BEB\u79D2\uFF09 */\n duration?: number\n /** \u6A21\u578B\u540D\u79F0 */\n model?: string\n /** \u65F6\u95F4\u6233 */\n timestamp?: Date | number\n}\n\n/**\n * \u683C\u5F0F\u5316\u8017\u65F6\n * - < 60s: X.Xs (\u5982 2.4s)\n * - >= 60s: Xm Xs (\u5982 1m 23s)\n * - \u672A\u77E5: --\n */\nexport function formatDuration(durationMs?: number): string {\n if (durationMs === undefined || durationMs === null) {\n return '--'\n }\n\n const seconds = durationMs / 1000\n\n if (seconds < 60) {\n // \u5C0F\u4E8E 60 \u79D2\uFF0C\u663E\u793A X.Xs\n return `${seconds.toFixed(1)}s`\n }\n\n // \u5927\u4E8E\u7B49\u4E8E 60 \u79D2\uFF0C\u663E\u793A Xm Xs\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = Math.floor(seconds % 60)\n return `${minutes}m ${remainingSeconds}s`\n}\n\n/**\n * \u683C\u5F0F\u5316\u6A21\u578B\u540D\u79F0\uFF08\u7B80\u5199\uFF09\n * - claude-3-opus-20240229 -> opus\n * - claude-3-sonnet-20240229 -> sonnet\n * - glm-4.7 -> glm-4.7\n */\nexport function formatModelName(model?: string): string {\n if (!model) return ''\n\n // Claude \u6A21\u578B\u7B80\u5199\n if (model.includes('opus')) return 'opus'\n if (model.includes('sonnet')) return 'sonnet'\n if (model.includes('haiku')) return 'haiku'\n\n // \u5176\u4ED6\u6A21\u578B\u4FDD\u6301\u539F\u6837\u6216\u622A\u65AD\n // \u5982\u679C\u540D\u79F0\u592A\u957F\uFF0C\u53D6\u6700\u540E\u4E00\u90E8\u5206\n const parts = model.split('-')\n if (parts.length > 2 && model.length > 15) {\n // \u5C1D\u8BD5\u63D0\u53D6\u6709\u610F\u4E49\u7684\u90E8\u5206\n return parts.slice(0, 2).join('-')\n }\n\n return model\n}\n\n/**\n * \u683C\u5F0F\u5316\u65F6\u95F4\u6233\n * \u683C\u5F0F: H:MM (24\u5C0F\u65F6\u5236)\n */\nexport function formatTimestamp(timestamp?: Date | number): string {\n if (!timestamp) return ''\n\n const date = timestamp instanceof Date ? timestamp : new Date(timestamp)\n const hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n\n return `${hours}:${minutes}`\n}\n\n/**\n * \u683C\u5F0F\u5316\u5143\u4FE1\u606F\n *\n * \u89C4\u5219\uFF1A\n * - \u6709\u8017\u65F6\uFF1A\u8017\u65F6 \u00B7 \u6A21\u578B \u00B7 \u65F6\u95F4 (\u5982 \"2.4s \u00B7 glm-4.7 \u00B7 9:21\")\n * - \u65E0\u8017\u65F6\uFF1A\u6A21\u578B \u00B7 \u65F6\u95F4 (\u5982 \"glm-4.7 \u00B7 9:21\")\n *\n * @param meta - \u5143\u4FE1\u606F\u5BF9\u8C61\n * @returns \u683C\u5F0F\u5316\u540E\u7684\u5B57\u7B26\u4E32\uFF0C\u5982\u679C\u6CA1\u6709\u4EFB\u4F55\u4FE1\u606F\u5219\u8FD4\u56DE\u7A7A\u5B57\u7B26\u4E32\n */\nexport function formatMetaInfo(meta: MetaInfo): string {\n const parts: string[] = []\n\n // \u6709\u8017\u65F6\u65F6\uFF0C\u8017\u65F6\u653E\u5728\u6700\u524D\u9762\n if (meta.duration !== undefined && meta.duration !== null) {\n parts.push(formatDuration(meta.duration))\n }\n\n // \u6A21\u578B\u540D\u79F0\n const modelName = formatModelName(meta.model)\n if (modelName) {\n parts.push(modelName)\n }\n\n // \u65F6\u95F4\u6233\n const time = formatTimestamp(meta.timestamp)\n if (time) {\n parts.push(time)\n }\n\n // \u4F7F\u7528 \" \u00B7 \" \u5206\u9694\n return parts.join(' \u00B7 ')\n}\n\n/**\n * Tool use history item\n */\nexport interface ToolUseHistoryItem {\n /** Tool name */\n name: string\n /** Tool use ID */\n id: string\n /** Brief description of what the tool did */\n description: string\n /** Timestamp (message index for ordering) */\n messageIndex: number\n /** Whether this tool is currently executing (no result yet) */\n isExecuting?: boolean\n}\n\n/**\n * Get tool use history from a transcript\n * Returns tool uses in chronological order (oldest first)\n * Also marks tools that are currently executing (no result yet)\n */\nexport function getToolUseHistory(\n transcript: AgentTranscript,\n): ToolUseHistoryItem[] {\n const history: ToolUseHistoryItem[] = []\n\n // Collect all tool_result IDs to identify completed tools\n const completedToolIds = new Set<string>()\n for (const msg of transcript.messages) {\n if (msg.type === 'user') {\n const content = msg.message.content\n if (!Array.isArray(content)) continue\n\n for (const block of content) {\n if (block.type === 'tool_result' && 'tool_use_id' in block) {\n completedToolIds.add(block.tool_use_id)\n }\n }\n }\n }\n\n for (let i = 0; i < transcript.messages.length; i++) {\n const msg = transcript.messages[i]\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n for (const block of content) {\n if (block.type === 'tool_use') {\n const toolUse = block as ToolUseBlockParam\n const description = getToolUseDescription(toolUse)\n const isExecuting = !completedToolIds.has(toolUse.id)\n\n history.push({\n name: toolUse.name,\n id: toolUse.id,\n description,\n messageIndex: i,\n isExecuting,\n })\n }\n }\n }\n }\n\n return history\n}\n\n/**\n * Extract just the filename from a path for concise display\n */\nfunction getFileName(filePath: string): string {\n const parts = filePath.split('/')\n return parts[parts.length - 1] || filePath\n}\n\n/**\n * Map internal tool names to user-friendly display names\n * Note: Some tools have different internal names (e.g., 'View' \u2192 'Read')\n */\nconst TOOL_DISPLAY_NAMES: Record<string, string> = {\n View: 'Read',\n // Add more mappings as needed\n}\n\n/**\n * Get the user-friendly display name for a tool\n */\nexport function getToolDisplayName(internalName: string): string {\n return TOOL_DISPLAY_NAMES[internalName] || internalName\n}\n\n/**\n * Get a brief description of what a tool use did\n * Note: Description should NOT include the tool name - it's displayed separately\n */\nfunction getToolUseDescription(toolUse: ToolUseBlockParam): string {\n const input = toolUse.input as Record<string, unknown>\n\n switch (toolUse.name) {\n case 'Read':\n case 'View': // View is aliased to Read\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Write':\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Edit':\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Glob':\n return input.pattern ? String(input.pattern) : 'files'\n case 'Grep':\n return input.pattern ? `\"${input.pattern}\"` : 'content'\n case 'Bash':\n return input.command\n ? String(input.command).slice(0, 50) +\n (String(input.command).length > 50 ? '...' : '')\n : 'command'\n case 'Task':\n return input.description ? String(input.description) : 'sub-task'\n case 'WebFetch':\n return input.url ? String(input.url) : 'URL'\n case 'WebSearch':\n return input.query ? String(input.query) : 'web'\n default:\n // Try to extract a meaningful description from common input fields\n // Note: Don't include tool name in description - it's displayed separately\n if (input.file_path) return getFileName(String(input.file_path))\n if (input.path) return getFileName(String(input.path))\n if (input.query) return String(input.query)\n if (input.pattern) return String(input.pattern)\n return ''\n }\n}\n\n/**\n * Get tool use history for display, respecting display config\n * @param transcript The agent transcript\n * @param config Display configuration\n * @returns Tool uses to display (recent first for normal mode, chronological for verbose)\n */\nexport function getToolUseHistoryForDisplay(\n transcript: AgentTranscript,\n config: DisplayConfig,\n): { tools: ToolUseHistoryItem[]; hiddenCount: number } {\n const allTools = getToolUseHistory(transcript)\n\n if (config.showAllChildren) {\n // Verbose mode: show all tools in chronological order\n return { tools: allTools, hiddenCount: 0 }\n }\n\n // Normal mode: show recent N tools (most recent last for display)\n const maxTools = config.maxRecentChildren\n if (allTools.length <= maxTools) {\n return { tools: allTools, hiddenCount: 0 }\n }\n\n // Take the most recent tools\n const recentTools = allTools.slice(-maxTools)\n return {\n tools: recentTools,\n hiddenCount: allTools.length - maxTools,\n }\n}\n"],
|
|
5
|
-
"mappings": "AAaA,SAAS,oBAAoB,6BAA6B;AAC1D,SAA0B,qBAAqB;AAC/C,SAAS,eAAe;AAKjB,SAAS,gBAAgB,YAAqC;AACnE,QAAM,WAAW,WAAW;AAG5B,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,IAAI,SAAS,aAAa;AAC5B,YAAM,UAAU,IAAI,QAAQ;AAC5B,UAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,OAAO,EAAG;AAEzC,YAAM,YAAY,QAAQ,KAAK,OAAK,EAAE,SAAS,MAAM;AACrD,UAAI,aAAa,UAAU,WAAW;AACpC,eAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,eAAe,YAAgD;AAC7E,QAAM,SAA4B,CAAC;AAEnC,aAAW,OAAO,WAAW,UAAU;AACrC,QAAI,IAAI,SAAS,aAAa;AAC5B,YAAM,UAAU,IAAI,QAAQ;AAC5B,UAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,OAAO,EAAG;AAEzC,iBAAW,SAAS,SAAS;AAC3B,
|
|
4
|
+
"sourcesContent": ["/**\n * Task Display Utilities\n *\n * Utilities for computing task display content with truncation rules.\n * Implements V3's intermediate state display logic.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { AgentTranscript } from './agentTranscripts'\nimport type {\n DisplayConfig,\n TaskDisplayContent,\n} from '@minto-types/messageGroup'\nimport { getAgentTranscript, getAgentIdByToolUseId } from './agentTranscripts'\nimport { SEMANTIC_COLORS, SYMBOL_COLORS } from '@constants/colors'\nimport { SYMBOLS } from '@constants/symbols'\n\n/**\n * Get the latest text output from a transcript\n */\nexport function getLatestOutput(transcript: AgentTranscript): string {\n const messages = transcript.messages\n\n // Search from the end for the most recent text output\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n const textBlock = content.find(b => b.type === 'text')\n if (textBlock && 'text' in textBlock) {\n return textBlock.text\n }\n }\n }\n\n return ''\n}\n\n/**\n * Get all nested Task transcripts from a parent transcript\n */\nexport function getNestedTasks(transcript: AgentTranscript): AgentTranscript[] {\n const nested: AgentTranscript[] = []\n\n for (const msg of transcript.messages) {\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n for (const block of content) {\n if (\n block.type === 'tool_use' &&\n (block.name === 'Agent' || block.name === 'Task')\n ) {\n const toolUse = block as ToolUseBlockParam\n const nestedAgentId = getAgentIdByToolUseId(toolUse.id)\n if (nestedAgentId) {\n const nestedTranscript = getAgentTranscript(nestedAgentId)\n if (nestedTranscript) {\n nested.push(nestedTranscript)\n }\n }\n }\n }\n }\n }\n\n return nested\n}\n\n/**\n * Truncate text to specified length with ellipsis\n */\nexport function truncate(text: string, maxLength: number): string {\n if (!text) return ''\n // Clean up whitespace\n const cleaned = text.trim().replace(/\\n+/g, ' ').replace(/\\s+/g, ' ')\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength - 3) + '...'\n}\n\n/**\n * Get task display content with truncation rules (from V3)\n */\nexport function getTaskDisplayContent(\n transcript: AgentTranscript,\n config: DisplayConfig,\n): TaskDisplayContent {\n const nestedTasks = getNestedTasks(transcript)\n\n if (nestedTasks.length === 0) {\n // No children: show latest output, truncated\n const latestOutput = getLatestOutput(transcript)\n return {\n type: 'simple',\n content: truncate(latestOutput, config.maxCharsWithoutChildren),\n }\n }\n\n // Has children: show recent children based on config\n const tasksToShow = config.showAllChildren\n ? nestedTasks\n : nestedTasks.slice(-config.maxRecentChildren)\n\n const children = tasksToShow.map(task => ({\n description: task.description,\n status: task.status,\n content: truncate(getLatestOutput(task), config.maxCharsPerChild),\n }))\n\n return {\n type: 'nested',\n children,\n hiddenCount: nestedTasks.length - tasksToShow.length,\n }\n}\n\n/**\n * Get status icon for a task status\n * \u9075\u5FAA REPL \u89C4\u8303\uFF1A\n * - pending: \u25CB (\u7A7A\u5FC3\u5706)\n * - running: \u25D0 (\u534A\u5706\uFF0CTOOL_RUNNING)\n * - completed: \u2713 (\u52FE\uFF0CTOOL_SUCCESS)\n * - failed: \u2717 (\u53C9\uFF0CTOOL_ERROR)\n */\nexport function getStatusIcon(status: string): string {\n switch (status) {\n case 'pending':\n return '\u25CB' // \u7A7A\u5FC3\u5706 - pending\n case 'running':\n return SYMBOLS.TOOL_RUNNING // \u25D0 \u534A\u5706 - in progress\n case 'completed':\n return SYMBOLS.TOOL_SUCCESS // \u2713 \u52FE - completed\n case 'failed':\n return SYMBOLS.TOOL_ERROR // \u2717 - failed\n case 'interrupted':\n return '\u2298'\n default:\n return '\u25CB'\n }\n}\n\n/**\n * Get status color for a task status\n * \u4F7F\u7528 SYMBOL_COLORS \u4E0E Logo \u54C1\u724C\u914D\u8272\u4FDD\u6301\u4E00\u81F4\n */\nexport function getStatusColor(status: string): string {\n switch (status) {\n case 'pending':\n return SYMBOL_COLORS.pending\n case 'running':\n return SYMBOL_COLORS.running\n case 'completed':\n return SYMBOL_COLORS.success\n case 'failed':\n return SYMBOL_COLORS.error\n case 'interrupted':\n return SYMBOL_COLORS.pending\n default:\n return SYMBOL_COLORS.pending\n }\n}\n\n// ============================================================================\n// \u5143\u4FE1\u606F\u683C\u5F0F\u5316 (Meta Info Formatting)\n// \u57FA\u4E8E REPL \u663E\u793A\u89C4\u8303\uFF1A\u8017\u65F6 \u00B7 \u6A21\u578B \u00B7 \u65F6\u95F4\n// ============================================================================\n\n/**\n * \u5143\u4FE1\u606F\u6570\u636E\u7ED3\u6784\n */\nexport interface MetaInfo {\n /** \u8017\u65F6\uFF08\u6BEB\u79D2\uFF09 */\n duration?: number\n /** \u6A21\u578B\u540D\u79F0 */\n model?: string\n /** \u65F6\u95F4\u6233 */\n timestamp?: Date | number\n}\n\n/**\n * \u683C\u5F0F\u5316\u8017\u65F6\n * - < 60s: X.Xs (\u5982 2.4s)\n * - >= 60s: Xm Xs (\u5982 1m 23s)\n * - \u672A\u77E5: --\n */\nexport function formatDuration(durationMs?: number): string {\n if (durationMs === undefined || durationMs === null) {\n return '--'\n }\n\n const seconds = durationMs / 1000\n\n if (seconds < 60) {\n // \u5C0F\u4E8E 60 \u79D2\uFF0C\u663E\u793A X.Xs\n return `${seconds.toFixed(1)}s`\n }\n\n // \u5927\u4E8E\u7B49\u4E8E 60 \u79D2\uFF0C\u663E\u793A Xm Xs\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = Math.floor(seconds % 60)\n return `${minutes}m ${remainingSeconds}s`\n}\n\n/**\n * \u683C\u5F0F\u5316\u6A21\u578B\u540D\u79F0\uFF08\u7B80\u5199\uFF09\n * - claude-3-opus-20240229 -> opus\n * - claude-3-sonnet-20240229 -> sonnet\n * - glm-4.7 -> glm-4.7\n */\nexport function formatModelName(model?: string): string {\n if (!model) return ''\n\n // Claude \u6A21\u578B\u7B80\u5199\n if (model.includes('opus')) return 'opus'\n if (model.includes('sonnet')) return 'sonnet'\n if (model.includes('haiku')) return 'haiku'\n\n // \u5176\u4ED6\u6A21\u578B\u4FDD\u6301\u539F\u6837\u6216\u622A\u65AD\n // \u5982\u679C\u540D\u79F0\u592A\u957F\uFF0C\u53D6\u6700\u540E\u4E00\u90E8\u5206\n const parts = model.split('-')\n if (parts.length > 2 && model.length > 15) {\n // \u5C1D\u8BD5\u63D0\u53D6\u6709\u610F\u4E49\u7684\u90E8\u5206\n return parts.slice(0, 2).join('-')\n }\n\n return model\n}\n\n/**\n * \u683C\u5F0F\u5316\u65F6\u95F4\u6233\n * \u683C\u5F0F: H:MM (24\u5C0F\u65F6\u5236)\n */\nexport function formatTimestamp(timestamp?: Date | number): string {\n if (!timestamp) return ''\n\n const date = timestamp instanceof Date ? timestamp : new Date(timestamp)\n const hours = date.getHours()\n const minutes = date.getMinutes().toString().padStart(2, '0')\n\n return `${hours}:${minutes}`\n}\n\n/**\n * \u683C\u5F0F\u5316\u5143\u4FE1\u606F\n *\n * \u89C4\u5219\uFF1A\n * - \u6709\u8017\u65F6\uFF1A\u8017\u65F6 \u00B7 \u6A21\u578B \u00B7 \u65F6\u95F4 (\u5982 \"2.4s \u00B7 glm-4.7 \u00B7 9:21\")\n * - \u65E0\u8017\u65F6\uFF1A\u6A21\u578B \u00B7 \u65F6\u95F4 (\u5982 \"glm-4.7 \u00B7 9:21\")\n *\n * @param meta - \u5143\u4FE1\u606F\u5BF9\u8C61\n * @returns \u683C\u5F0F\u5316\u540E\u7684\u5B57\u7B26\u4E32\uFF0C\u5982\u679C\u6CA1\u6709\u4EFB\u4F55\u4FE1\u606F\u5219\u8FD4\u56DE\u7A7A\u5B57\u7B26\u4E32\n */\nexport function formatMetaInfo(meta: MetaInfo): string {\n const parts: string[] = []\n\n // \u6709\u8017\u65F6\u65F6\uFF0C\u8017\u65F6\u653E\u5728\u6700\u524D\u9762\n if (meta.duration !== undefined && meta.duration !== null) {\n parts.push(formatDuration(meta.duration))\n }\n\n // \u6A21\u578B\u540D\u79F0\n const modelName = formatModelName(meta.model)\n if (modelName) {\n parts.push(modelName)\n }\n\n // \u65F6\u95F4\u6233\n const time = formatTimestamp(meta.timestamp)\n if (time) {\n parts.push(time)\n }\n\n // \u4F7F\u7528 \" \u00B7 \" \u5206\u9694\n return parts.join(' \u00B7 ')\n}\n\n/**\n * Tool use history item\n */\nexport interface ToolUseHistoryItem {\n /** Tool name */\n name: string\n /** Tool use ID */\n id: string\n /** Brief description of what the tool did */\n description: string\n /** Timestamp (message index for ordering) */\n messageIndex: number\n /** Whether this tool is currently executing (no result yet) */\n isExecuting?: boolean\n}\n\n/**\n * Get tool use history from a transcript\n * Returns tool uses in chronological order (oldest first)\n * Also marks tools that are currently executing (no result yet)\n */\nexport function getToolUseHistory(\n transcript: AgentTranscript,\n): ToolUseHistoryItem[] {\n const history: ToolUseHistoryItem[] = []\n\n // Collect all tool_result IDs to identify completed tools\n const completedToolIds = new Set<string>()\n for (const msg of transcript.messages) {\n if (msg.type === 'user') {\n const content = msg.message.content\n if (!Array.isArray(content)) continue\n\n for (const block of content) {\n if (block.type === 'tool_result' && 'tool_use_id' in block) {\n completedToolIds.add(block.tool_use_id)\n }\n }\n }\n }\n\n for (let i = 0; i < transcript.messages.length; i++) {\n const msg = transcript.messages[i]\n if (msg.type === 'assistant') {\n const content = msg.message.content\n if (!content || !Array.isArray(content)) continue\n\n for (const block of content) {\n if (block.type === 'tool_use') {\n const toolUse = block as ToolUseBlockParam\n const description = getToolUseDescription(toolUse)\n const isExecuting = !completedToolIds.has(toolUse.id)\n\n history.push({\n name: toolUse.name,\n id: toolUse.id,\n description,\n messageIndex: i,\n isExecuting,\n })\n }\n }\n }\n }\n\n return history\n}\n\n/**\n * Extract just the filename from a path for concise display\n */\nfunction getFileName(filePath: string): string {\n const parts = filePath.split('/')\n return parts[parts.length - 1] || filePath\n}\n\n/**\n * Map internal tool names to user-friendly display names\n * Note: Some tools have different internal names (e.g., 'View' \u2192 'Read')\n */\nconst TOOL_DISPLAY_NAMES: Record<string, string> = {\n View: 'Read',\n // Add more mappings as needed\n}\n\n/**\n * Get the user-friendly display name for a tool\n */\nexport function getToolDisplayName(internalName: string): string {\n return TOOL_DISPLAY_NAMES[internalName] || internalName\n}\n\n/**\n * Get a brief description of what a tool use did\n * Note: Description should NOT include the tool name - it's displayed separately\n */\nfunction getToolUseDescription(toolUse: ToolUseBlockParam): string {\n const input = toolUse.input as Record<string, unknown>\n\n switch (toolUse.name) {\n case 'Read':\n case 'View': // View is aliased to Read\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Write':\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Edit':\n return input.file_path ? getFileName(String(input.file_path)) : 'file'\n case 'Glob':\n return input.pattern ? String(input.pattern) : 'files'\n case 'Grep':\n return input.pattern ? `\"${input.pattern}\"` : 'content'\n case 'Bash':\n return input.command\n ? String(input.command).slice(0, 50) +\n (String(input.command).length > 50 ? '...' : '')\n : 'command'\n case 'Agent':\n case 'Task':\n return input.description ? String(input.description) : 'sub-task'\n case 'WebFetch':\n return input.url ? String(input.url) : 'URL'\n case 'WebSearch':\n return input.query ? String(input.query) : 'web'\n default:\n // Try to extract a meaningful description from common input fields\n // Note: Don't include tool name in description - it's displayed separately\n if (input.file_path) return getFileName(String(input.file_path))\n if (input.path) return getFileName(String(input.path))\n if (input.query) return String(input.query)\n if (input.pattern) return String(input.pattern)\n return ''\n }\n}\n\n/**\n * Get tool use history for display, respecting display config\n * @param transcript The agent transcript\n * @param config Display configuration\n * @returns Tool uses to display (recent first for normal mode, chronological for verbose)\n */\nexport function getToolUseHistoryForDisplay(\n transcript: AgentTranscript,\n config: DisplayConfig,\n): { tools: ToolUseHistoryItem[]; hiddenCount: number } {\n const allTools = getToolUseHistory(transcript)\n\n if (config.showAllChildren) {\n // Verbose mode: show all tools in chronological order\n return { tools: allTools, hiddenCount: 0 }\n }\n\n // Normal mode: show recent N tools (most recent last for display)\n const maxTools = config.maxRecentChildren\n if (allTools.length <= maxTools) {\n return { tools: allTools, hiddenCount: 0 }\n }\n\n // Take the most recent tools\n const recentTools = allTools.slice(-maxTools)\n return {\n tools: recentTools,\n hiddenCount: allTools.length - maxTools,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/teamConfig.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
getMutableGlobalConfig,
|
|
4
4
|
saveGlobalConfig
|
|
5
5
|
} from "./config.js";
|
|
6
6
|
import { debug as debugLogger } from "./debugLogger.js";
|
|
@@ -135,7 +135,7 @@ function applyTeamConfig(teamConfig, strategy = "merge") {
|
|
|
135
135
|
configName: teamConfig.name,
|
|
136
136
|
strategy
|
|
137
137
|
});
|
|
138
|
-
const globalConfig =
|
|
138
|
+
const globalConfig = getMutableGlobalConfig();
|
|
139
139
|
let modelsAdded = 0;
|
|
140
140
|
let mcpServersAdded = 0;
|
|
141
141
|
const settingsUpdated = [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/teamConfig.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Team Configuration System\n *\n * Enables teams to share a unified Minto configuration via remote URLs.\n * Supports environment variable interpolation and flexible configuration merging.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport {\n getGlobalConfig,\n saveGlobalConfig,\n ModelProfile,\n ModelPointers,\n McpServerConfig,\n ProviderType,\n} from './config'\nimport { debug as debugLogger } from './debugLogger'\nimport { safeParseJSON } from './json'\nimport { ensureProxyBypass, hasSystemProxy } from './envConfig'\n\n/**\n * Scope for team config export/import\n */\nexport type TeamConfigScope = 'user' | 'project' | 'all'\n\n/**\n * Standalone skill configuration for team config\n */\nexport type TeamSkillConfig = {\n name: string\n description: string\n content: string // markdown body\n argumentHint?: string\n disableModelInvocation?: boolean\n userInvocable?: boolean\n allowedTools?: string[]\n model?: string\n context?: string\n agent?: string\n}\n\n/**\n * Standalone command configuration for team config\n */\nexport type TeamCommandConfig = {\n name: string\n description?: string\n content: string // markdown body\n aliases?: string[]\n enabled?: boolean\n hidden?: boolean\n progressMessage?: string\n argNames?: string[]\n allowedTools?: string[]\n}\n\n/**\n * Team configuration schema\n * Represents a shareable configuration template for teams\n */\nexport type TeamConfig = {\n version: '1.0'\n name: string // Configuration name (e.g., \"Acme Inc. Default Config\")\n description?: string // Optional description\n scope?: TeamConfigScope // Scope that was used during export\n\n // Model Configuration\n models?: {\n profiles?: TeamModelProfile[]\n pointers?: Partial<ModelPointers> // Default model pointers\n defaultModel?: string // Default model name\n }\n\n // MCP Server Configuration\n mcpServers?: Record<string, TeamMcpServerConfig>\n\n // Plugin Marketplace Configuration\n plugins?: {\n // Plugin marketplace URLs (marketplace.json)\n marketplaces?: string[]\n // Specific plugins to install from marketplaces\n install?: string[] // v1.0 compat: no scope, defaults to user\n userInstall?: string[] // User-scope plugins\n projectInstall?: string[] // Project-scope plugins\n }\n\n // Global Settings\n settings?: {\n theme?: 'dark' | 'light'\n verbose?: boolean\n compressionMode?: 'business' | 'code'\n thinking?: boolean\n proxy?: string\n stream?: boolean\n // \u65B0\u589E\u8BBE\u7F6E\u9879\n language?: 'en' | 'zh-CN'\n safetyMode?: 'yolo' | 'smart' | 'strict' | 'free'\n skipOnboarding?: boolean // \u8DF3\u8FC7\u5165\u95E8\u6D41\u7A0B\n }\n\n // Agent \u914D\u7F6E\uFF08\u5185\u8054\u6216\u8FDC\u7A0B URL\uFF09\n agents?: {\n // \u8FDC\u7A0B agent \u6587\u4EF6 URL \u5217\u8868\n remoteAgents?: string[]\n // \u5185\u8054 agent \u5B9A\u4E49\n inlineAgents?: TeamAgentConfig[] // v1.0 compat: no scope, defaults to user\n userAgents?: TeamAgentConfig[]\n projectAgents?: TeamAgentConfig[]\n }\n\n // Skill \u914D\u7F6E\uFF08standalone skills\uFF09\n skills?: {\n userSkills?: TeamSkillConfig[]\n projectSkills?: TeamSkillConfig[]\n }\n\n // Command \u914D\u7F6E\uFF08standalone commands\uFF09\n commands?: {\n userCommands?: TeamCommandConfig[]\n projectCommands?: TeamCommandConfig[]\n }\n\n // Hook \u914D\u7F6E\n hooks?: TeamHooksConfig // User-scope hooks\n projectHooks?: TeamHooksConfig // Project-scope hooks\n\n // Instructions for users\n postInstallInstructions?: string\n}\n\n/**\n * Model profile template with environment variable support\n */\nexport type TeamModelProfile = {\n name: string\n provider: ProviderType\n modelName: string\n baseURL?: string\n apiKey: string // Can be env var like \"${ANTHROPIC_API_KEY}\"\n maxTokens: number\n contextLength: number\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal'\n isActive?: boolean\n}\n\n/**\n * Inline agent configuration for team config\n */\nexport type TeamAgentConfig = {\n name: string // Agent identifier (e.g., \"research-analyst\")\n description: string // When to use this agent\n tools: string[] | '*' // Tool permissions\n systemPrompt: string // System prompt content\n model?: string // Optional model override\n color?: string // Optional UI color\n}\n\n/**\n * Hook configuration for team config\n */\nexport type TeamHooksConfig = {\n // Session lifecycle hooks\n sessionStart?: TeamHookDefinition[]\n sessionEnd?: TeamHookDefinition[]\n // User input hooks\n userPromptSubmit?: TeamHookDefinition[]\n // Tool lifecycle hooks\n preToolUse?: TeamToolHook[]\n postToolUse?: TeamToolHook[]\n}\n\nexport type TeamHookDefinition = {\n type: 'command' | 'prompt'\n command?: string\n prompt?: string\n timeout?: number\n description?: string\n}\n\nexport type TeamToolHook = {\n matcher: string // Tool name regex or \"*\"\n hooks: TeamHookDefinition[]\n}\n\n/**\n * MCP server config with env var support\n */\nexport type TeamMcpServerConfig = {\n type?: 'stdio' | 'sse'\n command?: string // For stdio\n args?: string[] // For stdio, supports env vars like \"${HOME}/.local/bin/mcp-server\"\n url?: string // For SSE\n env?: Record<string, string> // Env vars, supports interpolation\n enabled?: boolean\n}\n\n/**\n * Interpolate environment variables in a string\n * Supports ${VAR_NAME} syntax\n */\nexport function interpolateEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName.trim()]\n if (envValue === undefined) {\n debugLogger.warn('ENV_VAR_NOT_FOUND', {\n varName,\n original: match,\n })\n // Keep the placeholder if env var not found\n return match\n }\n return envValue\n })\n}\n\n/**\n * Recursively interpolate env vars in an object\n */\nexport function interpolateEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return interpolateEnvVars(obj) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => interpolateEnvVarsInObject(item)) as T\n }\n\n if (obj && typeof obj === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = interpolateEnvVarsInObject(value)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Convert team model profile to runtime model profile\n */\nexport function convertTeamModelProfile(\n teamProfile: TeamModelProfile,\n): ModelProfile {\n const now = Date.now()\n\n return {\n name: teamProfile.name,\n provider: teamProfile.provider,\n modelName: teamProfile.modelName,\n baseURL: teamProfile.baseURL,\n apiKey: interpolateEnvVars(teamProfile.apiKey),\n maxTokens: teamProfile.maxTokens,\n contextLength: teamProfile.contextLength,\n reasoningEffort: teamProfile.reasoningEffort,\n isActive: teamProfile.isActive ?? true,\n createdAt: now,\n lastUsed: now,\n }\n}\n\n/**\n * Convert team MCP config to runtime MCP config\n */\nexport function convertTeamMcpConfig(\n teamConfig: TeamMcpServerConfig,\n): McpServerConfig {\n if (teamConfig.type === 'sse') {\n return {\n type: 'sse',\n url: interpolateEnvVars(teamConfig.url || ''),\n enabled: teamConfig.enabled ?? true,\n }\n }\n\n // Default to stdio \u2014 auto-inject proxy bypass if system has proxy configured\n const env = teamConfig.env\n ? ensureProxyBypass(interpolateEnvVarsInObject(teamConfig.env))\n : hasSystemProxy()\n ? { no_proxy: '*', NO_PROXY: '*' }\n : undefined\n\n return {\n type: 'stdio',\n command: interpolateEnvVars(teamConfig.command || ''),\n args: (teamConfig.args || []).map(arg => interpolateEnvVars(arg)),\n env,\n enabled: teamConfig.enabled ?? true,\n }\n}\n\n/**\n * Fetch team configuration from a URL\n */\nexport async function fetchTeamConfig(url: string): Promise<TeamConfig> {\n debugLogger.state('TEAM_CONFIG_FETCH_START', { url })\n\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n })\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n )\n }\n\n const configText = await response.text()\n const config = JSON.parse(configText) as TeamConfig\n\n // Validate version\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_FETCH_SUCCESS', {\n url,\n configName: config.name,\n hasModels: !!config.models,\n hasMcpServers: !!config.mcpServers,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_FETCH_ERROR', {\n url,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Load team configuration from a local file\n */\nexport function loadTeamConfigFromFile(filePath: string): TeamConfig {\n debugLogger.state('TEAM_CONFIG_LOAD_FILE', { filePath })\n\n if (!existsSync(filePath)) {\n throw new Error(`Configuration file not found: ${filePath}`)\n }\n\n try {\n const configText = readFileSync(filePath, 'utf-8')\n const config = safeParseJSON(configText) as TeamConfig\n\n if (!config) {\n throw new Error('Invalid JSON in configuration file')\n }\n\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_LOAD_FILE_SUCCESS', {\n filePath,\n configName: config.name,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_LOAD_FILE_ERROR', {\n filePath,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Merge strategy for configuration\n */\nexport type MergeStrategy = 'replace' | 'merge' | 'skip-existing'\n\n/**\n * Apply team configuration to global config\n */\nexport function applyTeamConfig(\n teamConfig: TeamConfig,\n strategy: MergeStrategy = 'merge',\n): {\n applied: boolean\n modelsAdded: number\n mcpServersAdded: number\n settingsUpdated: string[]\n} {\n debugLogger.state('TEAM_CONFIG_APPLY_START', {\n configName: teamConfig.name,\n strategy,\n })\n\n const globalConfig = getGlobalConfig()\n let modelsAdded = 0\n let mcpServersAdded = 0\n const settingsUpdated: string[] = []\n\n // Apply model profiles\n if (teamConfig.models?.profiles) {\n const existingProfiles = globalConfig.modelProfiles || []\n const existingModelNames = new Set(existingProfiles.map(p => p.modelName))\n\n for (const teamProfile of teamConfig.models.profiles) {\n const runtimeProfile = convertTeamModelProfile(teamProfile)\n\n if (\n strategy === 'skip-existing' &&\n existingModelNames.has(runtimeProfile.modelName)\n ) {\n debugLogger.state('TEAM_CONFIG_SKIP_MODEL', {\n modelName: runtimeProfile.modelName,\n reason: 'already_exists',\n })\n continue\n }\n\n if (strategy === 'replace') {\n // Remove existing profile with same modelName\n const index = existingProfiles.findIndex(\n p => p.modelName === runtimeProfile.modelName,\n )\n if (index !== -1) {\n existingProfiles.splice(index, 1)\n }\n }\n\n existingProfiles.push(runtimeProfile)\n modelsAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MODEL', {\n modelName: runtimeProfile.modelName,\n provider: runtimeProfile.provider,\n })\n }\n\n globalConfig.modelProfiles = existingProfiles\n }\n\n // Apply model pointers\n if (teamConfig.models?.pointers) {\n globalConfig.modelPointers = {\n ...(globalConfig.modelPointers || {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n }),\n ...teamConfig.models.pointers,\n }\n settingsUpdated.push('modelPointers')\n }\n\n // Apply default model\n if (teamConfig.models?.defaultModel) {\n globalConfig.defaultModelName = teamConfig.models.defaultModel\n settingsUpdated.push('defaultModelName')\n }\n\n // Apply MCP servers\n if (teamConfig.mcpServers) {\n const existingMcpServers = globalConfig.mcpServers || {}\n const existingServerNames = new Set(Object.keys(existingMcpServers))\n\n for (const [serverName, teamMcpConfig] of Object.entries(\n teamConfig.mcpServers,\n )) {\n if (strategy === 'skip-existing' && existingServerNames.has(serverName)) {\n debugLogger.state('TEAM_CONFIG_SKIP_MCP', {\n serverName,\n reason: 'already_exists',\n })\n continue\n }\n\n const runtimeMcpConfig = convertTeamMcpConfig(teamMcpConfig)\n existingMcpServers[serverName] = runtimeMcpConfig\n mcpServersAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MCP', {\n serverName,\n type: runtimeMcpConfig.type || 'stdio',\n })\n }\n\n globalConfig.mcpServers = existingMcpServers\n }\n\n // Apply global settings\n if (teamConfig.settings) {\n const { settings } = teamConfig\n\n if (settings.theme !== undefined) {\n globalConfig.theme = settings.theme\n settingsUpdated.push('theme')\n }\n\n if (settings.verbose !== undefined) {\n globalConfig.verbose = settings.verbose\n settingsUpdated.push('verbose')\n }\n\n if (settings.compressionMode !== undefined) {\n globalConfig.compressionMode = settings.compressionMode\n settingsUpdated.push('compressionMode')\n }\n\n if (settings.thinking !== undefined) {\n globalConfig.thinking = settings.thinking\n settingsUpdated.push('thinking')\n }\n\n if (settings.proxy !== undefined) {\n globalConfig.proxy = settings.proxy\n settingsUpdated.push('proxy')\n }\n\n if (settings.stream !== undefined) {\n globalConfig.stream = settings.stream\n settingsUpdated.push('stream')\n }\n\n if (settings.language !== undefined) {\n globalConfig.language = settings.language\n settingsUpdated.push('language')\n }\n\n if (settings.safetyMode !== undefined) {\n globalConfig.safetyMode = settings.safetyMode\n settingsUpdated.push('safetyMode')\n }\n\n if (settings.skipOnboarding) {\n globalConfig.hasCompletedOnboarding = true\n settingsUpdated.push('hasCompletedOnboarding')\n }\n }\n\n // Save updated config\n saveGlobalConfig(globalConfig)\n\n debugLogger.state('TEAM_CONFIG_APPLY_SUCCESS', {\n configName: teamConfig.name,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated: settingsUpdated.join(', '),\n })\n\n return {\n applied: true,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated,\n }\n}\n\n/**\n * Add marketplaces from URLs\n */\nexport async function addMarketplaces(\n marketplaceUrls: string[],\n): Promise<{ added: number; failed: number; errors: string[] }> {\n let added = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager\n const { addMarketplace } = await import('./marketplaceManager')\n\n for (const url of marketplaceUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE', { url })\n\n await addMarketplace(url)\n added++\n\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE_SUCCESS', { url })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_ADD_MARKETPLACE_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { added, failed, errors }\n}\n\n/**\n * Install plugins from marketplaces\n */\nexport async function installPlugins(\n pluginNames: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager and path utilities\n const { installPluginFromMarketplace } = await import('./marketplaceManager')\n const { join } = await import('path')\n const { homedir } = await import('os')\n\n // Default target: ~/.minto/plugins\n const installDir = targetDir || join(homedir(), '.minto', 'plugins')\n\n for (const pluginSpec of pluginNames) {\n // Parse name@marketplace format (e.g., \"backend-development@claude-code-workflows\")\n const atIndex = pluginSpec.indexOf('@')\n const pluginName =\n atIndex !== -1 ? pluginSpec.slice(0, atIndex) : pluginSpec\n const marketplaceName =\n atIndex !== -1 ? pluginSpec.slice(atIndex + 1) : undefined\n\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN', {\n pluginName,\n marketplace: marketplaceName,\n targetDir: installDir,\n })\n\n await installPluginFromMarketplace(\n pluginName,\n marketplaceName,\n join(installDir, pluginName),\n )\n\n installed++\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN_SUCCESS', { pluginName })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${pluginName}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_PLUGIN_ERROR', {\n pluginName,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Download and install remote agents\n */\nexport async function installRemoteAgents(\n agentUrls: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/agents\n const agentsDir = targetDir || join(homedir(), '.minto', 'agents')\n if (!existsSync(agentsDir)) {\n mkdirSync(agentsDir, { recursive: true })\n }\n\n for (const url of agentUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_DOWNLOAD_AGENT', { url })\n\n const response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n })\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const content = await response.text()\n\n // Extract filename from URL\n const filename = url.split('/').pop() || 'agent.md'\n const targetPath = join(agentsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_DOWNLOAD_AGENT_SUCCESS', {\n url,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_DOWNLOAD_AGENT_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install inline agents from team config\n */\nexport async function installInlineAgents(\n agents: TeamAgentConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/agents\n const agentsDir = targetDir || join(homedir(), '.minto', 'agents')\n if (!existsSync(agentsDir)) {\n mkdirSync(agentsDir, { recursive: true })\n }\n\n for (const agent of agents) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_INLINE_AGENT', {\n name: agent.name,\n })\n\n // Generate agent markdown file\n const tools = agent.tools === '*' ? '*' : JSON.stringify(agent.tools)\n\n const content = `---\nname: ${agent.name}\ndescription: \"${agent.description.replace(/\"/g, '\\\\\"')}\"\ntools: ${tools}${agent.model ? `\\nmodel_name: ${agent.model}` : ''}${agent.color ? `\\ncolor: \"${agent.color}\"` : ''}\n---\n\n${agent.systemPrompt}\n`\n\n const filename = `${agent.name}.md`\n const targetPath = join(agentsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_INLINE_AGENT_SUCCESS', {\n name: agent.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${agent.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_INLINE_AGENT_ERROR', {\n name: agent.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install hooks from team config\n */\nexport async function installTeamHooks(\n hooks: TeamHooksConfig,\n targetPath?: string,\n): Promise<{ installed: boolean; error?: string }> {\n const { join, dirname } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync, readFileSync } = await import(\n 'fs'\n )\n\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_HOOKS', {})\n\n // Target: specified path or ~/.minto/hooks.json\n const hooksPath = targetPath || join(homedir(), '.minto', 'hooks.json')\n const hooksDir = dirname(hooksPath)\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true })\n }\n\n // Convert TeamHooksConfig to standard hooks format\n const hooksConfig: Record<string, unknown> = {\n description: 'Team-configured hooks',\n hooks: {} as Record<string, unknown>,\n }\n\n const hooksObj = hooksConfig.hooks as Record<string, unknown>\n\n if (hooks.sessionStart) {\n hooksObj.SessionStart = [{ matcher: '*', hooks: hooks.sessionStart }]\n }\n if (hooks.sessionEnd) {\n hooksObj.SessionEnd = [{ matcher: '*', hooks: hooks.sessionEnd }]\n }\n if (hooks.userPromptSubmit) {\n hooksObj.UserPromptSubmit = [\n { matcher: '*', hooks: hooks.userPromptSubmit },\n ]\n }\n if (hooks.preToolUse) {\n hooksObj.PreToolUse = hooks.preToolUse\n }\n if (hooks.postToolUse) {\n hooksObj.PostToolUse = hooks.postToolUse\n }\n\n // Merge with existing hooks if present\n if (existsSync(hooksPath)) {\n try {\n const existingContent = readFileSync(hooksPath, 'utf-8')\n const existingHooks = JSON.parse(existingContent)\n // Deep merge\n for (const [event, matchers] of Object.entries(hooksObj)) {\n if (existingHooks.hooks?.[event]) {\n existingHooks.hooks[event] = [\n ...existingHooks.hooks[event],\n ...(matchers as unknown[]),\n ]\n } else {\n existingHooks.hooks = existingHooks.hooks || {}\n existingHooks.hooks[event] = matchers\n }\n }\n hooksConfig.hooks = existingHooks.hooks\n } catch {\n // If parsing fails, overwrite\n }\n }\n\n writeFileSync(hooksPath, JSON.stringify(hooksConfig, null, 2), 'utf-8')\n\n debugLogger.state('TEAM_CONFIG_INSTALL_HOOKS_SUCCESS', { hooksPath })\n\n return { installed: true }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n debugLogger.error('TEAM_CONFIG_INSTALL_HOOKS_ERROR', { error: errorMsg })\n return { installed: false, error: errorMsg }\n }\n}\n\n/**\n * Install standalone skills from team config\n */\nexport async function installInlineSkills(\n skills: TeamSkillConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/skills\n const skillsDir = targetDir || join(homedir(), '.minto', 'skills')\n if (!existsSync(skillsDir)) {\n mkdirSync(skillsDir, { recursive: true })\n }\n\n for (const skill of skills) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_SKILL', { name: skill.name })\n\n // Build frontmatter\n const frontmatterLines: string[] = [\n `name: ${skill.name}`,\n `description: \"${skill.description.replace(/\"/g, '\\\\\"')}\"`,\n ]\n if (skill.argumentHint) {\n frontmatterLines.push(`argument-hint: \"${skill.argumentHint}\"`)\n }\n if (skill.disableModelInvocation !== undefined) {\n frontmatterLines.push(\n `disable-model-invocation: ${skill.disableModelInvocation}`,\n )\n }\n if (skill.userInvocable !== undefined) {\n frontmatterLines.push(`user-invocable: ${skill.userInvocable}`)\n }\n if (skill.allowedTools && skill.allowedTools.length > 0) {\n frontmatterLines.push(\n `allowed-tools: ${JSON.stringify(skill.allowedTools)}`,\n )\n }\n if (skill.model) {\n frontmatterLines.push(`model: ${skill.model}`)\n }\n if (skill.context) {\n frontmatterLines.push(`context: \"${skill.context}\"`)\n }\n if (skill.agent) {\n frontmatterLines.push(`agent: \"${skill.agent}\"`)\n }\n\n const content = `---\\n${frontmatterLines.join('\\n')}\\n---\\n\\n${skill.content}\\n`\n\n const filename = `${skill.name}.md`\n const targetPath = join(skillsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_SKILL_SUCCESS', {\n name: skill.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${skill.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_SKILL_ERROR', {\n name: skill.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install standalone commands from team config\n */\nexport async function installInlineCommands(\n commands: TeamCommandConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/commands\n const commandsDir = targetDir || join(homedir(), '.minto', 'commands')\n if (!existsSync(commandsDir)) {\n mkdirSync(commandsDir, { recursive: true })\n }\n\n for (const cmd of commands) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_COMMAND', { name: cmd.name })\n\n // Build frontmatter\n const frontmatterLines: string[] = [`name: ${cmd.name}`]\n if (cmd.description) {\n frontmatterLines.push(\n `description: \"${cmd.description.replace(/\"/g, '\\\\\"')}\"`,\n )\n }\n if (cmd.aliases && cmd.aliases.length > 0) {\n frontmatterLines.push(`aliases: ${JSON.stringify(cmd.aliases)}`)\n }\n if (cmd.enabled !== undefined) {\n frontmatterLines.push(`enabled: ${cmd.enabled}`)\n }\n if (cmd.hidden !== undefined) {\n frontmatterLines.push(`hidden: ${cmd.hidden}`)\n }\n if (cmd.progressMessage) {\n frontmatterLines.push(`progressMessage: \"${cmd.progressMessage}\"`)\n }\n if (cmd.argNames && cmd.argNames.length > 0) {\n frontmatterLines.push(`argNames: ${JSON.stringify(cmd.argNames)}`)\n }\n if (cmd.allowedTools && cmd.allowedTools.length > 0) {\n frontmatterLines.push(\n `allowed-tools: ${JSON.stringify(cmd.allowedTools)}`,\n )\n }\n\n const content = `---\\n${frontmatterLines.join('\\n')}\\n---\\n\\n${cmd.content}\\n`\n\n const filename = `${cmd.name}.md`\n const targetPath = join(commandsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_COMMAND_SUCCESS', {\n name: cmd.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${cmd.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_COMMAND_ERROR', {\n name: cmd.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Team Configuration System\n *\n * Enables teams to share a unified Minto configuration via remote URLs.\n * Supports environment variable interpolation and flexible configuration merging.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport {\n getMutableGlobalConfig,\n saveGlobalConfig,\n ModelProfile,\n ModelPointers,\n McpServerConfig,\n ProviderType,\n} from './config'\nimport { debug as debugLogger } from './debugLogger'\nimport { safeParseJSON } from './json'\nimport { ensureProxyBypass, hasSystemProxy } from './envConfig'\n\n/**\n * Scope for team config export/import\n */\nexport type TeamConfigScope = 'user' | 'project' | 'all'\n\n/**\n * Standalone skill configuration for team config\n */\nexport type TeamSkillConfig = {\n name: string\n description: string\n content: string // markdown body\n argumentHint?: string\n disableModelInvocation?: boolean\n userInvocable?: boolean\n allowedTools?: string[]\n model?: string\n context?: string\n agent?: string\n}\n\n/**\n * Standalone command configuration for team config\n */\nexport type TeamCommandConfig = {\n name: string\n description?: string\n content: string // markdown body\n aliases?: string[]\n enabled?: boolean\n hidden?: boolean\n progressMessage?: string\n argNames?: string[]\n allowedTools?: string[]\n}\n\n/**\n * Team configuration schema\n * Represents a shareable configuration template for teams\n */\nexport type TeamConfig = {\n version: '1.0'\n name: string // Configuration name (e.g., \"Acme Inc. Default Config\")\n description?: string // Optional description\n scope?: TeamConfigScope // Scope that was used during export\n\n // Model Configuration\n models?: {\n profiles?: TeamModelProfile[]\n pointers?: Partial<ModelPointers> // Default model pointers\n defaultModel?: string // Default model name\n }\n\n // MCP Server Configuration\n mcpServers?: Record<string, TeamMcpServerConfig>\n\n // Plugin Marketplace Configuration\n plugins?: {\n // Plugin marketplace URLs (marketplace.json)\n marketplaces?: string[]\n // Specific plugins to install from marketplaces\n install?: string[] // v1.0 compat: no scope, defaults to user\n userInstall?: string[] // User-scope plugins\n projectInstall?: string[] // Project-scope plugins\n }\n\n // Global Settings\n settings?: {\n theme?: 'dark' | 'light'\n verbose?: boolean\n compressionMode?: 'business' | 'code'\n thinking?: boolean\n proxy?: string\n stream?: boolean\n // \u65B0\u589E\u8BBE\u7F6E\u9879\n language?: 'en' | 'zh-CN'\n safetyMode?: 'yolo' | 'smart' | 'strict' | 'free'\n skipOnboarding?: boolean // \u8DF3\u8FC7\u5165\u95E8\u6D41\u7A0B\n }\n\n // Agent \u914D\u7F6E\uFF08\u5185\u8054\u6216\u8FDC\u7A0B URL\uFF09\n agents?: {\n // \u8FDC\u7A0B agent \u6587\u4EF6 URL \u5217\u8868\n remoteAgents?: string[]\n // \u5185\u8054 agent \u5B9A\u4E49\n inlineAgents?: TeamAgentConfig[] // v1.0 compat: no scope, defaults to user\n userAgents?: TeamAgentConfig[]\n projectAgents?: TeamAgentConfig[]\n }\n\n // Skill \u914D\u7F6E\uFF08standalone skills\uFF09\n skills?: {\n userSkills?: TeamSkillConfig[]\n projectSkills?: TeamSkillConfig[]\n }\n\n // Command \u914D\u7F6E\uFF08standalone commands\uFF09\n commands?: {\n userCommands?: TeamCommandConfig[]\n projectCommands?: TeamCommandConfig[]\n }\n\n // Hook \u914D\u7F6E\n hooks?: TeamHooksConfig // User-scope hooks\n projectHooks?: TeamHooksConfig // Project-scope hooks\n\n // Instructions for users\n postInstallInstructions?: string\n}\n\n/**\n * Model profile template with environment variable support\n */\nexport type TeamModelProfile = {\n name: string\n provider: ProviderType\n modelName: string\n baseURL?: string\n apiKey: string // Can be env var like \"${ANTHROPIC_API_KEY}\"\n maxTokens: number\n contextLength: number\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal'\n isActive?: boolean\n}\n\n/**\n * Inline agent configuration for team config\n */\nexport type TeamAgentConfig = {\n name: string // Agent identifier (e.g., \"research-analyst\")\n description: string // When to use this agent\n tools: string[] | '*' // Tool permissions\n systemPrompt: string // System prompt content\n model?: string // Optional model override\n color?: string // Optional UI color\n}\n\n/**\n * Hook configuration for team config\n */\nexport type TeamHooksConfig = {\n // Session lifecycle hooks\n sessionStart?: TeamHookDefinition[]\n sessionEnd?: TeamHookDefinition[]\n // User input hooks\n userPromptSubmit?: TeamHookDefinition[]\n // Tool lifecycle hooks\n preToolUse?: TeamToolHook[]\n postToolUse?: TeamToolHook[]\n}\n\nexport type TeamHookDefinition = {\n type: 'command' | 'prompt'\n command?: string\n prompt?: string\n timeout?: number\n description?: string\n}\n\nexport type TeamToolHook = {\n matcher: string // Tool name regex or \"*\"\n hooks: TeamHookDefinition[]\n}\n\n/**\n * MCP server config with env var support\n */\nexport type TeamMcpServerConfig = {\n type?: 'stdio' | 'sse'\n command?: string // For stdio\n args?: string[] // For stdio, supports env vars like \"${HOME}/.local/bin/mcp-server\"\n url?: string // For SSE\n env?: Record<string, string> // Env vars, supports interpolation\n enabled?: boolean\n}\n\n/**\n * Interpolate environment variables in a string\n * Supports ${VAR_NAME} syntax\n */\nexport function interpolateEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName.trim()]\n if (envValue === undefined) {\n debugLogger.warn('ENV_VAR_NOT_FOUND', {\n varName,\n original: match,\n })\n // Keep the placeholder if env var not found\n return match\n }\n return envValue\n })\n}\n\n/**\n * Recursively interpolate env vars in an object\n */\nexport function interpolateEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return interpolateEnvVars(obj) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => interpolateEnvVarsInObject(item)) as T\n }\n\n if (obj && typeof obj === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = interpolateEnvVarsInObject(value)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Convert team model profile to runtime model profile\n */\nexport function convertTeamModelProfile(\n teamProfile: TeamModelProfile,\n): ModelProfile {\n const now = Date.now()\n\n return {\n name: teamProfile.name,\n provider: teamProfile.provider,\n modelName: teamProfile.modelName,\n baseURL: teamProfile.baseURL,\n apiKey: interpolateEnvVars(teamProfile.apiKey),\n maxTokens: teamProfile.maxTokens,\n contextLength: teamProfile.contextLength,\n reasoningEffort: teamProfile.reasoningEffort,\n isActive: teamProfile.isActive ?? true,\n createdAt: now,\n lastUsed: now,\n }\n}\n\n/**\n * Convert team MCP config to runtime MCP config\n */\nexport function convertTeamMcpConfig(\n teamConfig: TeamMcpServerConfig,\n): McpServerConfig {\n if (teamConfig.type === 'sse') {\n return {\n type: 'sse',\n url: interpolateEnvVars(teamConfig.url || ''),\n enabled: teamConfig.enabled ?? true,\n }\n }\n\n // Default to stdio \u2014 auto-inject proxy bypass if system has proxy configured\n const env = teamConfig.env\n ? ensureProxyBypass(interpolateEnvVarsInObject(teamConfig.env))\n : hasSystemProxy()\n ? { no_proxy: '*', NO_PROXY: '*' }\n : undefined\n\n return {\n type: 'stdio',\n command: interpolateEnvVars(teamConfig.command || ''),\n args: (teamConfig.args || []).map(arg => interpolateEnvVars(arg)),\n env,\n enabled: teamConfig.enabled ?? true,\n }\n}\n\n/**\n * Fetch team configuration from a URL\n */\nexport async function fetchTeamConfig(url: string): Promise<TeamConfig> {\n debugLogger.state('TEAM_CONFIG_FETCH_START', { url })\n\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n })\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n )\n }\n\n const configText = await response.text()\n const config = JSON.parse(configText) as TeamConfig\n\n // Validate version\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_FETCH_SUCCESS', {\n url,\n configName: config.name,\n hasModels: !!config.models,\n hasMcpServers: !!config.mcpServers,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_FETCH_ERROR', {\n url,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Load team configuration from a local file\n */\nexport function loadTeamConfigFromFile(filePath: string): TeamConfig {\n debugLogger.state('TEAM_CONFIG_LOAD_FILE', { filePath })\n\n if (!existsSync(filePath)) {\n throw new Error(`Configuration file not found: ${filePath}`)\n }\n\n try {\n const configText = readFileSync(filePath, 'utf-8')\n const config = safeParseJSON(configText) as TeamConfig\n\n if (!config) {\n throw new Error('Invalid JSON in configuration file')\n }\n\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_LOAD_FILE_SUCCESS', {\n filePath,\n configName: config.name,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_LOAD_FILE_ERROR', {\n filePath,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Merge strategy for configuration\n */\nexport type MergeStrategy = 'replace' | 'merge' | 'skip-existing'\n\n/**\n * Apply team configuration to global config\n */\nexport function applyTeamConfig(\n teamConfig: TeamConfig,\n strategy: MergeStrategy = 'merge',\n): {\n applied: boolean\n modelsAdded: number\n mcpServersAdded: number\n settingsUpdated: string[]\n} {\n debugLogger.state('TEAM_CONFIG_APPLY_START', {\n configName: teamConfig.name,\n strategy,\n })\n\n const globalConfig = getMutableGlobalConfig()\n let modelsAdded = 0\n let mcpServersAdded = 0\n const settingsUpdated: string[] = []\n\n // Apply model profiles\n if (teamConfig.models?.profiles) {\n const existingProfiles = globalConfig.modelProfiles || []\n const existingModelNames = new Set(existingProfiles.map(p => p.modelName))\n\n for (const teamProfile of teamConfig.models.profiles) {\n const runtimeProfile = convertTeamModelProfile(teamProfile)\n\n if (\n strategy === 'skip-existing' &&\n existingModelNames.has(runtimeProfile.modelName)\n ) {\n debugLogger.state('TEAM_CONFIG_SKIP_MODEL', {\n modelName: runtimeProfile.modelName,\n reason: 'already_exists',\n })\n continue\n }\n\n if (strategy === 'replace') {\n // Remove existing profile with same modelName\n const index = existingProfiles.findIndex(\n p => p.modelName === runtimeProfile.modelName,\n )\n if (index !== -1) {\n existingProfiles.splice(index, 1)\n }\n }\n\n existingProfiles.push(runtimeProfile)\n modelsAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MODEL', {\n modelName: runtimeProfile.modelName,\n provider: runtimeProfile.provider,\n })\n }\n\n globalConfig.modelProfiles = existingProfiles\n }\n\n // Apply model pointers\n if (teamConfig.models?.pointers) {\n globalConfig.modelPointers = {\n ...(globalConfig.modelPointers || {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n compact: '',\n }),\n ...teamConfig.models.pointers,\n }\n settingsUpdated.push('modelPointers')\n }\n\n // Apply default model\n if (teamConfig.models?.defaultModel) {\n globalConfig.defaultModelName = teamConfig.models.defaultModel\n settingsUpdated.push('defaultModelName')\n }\n\n // Apply MCP servers\n if (teamConfig.mcpServers) {\n const existingMcpServers = globalConfig.mcpServers || {}\n const existingServerNames = new Set(Object.keys(existingMcpServers))\n\n for (const [serverName, teamMcpConfig] of Object.entries(\n teamConfig.mcpServers,\n )) {\n if (strategy === 'skip-existing' && existingServerNames.has(serverName)) {\n debugLogger.state('TEAM_CONFIG_SKIP_MCP', {\n serverName,\n reason: 'already_exists',\n })\n continue\n }\n\n const runtimeMcpConfig = convertTeamMcpConfig(teamMcpConfig)\n existingMcpServers[serverName] = runtimeMcpConfig\n mcpServersAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MCP', {\n serverName,\n type: runtimeMcpConfig.type || 'stdio',\n })\n }\n\n globalConfig.mcpServers = existingMcpServers\n }\n\n // Apply global settings\n if (teamConfig.settings) {\n const { settings } = teamConfig\n\n if (settings.theme !== undefined) {\n globalConfig.theme = settings.theme\n settingsUpdated.push('theme')\n }\n\n if (settings.verbose !== undefined) {\n globalConfig.verbose = settings.verbose\n settingsUpdated.push('verbose')\n }\n\n if (settings.compressionMode !== undefined) {\n globalConfig.compressionMode = settings.compressionMode\n settingsUpdated.push('compressionMode')\n }\n\n if (settings.thinking !== undefined) {\n globalConfig.thinking = settings.thinking\n settingsUpdated.push('thinking')\n }\n\n if (settings.proxy !== undefined) {\n globalConfig.proxy = settings.proxy\n settingsUpdated.push('proxy')\n }\n\n if (settings.stream !== undefined) {\n globalConfig.stream = settings.stream\n settingsUpdated.push('stream')\n }\n\n if (settings.language !== undefined) {\n globalConfig.language = settings.language\n settingsUpdated.push('language')\n }\n\n if (settings.safetyMode !== undefined) {\n globalConfig.safetyMode = settings.safetyMode\n settingsUpdated.push('safetyMode')\n }\n\n if (settings.skipOnboarding) {\n globalConfig.hasCompletedOnboarding = true\n settingsUpdated.push('hasCompletedOnboarding')\n }\n }\n\n // Save updated config\n saveGlobalConfig(globalConfig)\n\n debugLogger.state('TEAM_CONFIG_APPLY_SUCCESS', {\n configName: teamConfig.name,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated: settingsUpdated.join(', '),\n })\n\n return {\n applied: true,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated,\n }\n}\n\n/**\n * Add marketplaces from URLs\n */\nexport async function addMarketplaces(\n marketplaceUrls: string[],\n): Promise<{ added: number; failed: number; errors: string[] }> {\n let added = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager\n const { addMarketplace } = await import('./marketplaceManager')\n\n for (const url of marketplaceUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE', { url })\n\n await addMarketplace(url)\n added++\n\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE_SUCCESS', { url })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_ADD_MARKETPLACE_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { added, failed, errors }\n}\n\n/**\n * Install plugins from marketplaces\n */\nexport async function installPlugins(\n pluginNames: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager and path utilities\n const { installPluginFromMarketplace } = await import('./marketplaceManager')\n const { join } = await import('path')\n const { homedir } = await import('os')\n\n // Default target: ~/.minto/plugins\n const installDir = targetDir || join(homedir(), '.minto', 'plugins')\n\n for (const pluginSpec of pluginNames) {\n // Parse name@marketplace format (e.g., \"backend-development@claude-code-workflows\")\n const atIndex = pluginSpec.indexOf('@')\n const pluginName =\n atIndex !== -1 ? pluginSpec.slice(0, atIndex) : pluginSpec\n const marketplaceName =\n atIndex !== -1 ? pluginSpec.slice(atIndex + 1) : undefined\n\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN', {\n pluginName,\n marketplace: marketplaceName,\n targetDir: installDir,\n })\n\n await installPluginFromMarketplace(\n pluginName,\n marketplaceName,\n join(installDir, pluginName),\n )\n\n installed++\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN_SUCCESS', { pluginName })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${pluginName}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_PLUGIN_ERROR', {\n pluginName,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Download and install remote agents\n */\nexport async function installRemoteAgents(\n agentUrls: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/agents\n const agentsDir = targetDir || join(homedir(), '.minto', 'agents')\n if (!existsSync(agentsDir)) {\n mkdirSync(agentsDir, { recursive: true })\n }\n\n for (const url of agentUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_DOWNLOAD_AGENT', { url })\n\n const response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n })\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const content = await response.text()\n\n // Extract filename from URL\n const filename = url.split('/').pop() || 'agent.md'\n const targetPath = join(agentsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_DOWNLOAD_AGENT_SUCCESS', {\n url,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_DOWNLOAD_AGENT_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install inline agents from team config\n */\nexport async function installInlineAgents(\n agents: TeamAgentConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/agents\n const agentsDir = targetDir || join(homedir(), '.minto', 'agents')\n if (!existsSync(agentsDir)) {\n mkdirSync(agentsDir, { recursive: true })\n }\n\n for (const agent of agents) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_INLINE_AGENT', {\n name: agent.name,\n })\n\n // Generate agent markdown file\n const tools = agent.tools === '*' ? '*' : JSON.stringify(agent.tools)\n\n const content = `---\nname: ${agent.name}\ndescription: \"${agent.description.replace(/\"/g, '\\\\\"')}\"\ntools: ${tools}${agent.model ? `\\nmodel_name: ${agent.model}` : ''}${agent.color ? `\\ncolor: \"${agent.color}\"` : ''}\n---\n\n${agent.systemPrompt}\n`\n\n const filename = `${agent.name}.md`\n const targetPath = join(agentsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_INLINE_AGENT_SUCCESS', {\n name: agent.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${agent.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_INLINE_AGENT_ERROR', {\n name: agent.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install hooks from team config\n */\nexport async function installTeamHooks(\n hooks: TeamHooksConfig,\n targetPath?: string,\n): Promise<{ installed: boolean; error?: string }> {\n const { join, dirname } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync, readFileSync } = await import(\n 'fs'\n )\n\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_HOOKS', {})\n\n // Target: specified path or ~/.minto/hooks.json\n const hooksPath = targetPath || join(homedir(), '.minto', 'hooks.json')\n const hooksDir = dirname(hooksPath)\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true })\n }\n\n // Convert TeamHooksConfig to standard hooks format\n const hooksConfig: Record<string, unknown> = {\n description: 'Team-configured hooks',\n hooks: {} as Record<string, unknown>,\n }\n\n const hooksObj = hooksConfig.hooks as Record<string, unknown>\n\n if (hooks.sessionStart) {\n hooksObj.SessionStart = [{ matcher: '*', hooks: hooks.sessionStart }]\n }\n if (hooks.sessionEnd) {\n hooksObj.SessionEnd = [{ matcher: '*', hooks: hooks.sessionEnd }]\n }\n if (hooks.userPromptSubmit) {\n hooksObj.UserPromptSubmit = [\n { matcher: '*', hooks: hooks.userPromptSubmit },\n ]\n }\n if (hooks.preToolUse) {\n hooksObj.PreToolUse = hooks.preToolUse\n }\n if (hooks.postToolUse) {\n hooksObj.PostToolUse = hooks.postToolUse\n }\n\n // Merge with existing hooks if present\n if (existsSync(hooksPath)) {\n try {\n const existingContent = readFileSync(hooksPath, 'utf-8')\n const existingHooks = JSON.parse(existingContent)\n // Deep merge\n for (const [event, matchers] of Object.entries(hooksObj)) {\n if (existingHooks.hooks?.[event]) {\n existingHooks.hooks[event] = [\n ...existingHooks.hooks[event],\n ...(matchers as unknown[]),\n ]\n } else {\n existingHooks.hooks = existingHooks.hooks || {}\n existingHooks.hooks[event] = matchers\n }\n }\n hooksConfig.hooks = existingHooks.hooks\n } catch {\n // If parsing fails, overwrite\n }\n }\n\n writeFileSync(hooksPath, JSON.stringify(hooksConfig, null, 2), 'utf-8')\n\n debugLogger.state('TEAM_CONFIG_INSTALL_HOOKS_SUCCESS', { hooksPath })\n\n return { installed: true }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n debugLogger.error('TEAM_CONFIG_INSTALL_HOOKS_ERROR', { error: errorMsg })\n return { installed: false, error: errorMsg }\n }\n}\n\n/**\n * Install standalone skills from team config\n */\nexport async function installInlineSkills(\n skills: TeamSkillConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/skills\n const skillsDir = targetDir || join(homedir(), '.minto', 'skills')\n if (!existsSync(skillsDir)) {\n mkdirSync(skillsDir, { recursive: true })\n }\n\n for (const skill of skills) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_SKILL', { name: skill.name })\n\n // Build frontmatter\n const frontmatterLines: string[] = [\n `name: ${skill.name}`,\n `description: \"${skill.description.replace(/\"/g, '\\\\\"')}\"`,\n ]\n if (skill.argumentHint) {\n frontmatterLines.push(`argument-hint: \"${skill.argumentHint}\"`)\n }\n if (skill.disableModelInvocation !== undefined) {\n frontmatterLines.push(\n `disable-model-invocation: ${skill.disableModelInvocation}`,\n )\n }\n if (skill.userInvocable !== undefined) {\n frontmatterLines.push(`user-invocable: ${skill.userInvocable}`)\n }\n if (skill.allowedTools && skill.allowedTools.length > 0) {\n frontmatterLines.push(\n `allowed-tools: ${JSON.stringify(skill.allowedTools)}`,\n )\n }\n if (skill.model) {\n frontmatterLines.push(`model: ${skill.model}`)\n }\n if (skill.context) {\n frontmatterLines.push(`context: \"${skill.context}\"`)\n }\n if (skill.agent) {\n frontmatterLines.push(`agent: \"${skill.agent}\"`)\n }\n\n const content = `---\\n${frontmatterLines.join('\\n')}\\n---\\n\\n${skill.content}\\n`\n\n const filename = `${skill.name}.md`\n const targetPath = join(skillsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_SKILL_SUCCESS', {\n name: skill.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${skill.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_SKILL_ERROR', {\n name: skill.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n\n/**\n * Install standalone commands from team config\n */\nexport async function installInlineCommands(\n commands: TeamCommandConfig[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { writeFileSync, mkdirSync, existsSync } = await import('fs')\n\n // Target: specified dir or ~/.minto/commands\n const commandsDir = targetDir || join(homedir(), '.minto', 'commands')\n if (!existsSync(commandsDir)) {\n mkdirSync(commandsDir, { recursive: true })\n }\n\n for (const cmd of commands) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_COMMAND', { name: cmd.name })\n\n // Build frontmatter\n const frontmatterLines: string[] = [`name: ${cmd.name}`]\n if (cmd.description) {\n frontmatterLines.push(\n `description: \"${cmd.description.replace(/\"/g, '\\\\\"')}\"`,\n )\n }\n if (cmd.aliases && cmd.aliases.length > 0) {\n frontmatterLines.push(`aliases: ${JSON.stringify(cmd.aliases)}`)\n }\n if (cmd.enabled !== undefined) {\n frontmatterLines.push(`enabled: ${cmd.enabled}`)\n }\n if (cmd.hidden !== undefined) {\n frontmatterLines.push(`hidden: ${cmd.hidden}`)\n }\n if (cmd.progressMessage) {\n frontmatterLines.push(`progressMessage: \"${cmd.progressMessage}\"`)\n }\n if (cmd.argNames && cmd.argNames.length > 0) {\n frontmatterLines.push(`argNames: ${JSON.stringify(cmd.argNames)}`)\n }\n if (cmd.allowedTools && cmd.allowedTools.length > 0) {\n frontmatterLines.push(\n `allowed-tools: ${JSON.stringify(cmd.allowedTools)}`,\n )\n }\n\n const content = `---\\n${frontmatterLines.join('\\n')}\\n---\\n\\n${cmd.content}\\n`\n\n const filename = `${cmd.name}.md`\n const targetPath = join(commandsDir, filename)\n\n writeFileSync(targetPath, content, 'utf-8')\n installed++\n\n debugLogger.state('TEAM_CONFIG_INSTALL_COMMAND_SUCCESS', {\n name: cmd.name,\n targetPath,\n })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${cmd.name}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_COMMAND_ERROR', {\n name: cmd.name,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["existsSync", "readFileSync"]
|
|
7
7
|
}
|
package/dist/utils/thinking.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { last } from "lodash-es";
|
|
2
2
|
import { ThinkTool } from "../tools/ThinkTool/ThinkTool.js";
|
|
3
3
|
import { getModelManager } from "./model.js";
|
|
4
|
+
import { getGlobalConfig } from "./config.js";
|
|
5
|
+
const DEFAULT_THINKING_TOKENS = 4e3;
|
|
4
6
|
async function getMaxThinkingTokens(messages) {
|
|
5
7
|
if (process.env.MAX_THINKING_TOKENS) {
|
|
6
8
|
const tokens = parseInt(process.env.MAX_THINKING_TOKENS, 10);
|
|
@@ -11,7 +13,8 @@ async function getMaxThinkingTokens(messages) {
|
|
|
11
13
|
}
|
|
12
14
|
const lastMessage = last(messages);
|
|
13
15
|
if (lastMessage?.type !== "user" || typeof lastMessage.message.content !== "string") {
|
|
14
|
-
|
|
16
|
+
const config2 = getGlobalConfig();
|
|
17
|
+
return config2.thinking ? DEFAULT_THINKING_TOKENS : 0;
|
|
15
18
|
}
|
|
16
19
|
const content = lastMessage.message.content.toLowerCase();
|
|
17
20
|
if (content.includes("think harder") || content.includes("think intensely") || content.includes("think longer") || content.includes("think really hard") || content.includes("think super hard") || content.includes("think very hard") || content.includes("ultrathink")) {
|
|
@@ -23,7 +26,8 @@ async function getMaxThinkingTokens(messages) {
|
|
|
23
26
|
if (content.includes("think")) {
|
|
24
27
|
return 4e3;
|
|
25
28
|
}
|
|
26
|
-
|
|
29
|
+
const config = getGlobalConfig();
|
|
30
|
+
return config.thinking ? DEFAULT_THINKING_TOKENS : 0;
|
|
27
31
|
}
|
|
28
32
|
async function getReasoningEffort(modelProfile, messages) {
|
|
29
33
|
const thinkingTokens = await getMaxThinkingTokens(messages);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/thinking.ts"],
|
|
4
|
-
"sourcesContent": ["import { last } from 'lodash-es'\nimport type { Message } from '@query'\nimport { getLastAssistantMessageId } from './messages'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { USE_BEDROCK, USE_VERTEX, getModelManager } from './model'\n\nexport async function getMaxThinkingTokens(\n messages: Message[],\n): Promise<number> {\n if (process.env.MAX_THINKING_TOKENS) {\n const tokens = parseInt(process.env.MAX_THINKING_TOKENS, 10)\n return tokens\n }\n\n if (await ThinkTool.isEnabled()) {\n return 0\n }\n\n const lastMessage = last(messages)\n if (\n lastMessage?.type !== 'user' ||\n typeof lastMessage.message.content !== 'string'\n ) {\n return 0\n }\n\n const content = lastMessage.message.content.toLowerCase()\n if (\n content.includes('think harder') ||\n content.includes('think intensely') ||\n content.includes('think longer') ||\n content.includes('think really hard') ||\n content.includes('think super hard') ||\n content.includes('think very hard') ||\n content.includes('ultrathink')\n ) {\n return 32_000 - 1\n }\n\n if (\n content.includes('think about it') ||\n content.includes('think a lot') ||\n content.includes('think hard') ||\n content.includes('think more') ||\n content.includes('megathink')\n ) {\n return 10_000\n }\n\n if (content.includes('think')) {\n return 4_000\n }\n\n return 0\n}\n\nexport async function getReasoningEffort(\n modelProfile: any,\n messages: Message[],\n): Promise<'low' | 'medium' | 'high' | null> {\n const thinkingTokens = await getMaxThinkingTokens(messages)\n\n // Get reasoning effort from ModelProfile first, then fallback to config\n let reasoningEffort: 'low' | 'medium' | 'high' | undefined\n if (modelProfile?.reasoningEffort) {\n reasoningEffort = modelProfile.reasoningEffort\n } else {\n // \uD83D\uDD27 Fix: Use ModelManager fallback instead of legacy config\n const modelManager = getModelManager()\n const fallbackProfile = modelManager.getModel('main')\n reasoningEffort =\n (fallbackProfile?.reasoningEffort === 'minimal'\n ? 'low'\n : fallbackProfile?.reasoningEffort) || 'medium'\n }\n\n const maxEffort =\n reasoningEffort === 'high'\n ? 2\n : reasoningEffort === 'medium'\n ? 1\n : reasoningEffort === 'low'\n ? 0\n : null\n if (!maxEffort) {\n return null\n }\n\n let effort = 0\n if (thinkingTokens < 10_000) {\n effort = 0\n } else if (thinkingTokens >= 10_000 && thinkingTokens < 30_000) {\n effort = 1\n } else {\n effort = 2\n }\n\n if (effort > maxEffort) {\n return maxEffort === 2 ? 'high' : maxEffort === 1 ? 'medium' : 'low'\n }\n\n return effort === 2 ? 'high' : effort === 1 ? 'medium' : 'low'\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAkC,uBAAuB;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { last } from 'lodash-es'\nimport type { Message } from '@query'\nimport { getLastAssistantMessageId } from './messages'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { USE_BEDROCK, USE_VERTEX, getModelManager } from './model'\nimport { getGlobalConfig } from './config'\n\n// Default thinking tokens when thinking mode is enabled via toggle\nconst DEFAULT_THINKING_TOKENS = 4_000\n\nexport async function getMaxThinkingTokens(\n messages: Message[],\n): Promise<number> {\n if (process.env.MAX_THINKING_TOKENS) {\n const tokens = parseInt(process.env.MAX_THINKING_TOKENS, 10)\n return tokens\n }\n\n if (await ThinkTool.isEnabled()) {\n return 0\n }\n\n const lastMessage = last(messages)\n if (\n lastMessage?.type !== 'user' ||\n typeof lastMessage.message.content !== 'string'\n ) {\n // Even without a text message, respect the thinking toggle\n const config = getGlobalConfig()\n return config.thinking ? DEFAULT_THINKING_TOKENS : 0\n }\n\n const content = lastMessage.message.content.toLowerCase()\n if (\n content.includes('think harder') ||\n content.includes('think intensely') ||\n content.includes('think longer') ||\n content.includes('think really hard') ||\n content.includes('think super hard') ||\n content.includes('think very hard') ||\n content.includes('ultrathink')\n ) {\n return 32_000 - 1\n }\n\n if (\n content.includes('think about it') ||\n content.includes('think a lot') ||\n content.includes('think hard') ||\n content.includes('think more') ||\n content.includes('megathink')\n ) {\n return 10_000\n }\n\n if (content.includes('think')) {\n return 4_000\n }\n\n // Fallback: respect config.thinking toggle\n const config = getGlobalConfig()\n return config.thinking ? DEFAULT_THINKING_TOKENS : 0\n}\n\nexport async function getReasoningEffort(\n modelProfile: any,\n messages: Message[],\n): Promise<'low' | 'medium' | 'high' | null> {\n const thinkingTokens = await getMaxThinkingTokens(messages)\n\n // Get reasoning effort from ModelProfile first, then fallback to config\n let reasoningEffort: 'low' | 'medium' | 'high' | undefined\n if (modelProfile?.reasoningEffort) {\n reasoningEffort = modelProfile.reasoningEffort\n } else {\n // \uD83D\uDD27 Fix: Use ModelManager fallback instead of legacy config\n const modelManager = getModelManager()\n const fallbackProfile = modelManager.getModel('main')\n reasoningEffort =\n (fallbackProfile?.reasoningEffort === 'minimal'\n ? 'low'\n : fallbackProfile?.reasoningEffort) || 'medium'\n }\n\n const maxEffort =\n reasoningEffort === 'high'\n ? 2\n : reasoningEffort === 'medium'\n ? 1\n : reasoningEffort === 'low'\n ? 0\n : null\n if (!maxEffort) {\n return null\n }\n\n let effort = 0\n if (thinkingTokens < 10_000) {\n effort = 0\n } else if (thinkingTokens >= 10_000 && thinkingTokens < 30_000) {\n effort = 1\n } else {\n effort = 2\n }\n\n if (effort > maxEffort) {\n return maxEffort === 2 ? 'high' : maxEffort === 1 ? 'medium' : 'low'\n }\n\n return effort === 2 ? 'high' : effort === 1 ? 'medium' : 'low'\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAkC,uBAAuB;AACzD,SAAS,uBAAuB;AAGhC,MAAM,0BAA0B;AAEhC,eAAsB,qBACpB,UACiB;AACjB,MAAI,QAAQ,IAAI,qBAAqB;AACnC,UAAM,SAAS,SAAS,QAAQ,IAAI,qBAAqB,EAAE;AAC3D,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,UAAU,UAAU,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,KAAK,QAAQ;AACjC,MACE,aAAa,SAAS,UACtB,OAAO,YAAY,QAAQ,YAAY,UACvC;AAEA,UAAMA,UAAS,gBAAgB;AAC/B,WAAOA,QAAO,WAAW,0BAA0B;AAAA,EACrD;AAEA,QAAM,UAAU,YAAY,QAAQ,QAAQ,YAAY;AACxD,MACE,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,kBAAkB,KACnC,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,YAAY,GAC7B;AACA,WAAO,OAAS;AAAA,EAClB;AAEA,MACE,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,aAAa,KAC9B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,WAAW,GAC5B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,gBAAgB;AAC/B,SAAO,OAAO,WAAW,0BAA0B;AACrD;AAEA,eAAsB,mBACpB,cACA,UAC2C;AAC3C,QAAM,iBAAiB,MAAM,qBAAqB,QAAQ;AAG1D,MAAI;AACJ,MAAI,cAAc,iBAAiB;AACjC,sBAAkB,aAAa;AAAA,EACjC,OAAO;AAEL,UAAM,eAAe,gBAAgB;AACrC,UAAM,kBAAkB,aAAa,SAAS,MAAM;AACpD,uBACG,iBAAiB,oBAAoB,YAClC,QACA,iBAAiB,oBAAoB;AAAA,EAC7C;AAEA,QAAM,YACJ,oBAAoB,SAChB,IACA,oBAAoB,WAClB,IACA,oBAAoB,QAClB,IACA;AACV,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,MAAI,iBAAiB,KAAQ;AAC3B,aAAS;AAAA,EACX,WAAW,kBAAkB,OAAU,iBAAiB,KAAQ;AAC9D,aAAS;AAAA,EACX,OAAO;AACL,aAAS;AAAA,EACX;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,cAAc,IAAI,SAAS,cAAc,IAAI,WAAW;AAAA,EACjE;AAEA,SAAO,WAAW,IAAI,SAAS,WAAW,IAAI,WAAW;AAC3D;",
|
|
6
|
+
"names": ["config"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getStreamingState,
|
|
3
|
+
setStreamingState,
|
|
4
|
+
getMainStreamingState
|
|
5
|
+
} from "./streamingState.js";
|
|
6
|
+
import { formatNumber } from "./format.js";
|
|
7
|
+
function beginTokenTracking() {
|
|
8
|
+
const state = getStreamingState();
|
|
9
|
+
const currentOutput = state.outputTokens || (state.receivedChars && state.receivedChars > 0 ? Math.round(state.receivedChars / 4) : 0);
|
|
10
|
+
setStreamingState({
|
|
11
|
+
sentChars: 0,
|
|
12
|
+
sentCharsSetAt: Date.now(),
|
|
13
|
+
receivedChars: 0,
|
|
14
|
+
inputTokens: void 0,
|
|
15
|
+
outputTokens: void 0,
|
|
16
|
+
streamingText: void 0,
|
|
17
|
+
cumulativeOutputTokens: (state.cumulativeOutputTokens || 0) + currentOutput
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function addPreparedChars(chars) {
|
|
21
|
+
const state = getStreamingState();
|
|
22
|
+
setStreamingState({
|
|
23
|
+
sentChars: (state.sentChars || 0) + chars
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function addReceivedChars(chars) {
|
|
27
|
+
const state = getStreamingState();
|
|
28
|
+
setStreamingState({
|
|
29
|
+
receivedChars: (state.receivedChars || 0) + chars
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function setFinalTokens(counts) {
|
|
33
|
+
const update = {};
|
|
34
|
+
if (counts.input !== void 0) update.inputTokens = counts.input;
|
|
35
|
+
if (counts.output !== void 0) update.outputTokens = counts.output;
|
|
36
|
+
setStreamingState(update);
|
|
37
|
+
}
|
|
38
|
+
function getTokenDisplay(agentId) {
|
|
39
|
+
const state = agentId ? getStreamingState(agentId) : getMainStreamingState();
|
|
40
|
+
const input = state.inputTokens || (state.sentChars && state.sentChars > 0 ? Math.round(state.sentChars / 4) : void 0);
|
|
41
|
+
const currentOutput = state.outputTokens || (state.receivedChars && state.receivedChars > 0 ? Math.round(state.receivedChars / 4) : 0);
|
|
42
|
+
const totalOutput = (state.cumulativeOutputTokens || 0) + currentOutput;
|
|
43
|
+
if (!totalOutput) return { input, output: void 0, formatted: "" };
|
|
44
|
+
const arrow = state.phase === "generating" ? "\u2193" : "\u2191";
|
|
45
|
+
const formatted = `${arrow} ${formatNumber(totalOutput)} tokens`;
|
|
46
|
+
return { input, output: totalOutput, formatted };
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
addPreparedChars,
|
|
50
|
+
addReceivedChars,
|
|
51
|
+
beginTokenTracking,
|
|
52
|
+
getTokenDisplay,
|
|
53
|
+
setFinalTokens
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=tokenProgress.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/tokenProgress.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Token Progress Tracking\n *\n * Unified module for tracking token counts during API request/response lifecycle.\n * Providers call mutator functions as data is prepared (system prompt, tools, messages)\n * and received (per streaming chunk). UI components call getTokenDisplay() for current values.\n *\n * Flow:\n * 1. beginTokenTracking() \u2014 reset counters at query start\n * 2. addPreparedChars(n) \u2014 called per preparation stage (system, tools, messages)\n * \u2191 grows in real-time as each part of the request payload is serialized\n * 3. addReceivedChars(n) \u2014 called per streaming content chunk\n * \u2193 grows in real-time as response data arrives\n * 4. setFinalTokens({in, out}) \u2014 called when API provides real token counts\n * Replaces estimates with accurate API-reported values\n */\n\nimport {\n getStreamingState,\n setStreamingState,\n getMainStreamingState,\n type StreamingStateData,\n} from './streamingState'\nimport { formatNumber } from './format'\n\n// \u2500\u2500 Provider API: call these as data is prepared/received \u2500\u2500\n\n/**\n * Begin tracking a new query. Resets per-call counters but preserves\n * cumulative output tokens so the display doesn't gap between API calls.\n * Call at the start of queryOpenAI / queryAnthropicNative.\n */\nexport function beginTokenTracking(): void {\n const state = getStreamingState()\n // Snapshot current output tokens into cumulative total before resetting.\n // This keeps the displayed count continuous across tool-use \u2192 re-query cycles.\n const currentOutput =\n state.outputTokens ||\n (state.receivedChars && state.receivedChars > 0\n ? Math.round(state.receivedChars / 4)\n : 0)\n setStreamingState({\n sentChars: 0,\n sentCharsSetAt: Date.now(),\n receivedChars: 0,\n inputTokens: undefined,\n outputTokens: undefined,\n streamingText: undefined,\n cumulativeOutputTokens: (state.cumulativeOutputTokens || 0) + currentOutput,\n })\n}\n\n/**\n * Add chars to the \"prepared for sending\" counter.\n * Call as each part of the request payload is serialized:\n * addPreparedChars(systemChars) \u2014 after system prompt\n * addPreparedChars(toolChars) \u2014 per tool schema (inside Promise.all)\n * addPreparedChars(messageChars) \u2014 after message conversion\n *\n * The \u2191 display updates in real-time as preparation progresses.\n */\nexport function addPreparedChars(chars: number): void {\n const state = getStreamingState()\n setStreamingState({\n sentChars: (state.sentChars || 0) + chars,\n })\n}\n\n/**\n * Add chars to the \"received from streaming\" counter.\n * Call for each content chunk received from the API.\n * The \u2193 display updates in real-time as data arrives.\n */\nexport function addReceivedChars(chars: number): void {\n const state = getStreamingState()\n setStreamingState({\n receivedChars: (state.receivedChars || 0) + chars,\n })\n}\n\n/**\n * Set final token counts from API response.\n * Replaces estimated values with accurate API-reported counts.\n *\n * Call when the API provides usage data:\n * Anthropic: message_start (input), message_delta (output)\n * OpenAI: stream end with usage (both)\n */\nexport function setFinalTokens(counts: {\n input?: number\n output?: number\n}): void {\n const update: Partial<StreamingStateData> = {}\n if (counts.input !== undefined) update.inputTokens = counts.input\n if (counts.output !== undefined) update.outputTokens = counts.output\n setStreamingState(update)\n}\n\n// \u2500\u2500 UI API: call this to get current display values \u2500\u2500\n\n/**\n * Get current token display values.\n *\n * Display format aligned with Claude Code:\n * \u2191 X tokens \u2014 during sending/processing phase (thinking, waiting, etc.)\n * \u2193 X tokens \u2014 during content receiving phase (generating)\n *\n * Arrow indicates streaming phase, number is cumulative output tokens\n * across all API calls within the current turn. This prevents the display\n * from disappearing between tool-use cycles.\n *\n * @param agentId - Optional agent ID. Null/undefined reads main agent state.\n */\nexport function getTokenDisplay(agentId?: string | null): {\n input?: number\n output?: number\n formatted: string\n} {\n const state = agentId ? getStreamingState(agentId) : getMainStreamingState()\n\n // Input: real API value > preparation progress estimate\n const input =\n state.inputTokens ||\n (state.sentChars && state.sentChars > 0\n ? Math.round(state.sentChars / 4)\n : undefined)\n\n // Current call's output: API value > received chars estimate\n const currentOutput =\n state.outputTokens ||\n (state.receivedChars && state.receivedChars > 0\n ? Math.round(state.receivedChars / 4)\n : 0)\n\n // Total output = cumulative from prior calls + current call\n const totalOutput = (state.cumulativeOutputTokens || 0) + currentOutput\n\n if (!totalOutput) return { input, output: undefined, formatted: '' }\n\n // Arrow indicates streaming phase: \u2191 = sending/processing, \u2193 = receiving content\n const arrow = state.phase === 'generating' ? '\u2193' : '\u2191'\n const formatted = `${arrow} ${formatNumber(totalOutput)} tokens`\n\n return { input, output: totalOutput, formatted }\n}\n"],
|
|
5
|
+
"mappings": "AAiBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,oBAAoB;AAStB,SAAS,qBAA2B;AACzC,QAAM,QAAQ,kBAAkB;AAGhC,QAAM,gBACJ,MAAM,iBACL,MAAM,iBAAiB,MAAM,gBAAgB,IAC1C,KAAK,MAAM,MAAM,gBAAgB,CAAC,IAClC;AACN,oBAAkB;AAAA,IAChB,WAAW;AAAA,IACX,gBAAgB,KAAK,IAAI;AAAA,IACzB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,eAAe;AAAA,IACf,yBAAyB,MAAM,0BAA0B,KAAK;AAAA,EAChE,CAAC;AACH;AAWO,SAAS,iBAAiB,OAAqB;AACpD,QAAM,QAAQ,kBAAkB;AAChC,oBAAkB;AAAA,IAChB,YAAY,MAAM,aAAa,KAAK;AAAA,EACtC,CAAC;AACH;AAOO,SAAS,iBAAiB,OAAqB;AACpD,QAAM,QAAQ,kBAAkB;AAChC,oBAAkB;AAAA,IAChB,gBAAgB,MAAM,iBAAiB,KAAK;AAAA,EAC9C,CAAC;AACH;AAUO,SAAS,eAAe,QAGtB;AACP,QAAM,SAAsC,CAAC;AAC7C,MAAI,OAAO,UAAU,OAAW,QAAO,cAAc,OAAO;AAC5D,MAAI,OAAO,WAAW,OAAW,QAAO,eAAe,OAAO;AAC9D,oBAAkB,MAAM;AAC1B;AAiBO,SAAS,gBAAgB,SAI9B;AACA,QAAM,QAAQ,UAAU,kBAAkB,OAAO,IAAI,sBAAsB;AAG3E,QAAM,QACJ,MAAM,gBACL,MAAM,aAAa,MAAM,YAAY,IAClC,KAAK,MAAM,MAAM,YAAY,CAAC,IAC9B;AAGN,QAAM,gBACJ,MAAM,iBACL,MAAM,iBAAiB,MAAM,gBAAgB,IAC1C,KAAK,MAAM,MAAM,gBAAgB,CAAC,IAClC;AAGN,QAAM,eAAe,MAAM,0BAA0B,KAAK;AAE1D,MAAI,CAAC,YAAa,QAAO,EAAE,OAAO,QAAQ,QAAW,WAAW,GAAG;AAGnE,QAAM,QAAQ,MAAM,UAAU,eAAe,WAAM;AACnD,QAAM,YAAY,GAAG,KAAK,IAAI,aAAa,WAAW,CAAC;AAEvD,SAAO,EAAE,OAAO,QAAQ,aAAa,UAAU;AACjD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -31,8 +31,8 @@ const TOOL_RISK_LEVELS = {
|
|
|
31
31
|
MCPTool: "dangerous"
|
|
32
32
|
};
|
|
33
33
|
const SAFE_BASH_PATTERNS = [
|
|
34
|
-
// Git -
|
|
35
|
-
/^git\s+(status|diff|log|branch|show|remote|fetch|
|
|
34
|
+
// Git - read-only operations (safe)
|
|
35
|
+
/^git\s+(status|diff|log|branch|show|remote|fetch|rev-parse|symbolic-ref)/i,
|
|
36
36
|
// File viewing (read-only)
|
|
37
37
|
/^ls(\s|$)/i,
|
|
38
38
|
/^cat\s/i,
|
|
@@ -54,11 +54,9 @@ const SAFE_BASH_PATTERNS = [
|
|
|
54
54
|
/^stat\s/i,
|
|
55
55
|
/^du\s/i,
|
|
56
56
|
/^df\s/i,
|
|
57
|
-
// Package managers - common development operations
|
|
57
|
+
// Package managers - common development operations (npx/bunx moved to monitored)
|
|
58
58
|
/^npm\s+(install|i|ci|run|test|start|build|list|ls|outdated|view|info|init|publish|pack|version|audit|dedupe)/i,
|
|
59
|
-
/^npx\s/i,
|
|
60
59
|
/^bun\s+(install|i|add|remove|run|test|build|pm|create|init|link|unlink|update|outdated)/i,
|
|
61
|
-
/^bunx\s/i,
|
|
62
60
|
/^yarn\s+(install|add|remove|run|test|build|init|create|link|unlink|upgrade|outdated)/i,
|
|
63
61
|
/^pnpm\s+(install|i|add|remove|run|test|build|init|create|link|unlink|update|outdated)/i,
|
|
64
62
|
/^pip\s+(install|list|show|freeze|check)/i,
|
|
@@ -72,10 +70,7 @@ const SAFE_BASH_PATTERNS = [
|
|
|
72
70
|
// Version queries
|
|
73
71
|
/^(node|npm|bun|yarn|pnpm|python|python3|pip|pip3|cargo|rustc|go|java|ruby|php)\s+(--version|-v|-V)$/i,
|
|
74
72
|
/^(node|npm|bun|yarn|pnpm|python|python3|pip|pip3|cargo|rustc|go|java|ruby|php)\s+-version$/i,
|
|
75
|
-
//
|
|
76
|
-
/^make(\s|$)/i,
|
|
77
|
-
/^cmake\s/i,
|
|
78
|
-
/^ninja(\s|$)/i,
|
|
73
|
+
// Test tools (make/cmake/ninja moved to monitored — can execute arbitrary code)
|
|
79
74
|
/^pytest(\s|$)/i,
|
|
80
75
|
/^jest(\s|$)/i,
|
|
81
76
|
/^vitest(\s|$)/i,
|
|
@@ -87,10 +82,10 @@ const SAFE_BASH_PATTERNS = [
|
|
|
87
82
|
/^eslint(\s|$)/i,
|
|
88
83
|
/^prettier(\s|$)/i,
|
|
89
84
|
/^biome(\s|$)/i,
|
|
90
|
-
// Docker (read-only
|
|
85
|
+
// Docker (read-only only — mutating commands moved to monitored)
|
|
91
86
|
/^docker\s+(ps|images|logs|inspect|version|info|stats|top|port|diff)/i,
|
|
92
|
-
/^docker\s+(build|
|
|
93
|
-
/^docker-compose\s+(ps|logs|config
|
|
87
|
+
/^docker\s+(build|pull)/i,
|
|
88
|
+
/^docker-compose\s+(ps|logs|config)/i,
|
|
94
89
|
// Kubernetes (read-only)
|
|
95
90
|
/^kubectl\s+(get|describe|logs|explain|version|config|cluster-info)/i,
|
|
96
91
|
// Process viewing
|
|
@@ -113,17 +108,30 @@ const SAFE_BASH_PATTERNS = [
|
|
|
113
108
|
/^sort(\s|$)/i,
|
|
114
109
|
/^uniq(\s|$)/i,
|
|
115
110
|
/^cut(\s|$)/i,
|
|
116
|
-
/^awk\s/i,
|
|
117
|
-
/^sed\s/i,
|
|
118
111
|
/^tr\s/i,
|
|
119
112
|
/^diff\s/i,
|
|
120
113
|
/^md5sum\s/i,
|
|
121
114
|
/^sha256sum\s/i,
|
|
122
|
-
// Directory operations (safe)
|
|
115
|
+
// Directory operations (safe creation; cp/mv moved to monitored)
|
|
123
116
|
/^mkdir\s/i,
|
|
124
|
-
/^touch\s/i
|
|
117
|
+
/^touch\s/i
|
|
118
|
+
];
|
|
119
|
+
const MONITORED_BASH_PATTERNS = [
|
|
120
|
+
// Git - mutating operations
|
|
121
|
+
/^git\s+(commit|add|checkout|merge|rebase|stash|tag|push|pull|clone|init|config)/i,
|
|
122
|
+
// Package runner / arbitrary code execution
|
|
123
|
+
/^npx\s/i,
|
|
124
|
+
/^bunx\s/i,
|
|
125
|
+
// Build tools (can execute arbitrary code via Makefiles, etc.)
|
|
126
|
+
/^make(\s|$)/i,
|
|
127
|
+
/^cmake\s/i,
|
|
128
|
+
/^ninja(\s|$)/i,
|
|
129
|
+
// File copy/move
|
|
125
130
|
/^cp\s/i,
|
|
126
|
-
/^mv\s/i
|
|
131
|
+
/^mv\s/i,
|
|
132
|
+
// Docker mutating operations
|
|
133
|
+
/^docker\s+(start|stop|restart|push)/i,
|
|
134
|
+
/^docker-compose\s+(up|down|build|pull|restart)/i
|
|
127
135
|
];
|
|
128
136
|
const DANGEROUS_BASH_PATTERNS = [
|
|
129
137
|
// File deletion
|
|
@@ -193,6 +201,7 @@ function getToolRiskLevel(toolName, input) {
|
|
|
193
201
|
}
|
|
194
202
|
export {
|
|
195
203
|
DANGEROUS_BASH_PATTERNS,
|
|
204
|
+
MONITORED_BASH_PATTERNS,
|
|
196
205
|
SAFE_BASH_PATTERNS,
|
|
197
206
|
TOOL_RISK_LEVELS,
|
|
198
207
|
classifyBashCommand,
|