@within-7/minto 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +461 -657
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +684 -94
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +425 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +457 -65
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +891 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +146 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +590 -565
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +26 -11
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +123 -48
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +11 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +21 -3
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +81 -68
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +299 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +300 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +20 -9
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +367 -9
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +8 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +84 -11
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +3 -5
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +91 -15
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +27 -151
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +68 -29
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +249 -57
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +77 -12
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +162 -16
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
|
@@ -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 plugin hooks lifecycle.\n * Coordinates hook execution across the application.\n */\n\nimport { HookEvent } from '../types/hooks'\nimport { LoadedPlugin } from '../types/plugin'\nimport {\n executeHooksForEvent,\n processHookDecisions,\n createPreToolUseInput,\n createPostToolUseInput,\n createUserPromptSubmitInput,\n createSessionStartInput,\n createSessionEndInput,\n type HookExecutionOptions,\n type HookExecutionResult,\n} from '../services/hookExecutor'\nimport { logError } from './log'\n\n// Simple logging helpers\nconst logInfo = (msg: string) => {\n // Only log in debug mode to reduce noise\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 * Hook manager instance\n */\nexport class HookManager {\n private plugins: LoadedPlugin[] = []\n private sessionId: string\n private transcriptPath: string\n private enabled: boolean = true\n\n constructor(sessionId: string, transcriptPath: string) {\n this.sessionId = sessionId\n this.transcriptPath = transcriptPath\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 * Enable or disable hook execution\n */\n setEnabled(enabled: boolean) {\n this.enabled = enabled\n logDebug(`HookManager: ${enabled ? 'Enabled' : 'Disabled'}`)\n }\n\n /**\n * Execute PreToolUse hooks\n */\n async executePreToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n ): Promise<{\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n }> {\n if (!this.enabled) {\n return { shouldContinue: true, shouldAskUser: false }\n }\n\n // Collect all hooks across all plugins\n const allHooks = this.plugins.flatMap(p => p.hooks)\n\n // Filter hooks that match this tool\n const matchingHooks = allHooks.filter(hook => {\n if (hook.event !== HookEvent.PreToolUse) return false\n if (!hook.matcher) return true // No matcher means match all\n if (hook.matcher === '*' || hook.matcher === '') return true\n\n // Check if tool name matches the pattern\n try {\n const regex = new RegExp(hook.matcher)\n return regex.test(toolName)\n } catch {\n // If regex is invalid, try exact match\n return hook.matcher === toolName\n }\n })\n\n if (matchingHooks.length === 0) {\n return { shouldContinue: true, shouldAskUser: false }\n }\n\n logDebug(\n `PreToolUse: ${matchingHooks.length} hook(s) matched for tool: ${toolName}`,\n )\n\n // Execute hooks\n const input = createPreToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n )\n\n const results: HookExecutionResult[] = []\n\n for (const hook of matchingHooks) {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n if (!plugin) continue\n\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: plugin.location,\n }\n\n const result = await executeHooksForEvent(\n HookEvent.PreToolUse,\n [hook],\n input,\n options,\n )\n\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n /**\n * Execute PostToolUse hooks\n */\n async executePostToolUse(\n toolName: string,\n toolInput: Record<string, unknown>,\n toolOutput: Record<string, unknown>,\n ): Promise<void> {\n if (!this.enabled) {\n return\n }\n\n const allHooks = this.plugins.flatMap(p => p.hooks)\n\n const matchingHooks = allHooks.filter(hook => {\n if (hook.event !== HookEvent.PostToolUse) return false\n if (!hook.matcher) return true\n if (hook.matcher === '*' || hook.matcher === '') return true\n\n try {\n const regex = new RegExp(hook.matcher)\n return regex.test(toolName)\n } catch {\n return hook.matcher === toolName\n }\n })\n\n if (matchingHooks.length === 0) {\n return\n }\n\n logDebug(\n `PostToolUse: ${matchingHooks.length} hook(s) matched for tool: ${toolName}`,\n )\n\n const input = createPostToolUseInput(\n this.sessionId,\n this.transcriptPath,\n toolName,\n toolInput,\n toolOutput,\n )\n\n for (const hook of matchingHooks) {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n if (!plugin) continue\n\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: plugin.location,\n }\n\n // PostToolUse hooks don't affect workflow, just execute them\n await executeHooksForEvent(HookEvent.PostToolUse, [hook], input, options)\n }\n }\n\n /**\n * Execute UserPromptSubmit hooks\n */\n async executeUserPromptSubmit(userPrompt: string): Promise<{\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n }> {\n if (!this.enabled) {\n return { shouldContinue: true, shouldAskUser: false }\n }\n\n const allHooks = this.plugins.flatMap(p => p.hooks)\n const matchingHooks = allHooks.filter(\n hook => hook.event === HookEvent.UserPromptSubmit,\n )\n\n if (matchingHooks.length === 0) {\n return { shouldContinue: true, shouldAskUser: false }\n }\n\n logDebug(`UserPromptSubmit: ${matchingHooks.length} hook(s)`)\n\n const input = createUserPromptSubmitInput(\n this.sessionId,\n this.transcriptPath,\n userPrompt,\n )\n\n const results: HookExecutionResult[] = []\n\n for (const hook of matchingHooks) {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n if (!plugin) continue\n\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: plugin.location,\n }\n\n const result = await executeHooksForEvent(\n HookEvent.UserPromptSubmit,\n [hook],\n input,\n options,\n )\n\n results.push(...result)\n }\n\n return processHookDecisions(results)\n }\n\n /**\n * Execute SessionStart hooks\n */\n async executeSessionStart(): Promise<void> {\n if (!this.enabled) {\n return\n }\n\n const allHooks = this.plugins.flatMap(p => p.hooks)\n const matchingHooks = allHooks.filter(\n hook => hook.event === HookEvent.SessionStart,\n )\n\n if (matchingHooks.length === 0) {\n return\n }\n\n logInfo(`SessionStart: Executing ${matchingHooks.length} hook(s)`)\n\n const input = createSessionStartInput(this.sessionId, this.transcriptPath)\n\n for (const hook of matchingHooks) {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n if (!plugin) continue\n\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: plugin.location,\n }\n\n await executeHooksForEvent(HookEvent.SessionStart, [hook], input, options)\n }\n }\n\n /**\n * Execute SessionEnd hooks\n */\n async executeSessionEnd(\n reason: 'clear' | 'logout' | 'prompt_input_exit' | 'other' = 'other',\n ): Promise<void> {\n if (!this.enabled) {\n return\n }\n\n const allHooks = this.plugins.flatMap(p => p.hooks)\n const matchingHooks = allHooks.filter(\n hook => hook.event === HookEvent.SessionEnd,\n )\n\n if (matchingHooks.length === 0) {\n return\n }\n\n logInfo(`SessionEnd: Executing ${matchingHooks.length} hook(s)`)\n\n const input = createSessionEndInput(\n this.sessionId,\n this.transcriptPath,\n reason,\n )\n\n for (const hook of matchingHooks) {\n const plugin = this.plugins.find(p => p.manifest.name === hook.pluginName)\n if (!plugin) continue\n\n const options: HookExecutionOptions = {\n sessionId: this.sessionId,\n transcriptPath: this.transcriptPath,\n pluginRoot: plugin.location,\n }\n\n await executeHooksForEvent(HookEvent.SessionEnd, [hook], input, options)\n }\n }\n}\n\n/**\n * Global hook manager instance\n */\nlet globalHookManager: HookManager | null = null\n\n/**\n * Initialize global hook manager\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 return globalHookManager\n}\n\n/**\n * Get global hook manager\n */\nexport function getHookManager(): HookManager | null {\n return globalHookManager\n}\n"],
|
|
5
|
-
"mappings": "
|
|
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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/markdown.js
CHANGED
|
@@ -79,9 +79,56 @@ function format(token, listDepth = 0, orderedListNumber = null, parent = null) {
|
|
|
79
79
|
} else {
|
|
80
80
|
return token.text;
|
|
81
81
|
}
|
|
82
|
+
case "table": {
|
|
83
|
+
const headerTexts = token.header.map(
|
|
84
|
+
(cell) => (cell.tokens ?? []).map((_) => format(_)).join("")
|
|
85
|
+
);
|
|
86
|
+
const rowTexts = token.rows.map(
|
|
87
|
+
(row) => row.map(
|
|
88
|
+
(cell) => (cell.tokens ?? []).map((_) => format(_)).join("")
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
const colCount = headerTexts.length;
|
|
92
|
+
const colWidths = [];
|
|
93
|
+
for (let c = 0; c < colCount; c++) {
|
|
94
|
+
let maxWidth = stripAnsi(headerTexts[c] ?? "").length;
|
|
95
|
+
for (const row of rowTexts) {
|
|
96
|
+
maxWidth = Math.max(maxWidth, stripAnsi(row[c] ?? "").length);
|
|
97
|
+
}
|
|
98
|
+
colWidths.push(Math.max(maxWidth, 3));
|
|
99
|
+
}
|
|
100
|
+
const headerRow = headerTexts.map(
|
|
101
|
+
(text, i) => chalk.bold(padCell(text, colWidths[i], token.align[i]))
|
|
102
|
+
).join(" | ");
|
|
103
|
+
const separator = colWidths.map((w, i) => {
|
|
104
|
+
const align = token.align[i];
|
|
105
|
+
if (align === "center") return ":" + "-".repeat(w - 2) + ":";
|
|
106
|
+
if (align === "right") return "-".repeat(w - 1) + ":";
|
|
107
|
+
if (align === "left") return ":" + "-".repeat(w - 1);
|
|
108
|
+
return "-".repeat(w);
|
|
109
|
+
}).join(" | ");
|
|
110
|
+
const dataRows = rowTexts.map(
|
|
111
|
+
(row) => row.map((text, i) => padCell(text, colWidths[i], token.align[i])).join(" | ")
|
|
112
|
+
);
|
|
113
|
+
return [headerRow, separator, ...dataRows].join(EOL) + EOL;
|
|
114
|
+
}
|
|
82
115
|
}
|
|
83
116
|
return "";
|
|
84
117
|
}
|
|
118
|
+
function stripAnsi(str) {
|
|
119
|
+
return str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
120
|
+
}
|
|
121
|
+
function padCell(text, width, align) {
|
|
122
|
+
const visibleLength = stripAnsi(text).length;
|
|
123
|
+
const padding = Math.max(0, width - visibleLength);
|
|
124
|
+
if (align === "right") return " ".repeat(padding) + text;
|
|
125
|
+
if (align === "center") {
|
|
126
|
+
const left = Math.floor(padding / 2);
|
|
127
|
+
const right = padding - left;
|
|
128
|
+
return " ".repeat(left) + text + " ".repeat(right);
|
|
129
|
+
}
|
|
130
|
+
return text + " ".repeat(padding);
|
|
131
|
+
}
|
|
85
132
|
const DEPTH_1_LIST_NUMBERS = [
|
|
86
133
|
"a",
|
|
87
134
|
"b",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/markdown.ts"],
|
|
4
|
-
"sourcesContent": ["import { marked, Token } from 'marked'\nimport { stripSystemMessages } from './messages'\nimport chalk from 'chalk'\nimport { EOL } from 'os'\nimport { highlight, supportsLanguage } from 'cli-highlight'\nimport { logError } from './log'\n\n/**\n * Strip outer markdown code block wrapper if present.\n * AI models sometimes wrap their response in ```markdown ... ``` which\n * causes the content to be parsed as a code block instead of actual markdown.\n */\nfunction stripMarkdownCodeBlockWrapper(content: string): string {\n const trimmed = content.trim()\n // Match ```markdown or ```md at the start and ``` at the end\n const codeBlockRegex = /^```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```$/\n const match = trimmed.match(codeBlockRegex)\n if (match) {\n return match[1] ?? trimmed\n }\n return content\n}\n\nexport function applyMarkdown(content: string): string {\n // Pre-process: remove outer markdown code block wrapper if present\n const preprocessed = stripMarkdownCodeBlockWrapper(\n stripSystemMessages(content),\n )\n return marked\n .lexer(preprocessed)\n .map(_ => format(_))\n .join('')\n .trim()\n}\n\nfunction format(\n token: Token,\n listDepth = 0,\n orderedListNumber: number | null = null,\n parent: Token | null = null,\n): string {\n switch (token.type) {\n case 'blockquote':\n return chalk.dim.italic((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'code':\n if (token.lang && supportsLanguage(token.lang)) {\n return highlight(token.text, { language: token.lang }) + EOL\n } else {\n logError(\n `Language not supported while highlighting code, falling back to markdown: ${token.lang}`,\n )\n return highlight(token.text, { language: 'markdown' }) + EOL\n }\n case 'codespan':\n // inline code\n return chalk.blue(token.text)\n case 'em':\n return chalk.italic((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'strong':\n return chalk.bold((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'heading':\n switch (token.depth) {\n case 1: // h1\n return (\n chalk.bold.italic.underline(\n (token.tokens ?? []).map(_ => format(_)).join(''),\n ) +\n EOL +\n EOL\n )\n case 2: // h2\n return (\n chalk.bold((token.tokens ?? []).map(_ => format(_)).join('')) +\n EOL +\n EOL\n )\n default: // h3+\n return (\n chalk.bold.dim((token.tokens ?? []).map(_ => format(_)).join('')) +\n EOL +\n EOL\n )\n }\n case 'hr':\n return '---'\n case 'image':\n return `[Image: ${token.title}: ${token.href}]`\n case 'link':\n return chalk.blue(token.href)\n case 'list': {\n return token.items\n .map((_: Token, index: number) =>\n format(\n _,\n listDepth,\n token.ordered ? token.start + index : null,\n token,\n ),\n )\n .join('')\n }\n case 'list_item':\n return (token.tokens ?? [])\n .map(\n _ =>\n `${' '.repeat(listDepth)}${format(_, listDepth + 1, orderedListNumber, token)}`,\n )\n .join('')\n case 'paragraph':\n return (token.tokens ?? []).map(_ => format(_)).join('') + EOL\n case 'space':\n return EOL\n case 'text':\n if (parent?.type === 'list_item') {\n return `${orderedListNumber === null ? '-' : getListNumber(listDepth, orderedListNumber) + '.'} ${token.tokens ? token.tokens.map(_ => format(_, listDepth, orderedListNumber, token)).join('') : token.text}${EOL}`\n } else {\n return token.text\n }\n }\n //
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { marked, Token } from 'marked'\nimport { stripSystemMessages } from './messages'\nimport chalk from 'chalk'\nimport { EOL } from 'os'\nimport { highlight, supportsLanguage } from 'cli-highlight'\nimport { logError } from './log'\n\n/**\n * Strip outer markdown code block wrapper if present.\n * AI models sometimes wrap their response in ```markdown ... ``` which\n * causes the content to be parsed as a code block instead of actual markdown.\n */\nfunction stripMarkdownCodeBlockWrapper(content: string): string {\n const trimmed = content.trim()\n // Match ```markdown or ```md at the start and ``` at the end\n const codeBlockRegex = /^```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```$/\n const match = trimmed.match(codeBlockRegex)\n if (match) {\n return match[1] ?? trimmed\n }\n return content\n}\n\nexport function applyMarkdown(content: string): string {\n // Pre-process: remove outer markdown code block wrapper if present\n const preprocessed = stripMarkdownCodeBlockWrapper(\n stripSystemMessages(content),\n )\n return marked\n .lexer(preprocessed)\n .map(_ => format(_))\n .join('')\n .trim()\n}\n\nfunction format(\n token: Token,\n listDepth = 0,\n orderedListNumber: number | null = null,\n parent: Token | null = null,\n): string {\n switch (token.type) {\n case 'blockquote':\n return chalk.dim.italic((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'code':\n if (token.lang && supportsLanguage(token.lang)) {\n return highlight(token.text, { language: token.lang }) + EOL\n } else {\n logError(\n `Language not supported while highlighting code, falling back to markdown: ${token.lang}`,\n )\n return highlight(token.text, { language: 'markdown' }) + EOL\n }\n case 'codespan':\n // inline code\n return chalk.blue(token.text)\n case 'em':\n return chalk.italic((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'strong':\n return chalk.bold((token.tokens ?? []).map(_ => format(_)).join(''))\n case 'heading':\n switch (token.depth) {\n case 1: // h1\n return (\n chalk.bold.italic.underline(\n (token.tokens ?? []).map(_ => format(_)).join(''),\n ) +\n EOL +\n EOL\n )\n case 2: // h2\n return (\n chalk.bold((token.tokens ?? []).map(_ => format(_)).join('')) +\n EOL +\n EOL\n )\n default: // h3+\n return (\n chalk.bold.dim((token.tokens ?? []).map(_ => format(_)).join('')) +\n EOL +\n EOL\n )\n }\n case 'hr':\n return '---'\n case 'image':\n return `[Image: ${token.title}: ${token.href}]`\n case 'link':\n return chalk.blue(token.href)\n case 'list': {\n return token.items\n .map((_: Token, index: number) =>\n format(\n _,\n listDepth,\n token.ordered ? token.start + index : null,\n token,\n ),\n )\n .join('')\n }\n case 'list_item':\n return (token.tokens ?? [])\n .map(\n _ =>\n `${' '.repeat(listDepth)}${format(_, listDepth + 1, orderedListNumber, token)}`,\n )\n .join('')\n case 'paragraph':\n return (token.tokens ?? []).map(_ => format(_)).join('') + EOL\n case 'space':\n return EOL\n case 'text':\n if (parent?.type === 'list_item') {\n return `${orderedListNumber === null ? '-' : getListNumber(listDepth, orderedListNumber) + '.'} ${token.tokens ? token.tokens.map(_ => format(_, listDepth, orderedListNumber, token)).join('') : token.text}${EOL}`\n } else {\n return token.text\n }\n case 'table': {\n // Render each cell's inline tokens to get display text\n const headerTexts = (token.header as any[]).map((cell: any) =>\n (cell.tokens ?? []).map((_: Token) => format(_)).join(''),\n )\n const rowTexts = (token.rows as any[][]).map((row: any[]) =>\n row.map((cell: any) =>\n (cell.tokens ?? []).map((_: Token) => format(_)).join(''),\n ),\n )\n\n // Calculate column widths (max of header and all rows)\n const colCount = headerTexts.length\n const colWidths: number[] = []\n for (let c = 0; c < colCount; c++) {\n let maxWidth = stripAnsi(headerTexts[c] ?? '').length\n for (const row of rowTexts) {\n maxWidth = Math.max(maxWidth, stripAnsi(row[c] ?? '').length)\n }\n colWidths.push(Math.max(maxWidth, 3)) // minimum 3 chars\n }\n\n // Build header row\n const headerRow = headerTexts\n .map((text, i) =>\n chalk.bold(padCell(text, colWidths[i]!, token.align[i])),\n )\n .join(' | ')\n\n // Build separator\n const separator = colWidths\n .map((w, i) => {\n const align = token.align[i]\n if (align === 'center') return ':' + '-'.repeat(w - 2) + ':'\n if (align === 'right') return '-'.repeat(w - 1) + ':'\n if (align === 'left') return ':' + '-'.repeat(w - 1)\n return '-'.repeat(w)\n })\n .join(' | ')\n\n // Build data rows\n const dataRows = rowTexts.map(row =>\n row\n .map((text, i) => padCell(text, colWidths[i]!, token.align[i]))\n .join(' | '),\n )\n\n return [headerRow, separator, ...dataRows].join(EOL) + EOL\n }\n }\n return ''\n}\n\n/**\n * Strip ANSI escape codes for accurate width calculation\n */\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B\\[[0-9;]*m/g, '')\n}\n\n/**\n * Pad a cell to a target width, respecting alignment and ANSI codes\n */\nfunction padCell(\n text: string,\n width: number,\n align: 'center' | 'left' | 'right' | null,\n): string {\n const visibleLength = stripAnsi(text).length\n const padding = Math.max(0, width - visibleLength)\n if (align === 'right') return ' '.repeat(padding) + text\n if (align === 'center') {\n const left = Math.floor(padding / 2)\n const right = padding - left\n return ' '.repeat(left) + text + ' '.repeat(right)\n }\n // left or null (default left)\n return text + ' '.repeat(padding)\n}\n\nconst DEPTH_1_LIST_NUMBERS = [\n 'a',\n 'b',\n 'c',\n 'd',\n 'e',\n 'f',\n 'g',\n 'h',\n 'i',\n 'j',\n 'k',\n 'l',\n 'm',\n 'n',\n 'o',\n 'p',\n 'q',\n 'r',\n 's',\n 't',\n 'u',\n 'v',\n 'w',\n 'x',\n 'y',\n 'z',\n 'aa',\n 'ab',\n 'ac',\n 'ad',\n 'ae',\n 'af',\n 'ag',\n 'ah',\n 'ai',\n 'aj',\n 'ak',\n 'al',\n 'am',\n 'an',\n 'ao',\n 'ap',\n 'aq',\n 'ar',\n 'as',\n 'at',\n 'au',\n 'av',\n 'aw',\n 'ax',\n 'ay',\n 'az',\n]\nconst DEPTH_2_LIST_NUMBERS = [\n 'i',\n 'ii',\n 'iii',\n 'iv',\n 'v',\n 'vi',\n 'vii',\n 'viii',\n 'ix',\n 'x',\n 'xi',\n 'xii',\n 'xiii',\n 'xiv',\n 'xv',\n 'xvi',\n 'xvii',\n 'xviii',\n 'xix',\n 'xx',\n 'xxi',\n 'xxii',\n 'xxiii',\n 'xxiv',\n 'xxv',\n 'xxvi',\n 'xxvii',\n 'xxviii',\n 'xxix',\n 'xxx',\n 'xxxi',\n 'xxxii',\n 'xxxiii',\n 'xxxiv',\n 'xxxv',\n 'xxxvi',\n 'xxxvii',\n 'xxxviii',\n 'xxxix',\n 'xl',\n]\n\nfunction getListNumber(listDepth: number, orderedListNumber: number): string {\n switch (listDepth) {\n case 0:\n case 1:\n return orderedListNumber.toString()\n case 2:\n return DEPTH_1_LIST_NUMBERS[orderedListNumber - 1]! // TODO: don't hard code the list\n case 3:\n return DEPTH_2_LIST_NUMBERS[orderedListNumber - 1]! // TODO: don't hard code the list\n default:\n return orderedListNumber.toString()\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "fs";
|
|
11
11
|
import { join, resolve, isAbsolute } from "path";
|
|
12
12
|
import { homedir } from "os";
|
|
13
|
-
import {
|
|
13
|
+
import { fetchRepo } from "./repoFetcher.js";
|
|
14
14
|
import {
|
|
15
15
|
MarketplaceManifestSchema,
|
|
16
16
|
MarketplaceError,
|
|
@@ -45,38 +45,13 @@ function saveRegistry(marketplaces) {
|
|
|
45
45
|
const registryPath = getRegistryPath();
|
|
46
46
|
writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), "utf-8");
|
|
47
47
|
}
|
|
48
|
-
async function cloneGitRepo(url, ref) {
|
|
49
|
-
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
50
|
-
mkdirSync(tempDir, { recursive: true });
|
|
51
|
-
try {
|
|
52
|
-
const args = ["clone", "--depth", "1"];
|
|
53
|
-
if (ref) {
|
|
54
|
-
args.push("--branch", ref);
|
|
55
|
-
}
|
|
56
|
-
args.push(url, tempDir);
|
|
57
|
-
const result = await execFileNoThrow("git", args);
|
|
58
|
-
if (result.code !== 0) {
|
|
59
|
-
throw new Error(`Git clone failed: ${result.stderr || result.stdout}`);
|
|
60
|
-
}
|
|
61
|
-
return tempDir;
|
|
62
|
-
} catch (error) {
|
|
63
|
-
try {
|
|
64
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
65
|
-
} catch (cleanupError) {
|
|
66
|
-
}
|
|
67
|
-
throw new MarketplaceError(
|
|
68
|
-
`Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`,
|
|
69
|
-
MarketplaceErrorCode.GIT_ERROR,
|
|
70
|
-
void 0,
|
|
71
|
-
error
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
48
|
function loadManifestFromDirectory(dir) {
|
|
76
|
-
const
|
|
77
|
-
|
|
49
|
+
const mintoPath = join(dir, ".minto-plugin", "marketplace.json");
|
|
50
|
+
const claudePath = join(dir, ".claude-plugin", "marketplace.json");
|
|
51
|
+
const manifestPath = existsSync(mintoPath) ? mintoPath : existsSync(claudePath) ? claudePath : null;
|
|
52
|
+
if (!manifestPath) {
|
|
78
53
|
throw new MarketplaceError(
|
|
79
|
-
`Marketplace manifest not found
|
|
54
|
+
`Marketplace manifest not found (checked .minto-plugin/ and .claude-plugin/ in ${dir})`,
|
|
80
55
|
MarketplaceErrorCode.MANIFEST_NOT_FOUND
|
|
81
56
|
);
|
|
82
57
|
}
|
|
@@ -94,10 +69,18 @@ function loadManifestFromDirectory(dir) {
|
|
|
94
69
|
}
|
|
95
70
|
}
|
|
96
71
|
async function fetchGitHubMarketplace(repo, ref) {
|
|
97
|
-
const
|
|
98
|
-
|
|
72
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
73
|
+
mkdirSync(tempDir, { recursive: true });
|
|
99
74
|
try {
|
|
75
|
+
await fetchRepo({ type: "github", repo, ref }, tempDir);
|
|
100
76
|
return loadManifestFromDirectory(tempDir);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
throw new MarketplaceError(
|
|
79
|
+
`Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,
|
|
80
|
+
MarketplaceErrorCode.GIT_ERROR,
|
|
81
|
+
void 0,
|
|
82
|
+
error
|
|
83
|
+
);
|
|
101
84
|
} finally {
|
|
102
85
|
try {
|
|
103
86
|
rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -106,9 +89,18 @@ async function fetchGitHubMarketplace(repo, ref) {
|
|
|
106
89
|
}
|
|
107
90
|
}
|
|
108
91
|
async function fetchUrlMarketplace(url, ref) {
|
|
109
|
-
const tempDir =
|
|
92
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
93
|
+
mkdirSync(tempDir, { recursive: true });
|
|
110
94
|
try {
|
|
95
|
+
await fetchRepo({ type: "url", url, ref }, tempDir);
|
|
111
96
|
return loadManifestFromDirectory(tempDir);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
throw new MarketplaceError(
|
|
99
|
+
`Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,
|
|
100
|
+
MarketplaceErrorCode.GIT_ERROR,
|
|
101
|
+
void 0,
|
|
102
|
+
error
|
|
103
|
+
);
|
|
112
104
|
} finally {
|
|
113
105
|
try {
|
|
114
106
|
rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -120,6 +112,24 @@ function loadLocalMarketplace(path) {
|
|
|
120
112
|
const resolvedPath = path.startsWith("/") ? path : join(getCwd(), path);
|
|
121
113
|
return loadManifestFromDirectory(resolvedPath);
|
|
122
114
|
}
|
|
115
|
+
function isMarketplaceRegistered(name) {
|
|
116
|
+
return loadRegistry().some((m) => m.name === name);
|
|
117
|
+
}
|
|
118
|
+
function registerMarketplaceFromDirectory(name, source, localDir) {
|
|
119
|
+
const registry = loadRegistry();
|
|
120
|
+
if (registry.some((m) => m.name === name)) return null;
|
|
121
|
+
const manifest = loadManifestFromDirectory(localDir);
|
|
122
|
+
const registered = {
|
|
123
|
+
name: manifest.name,
|
|
124
|
+
source,
|
|
125
|
+
manifest,
|
|
126
|
+
lastUpdated: /* @__PURE__ */ new Date(),
|
|
127
|
+
enabled: true
|
|
128
|
+
};
|
|
129
|
+
registry.push(registered);
|
|
130
|
+
saveRegistry(registry);
|
|
131
|
+
return registered;
|
|
132
|
+
}
|
|
123
133
|
function parseMarketplaceSource(input) {
|
|
124
134
|
if (/^[\w-]+\/[\w-]+$/.test(input)) {
|
|
125
135
|
return { type: "github", repo: input };
|
|
@@ -243,7 +253,9 @@ function loadMarketplaceSettings() {
|
|
|
243
253
|
const home = homedir();
|
|
244
254
|
const settingsPaths = [
|
|
245
255
|
{ path: join(cwd, ".minto", "settings.json"), label: "project" },
|
|
246
|
-
{ path: join(
|
|
256
|
+
{ path: join(cwd, ".claude", "settings.json"), label: "project/.claude" },
|
|
257
|
+
{ path: join(home, ".minto", "settings.json"), label: "user" },
|
|
258
|
+
{ path: join(home, ".claude", "settings.json"), label: "user/.claude" }
|
|
247
259
|
];
|
|
248
260
|
for (const { path, label } of settingsPaths) {
|
|
249
261
|
if (existsSync(path)) {
|
|
@@ -312,14 +324,28 @@ async function autoRegisterMarketplaces() {
|
|
|
312
324
|
async function getMarketplaceRepoPath(marketplace) {
|
|
313
325
|
switch (marketplace.source.type) {
|
|
314
326
|
case "github": {
|
|
315
|
-
const
|
|
316
|
-
|
|
327
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
328
|
+
mkdirSync(tempDir, { recursive: true });
|
|
329
|
+
await fetchRepo(
|
|
330
|
+
{
|
|
331
|
+
type: "github",
|
|
332
|
+
repo: marketplace.source.repo,
|
|
333
|
+
ref: marketplace.source.ref
|
|
334
|
+
},
|
|
335
|
+
tempDir
|
|
336
|
+
);
|
|
317
337
|
return { path: tempDir, cleanup: true };
|
|
318
338
|
}
|
|
319
339
|
case "url": {
|
|
320
|
-
const tempDir =
|
|
321
|
-
|
|
322
|
-
|
|
340
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
341
|
+
mkdirSync(tempDir, { recursive: true });
|
|
342
|
+
await fetchRepo(
|
|
343
|
+
{
|
|
344
|
+
type: "url",
|
|
345
|
+
url: marketplace.source.url,
|
|
346
|
+
ref: marketplace.source.ref
|
|
347
|
+
},
|
|
348
|
+
tempDir
|
|
323
349
|
);
|
|
324
350
|
return { path: tempDir, cleanup: true };
|
|
325
351
|
}
|
|
@@ -426,16 +452,25 @@ async function installPluginFromMarketplace(pluginName, marketplaceName, targetD
|
|
|
426
452
|
}
|
|
427
453
|
copyDirectory(pluginSourcePath, installDir);
|
|
428
454
|
} else if (plugin.source.source === "github") {
|
|
429
|
-
const
|
|
430
|
-
|
|
455
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
456
|
+
mkdirSync(tempDir, { recursive: true });
|
|
431
457
|
try {
|
|
458
|
+
await fetchRepo(
|
|
459
|
+
{ type: "github", repo: plugin.source.repo, ref: plugin.source.ref },
|
|
460
|
+
tempDir
|
|
461
|
+
);
|
|
432
462
|
copyDirectory(tempDir, installDir);
|
|
433
463
|
} finally {
|
|
434
464
|
rmSync(tempDir, { recursive: true, force: true });
|
|
435
465
|
}
|
|
436
466
|
} else if (plugin.source.source === "url") {
|
|
437
|
-
const tempDir =
|
|
467
|
+
const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
|
|
468
|
+
mkdirSync(tempDir, { recursive: true });
|
|
438
469
|
try {
|
|
470
|
+
await fetchRepo(
|
|
471
|
+
{ type: "url", url: plugin.source.url, ref: plugin.source.ref },
|
|
472
|
+
tempDir
|
|
473
|
+
);
|
|
439
474
|
copyDirectory(tempDir, installDir);
|
|
440
475
|
} finally {
|
|
441
476
|
rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -499,9 +534,11 @@ export {
|
|
|
499
534
|
findPlugin,
|
|
500
535
|
getMarketplace,
|
|
501
536
|
installPluginFromMarketplace,
|
|
537
|
+
isMarketplaceRegistered,
|
|
502
538
|
listMarketplaces,
|
|
503
539
|
loadMarketplaceSettings,
|
|
504
540
|
parseMarketplaceSource,
|
|
541
|
+
registerMarketplaceFromDirectory,
|
|
505
542
|
removeMarketplace,
|
|
506
543
|
updateMarketplace
|
|
507
544
|
};
|