@within-7/minto 0.4.0 → 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/groupHandlers/parallelTasksHandler.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Parallel Tasks Group Handler\n *\n * Handles concurrent Task tool calls (multiple Tasks in same AssistantMessage).\n * Creates a group that contains multiple task groups as children.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { NormalizedMessage } from '@utils/messages'\nimport type {\n MessageGroup,\n IdentifiedGroup,\n ResolutionState,\n PositionAnchor,\n} from '@minto-types/messageGroup'\nimport type { GroupTypeHandler } from './types'\nimport { getAgentIdByToolUseId } from '@utils/agentTranscripts'\n\nexport class ParallelTasksHandler implements GroupTypeHandler {\n type = 'parallel-tasks' as const\n\n identify(messages: NormalizedMessage[]): IdentifiedGroup[] {\n const groups: IdentifiedGroup[] = []\n const processedOriginalUuids = new Set<string>() // Track processed original message UUIDs\n\n // Strategy 1 (Primary): Use originalUuid to identify parallel Task groups\n // Normalized messages from the same original assistant message share the same originalUuid\n // This is more reliable than depending on progress messages\n const tasksByOriginalUuid = new Map<\n string,\n Array<{ uuid: string; toolUseId: string }>\n >()\n\n for (const msg of messages) {\n if (msg.type !== 'assistant') continue\n if (!Array.isArray(msg.message.content)) continue\n\n // Get the originalUuid (falls back to uuid for non-split messages)\n const originalUuid = msg.originalUuid || msg.uuid\n\n const toolUse = msg.message.content.find(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use'
|
|
5
|
-
"mappings": "AAgBA,SAAS,6BAA6B;AAE/B,MAAM,qBAAiD;AAAA,EAC5D,OAAO;AAAA,EAEP,SAAS,UAAkD;AACzD,UAAM,SAA4B,CAAC;AACnC,UAAM,yBAAyB,oBAAI,IAAY;AAK/C,UAAM,sBAAsB,oBAAI,IAG9B;AAEF,eAAW,OAAO,UAAU;AAC1B,UAAI,IAAI,SAAS,YAAa;AAC9B,UAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,OAAO,EAAG;AAGzC,YAAM,eAAe,IAAI,gBAAgB,IAAI;AAE7C,YAAM,UAAU,IAAI,QAAQ,QAAQ;AAAA,QAClC,CAAC,UACC,MAAM,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Parallel Tasks Group Handler\n *\n * Handles concurrent Task tool calls (multiple Tasks in same AssistantMessage).\n * Creates a group that contains multiple task groups as children.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { NormalizedMessage } from '@utils/messages'\nimport type {\n MessageGroup,\n IdentifiedGroup,\n ResolutionState,\n PositionAnchor,\n} from '@minto-types/messageGroup'\nimport type { GroupTypeHandler } from './types'\nimport { getAgentIdByToolUseId } from '@utils/agentTranscripts'\n\nexport class ParallelTasksHandler implements GroupTypeHandler {\n type = 'parallel-tasks' as const\n\n identify(messages: NormalizedMessage[]): IdentifiedGroup[] {\n const groups: IdentifiedGroup[] = []\n const processedOriginalUuids = new Set<string>() // Track processed original message UUIDs\n\n // Strategy 1 (Primary): Use originalUuid to identify parallel Task groups\n // Normalized messages from the same original assistant message share the same originalUuid\n // This is more reliable than depending on progress messages\n const tasksByOriginalUuid = new Map<\n string,\n Array<{ uuid: string; toolUseId: string }>\n >()\n\n for (const msg of messages) {\n if (msg.type !== 'assistant') continue\n if (!Array.isArray(msg.message.content)) continue\n\n // Get the originalUuid (falls back to uuid for non-split messages)\n const originalUuid = msg.originalUuid || msg.uuid\n\n const toolUse = msg.message.content.find(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' &&\n (block.name === 'Agent' || block.name === 'Task'),\n )\n\n if (toolUse) {\n if (!tasksByOriginalUuid.has(originalUuid)) {\n tasksByOriginalUuid.set(originalUuid, [])\n }\n tasksByOriginalUuid.get(originalUuid)!.push({\n uuid: msg.uuid,\n toolUseId: toolUse.id,\n })\n }\n }\n\n // Create groups for original messages that have multiple Task tool uses\n for (const [originalUuid, tasks] of tasksByOriginalUuid) {\n if (tasks.length > 1 && !processedOriginalUuids.has(originalUuid)) {\n groups.push({\n type: 'parallel-tasks',\n messageUuids: tasks.map(t => t.uuid),\n childIds: [],\n metadata: {\n siblingToolUseIds: tasks.map(t => t.toolUseId),\n },\n })\n processedOriginalUuids.add(originalUuid)\n }\n }\n\n // Strategy 2 (Fallback): Use progress messages for backward compatibility\n // This handles cases where originalUuid might not be set (e.g., historical messages)\n const processedSiblingKeys = new Set<string>()\n\n for (const msg of messages) {\n if (msg.type !== 'progress') continue\n\n const siblingIds = msg.siblingToolUseIDs\n if (!siblingIds || siblingIds.size <= 1) continue\n\n // Create a stable key for this sibling set\n const siblingKey = Array.from(siblingIds).sort().join(',')\n if (processedSiblingKeys.has(siblingKey)) continue\n\n // Check if this sibling set was already handled by Strategy 1\n const alreadyGrouped = Array.from(siblingIds).every(id =>\n groups.some(g =>\n (g.metadata.siblingToolUseIds as string[])?.includes(id),\n ),\n )\n if (alreadyGrouped) {\n processedSiblingKeys.add(siblingKey)\n continue\n }\n\n // Check if all siblings are Task tool uses\n const taskToolUseIds: string[] = []\n const messageUuids = new Set<string>()\n\n for (const toolUseId of siblingIds) {\n const assistantMsg = messages.find(\n m =>\n m.type === 'assistant' &&\n Array.isArray(m.message.content) &&\n m.message.content.some(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' && block.id === toolUseId,\n ),\n )\n\n if (assistantMsg && assistantMsg.type === 'assistant') {\n const content = assistantMsg.message.content\n const toolUse = content.find(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' && block.id === toolUseId,\n )\n\n if (\n toolUse &&\n (toolUse.name === 'Agent' || toolUse.name === 'Task')\n ) {\n taskToolUseIds.push(toolUseId)\n messageUuids.add(assistantMsg.uuid)\n }\n }\n }\n\n // Only create parallel group if there are multiple Tasks\n if (taskToolUseIds.length > 1) {\n groups.push({\n type: 'parallel-tasks',\n messageUuids: Array.from(messageUuids),\n childIds: [],\n metadata: {\n siblingToolUseIds: taskToolUseIds,\n },\n })\n processedSiblingKeys.add(siblingKey)\n }\n }\n\n return groups\n }\n\n computeResolution(\n group: MessageGroup,\n unresolvedToolUseIDs: Set<string>,\n ): ResolutionState {\n const memberIds = (group.metadata.siblingToolUseIds as string[]) || []\n\n // All members need to be resolved\n const unresolvedMembers = memberIds.filter(id =>\n unresolvedToolUseIDs.has(id),\n )\n const isSelfResolved = unresolvedMembers.length === 0\n\n // Note: isNestedResolved is computed by parent manager\n // after all child groups have been processed\n return {\n isSelfResolved,\n isNestedResolved: true, // Updated by parent computation\n isFullyResolved: isSelfResolved,\n unresolvedToolUseIds: unresolvedMembers,\n }\n }\n\n computeAnchor(\n group: MessageGroup,\n _messages: NormalizedMessage[],\n ): PositionAnchor {\n // Parallel module's position = first member's position\n return {\n anchorMessageUuid: group.messageUuids[0],\n anchorStrategy: 'first',\n }\n }\n\n /**\n * Get task info for each member of the parallel group\n */\n static getMemberTaskInfo(\n group: MessageGroup,\n messages: NormalizedMessage[],\n ): Array<{\n toolUseId: string\n agentId: string | null\n description: string\n agentType: string\n teamName?: string\n teammateName?: string\n }> {\n const memberIds = (group.metadata.siblingToolUseIds as string[]) || []\n const result: Array<{\n toolUseId: string\n agentId: string | null\n description: string\n agentType: string\n teamName?: string\n teammateName?: string\n }> = []\n\n // Since normalized messages split each content block into separate messages,\n // we need to find the message for each toolUseId individually\n for (const toolUseId of memberIds) {\n // Find the assistant message containing this specific tool use\n const msg = messages.find(\n m =>\n m.type === 'assistant' &&\n Array.isArray(m.message.content) &&\n m.message.content.some(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' && block.id === toolUseId,\n ),\n )\n\n if (!msg || msg.type !== 'assistant') continue\n\n const content = msg.message.content\n const toolUse = content.find(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' && block.id === toolUseId,\n )\n\n if (toolUse) {\n const input = toolUse.input as {\n description?: string\n subagent_type?: string\n team_name?: string\n name?: string\n }\n\n result.push({\n toolUseId,\n agentId: getAgentIdByToolUseId(toolUseId),\n description: input.description || 'Task',\n agentType: input.subagent_type || 'general-purpose',\n teamName: input.team_name,\n teammateName: input.name,\n })\n }\n }\n\n return result\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -13,7 +13,7 @@ class TaskGroupHandler {
|
|
|
13
13
|
const content = msg.message.content;
|
|
14
14
|
if (!content || content.length === 0) continue;
|
|
15
15
|
const taskToolUses = content.filter(
|
|
16
|
-
(block) => block.type === "tool_use" && block.name === "Task"
|
|
16
|
+
(block) => block.type === "tool_use" && (block.name === "Agent" || block.name === "Task")
|
|
17
17
|
);
|
|
18
18
|
if (taskToolUses.length !== 1) continue;
|
|
19
19
|
const taskToolUse = taskToolUses[0];
|
|
@@ -76,7 +76,7 @@ class TaskGroupHandler {
|
|
|
76
76
|
const content = message.message.content;
|
|
77
77
|
if (!content || !Array.isArray(content)) continue;
|
|
78
78
|
for (const block of content) {
|
|
79
|
-
if (block.type === "tool_use" && block.name === "Task") {
|
|
79
|
+
if (block.type === "tool_use" && (block.name === "Agent" || block.name === "Task")) {
|
|
80
80
|
if (unresolvedToolUseIDs.has(block.id)) {
|
|
81
81
|
unresolvedIds.push(block.id);
|
|
82
82
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/utils/groupHandlers/taskHandler.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Task Group Handler\n *\n * Handles single Task tool calls (not part of concurrent groups).\n * Includes recursive nested task checking from V3.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { NormalizedMessage } from '@utils/messages'\nimport type {\n MessageGroup,\n IdentifiedGroup,\n ResolutionState,\n PositionAnchor,\n} from '@minto-types/messageGroup'\nimport type { GroupTypeHandler, NestedTaskCheckResult } from './types'\nimport {\n getAgentIdByToolUseId,\n getAgentTranscript,\n} from '@utils/agentTranscripts'\n\nexport class TaskGroupHandler implements GroupTypeHandler {\n type = 'task' as const\n\n identify(messages: NormalizedMessage[]): IdentifiedGroup[] {\n const groups: IdentifiedGroup[] = []\n const processedUuids = new Set<string>()\n\n for (const msg of messages) {\n if (msg.type !== 'assistant') continue\n if (processedUuids.has(msg.uuid)) continue\n\n const content = msg.message.content\n if (!content || content.length === 0) continue\n\n // Find all Task tool uses in this message\n const taskToolUses = content.filter(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use'
|
|
5
|
-
"mappings": "AAgBA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,iBAA6C;AAAA,EACxD,OAAO;AAAA,EAEP,SAAS,UAAkD;AACzD,UAAM,SAA4B,CAAC;AACnC,UAAM,iBAAiB,oBAAI,IAAY;AAEvC,eAAW,OAAO,UAAU;AAC1B,UAAI,IAAI,SAAS,YAAa;AAC9B,UAAI,eAAe,IAAI,IAAI,IAAI,EAAG;AAElC,YAAM,UAAU,IAAI,QAAQ;AAC5B,UAAI,CAAC,WAAW,QAAQ,WAAW,EAAG;AAGtC,YAAM,eAAe,QAAQ;AAAA,QAC3B,CAAC,UACC,MAAM,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Task Group Handler\n *\n * Handles single Task tool calls (not part of concurrent groups).\n * Includes recursive nested task checking from V3.\n */\n\nimport type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { NormalizedMessage } from '@utils/messages'\nimport type {\n MessageGroup,\n IdentifiedGroup,\n ResolutionState,\n PositionAnchor,\n} from '@minto-types/messageGroup'\nimport type { GroupTypeHandler, NestedTaskCheckResult } from './types'\nimport {\n getAgentIdByToolUseId,\n getAgentTranscript,\n} from '@utils/agentTranscripts'\n\nexport class TaskGroupHandler implements GroupTypeHandler {\n type = 'task' as const\n\n identify(messages: NormalizedMessage[]): IdentifiedGroup[] {\n const groups: IdentifiedGroup[] = []\n const processedUuids = new Set<string>()\n\n for (const msg of messages) {\n if (msg.type !== 'assistant') continue\n if (processedUuids.has(msg.uuid)) continue\n\n const content = msg.message.content\n if (!content || content.length === 0) continue\n\n // Find all Task tool uses in this message\n const taskToolUses = content.filter(\n (block): block is ToolUseBlockParam =>\n block.type === 'tool_use' &&\n (block.name === 'Agent' || block.name === 'Task'),\n )\n\n // Skip if multiple Tasks (will be handled by parallel-tasks handler)\n if (taskToolUses.length !== 1) continue\n\n const taskToolUse = taskToolUses[0]\n const input = taskToolUse.input as {\n description?: string\n subagent_type?: string\n }\n const agentId = getAgentIdByToolUseId(taskToolUse.id)\n\n groups.push({\n type: 'task',\n messageUuids: [msg.uuid],\n metadata: {\n toolUseId: taskToolUse.id,\n agentId: agentId || undefined,\n description: input.description,\n agentType: input.subagent_type,\n },\n })\n\n processedUuids.add(msg.uuid)\n }\n\n return groups\n }\n\n computeResolution(\n group: MessageGroup,\n unresolvedToolUseIDs: Set<string>,\n ): ResolutionState {\n const toolUseId = group.metadata.toolUseId as string\n const agentId = group.metadata.agentId as string | undefined\n\n const isSelfResolved = !unresolvedToolUseIDs.has(toolUseId)\n\n // V3's nested checking logic\n let isNestedResolved = true\n const unresolvedNested: string[] = []\n\n if (agentId) {\n const nestedCheck = this.checkUnresolvedNestedTasks(\n agentId,\n unresolvedToolUseIDs,\n )\n if (nestedCheck.hasUnresolved) {\n isNestedResolved = false\n unresolvedNested.push(...nestedCheck.unresolvedIds)\n }\n }\n\n return {\n isSelfResolved,\n isNestedResolved,\n isFullyResolved: isSelfResolved && isNestedResolved,\n unresolvedToolUseIds: isSelfResolved\n ? unresolvedNested\n : [toolUseId, ...unresolvedNested],\n }\n }\n\n computeAnchor(\n group: MessageGroup,\n _messages: NormalizedMessage[],\n ): PositionAnchor {\n return {\n anchorMessageUuid: group.messageUuids[0],\n anchorStrategy: 'first',\n }\n }\n\n /**\n * Recursively check for unresolved nested tasks (from V3)\n */\n private checkUnresolvedNestedTasks(\n agentId: string,\n unresolvedToolUseIDs: Set<string>,\n ): NestedTaskCheckResult {\n const transcript = getAgentTranscript(agentId)\n if (!transcript) {\n return { hasUnresolved: false, unresolvedIds: [] }\n }\n\n const unresolvedIds: string[] = []\n\n for (const message of transcript.messages) {\n if (message.type === 'assistant') {\n const content = message.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 // Check if this nested Task itself is complete\n if (unresolvedToolUseIDs.has(block.id)) {\n unresolvedIds.push(block.id)\n }\n\n // Recursively check nested agent\n const nestedAgentId = getAgentIdByToolUseId(block.id)\n if (nestedAgentId) {\n const nested = this.checkUnresolvedNestedTasks(\n nestedAgentId,\n unresolvedToolUseIDs,\n )\n unresolvedIds.push(...nested.unresolvedIds)\n }\n }\n }\n }\n }\n\n return {\n hasUnresolved: unresolvedIds.length > 0,\n unresolvedIds,\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "AAgBA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,iBAA6C;AAAA,EACxD,OAAO;AAAA,EAEP,SAAS,UAAkD;AACzD,UAAM,SAA4B,CAAC;AACnC,UAAM,iBAAiB,oBAAI,IAAY;AAEvC,eAAW,OAAO,UAAU;AAC1B,UAAI,IAAI,SAAS,YAAa;AAC9B,UAAI,eAAe,IAAI,IAAI,IAAI,EAAG;AAElC,YAAM,UAAU,IAAI,QAAQ;AAC5B,UAAI,CAAC,WAAW,QAAQ,WAAW,EAAG;AAGtC,YAAM,eAAe,QAAQ;AAAA,QAC3B,CAAC,UACC,MAAM,SAAS,eACd,MAAM,SAAS,WAAW,MAAM,SAAS;AAAA,MAC9C;AAGA,UAAI,aAAa,WAAW,EAAG;AAE/B,YAAM,cAAc,aAAa,CAAC;AAClC,YAAM,QAAQ,YAAY;AAI1B,YAAM,UAAU,sBAAsB,YAAY,EAAE;AAEpD,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,cAAc,CAAC,IAAI,IAAI;AAAA,QACvB,UAAU;AAAA,UACR,WAAW,YAAY;AAAA,UACvB,SAAS,WAAW;AAAA,UACpB,aAAa,MAAM;AAAA,UACnB,WAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAED,qBAAe,IAAI,IAAI,IAAI;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,kBACE,OACA,sBACiB;AACjB,UAAM,YAAY,MAAM,SAAS;AACjC,UAAM,UAAU,MAAM,SAAS;AAE/B,UAAM,iBAAiB,CAAC,qBAAqB,IAAI,SAAS;AAG1D,QAAI,mBAAmB;AACvB,UAAM,mBAA6B,CAAC;AAEpC,QAAI,SAAS;AACX,YAAM,cAAc,KAAK;AAAA,QACvB;AAAA,QACA;AAAA,MACF;AACA,UAAI,YAAY,eAAe;AAC7B,2BAAmB;AACnB,yBAAiB,KAAK,GAAG,YAAY,aAAa;AAAA,MACpD;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,iBAAiB,kBAAkB;AAAA,MACnC,sBAAsB,iBAClB,mBACA,CAAC,WAAW,GAAG,gBAAgB;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,cACE,OACA,WACgB;AAChB,WAAO;AAAA,MACL,mBAAmB,MAAM,aAAa,CAAC;AAAA,MACvC,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,2BACN,SACA,sBACuB;AACvB,UAAM,aAAa,mBAAmB,OAAO;AAC7C,QAAI,CAAC,YAAY;AACf,aAAO,EAAE,eAAe,OAAO,eAAe,CAAC,EAAE;AAAA,IACnD;AAEA,UAAM,gBAA0B,CAAC;AAEjC,eAAW,WAAW,WAAW,UAAU;AACzC,UAAI,QAAQ,SAAS,aAAa;AAChC,cAAM,UAAU,QAAQ,QAAQ;AAChC,YAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,OAAO,EAAG;AAEzC,mBAAW,SAAS,SAAS;AAC3B,cACE,MAAM,SAAS,eACd,MAAM,SAAS,WAAW,MAAM,SAAS,SAC1C;AAEA,gBAAI,qBAAqB,IAAI,MAAM,EAAE,GAAG;AACtC,4BAAc,KAAK,MAAM,EAAE;AAAA,YAC7B;AAGA,kBAAM,gBAAgB,sBAAsB,MAAM,EAAE;AACpD,gBAAI,eAAe;AACjB,oBAAM,SAAS,KAAK;AAAA,gBAClB;AAAA,gBACA;AAAA,cACF;AACA,4BAAc,KAAK,GAAG,OAAO,aAAa;AAAA,YAC5C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,eAAe,cAAc,SAAS;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
createConfigChangeInput,
|
|
23
23
|
createTaskCompletedInput,
|
|
24
24
|
createTeammateIdleInput,
|
|
25
|
+
createWorktreeCreateInput,
|
|
26
|
+
createWorktreeRemoveInput,
|
|
25
27
|
resetOnceHooks
|
|
26
28
|
} from "../services/hookExecutor.js";
|
|
27
29
|
import { safeParseJSON } from "./json.js";
|
|
@@ -94,15 +96,31 @@ class HookManager {
|
|
|
94
96
|
loadSettingsHooks() {
|
|
95
97
|
const cwd = getCwd();
|
|
96
98
|
const home = homedir();
|
|
99
|
+
const isProjectTrusted = this.isProjectHooksTrusted(cwd);
|
|
97
100
|
const settingsPaths = [
|
|
98
|
-
join(home, ".claude", "settings.json"),
|
|
99
|
-
join(home, ".minto", "settings.json"),
|
|
100
|
-
join(cwd, ".minto", "settings.local.json"),
|
|
101
|
-
join(cwd, ".claude", "settings.json"),
|
|
102
|
-
join(cwd, ".minto", "settings.json")
|
|
101
|
+
{ path: join(home, ".claude", "settings.json"), isProject: false },
|
|
102
|
+
{ path: join(home, ".minto", "settings.json"), isProject: false },
|
|
103
|
+
{ path: join(cwd, ".minto", "settings.local.json"), isProject: true },
|
|
104
|
+
{ path: join(cwd, ".claude", "settings.json"), isProject: true },
|
|
105
|
+
{ path: join(cwd, ".minto", "settings.json"), isProject: true }
|
|
103
106
|
];
|
|
104
107
|
const allHooks = [];
|
|
105
|
-
for (const settingsPath of settingsPaths) {
|
|
108
|
+
for (const { path: settingsPath, isProject } of settingsPaths) {
|
|
109
|
+
if (isProject && !isProjectTrusted) {
|
|
110
|
+
try {
|
|
111
|
+
if (existsSync(settingsPath)) {
|
|
112
|
+
const raw = readFileSync(settingsPath, "utf-8");
|
|
113
|
+
const parsed = safeParseJSON(raw);
|
|
114
|
+
if (parsed && typeof parsed === "object" && parsed.hooks) {
|
|
115
|
+
logInfo(
|
|
116
|
+
`HookManager: Skipping untrusted project hooks from ${settingsPath}. Add this directory to trustedProjectHooksPaths in ~/.minto/settings.json to enable.`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
106
124
|
try {
|
|
107
125
|
if (!existsSync(settingsPath)) continue;
|
|
108
126
|
const content = readFileSync(settingsPath, "utf-8");
|
|
@@ -162,6 +180,25 @@ class HookManager {
|
|
|
162
180
|
}
|
|
163
181
|
logInfo(`HookManager: Loaded ${allHooks.length} hook(s) from settings`);
|
|
164
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Check if project-level hooks are trusted for a given directory.
|
|
185
|
+
* Looks for the directory in trustedProjectHooksPaths array
|
|
186
|
+
* in the global ~/.minto/settings.json.
|
|
187
|
+
*/
|
|
188
|
+
isProjectHooksTrusted(projectDir) {
|
|
189
|
+
try {
|
|
190
|
+
const globalSettingsPath = join(homedir(), ".minto", "settings.json");
|
|
191
|
+
if (!existsSync(globalSettingsPath)) return false;
|
|
192
|
+
const content = readFileSync(globalSettingsPath, "utf-8");
|
|
193
|
+
const settings = safeParseJSON(content);
|
|
194
|
+
if (!settings || typeof settings !== "object") return false;
|
|
195
|
+
const trusted = settings.trustedProjectHooksPaths;
|
|
196
|
+
if (!Array.isArray(trusted)) return false;
|
|
197
|
+
return trusted.includes(projectDir);
|
|
198
|
+
} catch {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
165
202
|
/**
|
|
166
203
|
* Dynamically add temporary hooks (e.g., skill-level hooks)
|
|
167
204
|
* Returns a cleanup function to remove them
|
|
@@ -463,6 +500,27 @@ class HookManager {
|
|
|
463
500
|
);
|
|
464
501
|
return this.executeBlockableEvent(HookEvent.TeammateIdle, input);
|
|
465
502
|
}
|
|
503
|
+
async executeWorktreeCreate(worktreePath, agentId, agentType) {
|
|
504
|
+
const input = createWorktreeCreateInput(
|
|
505
|
+
this.sessionId,
|
|
506
|
+
this.transcriptPath,
|
|
507
|
+
worktreePath,
|
|
508
|
+
agentId,
|
|
509
|
+
agentType
|
|
510
|
+
);
|
|
511
|
+
await this.executeFireAndForget(HookEvent.WorktreeCreate, input);
|
|
512
|
+
}
|
|
513
|
+
async executeWorktreeRemove(worktreePath, agentId, agentType, success) {
|
|
514
|
+
const input = createWorktreeRemoveInput(
|
|
515
|
+
this.sessionId,
|
|
516
|
+
this.transcriptPath,
|
|
517
|
+
worktreePath,
|
|
518
|
+
agentId,
|
|
519
|
+
agentType,
|
|
520
|
+
success
|
|
521
|
+
);
|
|
522
|
+
await this.executeFireAndForget(HookEvent.WorktreeRemove, input);
|
|
523
|
+
}
|
|
466
524
|
}
|
|
467
525
|
let globalHookManager = null;
|
|
468
526
|
function initializeHookManager(sessionId, transcriptPath, plugins) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/hookManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Hook Manager\n *\n * Central manager for hook lifecycle.\n * Coordinates hook execution across plugins and settings.json configurations.\n * Supports all CC hook events with proper toolInput matching.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport { HookEvent, HookMatcher, HooksConfigSchema } from '../types/hooks'\nimport { LoadedPlugin, LoadedHook } from '../types/plugin'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport {\n executeHooksForEvent,\n processHookDecisions,\n createPreToolUseInput,\n createPostToolUseInput,\n createPostToolUseFailureInput,\n createPermissionRequestInput,\n createUserPromptSubmitInput,\n createSessionStartInput,\n createSessionEndInput,\n createStopInput,\n createSubagentStartInput,\n createSubagentStopInput,\n createNotificationInput,\n createPreCompactInput,\n createPostCompactInput,\n createConfigChangeInput,\n createTaskCompletedInput,\n createTeammateIdleInput,\n resetOnceHooks,\n type HookExecutionOptions,\n type HookExecutionResult,\n} from '../services/hookExecutor'\nimport { logError } from './log'\nimport { safeParseJSON } from './json'\nimport { getCwd } from './state'\n\nconst logInfo = (msg: string) => {\n if (process.env.DEBUG) console.log(`[INFO] ${msg}`)\n}\nconst logDebug = (msg: string, ...args: any[]) => {\n if (process.env.DEBUG) console.log(`[DEBUG] ${msg}`, ...args)\n}\n\n/**\n * Check if a hook matcher matches a tool name and optionally tool input\n */\nfunction matchHook(\n hook: LoadedHook,\n toolName: string,\n toolInput?: Record<string, unknown>,\n): boolean {\n // Check tool name matcher\n if (hook.matcher) {\n if (hook.matcher !== '*' && hook.matcher !== '') {\n try {\n const regex = new RegExp(hook.matcher)\n if (!regex.test(toolName)) return false\n } catch {\n if (hook.matcher !== toolName) return false\n }\n }\n }\n\n // Check toolInput matcher (CC spec: matcher.toolInput field matching)\n const hookConfig = hook.config as any\n if (hookConfig.toolInput && toolInput) {\n for (const [field, pattern] of Object.entries(\n hookConfig.toolInput as Record<string, string>,\n )) {\n const fieldValue = String(toolInput[field] ?? '')\n try {\n const regex = new RegExp(pattern)\n if (!regex.test(fieldValue)) return false\n } catch {\n if (fieldValue !== pattern) return false\n }\n }\n }\n\n return true\n}\n\n/**\n * Standard decision return type for blocking hooks\n */\ninterface HookDecisionResult {\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n updatedInput?: Record<string, unknown>\n additionalContext?: string\n}\n\nconst ALLOW_RESULT: HookDecisionResult = {\n shouldContinue: true,\n shouldAskUser: false,\n}\n\n/**\n * Hook manager instance\n */\nexport class HookManager {\n private plugins: LoadedPlugin[] = []\n private settingsHooks: LoadedHook[] = []\n private managedHooks: LoadedHook[] = []\n private sessionId: string\n private transcriptPath: string\n private enabled: boolean = true\n private disableAllHooks: boolean = false\n\n constructor(sessionId: string, transcriptPath: string) {\n this.sessionId = sessionId\n this.transcriptPath = transcriptPath\n resetOnceHooks()\n }\n\n /**\n * Register plugins with hooks\n */\n registerPlugins(plugins: LoadedPlugin[]) {\n this.plugins = plugins\n const totalHooks = plugins.reduce((sum, p) => sum + p.hooks.length, 0)\n logInfo(\n `HookManager: Registered ${plugins.length} plugin(s) with ${totalHooks} hook(s)`,\n )\n }\n\n /**\n * Load hooks from settings.json files\n * Priority (high to low): managed > .minto/settings.json > .claude/settings.json >\n * .minto/settings.local.json > ~/.minto/settings.json > ~/.claude/settings.json\n */\n loadSettingsHooks() {\n const cwd = getCwd()\n const home = homedir()\n\n // Load paths in priority order (lowest first, higher overrides)\n const settingsPaths = [\n join(home, '.claude', 'settings.json'),\n join(home, '.minto', 'settings.json'),\n join(cwd, '.minto', 'settings.local.json'),\n join(cwd, '.claude', 'settings.json'),\n join(cwd, '.minto', 'settings.json'),\n ]\n\n const allHooks: LoadedHook[] = []\n\n for (const settingsPath of settingsPaths) {\n try {\n if (!existsSync(settingsPath)) continue\n const content = readFileSync(settingsPath, 'utf-8')\n const settings = safeParseJSON(content)\n if (!settings || typeof settings !== 'object') continue\n\n const hooksConfig = (settings as any).hooks\n if (!hooksConfig || typeof hooksConfig !== 'object') continue\n\n const parsed = HooksConfigSchema.safeParse({ hooks: hooksConfig })\n if (!parsed.success) {\n logDebug(`Invalid hooks in ${settingsPath}: ${parsed.error.message}`)\n continue\n }\n\n const hooks = parsed.data.hooks\n if (!hooks) continue\n\n for (const [eventName, matchers] of Object.entries(hooks)) {\n const event = eventName as HookEvent\n for (const matcher of matchers as HookMatcher[]) {\n for (let i = 0; i < matcher.hooks.length; i++) {\n const hookDef = matcher.hooks[i]!\n allHooks.push({\n name: `settings:${eventName}:${i}`,\n filePath: settingsPath,\n config: {\n event,\n matcher: matcher.matcher,\n type: hookDef.type as any,\n command: hookDef.command,\n timeout: hookDef.timeout,\n once: hookDef.once,\n async: hookDef.async,\n } as any,\n pluginName: 'settings',\n event,\n matcher: matcher.matcher,\n })\n }\n }\n }\n } catch (err) {\n logDebug(`Error loading hooks from ${settingsPath}: ${err}`)\n }\n }\n\n this.settingsHooks = allHooks\n\n // Check for disableAllHooks\n try {\n const localSettings = join(cwd, '.minto', 'settings.json')\n const globalSettings = join(home, '.minto', 'settings.json')\n for (const p of [localSettings, globalSettings]) {\n if (existsSync(p)) {\n const content = safeParseJSON(readFileSync(p, 'utf-8'))\n if (content && (content as any).disableAllHooks) {\n this.disableAllHooks = true\n break\n }\n }\n }\n } catch {\n // ignore\n }\n\n logInfo(`HookManager: Loaded ${allHooks.length} hook(s) from settings`)\n }\n\n /**\n * Dynamically add temporary hooks (e.g., skill-level hooks)\n * Returns a cleanup function to remove them\n */\n addHooks(hooks: LoadedHook[]): () => void {\n this.settingsHooks.push(...hooks)\n logDebug(`HookManager: Added ${hooks.length} temporary hook(s)`)\n return () => {\n this.settingsHooks = this.settingsHooks.filter(h => !hooks.includes(h))\n logDebug(`HookManager: Removed ${hooks.length} temporary hook(s)`)\n }\n }\n\n /**\n * Enable or disable hook execution\n */\n setEnabled(enabled: boolean) {\n this.enabled = enabled\n logDebug(`HookManager: ${enabled ? 'Enabled' : 'Disabled'}`)\n }\n\n /**\n * Get all hooks (plugins + settings), respecting disableAllHooks\n */\n private getAllHooks(): LoadedHook[] {\n // Managed hooks always execute even if disableAllHooks is true\n const managed = this.managedHooks\n\n if (this.disableAllHooks) {\n return managed\n }\n\n const pluginHooks = this.plugins.flatMap(p => p.hooks)\n return [...pluginHooks, ...this.settingsHooks, ...managed]\n }\n\n /**\n * Get matching hooks for a tool-based event\n */\n private getMatchingToolHooks(\n event: HookEvent,\n toolName: string,\n toolInput?: Record<string, unknown>,\n ): { hooks: LoadedHook[]; plugins: LoadedPlugin[] } {\n const allHooks = this.getAllHooks()\n const matching = allHooks.filter(hook => {\n if (hook.event !== event) return false\n return matchHook(hook, toolName, toolInput)\n })\n return { hooks: matching, plugins: this.plugins }\n }\n\n /**\n * Get matching hooks for a non-tool event\n */\n private getMatchingEventHooks(event: HookEvent): LoadedHook[] {\n return this.getAllHooks().filter(hook => hook.event === event)\n }\n\n /**\n * Find plugin root for a hook\n */\n private getPluginRoot(hook: LoadedHook): string {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n return plugin?.location || getCwd()\n }\n\n /**\n * Execute hooks for a tool-based event (PreToolUse, PostToolUse, etc.)\n */\n private async executeToolEvent(\n event: HookEvent,\n toolName: string,\n input: any,\n toolInput?: Record<string, unknown>,\n ): Promise<HookDecisionResult> {\n if (!this.enabled) return ALLOW_RESULT\n\n const { hooks } = this.getMatchingToolHooks(event, toolName, toolInput)\n if (hooks.length === 0) return ALLOW_RESULT\n\n logDebug(`${event}: ${hooks.length} hook(s) matched for tool: ${toolName}`)\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(event, [hook], input, options)\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n /**\n * Execute hooks for a non-tool event (fire-and-forget)\n */\n private async executeFireAndForget(\n event: HookEvent,\n input: any,\n ): Promise<void> {\n if (!this.enabled) return\n\n const hooks = this.getMatchingEventHooks(event)\n if (hooks.length === 0) return\n\n logDebug(`${event}: ${hooks.length} hook(s)`)\n\n // Fire-and-forget: don't await individual results\n await Promise.allSettled(\n hooks.map(hook => {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n return executeHooksForEvent(event, [hook], input, options)\n }),\n )\n }\n\n /**\n * Execute hooks for a blockable non-tool event\n */\n private async executeBlockableEvent(\n event: HookEvent,\n input: any,\n ): Promise<HookDecisionResult> {\n if (!this.enabled) return ALLOW_RESULT\n\n const hooks = this.getMatchingEventHooks(event)\n if (hooks.length === 0) return ALLOW_RESULT\n\n logDebug(`${event}: ${hooks.length} hook(s)`)\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(event, [hook], input, options)\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n // ========================================================================\n // Public event methods\n // ========================================================================\n\n async executePreToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n ): Promise<HookDecisionResult> {\n const input = createPreToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n )\n return this.executeToolEvent(\n HookEvent.PreToolUse,\n toolName,\n input,\n toolInput,\n )\n }\n\n async executePostToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n toolOutput: Record<string, unknown>,\n ): Promise<void> {\n const input = createPostToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n toolOutput,\n )\n await this.executeFireAndForget(HookEvent.PostToolUse, input)\n }\n\n async executePostToolUseFailure(\n toolName: string,\n toolInput: Record<string, unknown>,\n error: string,\n errorType?: string,\n ): Promise<void> {\n const input = createPostToolUseFailureInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n error,\n errorType,\n )\n await this.executeFireAndForget(HookEvent.PostToolUseFailure, input)\n\n // Emit diagnostics:new for tool failures (linter/compiler errors)\n emitReminderEvent('diagnostics:new', {\n source: toolName,\n count: 1,\n })\n }\n\n async executePermissionRequest(\n toolName: string,\n toolInput: Record<string, unknown>,\n permissionType: 'read' | 'write' | 'execute' | 'network' | 'other',\n description?: string,\n ): Promise<HookDecisionResult> {\n const input = createPermissionRequestInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n permissionType,\n description,\n )\n return this.executeBlockableEvent(HookEvent.PermissionRequest, input)\n }\n\n async executeUserPromptSubmit(\n userPrompt: string,\n ): Promise<HookDecisionResult> {\n const input = createUserPromptSubmitInput(\n this.sessionId,\n this.transcriptPath,\n userPrompt,\n )\n return this.executeBlockableEvent(HookEvent.UserPromptSubmit, input)\n }\n\n async executeSessionStart(): Promise<void> {\n const input = createSessionStartInput(this.sessionId, this.transcriptPath)\n await this.executeFireAndForget(HookEvent.SessionStart, input)\n }\n\n async executeSessionEnd(\n reason: 'clear' | 'logout' | 'prompt_input_exit' | 'other' = 'other',\n ): Promise<void> {\n const input = createSessionEndInput(\n this.sessionId,\n this.transcriptPath,\n reason,\n )\n await this.executeFireAndForget(HookEvent.SessionEnd, input)\n }\n\n async executeStop(\n lastAssistantMessage?: string,\n ): Promise<HookDecisionResult> {\n const input = createStopInput(this.sessionId, this.transcriptPath, true)\n if (lastAssistantMessage) {\n ;(input as any).last_assistant_message = lastAssistantMessage\n }\n return this.executeBlockableEvent(HookEvent.Stop, input)\n }\n\n async executeSubagentStart(\n agentType: string,\n agentDescription?: string,\n runInBackground?: boolean,\n ): Promise<void> {\n const input = createSubagentStartInput(\n this.sessionId,\n this.transcriptPath,\n agentType,\n agentDescription,\n runInBackground,\n )\n await this.executeFireAndForget(HookEvent.SubagentStart, input)\n }\n\n async executeSubagentStop(\n agentType: string,\n agentId?: string,\n transcriptPath?: string,\n lastMessage?: string,\n ): Promise<HookDecisionResult> {\n const input = createSubagentStopInput(\n this.sessionId,\n this.transcriptPath,\n agentType,\n agentId,\n )\n if (transcriptPath) {\n ;(input as any).agent_transcript_path = transcriptPath\n }\n if (lastMessage) {\n ;(input as any).last_message = lastMessage\n }\n return this.executeBlockableEvent(HookEvent.SubagentStop, input)\n }\n\n async executeNotification(\n message: string,\n title?: string,\n type?: string,\n ): Promise<{ suppressNotification?: boolean }> {\n if (!this.enabled) return {}\n\n const input = createNotificationInput(\n this.sessionId,\n this.transcriptPath,\n message,\n title,\n type,\n )\n\n const hooks = this.getMatchingEventHooks(HookEvent.Notification)\n if (hooks.length === 0) return {}\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(\n HookEvent.Notification,\n [hook],\n input,\n options,\n )\n results.push(...result)\n }\n\n // Check if any hook suppressed the notification\n const suppress = results.some(\n r => r.success && (r.output as any)?.suppressNotification,\n )\n return { suppressNotification: suppress }\n }\n\n async executePreCompact(\n trigger: 'manual' | 'auto',\n customInstructions?: string,\n ): Promise<void> {\n const input = createPreCompactInput(\n this.sessionId,\n this.transcriptPath,\n trigger,\n customInstructions || '',\n )\n await this.executeFireAndForget(HookEvent.PreCompact, input)\n }\n\n async executePostCompact(\n trigger: 'manual' | 'auto',\n summary: string,\n compressionRatio: number,\n originalTokens: number,\n compressedTokens: number,\n ): Promise<void> {\n const input = createPostCompactInput(\n this.sessionId,\n this.transcriptPath,\n trigger,\n summary,\n compressionRatio,\n originalTokens,\n compressedTokens,\n )\n await this.executeFireAndForget(HookEvent.PostCompact, input)\n }\n\n async executeConfigChange(\n source: 'settings' | 'project' | 'global' | 'env' | 'cli',\n filePath?: string,\n ): Promise<HookDecisionResult> {\n const input = createConfigChangeInput(\n this.sessionId,\n this.transcriptPath,\n source,\n filePath,\n )\n return this.executeBlockableEvent(HookEvent.ConfigChange, input)\n }\n\n async executeTaskCompleted(\n taskId: string,\n subject: string,\n description?: string,\n ): Promise<HookDecisionResult> {\n const input = createTaskCompletedInput(\n this.sessionId,\n this.transcriptPath,\n taskId,\n subject,\n description,\n )\n return this.executeBlockableEvent(HookEvent.TaskCompleted, input)\n }\n\n async executeTeammateIdle(\n teammateName: string,\n teamName: string,\n ): Promise<HookDecisionResult> {\n const input = createTeammateIdleInput(\n this.sessionId,\n this.transcriptPath,\n teammateName,\n teamName,\n )\n return this.executeBlockableEvent(HookEvent.TeammateIdle, input)\n }\n}\n\n// ============================================================================\n// Global Hook Manager\n// ============================================================================\n\nlet globalHookManager: HookManager | null = null\n\nexport function initializeHookManager(\n sessionId: string,\n transcriptPath: string,\n plugins: LoadedPlugin[],\n): HookManager {\n globalHookManager = new HookManager(sessionId, transcriptPath)\n globalHookManager.registerPlugins(plugins)\n globalHookManager.loadSettingsHooks()\n return globalHookManager\n}\n\nexport function getHookManager(): HookManager | null {\n return globalHookManager\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Hook Manager\n *\n * Central manager for hook lifecycle.\n * Coordinates hook execution across plugins and settings.json configurations.\n * Supports all CC hook events with proper toolInput matching.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport { HookEvent, HookMatcher, HooksConfigSchema } from '../types/hooks'\nimport { LoadedPlugin, LoadedHook } from '../types/plugin'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport {\n executeHooksForEvent,\n processHookDecisions,\n createPreToolUseInput,\n createPostToolUseInput,\n createPostToolUseFailureInput,\n createPermissionRequestInput,\n createUserPromptSubmitInput,\n createSessionStartInput,\n createSessionEndInput,\n createStopInput,\n createSubagentStartInput,\n createSubagentStopInput,\n createNotificationInput,\n createPreCompactInput,\n createPostCompactInput,\n createConfigChangeInput,\n createTaskCompletedInput,\n createTeammateIdleInput,\n createWorktreeCreateInput,\n createWorktreeRemoveInput,\n resetOnceHooks,\n type HookExecutionOptions,\n type HookExecutionResult,\n} from '../services/hookExecutor'\nimport { logError } from './log'\nimport { safeParseJSON } from './json'\nimport { getCwd } from './state'\n\nconst logInfo = (msg: string) => {\n if (process.env.DEBUG) console.log(`[INFO] ${msg}`)\n}\nconst logDebug = (msg: string, ...args: any[]) => {\n if (process.env.DEBUG) console.log(`[DEBUG] ${msg}`, ...args)\n}\n\n/**\n * Check if a hook matcher matches a tool name and optionally tool input\n */\nfunction matchHook(\n hook: LoadedHook,\n toolName: string,\n toolInput?: Record<string, unknown>,\n): boolean {\n // Check tool name matcher\n if (hook.matcher) {\n if (hook.matcher !== '*' && hook.matcher !== '') {\n try {\n const regex = new RegExp(hook.matcher)\n if (!regex.test(toolName)) return false\n } catch {\n if (hook.matcher !== toolName) return false\n }\n }\n }\n\n // Check toolInput matcher (CC spec: matcher.toolInput field matching)\n const hookConfig = hook.config as any\n if (hookConfig.toolInput && toolInput) {\n for (const [field, pattern] of Object.entries(\n hookConfig.toolInput as Record<string, string>,\n )) {\n const fieldValue = String(toolInput[field] ?? '')\n try {\n const regex = new RegExp(pattern)\n if (!regex.test(fieldValue)) return false\n } catch {\n if (fieldValue !== pattern) return false\n }\n }\n }\n\n return true\n}\n\n/**\n * Standard decision return type for blocking hooks\n */\ninterface HookDecisionResult {\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n updatedInput?: Record<string, unknown>\n additionalContext?: string\n}\n\nconst ALLOW_RESULT: HookDecisionResult = {\n shouldContinue: true,\n shouldAskUser: false,\n}\n\n/**\n * Hook manager instance\n */\nexport class HookManager {\n private plugins: LoadedPlugin[] = []\n private settingsHooks: LoadedHook[] = []\n private managedHooks: LoadedHook[] = []\n private sessionId: string\n private transcriptPath: string\n private enabled: boolean = true\n private disableAllHooks: boolean = false\n\n constructor(sessionId: string, transcriptPath: string) {\n this.sessionId = sessionId\n this.transcriptPath = transcriptPath\n resetOnceHooks()\n }\n\n /**\n * Register plugins with hooks\n */\n registerPlugins(plugins: LoadedPlugin[]) {\n this.plugins = plugins\n const totalHooks = plugins.reduce((sum, p) => sum + p.hooks.length, 0)\n logInfo(\n `HookManager: Registered ${plugins.length} plugin(s) with ${totalHooks} hook(s)`,\n )\n }\n\n /**\n * Load hooks from settings.json files\n * Priority (high to low): managed > .minto/settings.json > .claude/settings.json >\n * .minto/settings.local.json > ~/.minto/settings.json > ~/.claude/settings.json\n */\n loadSettingsHooks() {\n const cwd = getCwd()\n const home = homedir()\n\n // Determine if project-level hooks are trusted\n const isProjectTrusted = this.isProjectHooksTrusted(cwd)\n\n // Load paths in priority order (lowest first, higher overrides)\n const settingsPaths: { path: string; isProject: boolean }[] = [\n { path: join(home, '.claude', 'settings.json'), isProject: false },\n { path: join(home, '.minto', 'settings.json'), isProject: false },\n { path: join(cwd, '.minto', 'settings.local.json'), isProject: true },\n { path: join(cwd, '.claude', 'settings.json'), isProject: true },\n { path: join(cwd, '.minto', 'settings.json'), isProject: true },\n ]\n\n const allHooks: LoadedHook[] = []\n\n for (const { path: settingsPath, isProject } of settingsPaths) {\n // Skip project-level hooks if project is not trusted\n if (isProject && !isProjectTrusted) {\n try {\n if (existsSync(settingsPath)) {\n const raw = readFileSync(settingsPath, 'utf-8')\n const parsed = safeParseJSON(raw)\n if (parsed && typeof parsed === 'object' && (parsed as any).hooks) {\n logInfo(\n `HookManager: Skipping untrusted project hooks from ${settingsPath}. ` +\n `Add this directory to trustedProjectHooksPaths in ~/.minto/settings.json to enable.`,\n )\n }\n }\n } catch {\n // ignore\n }\n continue\n }\n try {\n if (!existsSync(settingsPath)) continue\n const content = readFileSync(settingsPath, 'utf-8')\n const settings = safeParseJSON(content)\n if (!settings || typeof settings !== 'object') continue\n\n const hooksConfig = (settings as any).hooks\n if (!hooksConfig || typeof hooksConfig !== 'object') continue\n\n const parsed = HooksConfigSchema.safeParse({ hooks: hooksConfig })\n if (!parsed.success) {\n logDebug(`Invalid hooks in ${settingsPath}: ${parsed.error.message}`)\n continue\n }\n\n const hooks = parsed.data.hooks\n if (!hooks) continue\n\n for (const [eventName, matchers] of Object.entries(hooks)) {\n const event = eventName as HookEvent\n for (const matcher of matchers as HookMatcher[]) {\n for (let i = 0; i < matcher.hooks.length; i++) {\n const hookDef = matcher.hooks[i]!\n allHooks.push({\n name: `settings:${eventName}:${i}`,\n filePath: settingsPath,\n config: {\n event,\n matcher: matcher.matcher,\n type: hookDef.type as any,\n command: hookDef.command,\n timeout: hookDef.timeout,\n once: hookDef.once,\n async: hookDef.async,\n } as any,\n pluginName: 'settings',\n event,\n matcher: matcher.matcher,\n })\n }\n }\n }\n } catch (err) {\n logDebug(`Error loading hooks from ${settingsPath}: ${err}`)\n }\n }\n\n this.settingsHooks = allHooks\n\n // Check for disableAllHooks\n try {\n const localSettings = join(cwd, '.minto', 'settings.json')\n const globalSettings = join(home, '.minto', 'settings.json')\n for (const p of [localSettings, globalSettings]) {\n if (existsSync(p)) {\n const content = safeParseJSON(readFileSync(p, 'utf-8'))\n if (content && (content as any).disableAllHooks) {\n this.disableAllHooks = true\n break\n }\n }\n }\n } catch {\n // ignore\n }\n\n logInfo(`HookManager: Loaded ${allHooks.length} hook(s) from settings`)\n }\n\n /**\n * Check if project-level hooks are trusted for a given directory.\n * Looks for the directory in trustedProjectHooksPaths array\n * in the global ~/.minto/settings.json.\n */\n private isProjectHooksTrusted(projectDir: string): boolean {\n try {\n const globalSettingsPath = join(homedir(), '.minto', 'settings.json')\n if (!existsSync(globalSettingsPath)) return false\n const content = readFileSync(globalSettingsPath, 'utf-8')\n const settings = safeParseJSON(content)\n if (!settings || typeof settings !== 'object') return false\n const trusted = (settings as any).trustedProjectHooksPaths\n if (!Array.isArray(trusted)) return false\n return trusted.includes(projectDir)\n } catch {\n return false\n }\n }\n\n /**\n * Dynamically add temporary hooks (e.g., skill-level hooks)\n * Returns a cleanup function to remove them\n */\n addHooks(hooks: LoadedHook[]): () => void {\n this.settingsHooks.push(...hooks)\n logDebug(`HookManager: Added ${hooks.length} temporary hook(s)`)\n return () => {\n this.settingsHooks = this.settingsHooks.filter(h => !hooks.includes(h))\n logDebug(`HookManager: Removed ${hooks.length} temporary hook(s)`)\n }\n }\n\n /**\n * Enable or disable hook execution\n */\n setEnabled(enabled: boolean) {\n this.enabled = enabled\n logDebug(`HookManager: ${enabled ? 'Enabled' : 'Disabled'}`)\n }\n\n /**\n * Get all hooks (plugins + settings), respecting disableAllHooks\n */\n private getAllHooks(): LoadedHook[] {\n // Managed hooks always execute even if disableAllHooks is true\n const managed = this.managedHooks\n\n if (this.disableAllHooks) {\n return managed\n }\n\n const pluginHooks = this.plugins.flatMap(p => p.hooks)\n return [...pluginHooks, ...this.settingsHooks, ...managed]\n }\n\n /**\n * Get matching hooks for a tool-based event\n */\n private getMatchingToolHooks(\n event: HookEvent,\n toolName: string,\n toolInput?: Record<string, unknown>,\n ): { hooks: LoadedHook[]; plugins: LoadedPlugin[] } {\n const allHooks = this.getAllHooks()\n const matching = allHooks.filter(hook => {\n if (hook.event !== event) return false\n return matchHook(hook, toolName, toolInput)\n })\n return { hooks: matching, plugins: this.plugins }\n }\n\n /**\n * Get matching hooks for a non-tool event\n */\n private getMatchingEventHooks(event: HookEvent): LoadedHook[] {\n return this.getAllHooks().filter(hook => hook.event === event)\n }\n\n /**\n * Find plugin root for a hook\n */\n private getPluginRoot(hook: LoadedHook): string {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n return plugin?.location || getCwd()\n }\n\n /**\n * Execute hooks for a tool-based event (PreToolUse, PostToolUse, etc.)\n */\n private async executeToolEvent(\n event: HookEvent,\n toolName: string,\n input: any,\n toolInput?: Record<string, unknown>,\n ): Promise<HookDecisionResult> {\n if (!this.enabled) return ALLOW_RESULT\n\n const { hooks } = this.getMatchingToolHooks(event, toolName, toolInput)\n if (hooks.length === 0) return ALLOW_RESULT\n\n logDebug(`${event}: ${hooks.length} hook(s) matched for tool: ${toolName}`)\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(event, [hook], input, options)\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n /**\n * Execute hooks for a non-tool event (fire-and-forget)\n */\n private async executeFireAndForget(\n event: HookEvent,\n input: any,\n ): Promise<void> {\n if (!this.enabled) return\n\n const hooks = this.getMatchingEventHooks(event)\n if (hooks.length === 0) return\n\n logDebug(`${event}: ${hooks.length} hook(s)`)\n\n // Fire-and-forget: don't await individual results\n await Promise.allSettled(\n hooks.map(hook => {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n return executeHooksForEvent(event, [hook], input, options)\n }),\n )\n }\n\n /**\n * Execute hooks for a blockable non-tool event\n */\n private async executeBlockableEvent(\n event: HookEvent,\n input: any,\n ): Promise<HookDecisionResult> {\n if (!this.enabled) return ALLOW_RESULT\n\n const hooks = this.getMatchingEventHooks(event)\n if (hooks.length === 0) return ALLOW_RESULT\n\n logDebug(`${event}: ${hooks.length} hook(s)`)\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(event, [hook], input, options)\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n // ========================================================================\n // Public event methods\n // ========================================================================\n\n async executePreToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n ): Promise<HookDecisionResult> {\n const input = createPreToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n )\n return this.executeToolEvent(\n HookEvent.PreToolUse,\n toolName,\n input,\n toolInput,\n )\n }\n\n async executePostToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n toolOutput: Record<string, unknown>,\n ): Promise<void> {\n const input = createPostToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n toolOutput,\n )\n await this.executeFireAndForget(HookEvent.PostToolUse, input)\n }\n\n async executePostToolUseFailure(\n toolName: string,\n toolInput: Record<string, unknown>,\n error: string,\n errorType?: string,\n ): Promise<void> {\n const input = createPostToolUseFailureInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n error,\n errorType,\n )\n await this.executeFireAndForget(HookEvent.PostToolUseFailure, input)\n\n // Emit diagnostics:new for tool failures (linter/compiler errors)\n emitReminderEvent('diagnostics:new', {\n source: toolName,\n count: 1,\n })\n }\n\n async executePermissionRequest(\n toolName: string,\n toolInput: Record<string, unknown>,\n permissionType: 'read' | 'write' | 'execute' | 'network' | 'other',\n description?: string,\n ): Promise<HookDecisionResult> {\n const input = createPermissionRequestInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n permissionType,\n description,\n )\n return this.executeBlockableEvent(HookEvent.PermissionRequest, input)\n }\n\n async executeUserPromptSubmit(\n userPrompt: string,\n ): Promise<HookDecisionResult> {\n const input = createUserPromptSubmitInput(\n this.sessionId,\n this.transcriptPath,\n userPrompt,\n )\n return this.executeBlockableEvent(HookEvent.UserPromptSubmit, input)\n }\n\n async executeSessionStart(): Promise<void> {\n const input = createSessionStartInput(this.sessionId, this.transcriptPath)\n await this.executeFireAndForget(HookEvent.SessionStart, input)\n }\n\n async executeSessionEnd(\n reason: 'clear' | 'logout' | 'prompt_input_exit' | 'other' = 'other',\n ): Promise<void> {\n const input = createSessionEndInput(\n this.sessionId,\n this.transcriptPath,\n reason,\n )\n await this.executeFireAndForget(HookEvent.SessionEnd, input)\n }\n\n async executeStop(\n lastAssistantMessage?: string,\n ): Promise<HookDecisionResult> {\n const input = createStopInput(this.sessionId, this.transcriptPath, true)\n if (lastAssistantMessage) {\n ;(input as any).last_assistant_message = lastAssistantMessage\n }\n return this.executeBlockableEvent(HookEvent.Stop, input)\n }\n\n async executeSubagentStart(\n agentType: string,\n agentDescription?: string,\n runInBackground?: boolean,\n ): Promise<void> {\n const input = createSubagentStartInput(\n this.sessionId,\n this.transcriptPath,\n agentType,\n agentDescription,\n runInBackground,\n )\n await this.executeFireAndForget(HookEvent.SubagentStart, input)\n }\n\n async executeSubagentStop(\n agentType: string,\n agentId?: string,\n transcriptPath?: string,\n lastMessage?: string,\n ): Promise<HookDecisionResult> {\n const input = createSubagentStopInput(\n this.sessionId,\n this.transcriptPath,\n agentType,\n agentId,\n )\n if (transcriptPath) {\n ;(input as any).agent_transcript_path = transcriptPath\n }\n if (lastMessage) {\n ;(input as any).last_message = lastMessage\n }\n return this.executeBlockableEvent(HookEvent.SubagentStop, input)\n }\n\n async executeNotification(\n message: string,\n title?: string,\n type?: string,\n ): Promise<{ suppressNotification?: boolean }> {\n if (!this.enabled) return {}\n\n const input = createNotificationInput(\n this.sessionId,\n this.transcriptPath,\n message,\n title,\n type,\n )\n\n const hooks = this.getMatchingEventHooks(HookEvent.Notification)\n if (hooks.length === 0) return {}\n\n const results: HookExecutionResult[] = []\n for (const hook of hooks) {\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: this.getPluginRoot(hook),\n }\n const result = await executeHooksForEvent(\n HookEvent.Notification,\n [hook],\n input,\n options,\n )\n results.push(...result)\n }\n\n // Check if any hook suppressed the notification\n const suppress = results.some(\n r => r.success && (r.output as any)?.suppressNotification,\n )\n return { suppressNotification: suppress }\n }\n\n async executePreCompact(\n trigger: 'manual' | 'auto',\n customInstructions?: string,\n ): Promise<void> {\n const input = createPreCompactInput(\n this.sessionId,\n this.transcriptPath,\n trigger,\n customInstructions || '',\n )\n await this.executeFireAndForget(HookEvent.PreCompact, input)\n }\n\n async executePostCompact(\n trigger: 'manual' | 'auto',\n summary: string,\n compressionRatio: number,\n originalTokens: number,\n compressedTokens: number,\n ): Promise<void> {\n const input = createPostCompactInput(\n this.sessionId,\n this.transcriptPath,\n trigger,\n summary,\n compressionRatio,\n originalTokens,\n compressedTokens,\n )\n await this.executeFireAndForget(HookEvent.PostCompact, input)\n }\n\n async executeConfigChange(\n source: 'settings' | 'project' | 'global' | 'env' | 'cli',\n filePath?: string,\n ): Promise<HookDecisionResult> {\n const input = createConfigChangeInput(\n this.sessionId,\n this.transcriptPath,\n source,\n filePath,\n )\n return this.executeBlockableEvent(HookEvent.ConfigChange, input)\n }\n\n async executeTaskCompleted(\n taskId: string,\n subject: string,\n description?: string,\n ): Promise<HookDecisionResult> {\n const input = createTaskCompletedInput(\n this.sessionId,\n this.transcriptPath,\n taskId,\n subject,\n description,\n )\n return this.executeBlockableEvent(HookEvent.TaskCompleted, input)\n }\n\n async executeTeammateIdle(\n teammateName: string,\n teamName: string,\n ): Promise<HookDecisionResult> {\n const input = createTeammateIdleInput(\n this.sessionId,\n this.transcriptPath,\n teammateName,\n teamName,\n )\n return this.executeBlockableEvent(HookEvent.TeammateIdle, input)\n }\n\n async executeWorktreeCreate(\n worktreePath: string,\n agentId: string,\n agentType: string,\n ): Promise<void> {\n const input = createWorktreeCreateInput(\n this.sessionId,\n this.transcriptPath,\n worktreePath,\n agentId,\n agentType,\n )\n await this.executeFireAndForget(HookEvent.WorktreeCreate, input)\n }\n\n async executeWorktreeRemove(\n worktreePath: string,\n agentId: string,\n agentType: string,\n success: boolean,\n ): Promise<void> {\n const input = createWorktreeRemoveInput(\n this.sessionId,\n this.transcriptPath,\n worktreePath,\n agentId,\n agentType,\n success,\n )\n await this.executeFireAndForget(HookEvent.WorktreeRemove, input)\n }\n}\n\n// ============================================================================\n// Global Hook Manager\n// ============================================================================\n\nlet globalHookManager: HookManager | null = null\n\nexport function initializeHookManager(\n sessionId: string,\n transcriptPath: string,\n plugins: LoadedPlugin[],\n): HookManager {\n globalHookManager = new HookManager(sessionId, transcriptPath)\n globalHookManager.registerPlugins(plugins)\n globalHookManager.loadSettingsHooks()\n return globalHookManager\n}\n\nexport function getHookManager(): HookManager | null {\n return globalHookManager\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/log.js
CHANGED
|
@@ -153,7 +153,10 @@ async function loadLogList(path = CACHE_PATHS.messages()) {
|
|
|
153
153
|
const logData = await Promise.all(
|
|
154
154
|
files.map(async (file, i) => {
|
|
155
155
|
const fullPath = join(path, file);
|
|
156
|
-
const content = await
|
|
156
|
+
const [content, stat] = await Promise.all([
|
|
157
|
+
fsPromises.readFile(fullPath, "utf8"),
|
|
158
|
+
fsPromises.stat(fullPath)
|
|
159
|
+
]);
|
|
157
160
|
const messages = JSON.parse(content);
|
|
158
161
|
const firstMessage = messages[0];
|
|
159
162
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -170,7 +173,8 @@ async function loadLogList(path = CACHE_PATHS.messages()) {
|
|
|
170
173
|
modified: lastMessage?.timestamp ? parseISOString(lastMessage.timestamp) : parseISOString(date),
|
|
171
174
|
firstPrompt: firstPrompt.split("\n")[0]?.slice(0, 50) + (firstPrompt.length > 50 ? "\u2026" : "") || "No prompt",
|
|
172
175
|
messageCount: messages.length,
|
|
173
|
-
sidechainNumber
|
|
176
|
+
sidechainNumber,
|
|
177
|
+
fileSize: stat.size
|
|
174
178
|
};
|
|
175
179
|
})
|
|
176
180
|
);
|
package/dist/utils/log.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/log.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n existsSync,\n mkdirSync,\n writeFileSync,\n readFileSync,\n promises as fsPromises,\n} from 'fs'\nimport { dirname, join } from 'path'\nimport { captureException } from '@services/sentry'\nimport { randomUUID } from 'crypto'\nimport envPaths from 'env-paths'\nimport type { LogOption, SerializedMessage } from '@minto-types/logs'\nimport { MACRO } from '@constants/macros'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\nconst IN_MEMORY_ERROR_LOG: Array<{ error: string; timestamp: string }> = []\nconst MAX_IN_MEMORY_ERRORS = 100 // Limit to prevent memory issues\n\nconst PERMISSION_ERROR_CODES = new Set(['EACCES', 'EPERM', 'EROFS'])\n\nfunction isPermissionError(error: unknown): error is NodeJS.ErrnoException {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n PERMISSION_ERROR_CODES.has((error as NodeJS.ErrnoException).code ?? '')\n )\n}\n\nfunction safeMkdir(dir: string): boolean {\n if (existsSync(dir)) return true\n try {\n mkdirSync(dir, { recursive: true })\n return true\n } catch (error) {\n if (isPermissionError(error)) {\n return false\n }\n throw error\n }\n}\n\nfunction safeWriteFile(\n path: string,\n data: string,\n encoding: BufferEncoding = 'utf8',\n): boolean {\n try {\n writeFileSync(path, data, encoding)\n return true\n } catch (error) {\n if (isPermissionError(error)) {\n return false\n }\n throw error\n }\n}\n\nexport const SESSION_ID = randomUUID()\n\nconst paths = envPaths(PRODUCT_COMMAND)\n\nfunction getProjectDir(cwd: string): string {\n return cwd.replace(/[^a-zA-Z0-9]/g, '-')\n}\n\nexport const CACHE_PATHS = {\n errors: () => join(paths.cache, getProjectDir(process.cwd()), 'errors'),\n messages: () => join(paths.cache, getProjectDir(process.cwd()), 'messages'),\n mcpLogs: (serverName: string) =>\n join(paths.cache, getProjectDir(process.cwd()), `mcp-logs-${serverName}`),\n}\n\nexport function dateToFilename(date: Date): string {\n return date.toISOString().replace(/[:.]/g, '-')\n}\n\nconst DATE = dateToFilename(new Date())\n\nfunction getErrorsPath(): string {\n return join(CACHE_PATHS.errors(), DATE + '.txt')\n}\n\nexport function getMessagesPath(\n messageLogName: string,\n forkNumber: number,\n sidechainNumber: number,\n): string {\n return join(\n CACHE_PATHS.messages(),\n `${messageLogName}${forkNumber > 0 ? `-${forkNumber}` : ''}${\n sidechainNumber > 0 ? `-sidechain-${sidechainNumber}` : ''\n }.json`,\n )\n}\n\nexport function logError(error: unknown): void {\n try {\n if (process.env.NODE_ENV === 'test') {\n console.error(error)\n }\n\n const errorStr =\n error instanceof Error ? error.stack || error.message : String(error)\n\n const errorInfo = {\n error: errorStr,\n timestamp: new Date().toISOString(),\n }\n\n if (IN_MEMORY_ERROR_LOG.length >= MAX_IN_MEMORY_ERRORS) {\n IN_MEMORY_ERROR_LOG.shift() // Remove oldest error\n }\n IN_MEMORY_ERROR_LOG.push(errorInfo)\n\n appendToLog(getErrorsPath(), {\n error: errorStr,\n })\n } catch {\n // pass\n }\n // Also send to Sentry with session ID, but don't await\n captureException(error)\n}\n\nexport function getErrorsLog(): object[] {\n return readLog(getErrorsPath())\n}\n\nexport function getInMemoryErrors(): object[] {\n return [...IN_MEMORY_ERROR_LOG]\n}\n\nfunction readLog(path: string): object[] {\n if (!existsSync(path)) {\n return []\n }\n try {\n return JSON.parse(readFileSync(path, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction appendToLog(path: string, message: object): void {\n if (process.env.USER_TYPE === 'external') {\n return\n }\n\n const dir = dirname(path)\n if (!safeMkdir(dir)) {\n return\n }\n\n // Create messages file with empty array if it doesn't exist\n if (!existsSync(path) && !safeWriteFile(path, '[]')) {\n return\n }\n\n const messages = readLog(path)\n const messageWithTimestamp = {\n ...message,\n cwd: process.cwd(),\n userType: process.env.USER_TYPE,\n sessionId: SESSION_ID,\n timestamp: new Date().toISOString(),\n version: MACRO.VERSION,\n }\n messages.push(messageWithTimestamp)\n\n safeWriteFile(path, JSON.stringify(messages, null, 2))\n}\n\nexport function overwriteLog(path: string, messages: object[]): void {\n if (process.env.USER_TYPE === 'external') {\n return\n }\n\n if (!messages.length) {\n return\n }\n\n const dir = dirname(path)\n if (!safeMkdir(dir)) {\n return\n }\n\n const messagesWithMetadata = messages.map(message => ({\n ...message,\n cwd: process.cwd(),\n userType: process.env.USER_TYPE,\n sessionId: SESSION_ID,\n timestamp: new Date().toISOString(),\n version: MACRO.VERSION,\n }))\n\n safeWriteFile(path, JSON.stringify(messagesWithMetadata, null, 2))\n}\n\nexport async function loadLogList(\n path = CACHE_PATHS.messages(),\n): Promise<LogOption[]> {\n if (!existsSync(path)) {\n logError(`No logs found at ${path}`)\n return []\n }\n\n const files = await fsPromises.readdir(path)\n const logData = await Promise.all(\n files.map(async (file, i) => {\n const fullPath = join(path, file)\n const content = await fsPromises.readFile(fullPath, 'utf8')\n const messages = JSON.parse(content) as SerializedMessage[]\n const firstMessage = messages[0]\n const lastMessage = messages[messages.length - 1]\n const firstPrompt =\n firstMessage?.type === 'user' &&\n typeof firstMessage?.message?.content === 'string'\n ? firstMessage?.message?.content\n : 'No prompt'\n\n const { date, forkNumber, sidechainNumber } = parseLogFilename(file)\n return {\n date,\n forkNumber,\n fullPath,\n messages,\n value: i, // hack: overwritten after sorting, right below this\n created: parseISOString(firstMessage?.timestamp || date),\n modified: lastMessage?.timestamp\n ? parseISOString(lastMessage.timestamp)\n : parseISOString(date),\n firstPrompt:\n firstPrompt.split('\\n')[0]?.slice(0, 50) +\n (firstPrompt.length > 50 ? '\u2026' : '') || 'No prompt',\n messageCount: messages.length,\n sidechainNumber,\n }\n }),\n )\n\n return sortLogs(logData.filter(_ => _.messages.length)).map((_, i) => ({\n ..._,\n value: i,\n }))\n}\n\nexport function parseLogFilename(filename: string): {\n date: string\n forkNumber: number | undefined\n sidechainNumber: number | undefined\n} {\n const base = filename.split('.')[0]!\n // Default timestamp format has 6 segments: 2025-01-27T01-31-35-104Z\n const segments = base.split('-')\n const hasSidechain = base.includes('-sidechain-')\n\n let date = base\n let forkNumber: number | undefined = undefined\n let sidechainNumber: number | undefined = undefined\n\n if (hasSidechain) {\n const sidechainIndex = segments.indexOf('sidechain')\n sidechainNumber = Number(segments[sidechainIndex + 1])\n // Fork number is before sidechain if exists\n if (sidechainIndex > 6) {\n forkNumber = Number(segments[sidechainIndex - 1])\n date = segments.slice(0, 6).join('-')\n } else {\n date = segments.slice(0, 6).join('-')\n }\n } else if (segments.length > 6) {\n // Has fork number\n const lastSegment = Number(segments[segments.length - 1])\n forkNumber = lastSegment >= 0 ? lastSegment : undefined\n date = segments.slice(0, 6).join('-')\n } else {\n // Basic timestamp only\n date = base\n }\n\n return { date, forkNumber, sidechainNumber }\n}\n\nexport function getNextAvailableLogForkNumber(\n date: string,\n forkNumber: number,\n // Main chain has sidechainNumber 0\n sidechainNumber: number,\n): number {\n while (existsSync(getMessagesPath(date, forkNumber, sidechainNumber))) {\n forkNumber++\n }\n return forkNumber\n}\n\nexport function getNextAvailableLogSidechainNumber(\n date: string,\n forkNumber: number,\n): number {\n let sidechainNumber = 1\n while (existsSync(getMessagesPath(date, forkNumber, sidechainNumber))) {\n sidechainNumber++\n }\n return sidechainNumber\n}\n\nexport function getForkNumberFromFilename(\n filename: string,\n): number | undefined {\n const base = filename.split('.')[0]!\n const segments = base.split('-')\n const hasSidechain = base.includes('-sidechain-')\n\n if (hasSidechain) {\n const sidechainIndex = segments.indexOf('sidechain')\n if (sidechainIndex > 6) {\n return Number(segments[sidechainIndex - 1])\n }\n return undefined\n }\n\n if (segments.length > 6) {\n const lastNumber = Number(segments[segments.length - 1])\n return lastNumber >= 0 ? lastNumber : undefined\n }\n return undefined\n}\n\nexport function sortLogs(logs: LogOption[]): LogOption[] {\n return logs.sort((a, b) => {\n // Sort by modified date (newest first)\n const modifiedDiff = b.modified.getTime() - a.modified.getTime()\n if (modifiedDiff !== 0) {\n return modifiedDiff\n }\n\n // If modified dates are equal, sort by created date\n const createdDiff = b.created.getTime() - a.created.getTime()\n if (createdDiff !== 0) {\n return createdDiff\n }\n\n // If both dates are equal, sort by fork number\n return (b.forkNumber ?? 0) - (a.forkNumber ?? 0)\n })\n}\n\nexport function formatDate(date: Date): string {\n const now = new Date()\n const yesterday = new Date(now)\n yesterday.setDate(yesterday.getDate() - 1)\n\n const isToday = date.toDateString() === now.toDateString()\n const isYesterday = date.toDateString() === yesterday.toDateString()\n\n const timeStr = date\n .toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n .toLowerCase()\n\n if (isToday) {\n return `Today at ${timeStr}`\n } else if (isYesterday) {\n return `Yesterday at ${timeStr}`\n } else {\n return (\n date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n }) + ` at ${timeStr}`\n )\n }\n}\n\nexport function parseISOString(s: string): Date {\n const b = s.split(/\\D+/)\n return new Date(\n Date.UTC(\n parseInt(b[0]!, 10),\n parseInt(b[1]!, 10) - 1,\n parseInt(b[2]!, 10),\n parseInt(b[3]!, 10),\n parseInt(b[4]!, 10),\n parseInt(b[5]!, 10),\n parseInt(b[6]!, 10),\n ),\n )\n}\n\nexport function logMCPError(serverName: string, error: unknown): void {\n try {\n const logDir = CACHE_PATHS.mcpLogs(serverName)\n const errorStr =\n error instanceof Error ? error.stack || error.message : String(error)\n const timestamp = new Date().toISOString()\n\n const logFile = join(logDir, DATE + '.txt')\n\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true })\n }\n\n if (!existsSync(logFile)) {\n writeFileSync(logFile, '[]', 'utf8')\n }\n\n const errorInfo = {\n error: errorStr,\n timestamp,\n sessionId: SESSION_ID,\n cwd: process.cwd(),\n }\n\n const messages = readLog(logFile)\n messages.push(errorInfo)\n writeFileSync(logFile, JSON.stringify(messages, null, 2), 'utf8')\n } catch {\n // Silently fail\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import {\n existsSync,\n mkdirSync,\n writeFileSync,\n readFileSync,\n promises as fsPromises,\n} from 'fs'\nimport { dirname, join } from 'path'\nimport { captureException } from '@services/sentry'\nimport { randomUUID } from 'crypto'\nimport envPaths from 'env-paths'\nimport type { LogOption, SerializedMessage } from '@minto-types/logs'\nimport { MACRO } from '@constants/macros'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\nconst IN_MEMORY_ERROR_LOG: Array<{ error: string; timestamp: string }> = []\nconst MAX_IN_MEMORY_ERRORS = 100 // Limit to prevent memory issues\n\nconst PERMISSION_ERROR_CODES = new Set(['EACCES', 'EPERM', 'EROFS'])\n\nfunction isPermissionError(error: unknown): error is NodeJS.ErrnoException {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n PERMISSION_ERROR_CODES.has((error as NodeJS.ErrnoException).code ?? '')\n )\n}\n\nfunction safeMkdir(dir: string): boolean {\n if (existsSync(dir)) return true\n try {\n mkdirSync(dir, { recursive: true })\n return true\n } catch (error) {\n if (isPermissionError(error)) {\n return false\n }\n throw error\n }\n}\n\nfunction safeWriteFile(\n path: string,\n data: string,\n encoding: BufferEncoding = 'utf8',\n): boolean {\n try {\n writeFileSync(path, data, encoding)\n return true\n } catch (error) {\n if (isPermissionError(error)) {\n return false\n }\n throw error\n }\n}\n\nexport const SESSION_ID = randomUUID()\n\nconst paths = envPaths(PRODUCT_COMMAND)\n\nfunction getProjectDir(cwd: string): string {\n return cwd.replace(/[^a-zA-Z0-9]/g, '-')\n}\n\nexport const CACHE_PATHS = {\n errors: () => join(paths.cache, getProjectDir(process.cwd()), 'errors'),\n messages: () => join(paths.cache, getProjectDir(process.cwd()), 'messages'),\n mcpLogs: (serverName: string) =>\n join(paths.cache, getProjectDir(process.cwd()), `mcp-logs-${serverName}`),\n}\n\nexport function dateToFilename(date: Date): string {\n return date.toISOString().replace(/[:.]/g, '-')\n}\n\nconst DATE = dateToFilename(new Date())\n\nfunction getErrorsPath(): string {\n return join(CACHE_PATHS.errors(), DATE + '.txt')\n}\n\nexport function getMessagesPath(\n messageLogName: string,\n forkNumber: number,\n sidechainNumber: number,\n): string {\n return join(\n CACHE_PATHS.messages(),\n `${messageLogName}${forkNumber > 0 ? `-${forkNumber}` : ''}${\n sidechainNumber > 0 ? `-sidechain-${sidechainNumber}` : ''\n }.json`,\n )\n}\n\nexport function logError(error: unknown): void {\n try {\n if (process.env.NODE_ENV === 'test') {\n console.error(error)\n }\n\n const errorStr =\n error instanceof Error ? error.stack || error.message : String(error)\n\n const errorInfo = {\n error: errorStr,\n timestamp: new Date().toISOString(),\n }\n\n if (IN_MEMORY_ERROR_LOG.length >= MAX_IN_MEMORY_ERRORS) {\n IN_MEMORY_ERROR_LOG.shift() // Remove oldest error\n }\n IN_MEMORY_ERROR_LOG.push(errorInfo)\n\n appendToLog(getErrorsPath(), {\n error: errorStr,\n })\n } catch {\n // pass\n }\n // Also send to Sentry with session ID, but don't await\n captureException(error)\n}\n\nexport function getErrorsLog(): object[] {\n return readLog(getErrorsPath())\n}\n\nexport function getInMemoryErrors(): object[] {\n return [...IN_MEMORY_ERROR_LOG]\n}\n\nfunction readLog(path: string): object[] {\n if (!existsSync(path)) {\n return []\n }\n try {\n return JSON.parse(readFileSync(path, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction appendToLog(path: string, message: object): void {\n if (process.env.USER_TYPE === 'external') {\n return\n }\n\n const dir = dirname(path)\n if (!safeMkdir(dir)) {\n return\n }\n\n // Create messages file with empty array if it doesn't exist\n if (!existsSync(path) && !safeWriteFile(path, '[]')) {\n return\n }\n\n const messages = readLog(path)\n const messageWithTimestamp = {\n ...message,\n cwd: process.cwd(),\n userType: process.env.USER_TYPE,\n sessionId: SESSION_ID,\n timestamp: new Date().toISOString(),\n version: MACRO.VERSION,\n }\n messages.push(messageWithTimestamp)\n\n safeWriteFile(path, JSON.stringify(messages, null, 2))\n}\n\nexport function overwriteLog(path: string, messages: object[]): void {\n if (process.env.USER_TYPE === 'external') {\n return\n }\n\n if (!messages.length) {\n return\n }\n\n const dir = dirname(path)\n if (!safeMkdir(dir)) {\n return\n }\n\n const messagesWithMetadata = messages.map(message => ({\n ...message,\n cwd: process.cwd(),\n userType: process.env.USER_TYPE,\n sessionId: SESSION_ID,\n timestamp: new Date().toISOString(),\n version: MACRO.VERSION,\n }))\n\n safeWriteFile(path, JSON.stringify(messagesWithMetadata, null, 2))\n}\n\nexport async function loadLogList(\n path = CACHE_PATHS.messages(),\n): Promise<LogOption[]> {\n if (!existsSync(path)) {\n logError(`No logs found at ${path}`)\n return []\n }\n\n const files = await fsPromises.readdir(path)\n const logData = await Promise.all(\n files.map(async (file, i) => {\n const fullPath = join(path, file)\n const [content, stat] = await Promise.all([\n fsPromises.readFile(fullPath, 'utf8'),\n fsPromises.stat(fullPath),\n ])\n const messages = JSON.parse(content) as SerializedMessage[]\n const firstMessage = messages[0]\n const lastMessage = messages[messages.length - 1]\n const firstPrompt =\n firstMessage?.type === 'user' &&\n typeof firstMessage?.message?.content === 'string'\n ? firstMessage?.message?.content\n : 'No prompt'\n\n const { date, forkNumber, sidechainNumber } = parseLogFilename(file)\n return {\n date,\n forkNumber,\n fullPath,\n messages,\n value: i, // hack: overwritten after sorting, right below this\n created: parseISOString(firstMessage?.timestamp || date),\n modified: lastMessage?.timestamp\n ? parseISOString(lastMessage.timestamp)\n : parseISOString(date),\n firstPrompt:\n firstPrompt.split('\\n')[0]?.slice(0, 50) +\n (firstPrompt.length > 50 ? '\u2026' : '') || 'No prompt',\n messageCount: messages.length,\n sidechainNumber,\n fileSize: stat.size,\n }\n }),\n )\n\n return sortLogs(logData.filter(_ => _.messages.length)).map((_, i) => ({\n ..._,\n value: i,\n }))\n}\n\nexport function parseLogFilename(filename: string): {\n date: string\n forkNumber: number | undefined\n sidechainNumber: number | undefined\n} {\n const base = filename.split('.')[0]!\n // Default timestamp format has 6 segments: 2025-01-27T01-31-35-104Z\n const segments = base.split('-')\n const hasSidechain = base.includes('-sidechain-')\n\n let date = base\n let forkNumber: number | undefined = undefined\n let sidechainNumber: number | undefined = undefined\n\n if (hasSidechain) {\n const sidechainIndex = segments.indexOf('sidechain')\n sidechainNumber = Number(segments[sidechainIndex + 1])\n // Fork number is before sidechain if exists\n if (sidechainIndex > 6) {\n forkNumber = Number(segments[sidechainIndex - 1])\n date = segments.slice(0, 6).join('-')\n } else {\n date = segments.slice(0, 6).join('-')\n }\n } else if (segments.length > 6) {\n // Has fork number\n const lastSegment = Number(segments[segments.length - 1])\n forkNumber = lastSegment >= 0 ? lastSegment : undefined\n date = segments.slice(0, 6).join('-')\n } else {\n // Basic timestamp only\n date = base\n }\n\n return { date, forkNumber, sidechainNumber }\n}\n\nexport function getNextAvailableLogForkNumber(\n date: string,\n forkNumber: number,\n // Main chain has sidechainNumber 0\n sidechainNumber: number,\n): number {\n while (existsSync(getMessagesPath(date, forkNumber, sidechainNumber))) {\n forkNumber++\n }\n return forkNumber\n}\n\nexport function getNextAvailableLogSidechainNumber(\n date: string,\n forkNumber: number,\n): number {\n let sidechainNumber = 1\n while (existsSync(getMessagesPath(date, forkNumber, sidechainNumber))) {\n sidechainNumber++\n }\n return sidechainNumber\n}\n\nexport function getForkNumberFromFilename(\n filename: string,\n): number | undefined {\n const base = filename.split('.')[0]!\n const segments = base.split('-')\n const hasSidechain = base.includes('-sidechain-')\n\n if (hasSidechain) {\n const sidechainIndex = segments.indexOf('sidechain')\n if (sidechainIndex > 6) {\n return Number(segments[sidechainIndex - 1])\n }\n return undefined\n }\n\n if (segments.length > 6) {\n const lastNumber = Number(segments[segments.length - 1])\n return lastNumber >= 0 ? lastNumber : undefined\n }\n return undefined\n}\n\nexport function sortLogs(logs: LogOption[]): LogOption[] {\n return logs.sort((a, b) => {\n // Sort by modified date (newest first)\n const modifiedDiff = b.modified.getTime() - a.modified.getTime()\n if (modifiedDiff !== 0) {\n return modifiedDiff\n }\n\n // If modified dates are equal, sort by created date\n const createdDiff = b.created.getTime() - a.created.getTime()\n if (createdDiff !== 0) {\n return createdDiff\n }\n\n // If both dates are equal, sort by fork number\n return (b.forkNumber ?? 0) - (a.forkNumber ?? 0)\n })\n}\n\nexport function formatDate(date: Date): string {\n const now = new Date()\n const yesterday = new Date(now)\n yesterday.setDate(yesterday.getDate() - 1)\n\n const isToday = date.toDateString() === now.toDateString()\n const isYesterday = date.toDateString() === yesterday.toDateString()\n\n const timeStr = date\n .toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n .toLowerCase()\n\n if (isToday) {\n return `Today at ${timeStr}`\n } else if (isYesterday) {\n return `Yesterday at ${timeStr}`\n } else {\n return (\n date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n }) + ` at ${timeStr}`\n )\n }\n}\n\nexport function parseISOString(s: string): Date {\n const b = s.split(/\\D+/)\n return new Date(\n Date.UTC(\n parseInt(b[0]!, 10),\n parseInt(b[1]!, 10) - 1,\n parseInt(b[2]!, 10),\n parseInt(b[3]!, 10),\n parseInt(b[4]!, 10),\n parseInt(b[5]!, 10),\n parseInt(b[6]!, 10),\n ),\n )\n}\n\nexport function logMCPError(serverName: string, error: unknown): void {\n try {\n const logDir = CACHE_PATHS.mcpLogs(serverName)\n const errorStr =\n error instanceof Error ? error.stack || error.message : String(error)\n const timestamp = new Date().toISOString()\n\n const logFile = join(logDir, DATE + '.txt')\n\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true })\n }\n\n if (!existsSync(logFile)) {\n writeFileSync(logFile, '[]', 'utf8')\n }\n\n const errorInfo = {\n error: errorStr,\n timestamp,\n sessionId: SESSION_ID,\n cwd: process.cwd(),\n }\n\n const messages = readLog(logFile)\n messages.push(errorInfo)\n writeFileSync(logFile, JSON.stringify(messages, null, 2), 'utf8')\n } catch {\n // Silently fail\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|