@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/services/plugins/lspServers.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * LSP Servers Service\n *\n * Handles loading and managing LSP (Language Server Protocol) server\n * configurations from plugins. This is a Claude Code CLI specific feature.\n *\n * LSP servers provide code intelligence features like:\n * - Go to definition\n * - Find references\n * - Hover information\n * - Code completion\n * - Diagnostics\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { z } from 'zod'\nimport { getAllPluginLspConfigFiles } from '@utils/session/sessionPlugins'\nimport { getCwd } from '@utils/state'\n\n/**\n * LSP server transport type\n */\nexport type LspTransport = 'stdio' | 'socket' | 'pipe'\n\n/**\n * LSP server configuration schema\n */\nexport const LspServerConfigSchema = z.object({\n // Required\n command: z.string().min(1),\n\n // Optional command args\n args: z.array(z.string()).optional().default([]),\n\n // Transport configuration\n transport: z.enum(['stdio', 'socket', 'pipe']).optional().default('stdio'),\n\n // Environment variables\n env: z.record(z.string()).optional().default({}),\n\n // File patterns this server handles\n filePatterns: z.array(z.string()).optional().default([]),\n\n // Language ID mapping (extension -> languageId)\n extensionToLanguage: z.record(z.string()).optional().default({}),\n\n // Server initialization options\n initializationOptions: z.unknown().optional(),\n\n // Server settings\n settings: z.unknown().optional(),\n\n // Workspace folder (defaults to cwd)\n workspaceFolder: z.string().optional(),\n\n // Root path for relative file resolution\n rootPath: z.string().optional(),\n\n // Timeouts\n startupTimeout: z.number().optional().default(30000), // 30s default\n shutdownTimeout: z.number().optional().default(5000), // 5s default\n\n // Restart behavior\n restartOnCrash: z.boolean().optional().default(true),\n maxRestarts: z.number().optional().default(3),\n\n // Logging\n loggingConfig: z\n .object({\n level: z\n .enum(['off', 'error', 'warn', 'info', 'debug', 'trace'])\n .optional(),\n logFile: z.string().optional(),\n })\n .optional(),\n})\n\nexport type LspServerConfig = z.infer<typeof LspServerConfigSchema>\n\n/**\n * LSP configuration file schema (.lsp.json)\n */\nexport const LspConfigSchema = z.record(z.string(), LspServerConfigSchema)\n\nexport type LspConfig = z.infer<typeof LspConfigSchema>\n\n/**\n * Loaded LSP server (runtime representation)\n */\nexport interface LoadedLspServer {\n /** Language ID this server handles */\n languageId: string\n\n /** Server configuration */\n config: LspServerConfig\n\n /** Resolved command (with plugin root expanded) */\n resolvedCommand: string\n\n /** Resolved args (with plugin root expanded) */\n resolvedArgs: string[]\n\n /** Source plugin name */\n pluginName?: string\n\n /** Source file path */\n filePath: string\n\n /** Plugin root directory */\n pluginRoot?: string\n}\n\n/**\n * LSP server state\n */\nexport interface LspServerState {\n /** Language ID */\n languageId: string\n\n /** Whether server is running */\n running: boolean\n\n /** Number of restarts */\n restartCount: number\n\n /** Last error message */\n lastError?: string\n\n /** Process ID if running */\n pid?: number\n}\n\n/**\n * Cache for loaded LSP servers\n */\nlet lspServersCache: Map<string, LoadedLspServer> | null = null\n\n/**\n * Resolve plugin path variables in a string\n */\nexport function resolvePluginPath(value: string, pluginRoot: string): string {\n if (!value) return value\n\n // Replace ${CLAUDE_PLUGIN_ROOT} variable\n let resolved = value.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginRoot)\n\n // Also support $CLAUDE_PLUGIN_ROOT without braces\n resolved = resolved.replace(/\\$CLAUDE_PLUGIN_ROOT/g, pluginRoot)\n\n // Replace ${MINTO_PLUGIN_ROOT} for Minto-specific plugins\n resolved = resolved.replace(/\\$\\{MINTO_PLUGIN_ROOT\\}/g, pluginRoot)\n resolved = resolved.replace(/\\$MINTO_PLUGIN_ROOT/g, pluginRoot)\n\n // Resolve relative paths\n if (!isAbsolute(resolved) && !resolved.startsWith('$')) {\n resolved = resolve(pluginRoot, resolved)\n }\n\n return resolved\n}\n\n/**\n * Resolve plugin path variables in an array\n */\nexport function resolvePluginPaths(\n values: string[],\n pluginRoot: string,\n): string[] {\n return values.map(v => resolvePluginPath(v, pluginRoot))\n}\n\n/**\n * Resolve plugin path variables in environment object\n */\nexport function resolvePluginEnv(\n env: Record<string, string>,\n pluginRoot: string,\n): Record<string, string> {\n const resolved: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(env)) {\n resolved[key] = resolvePluginPath(value, pluginRoot)\n }\n\n return resolved\n}\n\n/**\n * Parse and validate LSP config file\n */\nfunction parseLspConfigFile(\n filePath: string,\n pluginRoot?: string,\n): Map<string, LoadedLspServer> {\n const servers = new Map<string, LoadedLspServer>()\n\n if (!existsSync(filePath)) {\n return servers\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const data = JSON.parse(content)\n\n const result = LspConfigSchema.safeParse(data)\n\n if (!result.success) {\n console.warn(`Invalid LSP config in ${filePath}: ${result.error.message}`)\n return servers\n }\n\n const root = pluginRoot || join(filePath, '..')\n\n for (const [languageId, config] of Object.entries(result.data)) {\n const loadedServer: LoadedLspServer = {\n languageId,\n config,\n resolvedCommand: resolvePluginPath(config.command, root),\n resolvedArgs: resolvePluginPaths(config.args || [], root),\n filePath,\n pluginRoot: root,\n }\n\n servers.set(languageId, loadedServer)\n }\n } catch (error) {\n console.warn(\n `Failed to parse LSP config ${filePath}:`,\n error instanceof Error ? error.message : String(error),\n )\n }\n\n return servers\n}\n\n/**\n * Load all LSP servers from plugins\n */\nexport function loadAllLspServers(): LoadedLspServer[] {\n // Return cached servers if available\n if (lspServersCache !== null) {\n return Array.from(lspServersCache.values())\n }\n\n const servers = new Map<string, LoadedLspServer>()\n const configFiles = getAllPluginLspConfigFiles()\n\n for (const filePath of configFiles) {\n // Extract plugin root from config file path\n // Assuming structure: pluginRoot/.minto-plugin/lsp.json or pluginRoot/lsp.json\n const pluginRoot = filePath.includes('.minto-plugin')\n ? join(filePath, '..', '..')\n : join(filePath, '..')\n\n const fileServers = parseLspConfigFile(filePath, pluginRoot)\n\n // Merge servers, later configs override earlier ones\n for (const [languageId, server] of fileServers) {\n servers.set(languageId, server)\n }\n }\n\n // Cache the results\n lspServersCache = servers\n\n return Array.from(servers.values())\n}\n\n/**\n * Get LSP server for a specific language\n */\nexport function getLspServer(languageId: string): LoadedLspServer | undefined {\n // Ensure cache is populated\n if (lspServersCache === null) {\n loadAllLspServers()\n }\n\n return lspServersCache?.get(languageId)\n}\n\n/**\n * Get LSP server for a file based on extension\n */\nexport function getLspServerForFile(\n filePath: string,\n): LoadedLspServer | undefined {\n const servers = loadAllLspServers()\n\n // Extract extension\n const ext = filePath.includes('.') ? filePath.split('.').pop() : ''\n if (!ext) return undefined\n\n // Find server that handles this extension\n for (const server of servers) {\n // Check extensionToLanguage mapping\n if (server.config.extensionToLanguage?.[ext]) {\n return server\n }\n\n // Check filePatterns\n if (\n server.config.filePatterns?.some(pattern => {\n if (pattern.startsWith('*.')) {\n return ext === pattern.slice(2)\n }\n // Simple glob matching for **/*.ext patterns\n if (pattern.includes('**')) {\n const extPattern = pattern.split('**/*.').pop()\n return ext === extPattern\n }\n return false\n })\n ) {\n return server\n }\n }\n\n return undefined\n}\n\n/**\n * Get all supported language IDs\n */\nexport function getSupportedLanguages(): string[] {\n const servers = loadAllLspServers()\n return servers.map(s => s.languageId)\n}\n\n/**\n * Check if LSP is available for a language\n */\nexport function hasLspSupport(languageId: string): boolean {\n return getLspServer(languageId) !== undefined\n}\n\n/**\n * Clear the LSP servers cache\n */\nexport function clearLspServersCache(): void {\n lspServersCache = null\n}\n\n/**\n * Get count of loaded LSP servers\n */\nexport function getLspServerCount(): number {\n return loadAllLspServers().length\n}\n\n/**\n * Validate LSP server configuration\n */\nexport function validateLspConfig(config: unknown): {\n success: boolean\n data?: LspConfig\n error?: string\n} {\n const result = LspConfigSchema.safeParse(config)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n return { success: false, error: result.error.message }\n}\n\n/**\n * Create LSP initialization options with resolved paths\n */\nexport function createLspInitOptions(server: LoadedLspServer): {\n command: string\n args: string[]\n env: Record<string, string>\n workspaceFolder: string\n initializationOptions: unknown\n} {\n const root = server.pluginRoot || getCwd()\n\n return {\n command: server.resolvedCommand,\n args: server.resolvedArgs,\n env: resolvePluginEnv(server.config.env || {}, root),\n workspaceFolder: server.config.workspaceFolder\n ? resolvePluginPath(server.config.workspaceFolder, root)\n : getCwd(),\n initializationOptions: server.config.initializationOptions,\n }\n}\n"],
|
|
5
|
-
"mappings": "AAcA,SAAS,YAAY,oBAAoB;AACzC,SAAS,MAAM,SAAS,kBAAkB;AAC1C,SAAS,SAAS;AAClB,SAAS,kCAAkC;AAC3C,SAAS,cAAc;AAUhB,MAAM,wBAAwB,EAAE,OAAO;AAAA;AAAA,EAE5C,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAGzB,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAG/C,WAAW,EAAE,KAAK,CAAC,SAAS,UAAU,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,OAAO;AAAA;AAAA,EAGzE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAG/C,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGvD,qBAAqB,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAG/D,uBAAuB,EAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAG5C,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAG/B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAGrC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAG9B,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,GAAK;AAAA;AAAA,EACnD,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,GAAI;AAAA;AAAA;AAAA,EAGnD,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EACnD,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;AAAA;AAAA,EAG5C,eAAe,EACZ,OAAO;AAAA,IACN,OAAO,EACJ,KAAK,CAAC,OAAO,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC,EACvD,SAAS;AAAA,IACZ,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,CAAC,EACA,SAAS;AACd,CAAC;AAOM,MAAM,kBAAkB,EAAE,OAAO,EAAE,OAAO,GAAG,qBAAqB;AAqDzE,IAAI,kBAAuD;AAKpD,SAAS,kBAAkB,OAAe,YAA4B;AAC3E,MAAI,CAAC,MAAO,QAAO;AAGnB,MAAI,WAAW,MAAM,QAAQ,6BAA6B,UAAU;AAGpE,aAAW,SAAS,QAAQ,yBAAyB,UAAU;AAG/D,aAAW,SAAS,QAAQ,4BAA4B,UAAU;AAClE,aAAW,SAAS,QAAQ,wBAAwB,UAAU;AAG9D,MAAI,CAAC,WAAW,QAAQ,KAAK,CAAC,SAAS,WAAW,GAAG,GAAG;AACtD,eAAW,QAAQ,YAAY,QAAQ;AAAA,EACzC;AAEA,SAAO;AACT;AAKO,SAAS,mBACd,QACA,YACU;AACV,SAAO,OAAO,IAAI,OAAK,kBAAkB,GAAG,UAAU,CAAC;AACzD;AAKO,SAAS,iBACd,KACA,YACwB;AACxB,QAAM,WAAmC,CAAC;AAE1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,aAAS,GAAG,IAAI,kBAAkB,OAAO,UAAU;AAAA,EACrD;AAEA,SAAO;AACT;AAKA,SAAS,mBACP,UACA,YAC8B;AAC9B,QAAM,UAAU,oBAAI,IAA6B;AAEjD,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,UAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,UAAM,SAAS,gBAAgB,UAAU,IAAI;AAE7C,QAAI,CAAC,OAAO,SAAS;AACnB,cAAQ,KAAK,yBAAyB,QAAQ,KAAK,OAAO,MAAM,OAAO,EAAE;AACzE,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,cAAc,KAAK,UAAU,IAAI;AAE9C,eAAW,CAAC,YAAY,MAAM,KAAK,OAAO,QAAQ,OAAO,IAAI,GAAG;AAC9D,YAAM,eAAgC;AAAA,QACpC;AAAA,QACA;AAAA,QACA,iBAAiB,kBAAkB,OAAO,SAAS,IAAI;AAAA,QACvD,cAAc,mBAAmB,OAAO,QAAQ,CAAC,GAAG,IAAI;AAAA,QACxD;AAAA,QACA,YAAY;AAAA,MACd;AAEA,cAAQ,IAAI,YAAY,YAAY;AAAA,IACtC;AAAA,EACF,SAAS,OAAO;AACd,YAAQ;AAAA,MACN,8BAA8B,QAAQ;AAAA,MACtC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IACvD;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,oBAAuC;AAErD,MAAI,oBAAoB,MAAM;AAC5B,WAAO,MAAM,KAAK,gBAAgB,OAAO,CAAC;AAAA,EAC5C;AAEA,QAAM,UAAU,oBAAI,IAA6B;AACjD,QAAM,cAAc,2BAA2B;AAE/C,aAAW,YAAY,aAAa;AAGlC,UAAM,
|
|
4
|
+
"sourcesContent": ["/**\n * LSP Servers Service\n *\n * Handles loading and managing LSP (Language Server Protocol) server\n * configurations from plugins. This is a Claude Code CLI specific feature.\n *\n * LSP servers provide code intelligence features like:\n * - Go to definition\n * - Find references\n * - Hover information\n * - Code completion\n * - Diagnostics\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { z } from 'zod'\nimport { getAllPluginLspConfigFiles } from '@utils/session/sessionPlugins'\nimport { getCwd } from '@utils/state'\n\n/**\n * LSP server transport type\n */\nexport type LspTransport = 'stdio' | 'socket' | 'pipe'\n\n/**\n * LSP server configuration schema\n */\nexport const LspServerConfigSchema = z.object({\n // Required\n command: z.string().min(1),\n\n // Optional command args\n args: z.array(z.string()).optional().default([]),\n\n // Transport configuration\n transport: z.enum(['stdio', 'socket', 'pipe']).optional().default('stdio'),\n\n // Environment variables\n env: z.record(z.string()).optional().default({}),\n\n // File patterns this server handles\n filePatterns: z.array(z.string()).optional().default([]),\n\n // Language ID mapping (extension -> languageId)\n extensionToLanguage: z.record(z.string()).optional().default({}),\n\n // Server initialization options\n initializationOptions: z.unknown().optional(),\n\n // Server settings\n settings: z.unknown().optional(),\n\n // Workspace folder (defaults to cwd)\n workspaceFolder: z.string().optional(),\n\n // Root path for relative file resolution\n rootPath: z.string().optional(),\n\n // Timeouts\n startupTimeout: z.number().optional().default(30000), // 30s default\n shutdownTimeout: z.number().optional().default(5000), // 5s default\n\n // Restart behavior\n restartOnCrash: z.boolean().optional().default(true),\n maxRestarts: z.number().optional().default(3),\n\n // Logging\n loggingConfig: z\n .object({\n level: z\n .enum(['off', 'error', 'warn', 'info', 'debug', 'trace'])\n .optional(),\n logFile: z.string().optional(),\n })\n .optional(),\n})\n\nexport type LspServerConfig = z.infer<typeof LspServerConfigSchema>\n\n/**\n * LSP configuration file schema (.lsp.json)\n */\nexport const LspConfigSchema = z.record(z.string(), LspServerConfigSchema)\n\nexport type LspConfig = z.infer<typeof LspConfigSchema>\n\n/**\n * Loaded LSP server (runtime representation)\n */\nexport interface LoadedLspServer {\n /** Language ID this server handles */\n languageId: string\n\n /** Server configuration */\n config: LspServerConfig\n\n /** Resolved command (with plugin root expanded) */\n resolvedCommand: string\n\n /** Resolved args (with plugin root expanded) */\n resolvedArgs: string[]\n\n /** Source plugin name */\n pluginName?: string\n\n /** Source file path */\n filePath: string\n\n /** Plugin root directory */\n pluginRoot?: string\n}\n\n/**\n * LSP server state\n */\nexport interface LspServerState {\n /** Language ID */\n languageId: string\n\n /** Whether server is running */\n running: boolean\n\n /** Number of restarts */\n restartCount: number\n\n /** Last error message */\n lastError?: string\n\n /** Process ID if running */\n pid?: number\n}\n\n/**\n * Cache for loaded LSP servers\n */\nlet lspServersCache: Map<string, LoadedLspServer> | null = null\n\n/**\n * Resolve plugin path variables in a string\n */\nexport function resolvePluginPath(value: string, pluginRoot: string): string {\n if (!value) return value\n\n // Replace ${CLAUDE_PLUGIN_ROOT} variable\n let resolved = value.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginRoot)\n\n // Also support $CLAUDE_PLUGIN_ROOT without braces\n resolved = resolved.replace(/\\$CLAUDE_PLUGIN_ROOT/g, pluginRoot)\n\n // Replace ${MINTO_PLUGIN_ROOT} for Minto-specific plugins\n resolved = resolved.replace(/\\$\\{MINTO_PLUGIN_ROOT\\}/g, pluginRoot)\n resolved = resolved.replace(/\\$MINTO_PLUGIN_ROOT/g, pluginRoot)\n\n // Resolve relative paths\n if (!isAbsolute(resolved) && !resolved.startsWith('$')) {\n resolved = resolve(pluginRoot, resolved)\n }\n\n return resolved\n}\n\n/**\n * Resolve plugin path variables in an array\n */\nexport function resolvePluginPaths(\n values: string[],\n pluginRoot: string,\n): string[] {\n return values.map(v => resolvePluginPath(v, pluginRoot))\n}\n\n/**\n * Resolve plugin path variables in environment object\n */\nexport function resolvePluginEnv(\n env: Record<string, string>,\n pluginRoot: string,\n): Record<string, string> {\n const resolved: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(env)) {\n resolved[key] = resolvePluginPath(value, pluginRoot)\n }\n\n return resolved\n}\n\n/**\n * Parse and validate LSP config file\n */\nfunction parseLspConfigFile(\n filePath: string,\n pluginRoot?: string,\n): Map<string, LoadedLspServer> {\n const servers = new Map<string, LoadedLspServer>()\n\n if (!existsSync(filePath)) {\n return servers\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const data = JSON.parse(content)\n\n const result = LspConfigSchema.safeParse(data)\n\n if (!result.success) {\n console.warn(`Invalid LSP config in ${filePath}: ${result.error.message}`)\n return servers\n }\n\n const root = pluginRoot || join(filePath, '..')\n\n for (const [languageId, config] of Object.entries(result.data)) {\n const loadedServer: LoadedLspServer = {\n languageId,\n config,\n resolvedCommand: resolvePluginPath(config.command, root),\n resolvedArgs: resolvePluginPaths(config.args || [], root),\n filePath,\n pluginRoot: root,\n }\n\n servers.set(languageId, loadedServer)\n }\n } catch (error) {\n console.warn(\n `Failed to parse LSP config ${filePath}:`,\n error instanceof Error ? error.message : String(error),\n )\n }\n\n return servers\n}\n\n/**\n * Load all LSP servers from plugins\n */\nexport function loadAllLspServers(): LoadedLspServer[] {\n // Return cached servers if available\n if (lspServersCache !== null) {\n return Array.from(lspServersCache.values())\n }\n\n const servers = new Map<string, LoadedLspServer>()\n const configFiles = getAllPluginLspConfigFiles()\n\n for (const filePath of configFiles) {\n // Extract plugin root from config file path\n // Assuming structure: pluginRoot/.minto-plugin/lsp.json, pluginRoot/.claude-plugin/lsp.json, or pluginRoot/lsp.json\n const pluginRoot =\n filePath.includes('.minto-plugin') || filePath.includes('.claude-plugin')\n ? join(filePath, '..', '..')\n : join(filePath, '..')\n\n const fileServers = parseLspConfigFile(filePath, pluginRoot)\n\n // Merge servers, later configs override earlier ones\n for (const [languageId, server] of fileServers) {\n servers.set(languageId, server)\n }\n }\n\n // Cache the results\n lspServersCache = servers\n\n return Array.from(servers.values())\n}\n\n/**\n * Get LSP server for a specific language\n */\nexport function getLspServer(languageId: string): LoadedLspServer | undefined {\n // Ensure cache is populated\n if (lspServersCache === null) {\n loadAllLspServers()\n }\n\n return lspServersCache?.get(languageId)\n}\n\n/**\n * Get LSP server for a file based on extension\n */\nexport function getLspServerForFile(\n filePath: string,\n): LoadedLspServer | undefined {\n const servers = loadAllLspServers()\n\n // Extract extension\n const ext = filePath.includes('.') ? filePath.split('.').pop() : ''\n if (!ext) return undefined\n\n // Find server that handles this extension\n for (const server of servers) {\n // Check extensionToLanguage mapping\n if (server.config.extensionToLanguage?.[ext]) {\n return server\n }\n\n // Check filePatterns\n if (\n server.config.filePatterns?.some(pattern => {\n if (pattern.startsWith('*.')) {\n return ext === pattern.slice(2)\n }\n // Simple glob matching for **/*.ext patterns\n if (pattern.includes('**')) {\n const extPattern = pattern.split('**/*.').pop()\n return ext === extPattern\n }\n return false\n })\n ) {\n return server\n }\n }\n\n return undefined\n}\n\n/**\n * Get all supported language IDs\n */\nexport function getSupportedLanguages(): string[] {\n const servers = loadAllLspServers()\n return servers.map(s => s.languageId)\n}\n\n/**\n * Check if LSP is available for a language\n */\nexport function hasLspSupport(languageId: string): boolean {\n return getLspServer(languageId) !== undefined\n}\n\n/**\n * Clear the LSP servers cache\n */\nexport function clearLspServersCache(): void {\n lspServersCache = null\n}\n\n/**\n * Get count of loaded LSP servers\n */\nexport function getLspServerCount(): number {\n return loadAllLspServers().length\n}\n\n/**\n * Validate LSP server configuration\n */\nexport function validateLspConfig(config: unknown): {\n success: boolean\n data?: LspConfig\n error?: string\n} {\n const result = LspConfigSchema.safeParse(config)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n return { success: false, error: result.error.message }\n}\n\n/**\n * Create LSP initialization options with resolved paths\n */\nexport function createLspInitOptions(server: LoadedLspServer): {\n command: string\n args: string[]\n env: Record<string, string>\n workspaceFolder: string\n initializationOptions: unknown\n} {\n const root = server.pluginRoot || getCwd()\n\n return {\n command: server.resolvedCommand,\n args: server.resolvedArgs,\n env: resolvePluginEnv(server.config.env || {}, root),\n workspaceFolder: server.config.workspaceFolder\n ? resolvePluginPath(server.config.workspaceFolder, root)\n : getCwd(),\n initializationOptions: server.config.initializationOptions,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -97,8 +97,9 @@ function resolveManifestPaths(rootDir, value) {
|
|
|
97
97
|
}
|
|
98
98
|
function loadPluginFromDir(rootDir) {
|
|
99
99
|
const mintoManifestPath = join(rootDir, ".minto-plugin", "plugin.json");
|
|
100
|
+
const claudeManifestPath = join(rootDir, ".claude-plugin", "plugin.json");
|
|
100
101
|
const rootManifestPath = join(rootDir, "plugin.json");
|
|
101
|
-
const manifestPath = existsSync(mintoManifestPath) ? mintoManifestPath : existsSync(rootManifestPath) ? rootManifestPath : null;
|
|
102
|
+
const manifestPath = existsSync(mintoManifestPath) ? mintoManifestPath : existsSync(claudeManifestPath) ? claudeManifestPath : existsSync(rootManifestPath) ? rootManifestPath : null;
|
|
102
103
|
if (!manifestPath) {
|
|
103
104
|
throw new Error(
|
|
104
105
|
`Plugin manifest not found (expected .minto-plugin/plugin.json or plugin.json)`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/plugins/pluginRuntime.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Plugin Runtime\n *\n * Handles loading and managing plugins at runtime.\n * Compatible with Claude Code CLI plugin specification.\n */\n\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { homedir } from 'os'\nimport { join, resolve } from 'path'\nimport { z } from 'zod'\nimport { glob as globLib } from 'glob'\nimport { getCwd } from '@utils/state'\nimport {\n setSessionPlugins,\n getSessionPlugins,\n} from '@utils/session/sessionPlugins'\nimport type { SessionPlugin } from '@minto-types/plugin'\nimport { PluginManifestSchema } from './pluginValidation'\n\n/**\n * Expand ~ to home directory\n */\nfunction expandHome(input: string): string {\n const trimmed = input.trim()\n if (trimmed === '~') return homedir()\n if (trimmed.startsWith('~/') || trimmed.startsWith('~\\\\')) {\n return join(homedir(), trimmed.slice(2))\n }\n return trimmed\n}\n\n/**\n * Check if a string looks like a glob pattern\n */\nfunction isLikelyGlob(value: string): boolean {\n return /[*?[\\]]/.test(value)\n}\n\n/**\n * Expand plugin directory inputs (handles globs and ~ expansion)\n */\nasync function expandPluginDirInputs(\n pluginDirs: string[],\n baseDir: string,\n): Promise<string[]> {\n const out: string[] = []\n\n for (const raw of pluginDirs) {\n const trimmed = String(raw ?? '').trim()\n if (!trimmed) continue\n\n const expanded = expandHome(trimmed)\n const abs = resolve(baseDir, expanded)\n\n if (isLikelyGlob(trimmed) || isLikelyGlob(expanded)) {\n const patternsToTry =\n expanded !== trimmed ? [expanded, trimmed] : [trimmed]\n let matched = false\n\n for (const pattern of patternsToTry) {\n try {\n const matches = await globLib(pattern, {\n cwd: baseDir,\n absolute: true,\n nodir: false,\n nocase: process.platform === 'win32',\n })\n\n const dirs = matches.filter(match => {\n try {\n return existsSync(match) && statSync(match).isDirectory()\n } catch {\n return false\n }\n })\n\n if (dirs.length > 0) {\n out.push(...dirs)\n matched = true\n break\n }\n } catch {\n // Ignore glob errors\n }\n }\n\n if (matched) continue\n }\n\n out.push(abs)\n }\n\n // Remove duplicates\n const seen = new Set<string>()\n const unique: string[] = []\n for (const item of out) {\n if (seen.has(item)) continue\n seen.add(item)\n unique.push(item)\n }\n\n return unique\n}\n\n/**\n * List directory if it exists and is a directory\n */\nfunction listIfDir(path: string): string[] {\n try {\n if (!existsSync(path)) return []\n if (!statSync(path).isDirectory()) return []\n return [path]\n } catch {\n return []\n }\n}\n\n/**\n * Return file path if it exists and is a file\n */\nfunction fileIfExists(path: string): string[] {\n try {\n if (!existsSync(path)) return []\n if (!statSync(path).isFile()) return []\n return [path]\n } catch {\n return []\n }\n}\n\n/**\n * Resolve manifest paths (handles string or array values)\n */\nfunction resolveManifestPaths(\n rootDir: string,\n value: unknown,\n): { dirs: string[]; files: string[] } {\n const dirs: string[] = []\n const files: string[] = []\n const list = Array.isArray(value) ? value : value ? [value] : []\n\n for (const item of list) {\n if (typeof item !== 'string') continue\n const abs = resolve(rootDir, item)\n dirs.push(...listIfDir(abs))\n files.push(...fileIfExists(abs))\n }\n\n return { dirs, files }\n}\n\n/**\n * Load a plugin from a directory\n *\n * Uses .minto-plugin directory structure or root plugin.json.\n */\nfunction loadPluginFromDir(rootDir: string): SessionPlugin {\n // Check for manifest in order of preference\n const mintoManifestPath = join(rootDir, '.minto-plugin', 'plugin.json')\n const rootManifestPath = join(rootDir, 'plugin.json')\n\n const manifestPath = existsSync(mintoManifestPath)\n ? mintoManifestPath\n : existsSync(
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Plugin Runtime\n *\n * Handles loading and managing plugins at runtime.\n * Compatible with Claude Code CLI plugin specification.\n */\n\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { homedir } from 'os'\nimport { join, resolve } from 'path'\nimport { z } from 'zod'\nimport { glob as globLib } from 'glob'\nimport { getCwd } from '@utils/state'\nimport {\n setSessionPlugins,\n getSessionPlugins,\n} from '@utils/session/sessionPlugins'\nimport type { SessionPlugin } from '@minto-types/plugin'\nimport { PluginManifestSchema } from './pluginValidation'\n\n/**\n * Expand ~ to home directory\n */\nfunction expandHome(input: string): string {\n const trimmed = input.trim()\n if (trimmed === '~') return homedir()\n if (trimmed.startsWith('~/') || trimmed.startsWith('~\\\\')) {\n return join(homedir(), trimmed.slice(2))\n }\n return trimmed\n}\n\n/**\n * Check if a string looks like a glob pattern\n */\nfunction isLikelyGlob(value: string): boolean {\n return /[*?[\\]]/.test(value)\n}\n\n/**\n * Expand plugin directory inputs (handles globs and ~ expansion)\n */\nasync function expandPluginDirInputs(\n pluginDirs: string[],\n baseDir: string,\n): Promise<string[]> {\n const out: string[] = []\n\n for (const raw of pluginDirs) {\n const trimmed = String(raw ?? '').trim()\n if (!trimmed) continue\n\n const expanded = expandHome(trimmed)\n const abs = resolve(baseDir, expanded)\n\n if (isLikelyGlob(trimmed) || isLikelyGlob(expanded)) {\n const patternsToTry =\n expanded !== trimmed ? [expanded, trimmed] : [trimmed]\n let matched = false\n\n for (const pattern of patternsToTry) {\n try {\n const matches = await globLib(pattern, {\n cwd: baseDir,\n absolute: true,\n nodir: false,\n nocase: process.platform === 'win32',\n })\n\n const dirs = matches.filter(match => {\n try {\n return existsSync(match) && statSync(match).isDirectory()\n } catch {\n return false\n }\n })\n\n if (dirs.length > 0) {\n out.push(...dirs)\n matched = true\n break\n }\n } catch {\n // Ignore glob errors\n }\n }\n\n if (matched) continue\n }\n\n out.push(abs)\n }\n\n // Remove duplicates\n const seen = new Set<string>()\n const unique: string[] = []\n for (const item of out) {\n if (seen.has(item)) continue\n seen.add(item)\n unique.push(item)\n }\n\n return unique\n}\n\n/**\n * List directory if it exists and is a directory\n */\nfunction listIfDir(path: string): string[] {\n try {\n if (!existsSync(path)) return []\n if (!statSync(path).isDirectory()) return []\n return [path]\n } catch {\n return []\n }\n}\n\n/**\n * Return file path if it exists and is a file\n */\nfunction fileIfExists(path: string): string[] {\n try {\n if (!existsSync(path)) return []\n if (!statSync(path).isFile()) return []\n return [path]\n } catch {\n return []\n }\n}\n\n/**\n * Resolve manifest paths (handles string or array values)\n */\nfunction resolveManifestPaths(\n rootDir: string,\n value: unknown,\n): { dirs: string[]; files: string[] } {\n const dirs: string[] = []\n const files: string[] = []\n const list = Array.isArray(value) ? value : value ? [value] : []\n\n for (const item of list) {\n if (typeof item !== 'string') continue\n const abs = resolve(rootDir, item)\n dirs.push(...listIfDir(abs))\n files.push(...fileIfExists(abs))\n }\n\n return { dirs, files }\n}\n\n/**\n * Load a plugin from a directory\n *\n * Uses .minto-plugin directory structure or root plugin.json.\n */\nfunction loadPluginFromDir(rootDir: string): SessionPlugin {\n // Check for manifest in order of preference: .minto-plugin > .claude-plugin > root\n const mintoManifestPath = join(rootDir, '.minto-plugin', 'plugin.json')\n const claudeManifestPath = join(rootDir, '.claude-plugin', 'plugin.json')\n const rootManifestPath = join(rootDir, 'plugin.json')\n\n const manifestPath = existsSync(mintoManifestPath)\n ? mintoManifestPath\n : existsSync(claudeManifestPath)\n ? claudeManifestPath\n : existsSync(rootManifestPath)\n ? rootManifestPath\n : null\n\n if (!manifestPath) {\n throw new Error(\n `Plugin manifest not found (expected .minto-plugin/plugin.json or plugin.json)`,\n )\n }\n\n // Read manifest\n let manifestRaw: string\n try {\n manifestRaw = readFileSync(manifestPath, 'utf8')\n } catch (err) {\n throw new Error(`Failed to read ${manifestPath}: ${String(err)}`)\n }\n\n // Parse JSON\n let manifestJson: unknown\n try {\n manifestJson = JSON.parse(manifestRaw)\n } catch (err) {\n throw new Error(`Invalid JSON in ${manifestPath}: ${String(err)}`)\n }\n\n // Validate manifest\n const parsed = PluginManifestSchema.safeParse(manifestJson)\n if (!parsed.success) {\n throw new Error(\n `Invalid plugin manifest schema in ${manifestPath}: ${parsed.error.message}`,\n )\n }\n\n const name = parsed.data.name\n const manifestData = parsed.data as Record<string, unknown>\n\n // Resolve commands\n const manifestCommands = resolveManifestPaths(rootDir, manifestData.commands)\n const commandsDirs = [\n ...listIfDir(join(rootDir, 'commands')),\n ...manifestCommands.dirs,\n ...manifestCommands.files,\n ]\n\n // Resolve skills\n const skillsDirs = [\n ...listIfDir(join(rootDir, 'skills')),\n ...resolveManifestPaths(rootDir, manifestData.skills).dirs,\n ]\n\n // Resolve agents\n const manifestAgents = resolveManifestPaths(rootDir, manifestData.agents)\n const agentsDirs = [\n ...listIfDir(join(rootDir, 'agents')),\n ...manifestAgents.dirs,\n ...manifestAgents.files,\n ]\n\n // Resolve output styles\n const manifestOutputStyles = resolveManifestPaths(\n rootDir,\n manifestData.outputStyles,\n )\n const outputStylesDirs = [\n ...listIfDir(join(rootDir, 'output-styles')),\n ...manifestOutputStyles.dirs,\n ...manifestOutputStyles.files,\n ]\n\n // Resolve hooks\n const standardHook = fileIfExists(join(rootDir, 'hooks', 'hooks.json'))\n const hookFromManifest = resolveManifestPaths(\n rootDir,\n manifestData.hooks,\n ).files\n const hooksFiles = [...standardHook, ...hookFromManifest]\n\n // Resolve MCP config files\n const mcpConfigFiles = [\n ...fileIfExists(join(rootDir, '.mcp.json')),\n ...fileIfExists(join(rootDir, '.mcp.jsonc')),\n ...resolveManifestPaths(rootDir, manifestData.mcpServers).files,\n ]\n\n // Resolve LSP config files\n const lspConfigFiles = [\n ...fileIfExists(join(rootDir, '.lsp.json')),\n ...resolveManifestPaths(rootDir, manifestData.lspServers).files,\n ]\n\n return {\n name,\n rootDir,\n manifestPath,\n manifest: parsed.data,\n commandsDirs,\n skillsDirs,\n agentsDirs,\n hooksFiles,\n outputStylesDirs,\n mcpConfigFiles,\n lspConfigFiles,\n }\n}\n\n/**\n * Configure session plugins\n *\n * Loads plugins from the specified directories and sets them\n * as the current session plugins.\n */\nexport async function configureSessionPlugins(args: {\n pluginDirs: string[]\n baseDir?: string\n}): Promise<{ plugins: SessionPlugin[]; errors: string[] }> {\n const baseDir = args.baseDir ?? getCwd()\n const dirs = await expandPluginDirInputs(args.pluginDirs ?? [], baseDir)\n\n const plugins: SessionPlugin[] = []\n const errors: string[] = []\n\n for (const dir of dirs) {\n try {\n plugins.push(loadPluginFromDir(dir))\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err))\n }\n }\n\n // Set the plugins\n setSessionPlugins(plugins)\n\n // Reload dependent services\n try {\n // Reload custom commands\n const { reloadCustomCommands } = await import('@services/customCommands')\n reloadCustomCommands()\n\n // Clear command cache\n const { getCommands } = await import('@commands')\n ;(getCommands as any).cache?.clear?.()\n\n // Clear MCP tools cache\n const { getClients, getMCPTools } = await import('@services/mcpClient')\n ;(getClients as any).cache?.clear?.()\n ;(getMCPTools as any).cache?.clear?.()\n } catch {\n // Ignore errors during reload - services may not be available\n }\n\n return { plugins, errors }\n}\n\n/**\n * Load plugins from default locations\n *\n * Searches for plugins in:\n * 1. User plugins directory (~/.minto/plugins)\n * 2. Project plugins directory (.minto/plugins)\n */\nexport async function loadDefaultPlugins(): Promise<{\n plugins: SessionPlugin[]\n errors: string[]\n}> {\n const home = homedir()\n const cwd = getCwd()\n\n const pluginDirs = [\n // User-level plugins\n join(home, '.minto', 'plugins'),\n // Project-level plugins\n join(cwd, '.minto', 'plugins'),\n ].filter(dir => existsSync(dir))\n\n return configureSessionPlugins({ pluginDirs, baseDir: cwd })\n}\n\n/**\n * Get all currently loaded plugins\n */\nexport function getLoadedPlugins(): SessionPlugin[] {\n return getSessionPlugins()\n}\n\n/**\n * Check if any plugins are loaded\n */\nexport function hasLoadedPlugins(): boolean {\n return getSessionPlugins().length > 0\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -118,16 +118,18 @@ function validatePluginDirectory(rootDir) {
|
|
|
118
118
|
return { isValid: false, errors, warnings };
|
|
119
119
|
}
|
|
120
120
|
const mintoManifest = join(resolvedPath, ".minto-plugin", "plugin.json");
|
|
121
|
+
const claudeManifest = join(resolvedPath, ".claude-plugin", "plugin.json");
|
|
121
122
|
const rootManifest = join(resolvedPath, "plugin.json");
|
|
122
123
|
const hasMintoManifest = existsSync(mintoManifest);
|
|
124
|
+
const hasClaudeManifest = existsSync(claudeManifest);
|
|
123
125
|
const hasRootManifest = existsSync(rootManifest);
|
|
124
|
-
if (!hasMintoManifest && !hasRootManifest) {
|
|
126
|
+
if (!hasMintoManifest && !hasClaudeManifest && !hasRootManifest) {
|
|
125
127
|
errors.push(
|
|
126
128
|
"No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json"
|
|
127
129
|
);
|
|
128
130
|
return { isValid: false, errors, warnings };
|
|
129
131
|
}
|
|
130
|
-
const manifestPath = hasMintoManifest ? mintoManifest : rootManifest;
|
|
132
|
+
const manifestPath = hasMintoManifest ? mintoManifest : hasClaudeManifest ? claudeManifest : rootManifest;
|
|
131
133
|
try {
|
|
132
134
|
const content = readFileSync(manifestPath, "utf-8");
|
|
133
135
|
const data = JSON.parse(content);
|
|
@@ -193,7 +195,12 @@ function validateMarketplacePath(path) {
|
|
|
193
195
|
return { isValid: false, errors, warnings };
|
|
194
196
|
}
|
|
195
197
|
const mintoManifest = join(resolvedPath, ".minto-plugin", "marketplace.json");
|
|
196
|
-
|
|
198
|
+
const claudeManifest = join(
|
|
199
|
+
resolvedPath,
|
|
200
|
+
".claude-plugin",
|
|
201
|
+
"marketplace.json"
|
|
202
|
+
);
|
|
203
|
+
if (!existsSync(mintoManifest) && !existsSync(claudeManifest)) {
|
|
197
204
|
errors.push(
|
|
198
205
|
"No marketplace manifest found. Expected .minto-plugin/marketplace.json"
|
|
199
206
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/plugins/pluginValidation.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Plugin Validation\n *\n * Validates plugin manifests and configurations.\n * Compatible with Claude Code CLI plugin specification.\n */\n\nimport { z } from 'zod'\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { join, resolve } from 'path'\n\n/**\n * Author schema (can be string or object)\n */\nconst AuthorSchema = z.union([\n z.string(),\n z.object({\n name: z.string().optional(),\n email: z.string().email().optional(),\n url: z.string().url().optional(),\n }),\n])\n\n/**\n * Hooks configuration schema\n */\nconst HooksConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string().optional(),\n script: z.string().optional(),\n timeout: z.number().optional(),\n blocking: z.boolean().optional(),\n }),\n ),\n])\n\n/**\n * MCP Servers configuration schema\n */\nconst McpServersConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string()).optional(),\n type: z.enum(['stdio', 'http', 'sse']).optional(),\n url: z.string().optional(),\n headers: z.record(z.string()).optional(),\n timeout: z.number().optional(),\n }),\n ),\n])\n\n/**\n * LSP Servers configuration schema (Claude Code CLI specific)\n */\nconst LspServersConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string(),\n args: z.array(z.string()).optional(),\n rootPath: z.string().optional(),\n filePatterns: z.array(z.string()).optional(),\n }),\n ),\n])\n\n/**\n * Minimal plugin manifest schema for loading\n * More permissive than full schema to allow partial manifests\n */\nexport const PluginManifestSchema = z\n .object({\n name: z.string().min(1),\n })\n .passthrough()\n\nexport type PluginManifestBasic = z.infer<typeof PluginManifestSchema>\n\n/**\n * Full Claude Code CLI plugin manifest schema\n * Used for strict validation\n */\nexport const FullPluginManifestSchema = z.object({\n // Required field\n name: z\n .string()\n .min(1)\n .regex(\n /^[a-z0-9-]+$/,\n 'Plugin name must be lowercase alphanumeric with hyphens',\n ),\n\n // Metadata fields (Claude Code CLI specification)\n version: z\n .string()\n .regex(/^\\d+\\.\\d+\\.\\d+$/, 'Version must follow semver format (e.g., 1.0.0)')\n .optional(),\n description: z.string().optional(),\n author: AuthorSchema.optional(),\n homepage: z.string().url().optional(),\n repository: z.string().optional(), // Can be URL or \"owner/repo\"\n license: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n\n // Component path fields\n commands: z.union([z.string(), z.array(z.string())]).optional(),\n agents: z.union([z.string(), z.array(z.string())]).optional(),\n skills: z.union([z.string(), z.array(z.string())]).optional(),\n hooks: HooksConfigSchema.optional(),\n mcpServers: McpServersConfigSchema.optional(),\n outputStyles: z.union([z.string(), z.array(z.string())]).optional(),\n lspServers: LspServersConfigSchema.optional(), // Claude Code CLI specific\n\n // Engine requirements\n engines: z\n .object({\n minto: z.string().optional(),\n 'claude-code': z.string().optional(),\n node: z.string().optional(),\n })\n .optional(),\n\n // Plugin-specific configuration schema\n configSchema: z.record(z.any()).optional(),\n\n // Dependencies\n dependencies: z.record(z.string()).optional(),\n})\n\nexport type FullPluginManifest = z.infer<typeof FullPluginManifestSchema>\n\n/**\n * Validation result type\n */\nexport interface ValidationResult {\n isValid: boolean\n errors: string[]\n warnings: string[]\n}\n\n/**\n * Validate a plugin manifest (permissive)\n */\nexport function validatePluginManifest(\n manifest: unknown,\n):\n | { success: true; data: PluginManifestBasic }\n | { success: false; error: z.ZodError } {\n const result = PluginManifestSchema.safeParse(manifest)\n if (result.success) {\n return { success: true, data: result.data }\n }\n return { success: false, error: result.error }\n}\n\n/**\n * Validate a plugin manifest (strict - full Claude Code CLI specification)\n */\nexport function validatePluginManifestStrict(\n manifest: unknown,\n):\n | { success: true; data: FullPluginManifest }\n | { success: false; error: z.ZodError } {\n const result = FullPluginManifestSchema.safeParse(manifest)\n if (result.success) {\n return { success: true, data: result.data }\n }\n return { success: false, error: result.error }\n}\n\n/**\n * Validate a plugin directory structure\n */\nexport function validatePluginDirectory(rootDir: string): ValidationResult {\n const errors: string[] = []\n const warnings: string[] = []\n\n // Resolve path\n const resolvedPath = resolve(rootDir)\n\n // Check directory exists\n if (!existsSync(resolvedPath)) {\n errors.push(`Directory does not exist: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check it's a directory\n try {\n if (!statSync(resolvedPath).isDirectory()) {\n errors.push(`Path is not a directory: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n } catch {\n errors.push(`Cannot access path: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for manifest file\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'plugin.json')\n const rootManifest = join(resolvedPath, 'plugin.json')\n\n const hasMintoManifest = existsSync(mintoManifest)\n const hasRootManifest = existsSync(rootManifest)\n\n if (!hasMintoManifest && !hasRootManifest) {\n errors.push(\n 'No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json',\n )\n return { isValid: false, errors, warnings }\n }\n\n // Prefer .minto-plugin manifest if exists\n const manifestPath = hasMintoManifest ? mintoManifest : rootManifest\n\n // Validate manifest contents\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Permissive validation first\n const basicResult = validatePluginManifest(data)\n if (basicResult.success === false) {\n errors.push(`Invalid manifest: ${basicResult.error.message}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for recommended fields\n if (!data.version) {\n warnings.push('Manifest is missing recommended field: version')\n }\n if (!data.description) {\n warnings.push('Manifest is missing recommended field: description')\n }\n\n // Validate version format if present\n if (data.version && !/^\\d+\\.\\d+\\.\\d+$/.test(data.version)) {\n warnings.push(\n `Version \"${data.version}\" does not follow semver format (X.Y.Z)`,\n )\n }\n\n // Validate name format\n if (data.name && !/^[a-z0-9-]+$/.test(data.name)) {\n warnings.push(\n `Name \"${data.name}\" should be lowercase alphanumeric with hyphens`,\n )\n }\n\n // Check component paths exist\n const componentChecks = [\n { field: 'commands', paths: normalizeToArray(data.commands) },\n { field: 'agents', paths: normalizeToArray(data.agents) },\n { field: 'skills', paths: normalizeToArray(data.skills) },\n { field: 'outputStyles', paths: normalizeToArray(data.outputStyles) },\n ]\n\n for (const check of componentChecks) {\n for (const path of check.paths) {\n const fullPath = join(resolvedPath, path)\n if (!existsSync(fullPath)) {\n warnings.push(`${check.field} path does not exist: ${path}`)\n }\n }\n }\n } catch (error) {\n if (error instanceof SyntaxError) {\n errors.push(`Invalid JSON in manifest: ${error.message}`)\n } else {\n errors.push(\n `Error reading manifest: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n return { isValid: false, errors, warnings }\n }\n\n return { isValid: errors.length === 0, errors, warnings }\n}\n\n/**\n * Normalize string or array to array\n */\nfunction normalizeToArray(value: unknown): string[] {\n if (!value) return []\n if (typeof value === 'string') return [value]\n if (Array.isArray(value)) return value.filter(v => typeof v === 'string')\n return []\n}\n\n/**\n * Validate marketplace manifest path\n */\nexport function validateMarketplacePath(path: string): ValidationResult {\n const errors: string[] = []\n const warnings: string[] = []\n\n const resolvedPath = resolve(path)\n\n if (!existsSync(resolvedPath)) {\n errors.push(`Marketplace path does not exist: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for marketplace manifest\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'marketplace.json')\n\n if (!existsSync(mintoManifest)) {\n errors.push(\n 'No marketplace manifest found. Expected .minto-plugin/marketplace.json',\n )\n }\n\n return { isValid: errors.length === 0, errors, warnings }\n}\n\n/**\n * Check if a manifest is valid for loading (permissive)\n */\nexport function isValidManifest(data: unknown): boolean {\n return validatePluginManifest(data).success\n}\n\n/**\n * Check if a manifest is strictly valid\n */\nexport function isStrictlyValidManifest(data: unknown): boolean {\n return validatePluginManifestStrict(data).success\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Plugin Validation\n *\n * Validates plugin manifests and configurations.\n * Compatible with Claude Code CLI plugin specification.\n */\n\nimport { z } from 'zod'\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { join, resolve } from 'path'\n\n/**\n * Author schema (can be string or object)\n */\nconst AuthorSchema = z.union([\n z.string(),\n z.object({\n name: z.string().optional(),\n email: z.string().email().optional(),\n url: z.string().url().optional(),\n }),\n])\n\n/**\n * Hooks configuration schema\n */\nconst HooksConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string().optional(),\n script: z.string().optional(),\n timeout: z.number().optional(),\n blocking: z.boolean().optional(),\n }),\n ),\n])\n\n/**\n * MCP Servers configuration schema\n */\nconst McpServersConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string()).optional(),\n type: z.enum(['stdio', 'http', 'sse']).optional(),\n url: z.string().optional(),\n headers: z.record(z.string()).optional(),\n timeout: z.number().optional(),\n }),\n ),\n])\n\n/**\n * LSP Servers configuration schema (Claude Code CLI specific)\n */\nconst LspServersConfigSchema = z.union([\n z.string(),\n z.array(z.string()),\n z.record(\n z.object({\n command: z.string(),\n args: z.array(z.string()).optional(),\n rootPath: z.string().optional(),\n filePatterns: z.array(z.string()).optional(),\n }),\n ),\n])\n\n/**\n * Minimal plugin manifest schema for loading\n * More permissive than full schema to allow partial manifests\n */\nexport const PluginManifestSchema = z\n .object({\n name: z.string().min(1),\n })\n .passthrough()\n\nexport type PluginManifestBasic = z.infer<typeof PluginManifestSchema>\n\n/**\n * Full Claude Code CLI plugin manifest schema\n * Used for strict validation\n */\nexport const FullPluginManifestSchema = z.object({\n // Required field\n name: z\n .string()\n .min(1)\n .regex(\n /^[a-z0-9-]+$/,\n 'Plugin name must be lowercase alphanumeric with hyphens',\n ),\n\n // Metadata fields (Claude Code CLI specification)\n version: z\n .string()\n .regex(/^\\d+\\.\\d+\\.\\d+$/, 'Version must follow semver format (e.g., 1.0.0)')\n .optional(),\n description: z.string().optional(),\n author: AuthorSchema.optional(),\n homepage: z.string().url().optional(),\n repository: z.string().optional(), // Can be URL or \"owner/repo\"\n license: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n\n // Component path fields\n commands: z.union([z.string(), z.array(z.string())]).optional(),\n agents: z.union([z.string(), z.array(z.string())]).optional(),\n skills: z.union([z.string(), z.array(z.string())]).optional(),\n hooks: HooksConfigSchema.optional(),\n mcpServers: McpServersConfigSchema.optional(),\n outputStyles: z.union([z.string(), z.array(z.string())]).optional(),\n lspServers: LspServersConfigSchema.optional(), // Claude Code CLI specific\n\n // Engine requirements\n engines: z\n .object({\n minto: z.string().optional(),\n 'claude-code': z.string().optional(),\n node: z.string().optional(),\n })\n .optional(),\n\n // Plugin-specific configuration schema\n configSchema: z.record(z.any()).optional(),\n\n // Dependencies\n dependencies: z.record(z.string()).optional(),\n})\n\nexport type FullPluginManifest = z.infer<typeof FullPluginManifestSchema>\n\n/**\n * Validation result type\n */\nexport interface ValidationResult {\n isValid: boolean\n errors: string[]\n warnings: string[]\n}\n\n/**\n * Validate a plugin manifest (permissive)\n */\nexport function validatePluginManifest(\n manifest: unknown,\n):\n | { success: true; data: PluginManifestBasic }\n | { success: false; error: z.ZodError } {\n const result = PluginManifestSchema.safeParse(manifest)\n if (result.success) {\n return { success: true, data: result.data }\n }\n return { success: false, error: result.error }\n}\n\n/**\n * Validate a plugin manifest (strict - full Claude Code CLI specification)\n */\nexport function validatePluginManifestStrict(\n manifest: unknown,\n):\n | { success: true; data: FullPluginManifest }\n | { success: false; error: z.ZodError } {\n const result = FullPluginManifestSchema.safeParse(manifest)\n if (result.success) {\n return { success: true, data: result.data }\n }\n return { success: false, error: result.error }\n}\n\n/**\n * Validate a plugin directory structure\n */\nexport function validatePluginDirectory(rootDir: string): ValidationResult {\n const errors: string[] = []\n const warnings: string[] = []\n\n // Resolve path\n const resolvedPath = resolve(rootDir)\n\n // Check directory exists\n if (!existsSync(resolvedPath)) {\n errors.push(`Directory does not exist: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check it's a directory\n try {\n if (!statSync(resolvedPath).isDirectory()) {\n errors.push(`Path is not a directory: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n } catch {\n errors.push(`Cannot access path: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for manifest file (.minto-plugin, .claude-plugin, or root)\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'plugin.json')\n const claudeManifest = join(resolvedPath, '.claude-plugin', 'plugin.json')\n const rootManifest = join(resolvedPath, 'plugin.json')\n\n const hasMintoManifest = existsSync(mintoManifest)\n const hasClaudeManifest = existsSync(claudeManifest)\n const hasRootManifest = existsSync(rootManifest)\n\n if (!hasMintoManifest && !hasClaudeManifest && !hasRootManifest) {\n errors.push(\n 'No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json',\n )\n return { isValid: false, errors, warnings }\n }\n\n // Prefer .minto-plugin > .claude-plugin > root manifest\n const manifestPath = hasMintoManifest\n ? mintoManifest\n : hasClaudeManifest\n ? claudeManifest\n : rootManifest\n\n // Validate manifest contents\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Permissive validation first\n const basicResult = validatePluginManifest(data)\n if (basicResult.success === false) {\n errors.push(`Invalid manifest: ${basicResult.error.message}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for recommended fields\n if (!data.version) {\n warnings.push('Manifest is missing recommended field: version')\n }\n if (!data.description) {\n warnings.push('Manifest is missing recommended field: description')\n }\n\n // Validate version format if present\n if (data.version && !/^\\d+\\.\\d+\\.\\d+$/.test(data.version)) {\n warnings.push(\n `Version \"${data.version}\" does not follow semver format (X.Y.Z)`,\n )\n }\n\n // Validate name format\n if (data.name && !/^[a-z0-9-]+$/.test(data.name)) {\n warnings.push(\n `Name \"${data.name}\" should be lowercase alphanumeric with hyphens`,\n )\n }\n\n // Check component paths exist\n const componentChecks = [\n { field: 'commands', paths: normalizeToArray(data.commands) },\n { field: 'agents', paths: normalizeToArray(data.agents) },\n { field: 'skills', paths: normalizeToArray(data.skills) },\n { field: 'outputStyles', paths: normalizeToArray(data.outputStyles) },\n ]\n\n for (const check of componentChecks) {\n for (const path of check.paths) {\n const fullPath = join(resolvedPath, path)\n if (!existsSync(fullPath)) {\n warnings.push(`${check.field} path does not exist: ${path}`)\n }\n }\n }\n } catch (error) {\n if (error instanceof SyntaxError) {\n errors.push(`Invalid JSON in manifest: ${error.message}`)\n } else {\n errors.push(\n `Error reading manifest: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n return { isValid: false, errors, warnings }\n }\n\n return { isValid: errors.length === 0, errors, warnings }\n}\n\n/**\n * Normalize string or array to array\n */\nfunction normalizeToArray(value: unknown): string[] {\n if (!value) return []\n if (typeof value === 'string') return [value]\n if (Array.isArray(value)) return value.filter(v => typeof v === 'string')\n return []\n}\n\n/**\n * Validate marketplace manifest path\n */\nexport function validateMarketplacePath(path: string): ValidationResult {\n const errors: string[] = []\n const warnings: string[] = []\n\n const resolvedPath = resolve(path)\n\n if (!existsSync(resolvedPath)) {\n errors.push(`Marketplace path does not exist: ${resolvedPath}`)\n return { isValid: false, errors, warnings }\n }\n\n // Check for marketplace manifest (.minto-plugin or .claude-plugin)\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'marketplace.json')\n const claudeManifest = join(\n resolvedPath,\n '.claude-plugin',\n 'marketplace.json',\n )\n\n if (!existsSync(mintoManifest) && !existsSync(claudeManifest)) {\n errors.push(\n 'No marketplace manifest found. Expected .minto-plugin/marketplace.json',\n )\n }\n\n return { isValid: errors.length === 0, errors, warnings }\n}\n\n/**\n * Check if a manifest is valid for loading (permissive)\n */\nexport function isValidManifest(data: unknown): boolean {\n return validatePluginManifest(data).success\n}\n\n/**\n * Check if a manifest is strictly valid\n */\nexport function isStrictlyValidManifest(data: unknown): boolean {\n return validatePluginManifestStrict(data).success\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -132,7 +132,8 @@ async function fetchGitHubMarketplace(repo, ref, path) {
|
|
|
132
132
|
const url = `https://github.com/${repo}.git`;
|
|
133
133
|
const tempDir = await cloneGitRepo(url, ref);
|
|
134
134
|
try {
|
|
135
|
-
const
|
|
135
|
+
const baseDir = path ? join(tempDir, path) : tempDir;
|
|
136
|
+
const manifestPath = resolveManifestPath(baseDir, "marketplace.json");
|
|
136
137
|
return loadManifestFromPath(manifestPath);
|
|
137
138
|
} finally {
|
|
138
139
|
try {
|
|
@@ -144,7 +145,8 @@ async function fetchGitHubMarketplace(repo, ref, path) {
|
|
|
144
145
|
async function fetchGitMarketplace(url, ref, path) {
|
|
145
146
|
const tempDir = await cloneGitRepo(url, ref);
|
|
146
147
|
try {
|
|
147
|
-
const
|
|
148
|
+
const baseDir = path ? join(tempDir, path) : tempDir;
|
|
149
|
+
const manifestPath = resolveManifestPath(baseDir, "marketplace.json");
|
|
148
150
|
return loadManifestFromPath(manifestPath);
|
|
149
151
|
} finally {
|
|
150
152
|
try {
|
|
@@ -155,7 +157,10 @@ async function fetchGitMarketplace(url, ref, path) {
|
|
|
155
157
|
}
|
|
156
158
|
async function fetchUrlMarketplace(url, headers) {
|
|
157
159
|
try {
|
|
158
|
-
const response = await fetch(url, {
|
|
160
|
+
const response = await fetch(url, {
|
|
161
|
+
headers,
|
|
162
|
+
signal: AbortSignal.timeout(3e4)
|
|
163
|
+
});
|
|
159
164
|
if (!response.ok) {
|
|
160
165
|
throw new SkillMarketplaceError(
|
|
161
166
|
`HTTP ${response.status}: ${response.statusText}`,
|
|
@@ -212,10 +217,8 @@ async function fetchNpmMarketplace(packageName, version) {
|
|
|
212
217
|
"NPM_ERROR" /* NPM_ERROR */
|
|
213
218
|
);
|
|
214
219
|
}
|
|
215
|
-
const manifestPath =
|
|
216
|
-
tempDir,
|
|
217
|
-
"package",
|
|
218
|
-
".minto-plugin",
|
|
220
|
+
const manifestPath = resolveManifestPath(
|
|
221
|
+
join(tempDir, "package"),
|
|
219
222
|
"marketplace.json"
|
|
220
223
|
);
|
|
221
224
|
return loadManifestFromPath(manifestPath);
|
|
@@ -237,9 +240,16 @@ function fetchDirectoryMarketplace(dirPath) {
|
|
|
237
240
|
} else if (!isAbsolute(dirPath)) {
|
|
238
241
|
resolvedPath = resolve(getCwd(), dirPath);
|
|
239
242
|
}
|
|
240
|
-
const manifestPath =
|
|
243
|
+
const manifestPath = resolveManifestPath(resolvedPath, "marketplace.json");
|
|
241
244
|
return loadManifestFromPath(manifestPath);
|
|
242
245
|
}
|
|
246
|
+
function resolveManifestPath(baseDir, filename) {
|
|
247
|
+
const mintoPath = join(baseDir, ".minto-plugin", filename);
|
|
248
|
+
if (existsSync(mintoPath)) return mintoPath;
|
|
249
|
+
const claudePath = join(baseDir, ".claude-plugin", filename);
|
|
250
|
+
if (existsSync(claudePath)) return claudePath;
|
|
251
|
+
return mintoPath;
|
|
252
|
+
}
|
|
243
253
|
function loadManifestFromPath(manifestPath) {
|
|
244
254
|
if (!existsSync(manifestPath)) {
|
|
245
255
|
throw new SkillMarketplaceError(
|
|
@@ -524,8 +534,9 @@ function validatePluginPath(path) {
|
|
|
524
534
|
return { isValid: false, errors };
|
|
525
535
|
}
|
|
526
536
|
const mintoManifest = join(resolvedPath, ".minto-plugin", "plugin.json");
|
|
537
|
+
const claudeManifest = join(resolvedPath, ".claude-plugin", "plugin.json");
|
|
527
538
|
const rootManifest = join(resolvedPath, "plugin.json");
|
|
528
|
-
if (!existsSync(mintoManifest) && !existsSync(rootManifest)) {
|
|
539
|
+
if (!existsSync(mintoManifest) && !existsSync(claudeManifest) && !existsSync(rootManifest)) {
|
|
529
540
|
errors.push(
|
|
530
541
|
"No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json"
|
|
531
542
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/plugins/skillMarketplace.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Skill Marketplace Service\n *\n * Implements Claude Code CLI compatible marketplace functionality\n * for plugin/skill discovery and installation.\n *\n * Supports all Claude Code CLI source types:\n * - github: owner/repo format\n * - git: generic git URL\n * - url: HTTP/HTTPS URL to marketplace JSON\n * - npm: npm package name\n * - file: local file path\n * - directory: local directory path\n */\n\nimport { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { z } from 'zod'\nimport { execFileNoThrow } from '@utils/execFileNoThrow'\nimport { getCwd } from '@utils/state'\nimport type {\n SessionPlugin,\n PluginScope,\n InstalledSkillPlugin,\n} from '@minto-types/plugin'\n\n/**\n * Marketplace source types (Claude Code CLI compatible)\n */\nexport type MarketplaceSource =\n | { source: 'github'; repo: string; ref?: string; path?: string }\n | { source: 'git'; url: string; ref?: string; path?: string }\n | { source: 'url'; url: string; headers?: Record<string, string> }\n | { source: 'npm'; package: string; version?: string }\n | { source: 'file'; path: string }\n | { source: 'directory'; path: string }\n\n/**\n * Plugin entry schema in a marketplace manifest\n */\nconst PluginEntrySchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n source: z.string().optional().default('./'),\n strict: z.boolean().optional(),\n skills: z.union([z.string(), z.array(z.string())]).optional(),\n commands: z.union([z.string(), z.array(z.string())]).optional(),\n agents: z.union([z.string(), z.array(z.string())]).optional(),\n hooks: z.union([z.string(), z.array(z.string())]).optional(),\n mcpServers: z.union([z.string(), z.array(z.string())]).optional(),\n})\n\n/**\n * Plugin entry type (inferred from schema)\n */\nexport type PluginEntry = z.infer<typeof PluginEntrySchema>\n\n/**\n * Marketplace manifest schema (Claude Code CLI compatible)\n */\nexport const MarketplaceManifestSchema = z.object({\n $schema: z.string().optional(),\n name: z.string().min(1),\n description: z.string().optional(),\n owner: z\n .object({\n name: z.string().optional(),\n email: z.string().email().optional(),\n })\n .optional(),\n metadata: z.record(z.unknown()).optional(),\n plugins: z.array(PluginEntrySchema),\n})\n\nexport type MarketplaceManifest = z.infer<typeof MarketplaceManifestSchema>\n\n/**\n * Registered marketplace in user config\n */\nexport interface RegisteredMarketplace {\n name: string\n source: MarketplaceSource\n manifest: MarketplaceManifest\n lastUpdated: Date\n enabled: boolean\n}\n\n/**\n * Marketplace error codes\n */\nexport enum MarketplaceErrorCode {\n MANIFEST_INVALID = 'MANIFEST_INVALID',\n MANIFEST_NOT_FOUND = 'MANIFEST_NOT_FOUND',\n NETWORK_ERROR = 'NETWORK_ERROR',\n GIT_ERROR = 'GIT_ERROR',\n NPM_ERROR = 'NPM_ERROR',\n ALREADY_REGISTERED = 'ALREADY_REGISTERED',\n NOT_REGISTERED = 'NOT_REGISTERED',\n PLUGIN_NOT_FOUND = 'PLUGIN_NOT_FOUND',\n INSTALLATION_FAILED = 'INSTALLATION_FAILED',\n}\n\n/**\n * Marketplace error class\n */\nexport class SkillMarketplaceError extends Error {\n constructor(\n message: string,\n public code: MarketplaceErrorCode,\n public marketplaceName?: string,\n public details?: unknown,\n ) {\n super(message)\n this.name = 'SkillMarketplaceError'\n }\n}\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get installed plugins storage directory based on scope\n */\nfunction getInstalledPluginsDir(scope: PluginScope): string {\n const base =\n scope === 'user'\n ? join(homedir(), '.minto', 'plugins')\n : join(getCwd(), '.minto', 'plugins')\n\n if (!existsSync(base)) {\n mkdirSync(base, { recursive: true })\n }\n\n return base\n}\n\n/**\n * Get registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Get installed skills registry path\n */\nfunction getInstalledSkillsPath(): string {\n return join(getMarketplaceDir(), 'installed-skills.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch {\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Load installed skills registry\n */\nexport function loadInstalledSkills(): InstalledSkillPlugin[] {\n const path = getInstalledSkillsPath()\n\n if (!existsSync(path)) {\n return []\n }\n\n try {\n const content = readFileSync(path, 'utf-8')\n return JSON.parse(content)\n } catch {\n return []\n }\n}\n\n/**\n * Save installed skills registry\n */\nfunction saveInstalledSkills(skills: InstalledSkillPlugin[]): void {\n const path = getInstalledSkillsPath()\n writeFileSync(path, JSON.stringify(skills, null, 2), 'utf-8')\n}\n\n/**\n * Parse marketplace source from string\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { source: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { source: 'github', repo: match[1] }\n }\n }\n\n // NPM package (starts with @ or contains no slashes and not a URL)\n if (\n input.startsWith('@') ||\n (input.startsWith('npm:') && !input.includes('/'))\n ) {\n const pkg = input.replace(/^npm:/, '')\n return { source: 'npm', package: pkg }\n }\n\n // Git URL (http/https with .git or git://)\n if (\n input.startsWith('git://') ||\n (input.startsWith('http') && input.endsWith('.git'))\n ) {\n return { source: 'git', url: input }\n }\n\n // HTTP/HTTPS URL\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return { source: 'url', url: input }\n }\n\n // File path (starts with .)\n if (input.startsWith('./') || input.startsWith('../')) {\n return { source: 'file', path: input }\n }\n\n // Directory (absolute path or relative)\n if (input.startsWith('/') || input.startsWith('~')) {\n return { source: 'directory', path: input }\n }\n\n // Default to directory\n return { source: 'directory', path: input }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n path?: string,\n): Promise<MarketplaceManifest> {\n const url = `https://github.com/${repo}.git`\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n const manifestPath = path\n ? join(tempDir, path, '.minto-plugin', 'marketplace.json')\n : join(tempDir, '.minto-plugin', 'marketplace.json')\n\n return loadManifestFromPath(manifestPath)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchGitMarketplace(\n url: string,\n ref?: string,\n path?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n const manifestPath = path\n ? join(tempDir, path, '.minto-plugin', 'marketplace.json')\n : join(tempDir, '.minto-plugin', 'marketplace.json')\n\n return loadManifestFromPath(manifestPath)\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n headers?: Record<string, string>,\n): Promise<MarketplaceManifest> {\n try {\n const response = await fetch(url, { headers })\n\n if (!response.ok) {\n throw new SkillMarketplaceError(\n `HTTP ${response.status}: ${response.statusText}`,\n MarketplaceErrorCode.NETWORK_ERROR,\n )\n }\n\n const data = await response.json()\n const parsed = MarketplaceManifestSchema.safeParse(data)\n\n if (!parsed.success) {\n throw new SkillMarketplaceError(\n `Invalid manifest: ${parsed.error.message}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n\n return parsed.data\n } catch (error) {\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Failed to fetch manifest from URL: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.NETWORK_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from NPM\n */\nasync function fetchNpmMarketplace(\n packageName: string,\n version?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n const pkgSpec = version ? `${packageName}@${version}` : packageName\n const result = await execFileNoThrow('npm', [\n 'pack',\n pkgSpec,\n '--pack-destination',\n tempDir,\n ])\n\n if (result.code !== 0) {\n throw new SkillMarketplaceError(\n `NPM pack failed: ${result.stderr || result.stdout}`,\n MarketplaceErrorCode.NPM_ERROR,\n )\n }\n\n // Extract the tarball\n const tarballName = result.stdout.trim().split('\\n').pop() || ''\n const tarballPath = join(tempDir, tarballName)\n\n const extractResult = await execFileNoThrow('tar', [\n '-xzf',\n tarballPath,\n '-C',\n tempDir,\n ])\n if (extractResult.code !== 0) {\n throw new SkillMarketplaceError(\n `Failed to extract NPM package: ${extractResult.stderr}`,\n MarketplaceErrorCode.NPM_ERROR,\n )\n }\n\n // Look for marketplace manifest in package\n const manifestPath = join(\n tempDir,\n 'package',\n '.minto-plugin',\n 'marketplace.json',\n )\n return loadManifestFromPath(manifestPath)\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local file\n */\nfunction fetchFileMarketplace(filePath: string): MarketplaceManifest {\n const resolvedPath = isAbsolute(filePath)\n ? filePath\n : resolve(getCwd(), filePath)\n\n return loadManifestFromPath(resolvedPath)\n}\n\n/**\n * Load marketplace manifest from local directory\n */\nfunction fetchDirectoryMarketplace(dirPath: string): MarketplaceManifest {\n let resolvedPath = dirPath\n\n // Handle ~ expansion\n if (dirPath.startsWith('~')) {\n resolvedPath = join(homedir(), dirPath.slice(1))\n } else if (!isAbsolute(dirPath)) {\n resolvedPath = resolve(getCwd(), dirPath)\n }\n\n const manifestPath = join(resolvedPath, '.minto-plugin', 'marketplace.json')\n return loadManifestFromPath(manifestPath)\n}\n\n/**\n * Load manifest from file path\n */\nfunction loadManifestFromPath(manifestPath: string): MarketplaceManifest {\n if (!existsSync(manifestPath)) {\n throw new SkillMarketplaceError(\n `Marketplace manifest not found at ${manifestPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n const parsed = MarketplaceManifestSchema.safeParse(data)\n\n if (!parsed.success) {\n throw new SkillMarketplaceError(\n `Invalid manifest: ${parsed.error.message}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n\n return parsed.data\n } catch (error) {\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Failed to load manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Clone git repository\n */\nasync function cloneGitRepo(url: string, ref?: string): Promise<string> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n const args = ['clone', '--depth', '1']\n\n if (ref) {\n args.push('--branch', ref)\n }\n\n args.push(url, tempDir)\n\n const result = await execFileNoThrow('git', args)\n\n if (result.code !== 0) {\n throw new SkillMarketplaceError(\n `Git clone failed: ${result.stderr || result.stdout}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n\n return tempDir\n } catch (error) {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Git clone failed: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest based on source type\n */\nexport async function fetchMarketplaceManifest(\n source: MarketplaceSource,\n): Promise<MarketplaceManifest> {\n switch (source.source) {\n case 'github':\n return fetchGitHubMarketplace(source.repo, source.ref, source.path)\n case 'git':\n return fetchGitMarketplace(source.url, source.ref, source.path)\n case 'url':\n return fetchUrlMarketplace(source.url, source.headers)\n case 'npm':\n return fetchNpmMarketplace(source.package, source.version)\n case 'file':\n return fetchFileMarketplace(source.path)\n case 'directory':\n return fetchDirectoryMarketplace(source.path)\n default:\n throw new SkillMarketplaceError(\n `Unknown source type: ${(source as any).source}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string | MarketplaceSource,\n): Promise<RegisteredMarketplace> {\n const source =\n typeof input === 'string' ? parseMarketplaceSource(input) : input\n\n const manifest = await fetchMarketplaceManifest(source)\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new SkillMarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new SkillMarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update marketplace manifest\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new SkillMarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n const manifest = await fetchMarketplaceManifest(marketplace.source)\n\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n return loadRegistry().find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n): { marketplace: RegisteredMarketplace; plugin: PluginEntry } | undefined {\n const registry = loadRegistry()\n\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPlugin(\n pluginName: string,\n options: {\n marketplace?: string\n scope?: PluginScope\n force?: boolean\n } = {},\n): Promise<string> {\n const {\n marketplace: marketplaceName,\n scope = 'user',\n force = false,\n } = options\n\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new SkillMarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n const installDir = join(getInstalledPluginsDir(scope), plugin.name)\n\n // Check if already installed\n if (existsSync(installDir) && !force) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is already installed. Use --force to reinstall.`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n pluginName,\n )\n }\n\n // Remove existing if force\n if (existsSync(installDir) && force) {\n rmSync(installDir, { recursive: true, force: true })\n }\n\n // Create installation directory\n mkdirSync(installDir, { recursive: true })\n\n try {\n // Install based on marketplace source type and plugin source\n // For now, we'll use the marketplace manager's implementation\n // This will be enhanced in future iterations\n\n // Record installation\n const installed = loadInstalledSkills()\n const record: InstalledSkillPlugin = {\n plugin: plugin.name,\n marketplace: marketplace.name,\n scope,\n isEnabled: true,\n installedAt: new Date().toISOString(),\n pluginRoot: installDir,\n skills:\n typeof plugin.skills === 'string'\n ? [plugin.skills]\n : plugin.skills || [],\n commands:\n typeof plugin.commands === 'string'\n ? [plugin.commands]\n : plugin.commands || [],\n sourceMarketplacePath:\n marketplace.source.source === 'directory'\n ? (marketplace.source as { source: 'directory'; path: string }).path\n : marketplace.name,\n }\n\n // Remove existing record if present\n const filtered = installed.filter(\n i => !(i.plugin === plugin.name && i.scope === scope),\n )\n filtered.push(record)\n saveInstalledSkills(filtered)\n\n return installDir\n } catch (error) {\n // Clean up on failure\n try {\n rmSync(installDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n\n throw new SkillMarketplaceError(\n `Failed to install plugin: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.INSTALLATION_FAILED,\n pluginName,\n error,\n )\n }\n}\n\n/**\n * Uninstall plugin\n */\nexport function uninstallPlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n // Remove plugin directory\n if (record.pluginRoot && existsSync(record.pluginRoot)) {\n rmSync(record.pluginRoot, { recursive: true, force: true })\n }\n\n // Update registry\n const filtered = installed.filter(\n i => !(i.plugin === pluginName && i.scope === scope),\n )\n saveInstalledSkills(filtered)\n}\n\n/**\n * Enable plugin\n */\nexport function enablePlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n record.isEnabled = true\n saveInstalledSkills(installed)\n}\n\n/**\n * Disable plugin\n */\nexport function disablePlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n record.isEnabled = false\n saveInstalledSkills(installed)\n}\n\n/**\n * List installed plugins\n */\nexport function listInstalledPlugins(\n scope?: PluginScope,\n): InstalledSkillPlugin[] {\n const installed = loadInstalledSkills()\n\n if (scope) {\n return installed.filter(i => i.scope === scope)\n }\n\n return installed\n}\n\n/**\n * Validate marketplace manifest\n */\nexport function validateMarketplaceManifest(data: unknown): {\n success: boolean\n data?: MarketplaceManifest\n error?: string\n} {\n const result = MarketplaceManifestSchema.safeParse(data)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n return { success: false, error: result.error.message }\n}\n\n/**\n * Validate plugin path (used for local validation)\n */\nexport function validatePluginPath(path: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n const resolvedPath = isAbsolute(path) ? path : resolve(getCwd(), path)\n\n if (!existsSync(resolvedPath)) {\n errors.push(`Path does not exist: ${resolvedPath}`)\n return { isValid: false, errors }\n }\n\n // Check for plugin manifest\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'plugin.json')\n const rootManifest = join(resolvedPath, 'plugin.json')\n\n if (!existsSync(mintoManifest) && !existsSync(rootManifest)) {\n errors.push(\n 'No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json',\n )\n }\n\n return { isValid: errors.length === 0, errors }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Skill Marketplace Service\n *\n * Implements Claude Code CLI compatible marketplace functionality\n * for plugin/skill discovery and installation.\n *\n * Supports all Claude Code CLI source types:\n * - github: owner/repo format\n * - git: generic git URL\n * - url: HTTP/HTTPS URL to marketplace JSON\n * - npm: npm package name\n * - file: local file path\n * - directory: local directory path\n */\n\nimport { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { z } from 'zod'\nimport { execFileNoThrow } from '@utils/execFileNoThrow'\nimport { getCwd } from '@utils/state'\nimport type {\n SessionPlugin,\n PluginScope,\n InstalledSkillPlugin,\n} from '@minto-types/plugin'\n\n/**\n * Marketplace source types (Claude Code CLI compatible)\n */\nexport type MarketplaceSource =\n | { source: 'github'; repo: string; ref?: string; path?: string }\n | { source: 'git'; url: string; ref?: string; path?: string }\n | { source: 'url'; url: string; headers?: Record<string, string> }\n | { source: 'npm'; package: string; version?: string }\n | { source: 'file'; path: string }\n | { source: 'directory'; path: string }\n\n/**\n * Plugin entry schema in a marketplace manifest\n */\nconst PluginEntrySchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n source: z.string().optional().default('./'),\n strict: z.boolean().optional(),\n skills: z.union([z.string(), z.array(z.string())]).optional(),\n commands: z.union([z.string(), z.array(z.string())]).optional(),\n agents: z.union([z.string(), z.array(z.string())]).optional(),\n hooks: z.union([z.string(), z.array(z.string())]).optional(),\n mcpServers: z.union([z.string(), z.array(z.string())]).optional(),\n})\n\n/**\n * Plugin entry type (inferred from schema)\n */\nexport type PluginEntry = z.infer<typeof PluginEntrySchema>\n\n/**\n * Marketplace manifest schema (Claude Code CLI compatible)\n */\nexport const MarketplaceManifestSchema = z.object({\n $schema: z.string().optional(),\n name: z.string().min(1),\n description: z.string().optional(),\n owner: z\n .object({\n name: z.string().optional(),\n email: z.string().email().optional(),\n })\n .optional(),\n metadata: z.record(z.unknown()).optional(),\n plugins: z.array(PluginEntrySchema),\n})\n\nexport type MarketplaceManifest = z.infer<typeof MarketplaceManifestSchema>\n\n/**\n * Registered marketplace in user config\n */\nexport interface RegisteredMarketplace {\n name: string\n source: MarketplaceSource\n manifest: MarketplaceManifest\n lastUpdated: Date\n enabled: boolean\n}\n\n/**\n * Marketplace error codes\n */\nexport enum MarketplaceErrorCode {\n MANIFEST_INVALID = 'MANIFEST_INVALID',\n MANIFEST_NOT_FOUND = 'MANIFEST_NOT_FOUND',\n NETWORK_ERROR = 'NETWORK_ERROR',\n GIT_ERROR = 'GIT_ERROR',\n NPM_ERROR = 'NPM_ERROR',\n ALREADY_REGISTERED = 'ALREADY_REGISTERED',\n NOT_REGISTERED = 'NOT_REGISTERED',\n PLUGIN_NOT_FOUND = 'PLUGIN_NOT_FOUND',\n INSTALLATION_FAILED = 'INSTALLATION_FAILED',\n}\n\n/**\n * Marketplace error class\n */\nexport class SkillMarketplaceError extends Error {\n constructor(\n message: string,\n public code: MarketplaceErrorCode,\n public marketplaceName?: string,\n public details?: unknown,\n ) {\n super(message)\n this.name = 'SkillMarketplaceError'\n }\n}\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get installed plugins storage directory based on scope\n */\nfunction getInstalledPluginsDir(scope: PluginScope): string {\n const base =\n scope === 'user'\n ? join(homedir(), '.minto', 'plugins')\n : join(getCwd(), '.minto', 'plugins')\n\n if (!existsSync(base)) {\n mkdirSync(base, { recursive: true })\n }\n\n return base\n}\n\n/**\n * Get registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Get installed skills registry path\n */\nfunction getInstalledSkillsPath(): string {\n return join(getMarketplaceDir(), 'installed-skills.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch {\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Load installed skills registry\n */\nexport function loadInstalledSkills(): InstalledSkillPlugin[] {\n const path = getInstalledSkillsPath()\n\n if (!existsSync(path)) {\n return []\n }\n\n try {\n const content = readFileSync(path, 'utf-8')\n return JSON.parse(content)\n } catch {\n return []\n }\n}\n\n/**\n * Save installed skills registry\n */\nfunction saveInstalledSkills(skills: InstalledSkillPlugin[]): void {\n const path = getInstalledSkillsPath()\n writeFileSync(path, JSON.stringify(skills, null, 2), 'utf-8')\n}\n\n/**\n * Parse marketplace source from string\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { source: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { source: 'github', repo: match[1] }\n }\n }\n\n // NPM package (starts with @ or contains no slashes and not a URL)\n if (\n input.startsWith('@') ||\n (input.startsWith('npm:') && !input.includes('/'))\n ) {\n const pkg = input.replace(/^npm:/, '')\n return { source: 'npm', package: pkg }\n }\n\n // Git URL (http/https with .git or git://)\n if (\n input.startsWith('git://') ||\n (input.startsWith('http') && input.endsWith('.git'))\n ) {\n return { source: 'git', url: input }\n }\n\n // HTTP/HTTPS URL\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return { source: 'url', url: input }\n }\n\n // File path (starts with .)\n if (input.startsWith('./') || input.startsWith('../')) {\n return { source: 'file', path: input }\n }\n\n // Directory (absolute path or relative)\n if (input.startsWith('/') || input.startsWith('~')) {\n return { source: 'directory', path: input }\n }\n\n // Default to directory\n return { source: 'directory', path: input }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n path?: string,\n): Promise<MarketplaceManifest> {\n const url = `https://github.com/${repo}.git`\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n const baseDir = path ? join(tempDir, path) : tempDir\n const manifestPath = resolveManifestPath(baseDir, 'marketplace.json')\n\n return loadManifestFromPath(manifestPath)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchGitMarketplace(\n url: string,\n ref?: string,\n path?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n const baseDir = path ? join(tempDir, path) : tempDir\n const manifestPath = resolveManifestPath(baseDir, 'marketplace.json')\n\n return loadManifestFromPath(manifestPath)\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n headers?: Record<string, string>,\n): Promise<MarketplaceManifest> {\n try {\n const response = await fetch(url, {\n headers,\n signal: AbortSignal.timeout(30_000),\n })\n\n if (!response.ok) {\n throw new SkillMarketplaceError(\n `HTTP ${response.status}: ${response.statusText}`,\n MarketplaceErrorCode.NETWORK_ERROR,\n )\n }\n\n const data = await response.json()\n const parsed = MarketplaceManifestSchema.safeParse(data)\n\n if (!parsed.success) {\n throw new SkillMarketplaceError(\n `Invalid manifest: ${parsed.error.message}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n\n return parsed.data\n } catch (error) {\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Failed to fetch manifest from URL: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.NETWORK_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from NPM\n */\nasync function fetchNpmMarketplace(\n packageName: string,\n version?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n const pkgSpec = version ? `${packageName}@${version}` : packageName\n const result = await execFileNoThrow('npm', [\n 'pack',\n pkgSpec,\n '--pack-destination',\n tempDir,\n ])\n\n if (result.code !== 0) {\n throw new SkillMarketplaceError(\n `NPM pack failed: ${result.stderr || result.stdout}`,\n MarketplaceErrorCode.NPM_ERROR,\n )\n }\n\n // Extract the tarball\n const tarballName = result.stdout.trim().split('\\n').pop() || ''\n const tarballPath = join(tempDir, tarballName)\n\n const extractResult = await execFileNoThrow('tar', [\n '-xzf',\n tarballPath,\n '-C',\n tempDir,\n ])\n if (extractResult.code !== 0) {\n throw new SkillMarketplaceError(\n `Failed to extract NPM package: ${extractResult.stderr}`,\n MarketplaceErrorCode.NPM_ERROR,\n )\n }\n\n // Look for marketplace manifest in package\n const manifestPath = resolveManifestPath(\n join(tempDir, 'package'),\n 'marketplace.json',\n )\n return loadManifestFromPath(manifestPath)\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local file\n */\nfunction fetchFileMarketplace(filePath: string): MarketplaceManifest {\n const resolvedPath = isAbsolute(filePath)\n ? filePath\n : resolve(getCwd(), filePath)\n\n return loadManifestFromPath(resolvedPath)\n}\n\n/**\n * Load marketplace manifest from local directory\n */\nfunction fetchDirectoryMarketplace(dirPath: string): MarketplaceManifest {\n let resolvedPath = dirPath\n\n // Handle ~ expansion\n if (dirPath.startsWith('~')) {\n resolvedPath = join(homedir(), dirPath.slice(1))\n } else if (!isAbsolute(dirPath)) {\n resolvedPath = resolve(getCwd(), dirPath)\n }\n\n const manifestPath = resolveManifestPath(resolvedPath, 'marketplace.json')\n return loadManifestFromPath(manifestPath)\n}\n\n/**\n * Resolve manifest file path, checking .minto-plugin then .claude-plugin (legacy)\n */\nfunction resolveManifestPath(baseDir: string, filename: string): string {\n const mintoPath = join(baseDir, '.minto-plugin', filename)\n if (existsSync(mintoPath)) return mintoPath\n\n const claudePath = join(baseDir, '.claude-plugin', filename)\n if (existsSync(claudePath)) return claudePath\n\n // Return .minto-plugin path as default (will produce a clear error message)\n return mintoPath\n}\n\n/**\n * Load manifest from file path\n */\nfunction loadManifestFromPath(manifestPath: string): MarketplaceManifest {\n if (!existsSync(manifestPath)) {\n throw new SkillMarketplaceError(\n `Marketplace manifest not found at ${manifestPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n const parsed = MarketplaceManifestSchema.safeParse(data)\n\n if (!parsed.success) {\n throw new SkillMarketplaceError(\n `Invalid manifest: ${parsed.error.message}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n\n return parsed.data\n } catch (error) {\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Failed to load manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Clone git repository\n */\nasync function cloneGitRepo(url: string, ref?: string): Promise<string> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n const args = ['clone', '--depth', '1']\n\n if (ref) {\n args.push('--branch', ref)\n }\n\n args.push(url, tempDir)\n\n const result = await execFileNoThrow('git', args)\n\n if (result.code !== 0) {\n throw new SkillMarketplaceError(\n `Git clone failed: ${result.stderr || result.stdout}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n\n return tempDir\n } catch (error) {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof SkillMarketplaceError) throw error\n\n throw new SkillMarketplaceError(\n `Git clone failed: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest based on source type\n */\nexport async function fetchMarketplaceManifest(\n source: MarketplaceSource,\n): Promise<MarketplaceManifest> {\n switch (source.source) {\n case 'github':\n return fetchGitHubMarketplace(source.repo, source.ref, source.path)\n case 'git':\n return fetchGitMarketplace(source.url, source.ref, source.path)\n case 'url':\n return fetchUrlMarketplace(source.url, source.headers)\n case 'npm':\n return fetchNpmMarketplace(source.package, source.version)\n case 'file':\n return fetchFileMarketplace(source.path)\n case 'directory':\n return fetchDirectoryMarketplace(source.path)\n default:\n throw new SkillMarketplaceError(\n `Unknown source type: ${(source as any).source}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n )\n }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string | MarketplaceSource,\n): Promise<RegisteredMarketplace> {\n const source =\n typeof input === 'string' ? parseMarketplaceSource(input) : input\n\n const manifest = await fetchMarketplaceManifest(source)\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new SkillMarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new SkillMarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update marketplace manifest\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new SkillMarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n const manifest = await fetchMarketplaceManifest(marketplace.source)\n\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n return loadRegistry().find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n): { marketplace: RegisteredMarketplace; plugin: PluginEntry } | undefined {\n const registry = loadRegistry()\n\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPlugin(\n pluginName: string,\n options: {\n marketplace?: string\n scope?: PluginScope\n force?: boolean\n } = {},\n): Promise<string> {\n const {\n marketplace: marketplaceName,\n scope = 'user',\n force = false,\n } = options\n\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new SkillMarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n const installDir = join(getInstalledPluginsDir(scope), plugin.name)\n\n // Check if already installed\n if (existsSync(installDir) && !force) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is already installed. Use --force to reinstall.`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n pluginName,\n )\n }\n\n // Remove existing if force\n if (existsSync(installDir) && force) {\n rmSync(installDir, { recursive: true, force: true })\n }\n\n // Create installation directory\n mkdirSync(installDir, { recursive: true })\n\n try {\n // Install based on marketplace source type and plugin source\n // For now, we'll use the marketplace manager's implementation\n // This will be enhanced in future iterations\n\n // Record installation\n const installed = loadInstalledSkills()\n const record: InstalledSkillPlugin = {\n plugin: plugin.name,\n marketplace: marketplace.name,\n scope,\n isEnabled: true,\n installedAt: new Date().toISOString(),\n pluginRoot: installDir,\n skills:\n typeof plugin.skills === 'string'\n ? [plugin.skills]\n : plugin.skills || [],\n commands:\n typeof plugin.commands === 'string'\n ? [plugin.commands]\n : plugin.commands || [],\n sourceMarketplacePath:\n marketplace.source.source === 'directory'\n ? (marketplace.source as { source: 'directory'; path: string }).path\n : marketplace.name,\n }\n\n // Remove existing record if present\n const filtered = installed.filter(\n i => !(i.plugin === plugin.name && i.scope === scope),\n )\n filtered.push(record)\n saveInstalledSkills(filtered)\n\n return installDir\n } catch (error) {\n // Clean up on failure\n try {\n rmSync(installDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n\n throw new SkillMarketplaceError(\n `Failed to install plugin: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.INSTALLATION_FAILED,\n pluginName,\n error,\n )\n }\n}\n\n/**\n * Uninstall plugin\n */\nexport function uninstallPlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n // Remove plugin directory\n if (record.pluginRoot && existsSync(record.pluginRoot)) {\n rmSync(record.pluginRoot, { recursive: true, force: true })\n }\n\n // Update registry\n const filtered = installed.filter(\n i => !(i.plugin === pluginName && i.scope === scope),\n )\n saveInstalledSkills(filtered)\n}\n\n/**\n * Enable plugin\n */\nexport function enablePlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n record.isEnabled = true\n saveInstalledSkills(installed)\n}\n\n/**\n * Disable plugin\n */\nexport function disablePlugin(\n pluginName: string,\n scope: PluginScope = 'user',\n): void {\n const installed = loadInstalledSkills()\n const record = installed.find(\n i => i.plugin === pluginName && i.scope === scope,\n )\n\n if (!record) {\n throw new SkillMarketplaceError(\n `Plugin \"${pluginName}\" is not installed in ${scope} scope`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n pluginName,\n )\n }\n\n record.isEnabled = false\n saveInstalledSkills(installed)\n}\n\n/**\n * List installed plugins\n */\nexport function listInstalledPlugins(\n scope?: PluginScope,\n): InstalledSkillPlugin[] {\n const installed = loadInstalledSkills()\n\n if (scope) {\n return installed.filter(i => i.scope === scope)\n }\n\n return installed\n}\n\n/**\n * Validate marketplace manifest\n */\nexport function validateMarketplaceManifest(data: unknown): {\n success: boolean\n data?: MarketplaceManifest\n error?: string\n} {\n const result = MarketplaceManifestSchema.safeParse(data)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n return { success: false, error: result.error.message }\n}\n\n/**\n * Validate plugin path (used for local validation)\n */\nexport function validatePluginPath(path: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n const resolvedPath = isAbsolute(path) ? path : resolve(getCwd(), path)\n\n if (!existsSync(resolvedPath)) {\n errors.push(`Path does not exist: ${resolvedPath}`)\n return { isValid: false, errors }\n }\n\n // Check for plugin manifest (.minto-plugin, .claude-plugin, or root)\n const mintoManifest = join(resolvedPath, '.minto-plugin', 'plugin.json')\n const claudeManifest = join(resolvedPath, '.claude-plugin', 'plugin.json')\n const rootManifest = join(resolvedPath, 'plugin.json')\n\n if (\n !existsSync(mintoManifest) &&\n !existsSync(claudeManifest) &&\n !existsSync(rootManifest)\n ) {\n errors.push(\n 'No plugin manifest found. Expected .minto-plugin/plugin.json or plugin.json',\n )\n }\n\n return { isValid: errors.length === 0, errors }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["MarketplaceErrorCode"]
|
|
7
7
|
}
|
package/dist/services/sentry.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/sentry.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Sentry stub \u2014 Minto does not use Sentry error tracking.\n * These no-op exports satisfy import sites without adding a dependency.\n */\nexport function initSentry(): void {}\n\nexport async function captureException(_error: unknown): Promise<void> {}\n"],
|
|
5
|
+
"mappings": "AAIO,SAAS,aAAmB;AAAC;AAEpC,eAAsB,iBAAiB,QAAgC;AAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|