@within-7/minto 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +461 -657
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +684 -94
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +425 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +457 -65
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +891 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +146 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +590 -565
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +26 -11
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +123 -48
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +11 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +21 -3
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +81 -68
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +299 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +300 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +20 -9
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +367 -9
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +8 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +84 -11
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +3 -5
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +91 -15
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +27 -151
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +68 -29
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +249 -57
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +77 -12
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +162 -16
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/skillLoader.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Skill Loader\n *\n * Progressive disclosure system for loading skills from plugins and standalone directories.\n * Implements Claude Code skill specification for plugin and standalone skills.\n *\n * Directory Priority (later overrides earlier):\n * 1. Plugin skills\n * 2. ~/.minto/skills/ (user directory)\n * 3. ./.minto/skills/ (project directory - highest priority)\n *\n * Supports two file patterns:\n * - skill-name/SKILL.md (subdirectory pattern)\n * - skill-name.md (flat file pattern)\n */\n\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs'\nimport { join, basename, dirname } from 'path'\nimport { homedir } from 'os'\nimport matter from 'gray-matter'\nimport { LoadedSkill, SkillConfig } from '../types/plugin'\nimport { loadAllPlugins } from './pluginLoader'\nimport { getCwd } from './state'\n\n/**\n * In-memory cache for loaded skills\n * Maps skill name to skill object\n */\nlet skillsCache: Map<string, LoadedSkill> | null = null\n\n/**\n * Cache for fully-loaded skill content\n * Maps skill name to full markdown content\n */\nconst contentCache = new Map<string, string>()\n\n/**\n * Parse a skill file and extract configuration\n * Supports Claude Code skill specification frontmatter fields\n */\nfunction parseSkillFile(\n filePath: string,\n source: 'user' | 'project',\n): LoadedSkill | null {\n try {\n if (!existsSync(filePath)) return null\n\n const fileContent = readFileSync(filePath, 'utf-8')\n const { data: frontmatter, content } = matter(fileContent)\n\n // Determine skill name from frontmatter or filename\n const fileName = basename(filePath, '.md')\n const name =\n frontmatter.name ||\n (fileName === 'SKILL' ? basename(dirname(filePath)) : fileName)\n\n // Parse Claude Code spec fields\n const config: SkillConfig = {\n name,\n description: frontmatter.description || '',\n argumentHint: frontmatter['argument-hint'] || frontmatter.argumentHint,\n disableModelInvocation:\n frontmatter['disable-model-invocation'] ??\n frontmatter.disableModelInvocation,\n userInvocable:\n frontmatter['user-invocable'] ?? frontmatter.userInvocable ?? true,\n allowedTools: parseStringOrArray(\n frontmatter['allowed-tools'] || frontmatter.allowedTools,\n ),\n model: frontmatter.model,\n context: frontmatter.context,\n agent: frontmatter.agent,\n content: content.trim(),\n }\n\n return {\n name,\n filePath,\n config,\n pluginName: 'standalone',\n source,\n }\n } catch (error) {\n console.warn(`Failed to parse skill file ${filePath}:`, error)\n return null\n }\n}\n\n/**\n * Parse a value that could be a string, array, or comma-separated string\n */\nfunction parseStringOrArray(value: unknown): string[] | undefined {\n if (!value) return undefined\n if (Array.isArray(value)) return value.map(String)\n if (typeof value === 'string') {\n return value.split(',').map(s => s.trim())\n }\n return undefined\n}\n\n/**\n * Scan a standalone skills directory\n * Supports both patterns:\n * - skill-name/SKILL.md (subdirectory pattern)\n * - skill-name.md (flat file pattern)\n */\nfunction scanStandaloneSkillsDirectory(\n dirPath: string,\n source: 'user' | 'project',\n): LoadedSkill[] {\n const skills: LoadedSkill[] = []\n\n if (!existsSync(dirPath)) return skills\n\n try {\n const entries = readdirSync(dirPath, { withFileTypes: true })\n\n for (const entry of entries) {\n const entryPath = join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n // Pattern 1: skill-name/SKILL.md\n const skillMdPath = join(entryPath, 'SKILL.md')\n if (existsSync(skillMdPath)) {\n const skill = parseSkillFile(skillMdPath, source)\n if (skill) skills.push(skill)\n }\n } else if (entry.name.endsWith('.md') && entry.name !== 'README.md') {\n // Pattern 2: skill-name.md\n const skill = parseSkillFile(entryPath, source)\n if (skill) skills.push(skill)\n }\n }\n } catch (error) {\n console.warn(`Failed to scan skills directory ${dirPath}:`, error)\n }\n\n return skills\n}\n\n/**\n * Load all standalone skills from user and project directories\n */\nfunction loadStandaloneSkills(): LoadedSkill[] {\n const home = homedir()\n const cwd = getCwd()\n\n const userSkillsDir = join(home, '.minto', 'skills')\n const projectSkillsDir = join(cwd, '.minto', 'skills')\n\n const userSkills = scanStandaloneSkillsDirectory(userSkillsDir, 'user')\n const projectSkills = scanStandaloneSkillsDirectory(\n projectSkillsDir,\n 'project',\n )\n\n return [...userSkills, ...projectSkills]\n}\n\n/**\n * Load all skills from plugins and standalone directories\n * Uses progressive disclosure - only loads metadata (name, description)\n * Content is lazy-loaded when needed\n *\n * Priority: plugin < user < project (later overrides earlier)\n */\nexport function loadAllSkills(): LoadedSkill[] {\n // Return cached skills if available\n if (skillsCache !== null) {\n return Array.from(skillsCache.values())\n }\n\n const pluginSkills: LoadedSkill[] = []\n const plugins = loadAllPlugins()\n\n // Collect all skills from all plugins\n for (const plugin of plugins) {\n if (!plugin.enabled) continue\n\n for (const skill of plugin.skills) {\n // Ensure plugin skills have source field\n pluginSkills.push({\n ...skill,\n source: 'plugin',\n })\n }\n }\n\n // Load standalone skills\n const standaloneSkills = loadStandaloneSkills()\n\n // Build cache map for fast lookups (later entries override earlier ones)\n skillsCache = new Map()\n\n // Add in priority order: plugin < standalone (user < project)\n for (const skill of pluginSkills) {\n skillsCache.set(skill.name, skill)\n }\n for (const skill of standaloneSkills) {\n skillsCache.set(skill.name, skill)\n }\n\n return Array.from(skillsCache.values())\n}\n\n/**\n * Get a specific skill by name\n * Returns undefined if skill not found\n */\nexport function getSkill(name: string): LoadedSkill | undefined {\n // Ensure cache is populated\n if (skillsCache === null) {\n loadAllSkills()\n }\n\n return skillsCache?.get(name)\n}\n\n/**\n * Load the full content of a skill\n * Uses caching to avoid repeated file reads\n */\nexport async function loadSkillContent(skill: LoadedSkill): Promise<string> {\n // Check content cache first\n if (contentCache.has(skill.name)) {\n return contentCache.get(skill.name)!\n }\n\n // If content was already loaded in the skill object, use it\n if (skill.config.content) {\n contentCache.set(skill.name, skill.config.content)\n return skill.config.content\n }\n\n // Otherwise, read from file\n try {\n const fileContent = readFileSync(skill.filePath, 'utf-8')\n const { content } = matter(fileContent)\n const trimmedContent = content.trim()\n\n // Cache the content\n contentCache.set(skill.name, trimmedContent)\n\n // Update the skill object\n skill.config.content = trimmedContent\n\n return trimmedContent\n } catch (error) {\n throw new Error(\n `Failed to load skill content for \"${skill.name}\": ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Search skills by name or description\n * Returns skills matching the query (case-insensitive)\n */\nexport function searchSkills(query: string): LoadedSkill[] {\n const allSkills = loadAllSkills()\n const lowerQuery = query.toLowerCase()\n\n return allSkills.filter(\n skill =>\n skill.name.toLowerCase().includes(lowerQuery) ||\n skill.config.description.toLowerCase().includes(lowerQuery) ||\n skill.pluginName.toLowerCase().includes(lowerQuery),\n )\n}\n\n/**\n * Get skills from a specific plugin\n */\nexport function getSkillsByPlugin(pluginName: string): LoadedSkill[] {\n const allSkills = loadAllSkills()\n return allSkills.filter(skill => skill.pluginName === pluginName)\n}\n\n/**\n * Clear the skills cache (useful for hot-reloading)\n */\nexport function clearSkillsCache(): void {\n skillsCache = null\n contentCache.clear()\n}\n\n/**\n * Get count of available skills\n */\nexport function getSkillCount(): number {\n const skills = loadAllSkills()\n return skills.length\n}\n"],
|
|
5
|
-
"mappings": "AAgBA,SAAS,YAAY,cAAc,mBAA6B;AAChE,SAAS,MAAM,UAAU,eAAe;AACxC,SAAS,eAAe;AACxB,OAAO,YAAY;AAEnB,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AAMvB,IAAI,cAA+C;AAMnD,MAAM,eAAe,oBAAI,IAAoB;AAM7C,SAAS,eACP,UACA,QACoB;AACpB,MAAI;AACF,QAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,UAAM,cAAc,aAAa,UAAU,OAAO;AAClD,UAAM,EAAE,MAAM,aAAa,QAAQ,IAAI,OAAO,WAAW;AAGzD,UAAM,WAAW,SAAS,UAAU,KAAK;AACzC,UAAM,OACJ,YAAY,SACX,aAAa,UAAU,SAAS,QAAQ,QAAQ,CAAC,IAAI;AAGxD,UAAM,SAAsB;AAAA,MAC1B;AAAA,MACA,aAAa,YAAY,eAAe;AAAA,MACxC,cAAc,YAAY,eAAe,KAAK,YAAY;AAAA,MAC1D,wBACE,YAAY,0BAA0B,KACtC,YAAY;AAAA,MACd,eACE,YAAY,gBAAgB,KAAK,YAAY,iBAAiB;AAAA,MAChE,cAAc;AAAA,QACZ,YAAY,eAAe,KAAK,YAAY;AAAA,MAC9C;AAAA,MACA,OAAO,YAAY;AAAA,MACnB,SAAS,YAAY;AAAA,MACrB,OAAO,YAAY;AAAA,MACnB,SAAS,QAAQ,KAAK;AAAA,IACxB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,8BAA8B,QAAQ,KAAK,KAAK;AAC7D,WAAO;AAAA,EACT;AACF;AAKA,SAAS,mBAAmB,OAAsC;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,MAAM;AACjD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAQA,SAAS,8BACP,SACA,QACe;AACf,QAAM,SAAwB,CAAC;AAE/B,MAAI,CAAC,WAAW,OAAO,EAAG,QAAO;AAEjC,MAAI;AACF,UAAM,UAAU,YAAY,SAAS,EAAE,eAAe,KAAK,CAAC;AAE5D,eAAW,SAAS,SAAS;AAC3B,YAAM,YAAY,KAAK,SAAS,MAAM,IAAI;AAE1C,UAAI,MAAM,YAAY,GAAG;AAEvB,cAAM,cAAc,KAAK,WAAW,UAAU;AAC9C,YAAI,WAAW,WAAW,GAAG;AAC3B,gBAAM,QAAQ,eAAe,aAAa,MAAM;AAChD,cAAI,MAAO,QAAO,KAAK,KAAK;AAAA,QAC9B;AAAA,MACF,WAAW,MAAM,KAAK,SAAS,KAAK,KAAK,MAAM,SAAS,aAAa;AAEnE,cAAM,QAAQ,eAAe,WAAW,MAAM;AAC9C,YAAI,MAAO,QAAO,KAAK,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,mCAAmC,OAAO,KAAK,KAAK;AAAA,EACnE;AAEA,SAAO;AACT;AAKA,SAAS,uBAAsC;AAC7C,QAAM,OAAO,QAAQ;AACrB,QAAM,MAAM,OAAO;
|
|
4
|
+
"sourcesContent": ["/**\n * Skill Loader\n *\n * Progressive disclosure system for loading skills from plugins and standalone directories.\n * Implements Claude Code skill specification for plugin and standalone skills.\n *\n * Directory Priority (later overrides earlier):\n * 1. Plugin skills\n * 2. ~/.minto/skills/ (user directory)\n * 3. ./.minto/skills/ (project directory - highest priority)\n *\n * Supports two file patterns:\n * - skill-name/SKILL.md (subdirectory pattern)\n * - skill-name.md (flat file pattern)\n */\n\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs'\nimport { join, basename, dirname } from 'path'\nimport { homedir } from 'os'\nimport matter from 'gray-matter'\nimport { LoadedSkill, SkillConfig, SkillHookDefinition } from '../types/plugin'\nimport { loadAllPlugins } from './pluginLoader'\nimport { getCwd } from './state'\n\n/**\n * In-memory cache for loaded skills\n * Maps skill name to skill object\n */\nlet skillsCache: Map<string, LoadedSkill> | null = null\n\n/**\n * Cache for fully-loaded skill content\n * Maps skill name to full markdown content\n */\nconst contentCache = new Map<string, string>()\n\n/**\n * Parse a skill file and extract configuration\n * Supports Claude Code skill specification frontmatter fields\n */\nfunction parseSkillFile(\n filePath: string,\n source: 'user' | 'project',\n): LoadedSkill | null {\n try {\n if (!existsSync(filePath)) return null\n\n const fileContent = readFileSync(filePath, 'utf-8')\n const { data: frontmatter, content } = matter(fileContent)\n\n // Determine skill name from frontmatter or filename\n const fileName = basename(filePath, '.md')\n const name =\n frontmatter.name ||\n (fileName === 'SKILL' ? basename(dirname(filePath)) : fileName)\n\n // Parse hooks from frontmatter\n const hooks = parseSkillHooks(frontmatter.hooks)\n\n // Parse Claude Code spec fields\n const config: SkillConfig = {\n name,\n description: frontmatter.description || '',\n argumentHint: frontmatter['argument-hint'] || frontmatter.argumentHint,\n disableModelInvocation:\n frontmatter['disable-model-invocation'] ??\n frontmatter.disableModelInvocation,\n userInvocable:\n frontmatter['user-invocable'] ?? frontmatter.userInvocable ?? true,\n allowedTools: parseStringOrArray(\n frontmatter['allowed-tools'] || frontmatter.allowedTools,\n ),\n model: frontmatter.model,\n context: frontmatter.context,\n agent: frontmatter.agent,\n ...(hooks?.length && { hooks }),\n ...(frontmatter.license && { license: frontmatter.license }),\n ...(frontmatter.compatibility && {\n compatibility: frontmatter.compatibility,\n }),\n ...(frontmatter.metadata && { metadata: frontmatter.metadata }),\n content: content.trim(),\n }\n\n return {\n name,\n filePath,\n config,\n pluginName: 'standalone',\n source,\n }\n } catch (error) {\n console.warn(`Failed to parse skill file ${filePath}:`, error)\n return null\n }\n}\n\n/**\n * Parse skill-level hooks from frontmatter\n */\nfunction parseSkillHooks(hooks: unknown): SkillHookDefinition[] | undefined {\n if (!hooks) return undefined\n if (!Array.isArray(hooks)) return undefined\n\n const parsed: SkillHookDefinition[] = []\n for (const h of hooks) {\n if (!h || typeof h !== 'object') continue\n if (!h.event) continue\n parsed.push({\n event: h.event,\n ...(h.matcher && { matcher: h.matcher }),\n ...(h.type && { type: h.type }),\n ...(h.command && { command: h.command }),\n ...(h.prompt && { prompt: h.prompt }),\n ...(h.timeout && { timeout: Number(h.timeout) }),\n })\n }\n return parsed.length > 0 ? parsed : undefined\n}\n\n/**\n * Parse a value that could be a string, array, or comma-separated string\n */\nfunction parseStringOrArray(value: unknown): string[] | undefined {\n if (!value) return undefined\n if (Array.isArray(value)) return value.map(String)\n if (typeof value === 'string') {\n return value.split(',').map(s => s.trim())\n }\n return undefined\n}\n\n/**\n * Scan a standalone skills directory\n * Supports both patterns:\n * - skill-name/SKILL.md (subdirectory pattern)\n * - skill-name.md (flat file pattern)\n */\nfunction scanStandaloneSkillsDirectory(\n dirPath: string,\n source: 'user' | 'project',\n): LoadedSkill[] {\n const skills: LoadedSkill[] = []\n\n if (!existsSync(dirPath)) return skills\n\n try {\n const entries = readdirSync(dirPath, { withFileTypes: true })\n\n for (const entry of entries) {\n const entryPath = join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n // Pattern 1: skill-name/SKILL.md\n const skillMdPath = join(entryPath, 'SKILL.md')\n if (existsSync(skillMdPath)) {\n const skill = parseSkillFile(skillMdPath, source)\n if (skill) skills.push(skill)\n }\n } else if (entry.name.endsWith('.md') && entry.name !== 'README.md') {\n // Pattern 2: skill-name.md\n const skill = parseSkillFile(entryPath, source)\n if (skill) skills.push(skill)\n }\n }\n } catch (error) {\n console.warn(`Failed to scan skills directory ${dirPath}:`, error)\n }\n\n return skills\n}\n\n/**\n * Load all standalone skills from user and project directories\n */\nfunction loadStandaloneSkills(): LoadedSkill[] {\n const home = homedir()\n const cwd = getCwd()\n\n // .claude/ dirs are legacy fallbacks, .minto/ dirs take precedence\n const userClaudeDir = join(home, '.claude', 'skills')\n const userMintoDir = join(home, '.minto', 'skills')\n const projectClaudeDir = join(cwd, '.claude', 'skills')\n const projectMintoDir = join(cwd, '.minto', 'skills')\n\n const userClaudeSkills = scanStandaloneSkillsDirectory(userClaudeDir, 'user')\n const userMintoSkills = scanStandaloneSkillsDirectory(userMintoDir, 'user')\n const projectClaudeSkills = scanStandaloneSkillsDirectory(\n projectClaudeDir,\n 'project',\n )\n const projectMintoSkills = scanStandaloneSkillsDirectory(\n projectMintoDir,\n 'project',\n )\n\n return [\n ...userClaudeSkills,\n ...userMintoSkills,\n ...projectClaudeSkills,\n ...projectMintoSkills,\n ]\n}\n\n/**\n * Load all skills from plugins and standalone directories\n * Uses progressive disclosure - only loads metadata (name, description)\n * Content is lazy-loaded when needed\n *\n * Priority: plugin < user < project (later overrides earlier)\n */\nexport function loadAllSkills(): LoadedSkill[] {\n // Return cached skills if available\n if (skillsCache !== null) {\n return Array.from(skillsCache.values())\n }\n\n const pluginSkills: LoadedSkill[] = []\n const plugins = loadAllPlugins()\n\n // Collect all skills from all plugins\n for (const plugin of plugins) {\n if (!plugin.enabled) continue\n\n for (const skill of plugin.skills) {\n // Ensure plugin skills have source field\n pluginSkills.push({\n ...skill,\n source: 'plugin',\n })\n }\n }\n\n // Load standalone skills\n const standaloneSkills = loadStandaloneSkills()\n\n // Build cache map for fast lookups (later entries override earlier ones)\n skillsCache = new Map()\n\n // Add in priority order: plugin < standalone (user < project)\n // Plugin skills are namespaced as \"pluginName:skillName\"\n for (const skill of pluginSkills) {\n if (skill.pluginName && skill.pluginName !== 'standalone') {\n const namespacedKey = `${skill.pluginName}:${skill.name}`\n skillsCache.set(namespacedKey, skill)\n } else {\n skillsCache.set(skill.name, skill)\n }\n }\n // Standalone skills keep their original name (no namespace)\n for (const skill of standaloneSkills) {\n skillsCache.set(skill.name, skill)\n }\n\n return Array.from(skillsCache.values())\n}\n\n/**\n * Get a specific skill by name\n * Supports both namespaced (\"plugin:skill\") and bare (\"skill\") lookups.\n * Bare names match standalone skills first; if not found, searches plugin skills.\n */\nexport function getSkill(name: string): LoadedSkill | undefined {\n // Ensure cache is populated\n if (skillsCache === null) {\n loadAllSkills()\n }\n\n // Direct match (namespaced \"plugin:skill\" or standalone \"skill\")\n const direct = skillsCache?.get(name)\n if (direct) return direct\n\n // If no colon in name, try to find among plugin skills by bare component name\n if (!name.includes(':')) {\n for (const [key, skill] of skillsCache ?? []) {\n if (key.includes(':') && key.split(':').pop() === name) {\n return skill\n }\n }\n }\n\n return undefined\n}\n\n/**\n * Get the cache key for a skill (namespaced if from a plugin)\n */\nfunction getSkillCacheKey(skill: LoadedSkill): string {\n if (skill.pluginName && skill.pluginName !== 'standalone') {\n return `${skill.pluginName}:${skill.name}`\n }\n return skill.name\n}\n\n/**\n * Load the full content of a skill\n * Uses caching to avoid repeated file reads\n */\nexport async function loadSkillContent(skill: LoadedSkill): Promise<string> {\n const cacheKey = getSkillCacheKey(skill)\n\n // Check content cache first\n if (contentCache.has(cacheKey)) {\n return contentCache.get(cacheKey)!\n }\n\n // If content was already loaded in the skill object, use it\n if (skill.config.content) {\n contentCache.set(cacheKey, skill.config.content)\n return skill.config.content\n }\n\n // Otherwise, read from file\n try {\n const fileContent = readFileSync(skill.filePath, 'utf-8')\n const { content } = matter(fileContent)\n const trimmedContent = content.trim()\n\n // Cache the content\n contentCache.set(cacheKey, trimmedContent)\n\n // Update the skill object\n skill.config.content = trimmedContent\n\n return trimmedContent\n } catch (error) {\n throw new Error(\n `Failed to load skill content for \"${skill.name}\": ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Get all skills with their cache keys (may be namespaced)\n * Returns [key, skill] entries from the cache\n */\nexport function getAllSkillEntries(): [string, LoadedSkill][] {\n if (skillsCache === null) {\n loadAllSkills()\n }\n return Array.from(skillsCache?.entries() ?? [])\n}\n\n/**\n * Search skills by name or description\n * Returns skills matching the query (case-insensitive)\n */\nexport function searchSkills(query: string): LoadedSkill[] {\n const allSkills = loadAllSkills()\n const lowerQuery = query.toLowerCase()\n\n return allSkills.filter(\n skill =>\n skill.name.toLowerCase().includes(lowerQuery) ||\n skill.config.description.toLowerCase().includes(lowerQuery) ||\n skill.pluginName.toLowerCase().includes(lowerQuery),\n )\n}\n\n/**\n * Get skills from a specific plugin\n */\nexport function getSkillsByPlugin(pluginName: string): LoadedSkill[] {\n const allSkills = loadAllSkills()\n return allSkills.filter(skill => skill.pluginName === pluginName)\n}\n\n/**\n * Clear the skills cache (useful for hot-reloading)\n */\nexport function clearSkillsCache(): void {\n skillsCache = null\n contentCache.clear()\n}\n\n/**\n * Get count of available skills\n */\nexport function getSkillCount(): number {\n const skills = loadAllSkills()\n return skills.length\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function createDefaultState() {
|
|
2
|
+
return { phase: "thinking" };
|
|
3
|
+
}
|
|
4
|
+
const streamingStates = /* @__PURE__ */ new Map([
|
|
5
|
+
["__main__", createDefaultState()]
|
|
6
|
+
]);
|
|
7
|
+
const agentContextStack = ["__main__"];
|
|
8
|
+
function getCurrentAgentContext() {
|
|
9
|
+
return agentContextStack[agentContextStack.length - 1] ?? "__main__";
|
|
10
|
+
}
|
|
11
|
+
function pushAgentContext(agentId) {
|
|
12
|
+
agentContextStack.push(agentId);
|
|
13
|
+
if (!streamingStates.has(agentId)) {
|
|
14
|
+
streamingStates.set(agentId, createDefaultState());
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function popAgentContext() {
|
|
18
|
+
if (agentContextStack.length > 1) {
|
|
19
|
+
return agentContextStack.pop();
|
|
20
|
+
}
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
function setStreamingState(state, agentId) {
|
|
24
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
25
|
+
const current = streamingStates.get(targetId) ?? createDefaultState();
|
|
26
|
+
streamingStates.set(targetId, { ...current, ...state });
|
|
27
|
+
}
|
|
28
|
+
function resetStreamingState(agentId) {
|
|
29
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
30
|
+
streamingStates.set(targetId, createDefaultState());
|
|
31
|
+
}
|
|
32
|
+
function getStreamingState(agentId) {
|
|
33
|
+
const targetId = agentId ?? getCurrentAgentContext();
|
|
34
|
+
return streamingStates.get(targetId) ?? createDefaultState();
|
|
35
|
+
}
|
|
36
|
+
function getMainStreamingState() {
|
|
37
|
+
return streamingStates.get("__main__") ?? createDefaultState();
|
|
38
|
+
}
|
|
39
|
+
function cleanupAgentStreamingState(agentId) {
|
|
40
|
+
streamingStates.delete(agentId);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
cleanupAgentStreamingState,
|
|
44
|
+
getCurrentAgentContext,
|
|
45
|
+
getMainStreamingState,
|
|
46
|
+
getStreamingState,
|
|
47
|
+
popAgentContext,
|
|
48
|
+
pushAgentContext,
|
|
49
|
+
resetStreamingState,
|
|
50
|
+
setStreamingState
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=streamingState.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/streamingState.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Streaming State Management\n *\n * Extracted from Spinner.tsx to break the layer violation where\n * service-layer code (claude.ts, query.ts) imported from a UI component.\n *\n * Provides per-agent streaming state tracking with hierarchical context support.\n */\n\n// Streaming phases for better UX feedback\nexport type StreamingPhase =\n | 'thinking' // Initial thinking phase\n | 'generating' // Generating response content\n | 'tool_use' // Executing a tool\n | 'waiting' // Waiting for API response\n | 'deep_thinking' // Extended thinking mode (Claude thinking blocks)\n | 'retrying' // API retry in progress\n | 'permission' // Waiting for user permission\n | 'compacting' // Compacting conversation context\n | 'concurrent' // Running concurrent tasks\n\n// Streaming state type definition\nexport interface StreamingStateData {\n phase: StreamingPhase\n toolName?: string\n tokenCount?: number\n chunkCount?: number\n // New fields for enhanced feedback\n retryCount?: number\n maxRetries?: number\n errorName?: string\n concurrentCount?: number\n thinkingMaxTokens?: number\n // Token usage from API (real-time streaming)\n inputTokens?: number\n outputTokens?: number\n // Character counts for approximate token estimation\n sentChars?: number // Characters sent to API (input)\n receivedChars?: number // Characters received from API (output)\n // Thinking timing\n thinkingStartTime?: number\n thinkingDurationMs?: number\n}\n\n// Default state factory\nfunction createDefaultState(): StreamingStateData {\n return { phase: 'thinking' }\n}\n\n// Store streaming state per agent (agentId -> state)\n// '__main__' is used for the main/root agent\nconst streamingStates: Map<string, StreamingStateData> = new Map([\n ['__main__', createDefaultState()],\n])\n\n// Current active agent context (stack to support nesting)\nconst agentContextStack: string[] = ['__main__']\n\n/**\n * Get the current active agent ID\n */\nexport function getCurrentAgentContext(): string {\n return agentContextStack[agentContextStack.length - 1] ?? '__main__'\n}\n\n/**\n * Push a new agent context (when entering a subagent)\n */\nexport function pushAgentContext(agentId: string): void {\n agentContextStack.push(agentId)\n if (!streamingStates.has(agentId)) {\n streamingStates.set(agentId, createDefaultState())\n }\n}\n\n/**\n * Pop the current agent context (when exiting a subagent)\n */\nexport function popAgentContext(): string | undefined {\n if (agentContextStack.length > 1) {\n return agentContextStack.pop()\n }\n return undefined\n}\n\n/**\n * Set streaming state for a specific agent (or current context if not specified)\n */\nexport function setStreamingState(\n state: Partial<StreamingStateData>,\n agentId?: string,\n): void {\n const targetId = agentId ?? getCurrentAgentContext()\n const current = streamingStates.get(targetId) ?? createDefaultState()\n streamingStates.set(targetId, { ...current, ...state })\n}\n\n/**\n * Reset streaming state for a specific agent (or current context if not specified)\n */\nexport function resetStreamingState(agentId?: string): void {\n const targetId = agentId ?? getCurrentAgentContext()\n streamingStates.set(targetId, createDefaultState())\n}\n\n/**\n * Get streaming state for a specific agent (or current context if not specified)\n */\nexport function getStreamingState(agentId?: string): StreamingStateData {\n const targetId = agentId ?? getCurrentAgentContext()\n return streamingStates.get(targetId) ?? createDefaultState()\n}\n\n/**\n * Get streaming state for the main/root agent (used by main Spinner)\n */\nexport function getMainStreamingState(): StreamingStateData {\n return streamingStates.get('__main__') ?? createDefaultState()\n}\n\n/**\n * Clean up streaming state for a completed agent\n */\nexport function cleanupAgentStreamingState(agentId: string): void {\n streamingStates.delete(agentId)\n}\n"],
|
|
5
|
+
"mappings": "AA6CA,SAAS,qBAAyC;AAChD,SAAO,EAAE,OAAO,WAAW;AAC7B;AAIA,MAAM,kBAAmD,oBAAI,IAAI;AAAA,EAC/D,CAAC,YAAY,mBAAmB,CAAC;AACnC,CAAC;AAGD,MAAM,oBAA8B,CAAC,UAAU;AAKxC,SAAS,yBAAiC;AAC/C,SAAO,kBAAkB,kBAAkB,SAAS,CAAC,KAAK;AAC5D;AAKO,SAAS,iBAAiB,SAAuB;AACtD,oBAAkB,KAAK,OAAO;AAC9B,MAAI,CAAC,gBAAgB,IAAI,OAAO,GAAG;AACjC,oBAAgB,IAAI,SAAS,mBAAmB,CAAC;AAAA,EACnD;AACF;AAKO,SAAS,kBAAsC;AACpD,MAAI,kBAAkB,SAAS,GAAG;AAChC,WAAO,kBAAkB,IAAI;AAAA,EAC/B;AACA,SAAO;AACT;AAKO,SAAS,kBACd,OACA,SACM;AACN,QAAM,WAAW,WAAW,uBAAuB;AACnD,QAAM,UAAU,gBAAgB,IAAI,QAAQ,KAAK,mBAAmB;AACpE,kBAAgB,IAAI,UAAU,EAAE,GAAG,SAAS,GAAG,MAAM,CAAC;AACxD;AAKO,SAAS,oBAAoB,SAAwB;AAC1D,QAAM,WAAW,WAAW,uBAAuB;AACnD,kBAAgB,IAAI,UAAU,mBAAmB,CAAC;AACpD;AAKO,SAAS,kBAAkB,SAAsC;AACtE,QAAM,WAAW,WAAW,uBAAuB;AACnD,SAAO,gBAAgB,IAAI,QAAQ,KAAK,mBAAmB;AAC7D;AAKO,SAAS,wBAA4C;AAC1D,SAAO,gBAAgB,IAAI,UAAU,KAAK,mBAAmB;AAC/D;AAKO,SAAS,2BAA2B,SAAuB;AAChE,kBAAgB,OAAO,OAAO;AAChC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -50,10 +50,7 @@ async function substituteVariables(content, args, context = {}) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
} else {
|
|
53
|
-
result = result.replace(
|
|
54
|
-
/!\`([^`]+)\`/g,
|
|
55
|
-
"(dynamic commands disabled)"
|
|
56
|
-
);
|
|
53
|
+
result = result.replace(/!\`([^`]+)\`/g, "(dynamic commands disabled)");
|
|
57
54
|
}
|
|
58
55
|
return result;
|
|
59
56
|
}
|
|
@@ -86,7 +83,9 @@ function extractSubstitutionPatterns(content) {
|
|
|
86
83
|
for (const match of cmdMatches) {
|
|
87
84
|
patterns.commands.push(match[1]);
|
|
88
85
|
}
|
|
89
|
-
patterns.indexedArgs = [...new Set(patterns.indexedArgs)].sort(
|
|
86
|
+
patterns.indexedArgs = [...new Set(patterns.indexedArgs)].sort(
|
|
87
|
+
(a, b) => a - b
|
|
88
|
+
);
|
|
90
89
|
patterns.variables = [...new Set(patterns.variables)];
|
|
91
90
|
return patterns;
|
|
92
91
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/stringSubstitution.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * String Substitution Engine\n *\n * Implements Claude Code skill specification for variable substitution.\n * Supports the following patterns:\n *\n * - $ARGUMENTS - All arguments as a single string\n * - $ARGUMENTS[N] - Indexed argument (0-based)\n * - $N - Shorthand for $ARGUMENTS[N]\n * - ${VARIABLE_NAME} - Environment variable or context variable\n * - !`command` - Dynamic command execution (with security controls)\n */\n\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\n\nconst execAsync = promisify(exec)\n\n/**\n * Context for string substitution\n */\nexport interface SubstitutionContext {\n sessionId?: string\n cwd?: string\n env?: Record<string, string>\n /**\n * Allow dynamic command execution (!`command`)\n * Default: false (security consideration)\n */\n allowDynamicCommands?: boolean\n /**\n * Timeout for dynamic command execution in milliseconds\n * Default: 10000 (10 seconds)\n */\n commandTimeout?: number\n}\n\n/**\n * Default substitution context\n */\nconst DEFAULT_CONTEXT: Required<SubstitutionContext> = {\n sessionId: '',\n cwd: process.cwd(),\n env: {},\n allowDynamicCommands: false,\n commandTimeout: 10000,\n}\n\n/**\n * Substitute variables in a string\n *\n * @param content - The content to substitute variables in\n * @param args - Arguments string (space-separated)\n * @param context - Substitution context\n * @returns The content with variables substituted\n */\nexport async function substituteVariables(\n content: string,\n args: string,\n context: SubstitutionContext = {},\n): Promise<string> {\n const ctx = { ...DEFAULT_CONTEXT, ...context }\n let result = content\n const argValues = args.trim() ? args.trim().split(/\\s+/) : []\n\n // 1. $ARGUMENTS - All arguments as a single string\n // Use negative lookahead to avoid matching $ARGUMENTS[N]\n result = result.replace(/\\$ARGUMENTS(?!\\[)/g, args)\n\n // 2. $ARGUMENTS[N] - Indexed argument (0-based)\n result = result.replace(/\\$ARGUMENTS\\[(\\d+)\\]/g, (_, indexStr) => {\n const index = parseInt(indexStr, 10)\n return argValues[index] ?? ''\n })\n\n // 3. $N - Shorthand for indexed argument (0-based)\n // Use negative lookahead to avoid matching multi-digit or $ARGUMENTS\n result = result.replace(/\\$(\\d+)(?!\\d)/g, (_, indexStr) => {\n const index = parseInt(indexStr, 10)\n return argValues[index] ?? ''\n })\n\n // 4. ${VARIABLE_NAME} - Context and environment variables\n result = result.replace(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/gi, (_, varName) => {\n // Built-in context variables (Claude Code spec)\n switch (varName.toUpperCase()) {\n case 'CLAUDE_SESSION_ID':\n case 'SESSION_ID':\n return ctx.sessionId || ''\n case 'CWD':\n case 'PWD':\n return ctx.cwd\n default:\n // Check custom context env first, then process.env\n return ctx.env[varName] ?? process.env[varName] ?? ''\n }\n })\n\n // 5. !`command` - Dynamic command execution\n // Only execute if explicitly allowed (security consideration)\n if (ctx.allowDynamicCommands) {\n const commandPattern = /!\\`([^`]+)\\`/g\n const matches = [...result.matchAll(commandPattern)]\n\n for (const match of matches) {\n const command = match[1]\n try {\n const { stdout } = await execAsync(command, {\n timeout: ctx.commandTimeout,\n cwd: ctx.cwd,\n })\n result = result.replace(match[0], stdout.trim())\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n result = result.replace(match[0], `(error: ${errorMessage})`)\n }\n }\n } else {\n // Replace !`command` with placeholder when not allowed\n result = result.replace(
|
|
5
|
-
"mappings": "AAaA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,MAAM,YAAY,UAAU,IAAI;AAwBhC,MAAM,kBAAiD;AAAA,EACrD,WAAW;AAAA,EACX,KAAK,QAAQ,IAAI;AAAA,EACjB,KAAK,CAAC;AAAA,EACN,sBAAsB;AAAA,EACtB,gBAAgB;AAClB;AAUA,eAAsB,oBACpB,SACA,MACA,UAA+B,CAAC,GACf;AACjB,QAAM,MAAM,EAAE,GAAG,iBAAiB,GAAG,QAAQ;AAC7C,MAAI,SAAS;AACb,QAAM,YAAY,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAI5D,WAAS,OAAO,QAAQ,sBAAsB,IAAI;AAGlD,WAAS,OAAO,QAAQ,yBAAyB,CAAC,GAAG,aAAa;AAChE,UAAM,QAAQ,SAAS,UAAU,EAAE;AACnC,WAAO,UAAU,KAAK,KAAK;AAAA,EAC7B,CAAC;AAID,WAAS,OAAO,QAAQ,kBAAkB,CAAC,GAAG,aAAa;AACzD,UAAM,QAAQ,SAAS,UAAU,EAAE;AACnC,WAAO,UAAU,KAAK,KAAK;AAAA,EAC7B,CAAC;AAGD,WAAS,OAAO,QAAQ,8BAA8B,CAAC,GAAG,YAAY;AAEpE,YAAQ,QAAQ,YAAY,GAAG;AAAA,MAC7B,KAAK;AAAA,MACL,KAAK;AACH,eAAO,IAAI,aAAa;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AACH,eAAO,IAAI;AAAA,MACb;AAEE,eAAO,IAAI,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK;AAAA,IACvD;AAAA,EACF,CAAC;AAID,MAAI,IAAI,sBAAsB;AAC5B,UAAM,iBAAiB;AACvB,UAAM,UAAU,CAAC,GAAG,OAAO,SAAS,cAAc,CAAC;AAEnD,eAAW,SAAS,SAAS;AAC3B,YAAM,UAAU,MAAM,CAAC;AACvB,UAAI;AACF,cAAM,EAAE,OAAO,IAAI,MAAM,UAAU,SAAS;AAAA,UAC1C,SAAS,IAAI;AAAA,UACb,KAAK,IAAI;AAAA,QACX,CAAC;AACD,iBAAS,OAAO,QAAQ,MAAM,CAAC,GAAG,OAAO,KAAK,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,cAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACvD,iBAAS,OAAO,QAAQ,MAAM,CAAC,GAAG,WAAW,YAAY,GAAG;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,OAAO;AAEL,aAAS,OAAO
|
|
4
|
+
"sourcesContent": ["/**\n * String Substitution Engine\n *\n * Implements Claude Code skill specification for variable substitution.\n * Supports the following patterns:\n *\n * - $ARGUMENTS - All arguments as a single string\n * - $ARGUMENTS[N] - Indexed argument (0-based)\n * - $N - Shorthand for $ARGUMENTS[N]\n * - ${VARIABLE_NAME} - Environment variable or context variable\n * - !`command` - Dynamic command execution (with security controls)\n */\n\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\n\nconst execAsync = promisify(exec)\n\n/**\n * Context for string substitution\n */\nexport interface SubstitutionContext {\n sessionId?: string\n cwd?: string\n env?: Record<string, string>\n /**\n * Allow dynamic command execution (!`command`)\n * Default: false (security consideration)\n */\n allowDynamicCommands?: boolean\n /**\n * Timeout for dynamic command execution in milliseconds\n * Default: 10000 (10 seconds)\n */\n commandTimeout?: number\n}\n\n/**\n * Default substitution context\n */\nconst DEFAULT_CONTEXT: Required<SubstitutionContext> = {\n sessionId: '',\n cwd: process.cwd(),\n env: {},\n allowDynamicCommands: false,\n commandTimeout: 10000,\n}\n\n/**\n * Substitute variables in a string\n *\n * @param content - The content to substitute variables in\n * @param args - Arguments string (space-separated)\n * @param context - Substitution context\n * @returns The content with variables substituted\n */\nexport async function substituteVariables(\n content: string,\n args: string,\n context: SubstitutionContext = {},\n): Promise<string> {\n const ctx = { ...DEFAULT_CONTEXT, ...context }\n let result = content\n const argValues = args.trim() ? args.trim().split(/\\s+/) : []\n\n // 1. $ARGUMENTS - All arguments as a single string\n // Use negative lookahead to avoid matching $ARGUMENTS[N]\n result = result.replace(/\\$ARGUMENTS(?!\\[)/g, args)\n\n // 2. $ARGUMENTS[N] - Indexed argument (0-based)\n result = result.replace(/\\$ARGUMENTS\\[(\\d+)\\]/g, (_, indexStr) => {\n const index = parseInt(indexStr, 10)\n return argValues[index] ?? ''\n })\n\n // 3. $N - Shorthand for indexed argument (0-based)\n // Use negative lookahead to avoid matching multi-digit or $ARGUMENTS\n result = result.replace(/\\$(\\d+)(?!\\d)/g, (_, indexStr) => {\n const index = parseInt(indexStr, 10)\n return argValues[index] ?? ''\n })\n\n // 4. ${VARIABLE_NAME} - Context and environment variables\n result = result.replace(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/gi, (_, varName) => {\n // Built-in context variables (Claude Code spec)\n switch (varName.toUpperCase()) {\n case 'CLAUDE_SESSION_ID':\n case 'SESSION_ID':\n return ctx.sessionId || ''\n case 'CWD':\n case 'PWD':\n return ctx.cwd\n default:\n // Check custom context env first, then process.env\n return ctx.env[varName] ?? process.env[varName] ?? ''\n }\n })\n\n // 5. !`command` - Dynamic command execution\n // Only execute if explicitly allowed (security consideration)\n if (ctx.allowDynamicCommands) {\n const commandPattern = /!\\`([^`]+)\\`/g\n const matches = [...result.matchAll(commandPattern)]\n\n for (const match of matches) {\n const command = match[1]\n try {\n const { stdout } = await execAsync(command, {\n timeout: ctx.commandTimeout,\n cwd: ctx.cwd,\n })\n result = result.replace(match[0], stdout.trim())\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n result = result.replace(match[0], `(error: ${errorMessage})`)\n }\n }\n } else {\n // Replace !`command` with placeholder when not allowed\n result = result.replace(/!\\`([^`]+)\\`/g, '(dynamic commands disabled)')\n }\n\n return result\n}\n\n/**\n * Check if a string contains substitution patterns\n * Useful for optimization - skip substitution if no patterns present\n */\nexport function hasSubstitutionPatterns(content: string): boolean {\n return /\\$(?:ARGUMENTS|\\d+|\\{[A-Z_][A-Z0-9_]*\\})|!\\`/.test(content)\n}\n\n/**\n * Extract all substitution patterns from a string\n * Useful for validation and documentation\n */\nexport function extractSubstitutionPatterns(content: string): {\n arguments: string[]\n indexedArgs: number[]\n variables: string[]\n commands: string[]\n} {\n const patterns = {\n arguments: [] as string[],\n indexedArgs: [] as number[],\n variables: [] as string[],\n commands: [] as string[],\n }\n\n // $ARGUMENTS\n if (/\\$ARGUMENTS(?!\\[)/.test(content)) {\n patterns.arguments.push('$ARGUMENTS')\n }\n\n // $ARGUMENTS[N]\n const argIndexMatches = content.matchAll(/\\$ARGUMENTS\\[(\\d+)\\]/g)\n for (const match of argIndexMatches) {\n patterns.indexedArgs.push(parseInt(match[1], 10))\n }\n\n // $N\n const shortIndexMatches = content.matchAll(/\\$(\\d+)(?!\\d)/g)\n for (const match of shortIndexMatches) {\n patterns.indexedArgs.push(parseInt(match[1], 10))\n }\n\n // ${VARIABLE}\n const varMatches = content.matchAll(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/gi)\n for (const match of varMatches) {\n patterns.variables.push(match[1])\n }\n\n // !`command`\n const cmdMatches = content.matchAll(/!\\`([^`]+)\\`/g)\n for (const match of cmdMatches) {\n patterns.commands.push(match[1])\n }\n\n // Deduplicate indexed args\n patterns.indexedArgs = [...new Set(patterns.indexedArgs)].sort(\n (a, b) => a - b,\n )\n patterns.variables = [...new Set(patterns.variables)]\n\n return patterns\n}\n\n/**\n * Validate arguments against expected patterns\n * Returns error message if validation fails, null if valid\n */\nexport function validateArguments(\n args: string,\n patterns: ReturnType<typeof extractSubstitutionPatterns>,\n): string | null {\n const argValues = args.trim() ? args.trim().split(/\\s+/) : []\n const maxIndex = Math.max(...patterns.indexedArgs, -1)\n\n if (maxIndex >= 0 && argValues.length <= maxIndex) {\n return `Expected at least ${maxIndex + 1} argument(s), got ${argValues.length}`\n }\n\n return null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/style.js
CHANGED
|
@@ -9,11 +9,14 @@ const getCodeStyle = memoize(() => {
|
|
|
9
9
|
let currentDir = getCwd();
|
|
10
10
|
while (currentDir !== parse(currentDir).root) {
|
|
11
11
|
const stylePath = join(currentDir, PROJECT_FILE);
|
|
12
|
-
|
|
12
|
+
const agentsStylePath = join(currentDir, "AGENTS.md");
|
|
13
|
+
const claudeStylePath = join(currentDir, "CLAUDE.md");
|
|
14
|
+
const foundPath = existsSync(stylePath) ? stylePath : existsSync(agentsStylePath) ? agentsStylePath : existsSync(claudeStylePath) ? claudeStylePath : null;
|
|
15
|
+
if (foundPath) {
|
|
13
16
|
styles.push(
|
|
14
|
-
`Contents of ${
|
|
17
|
+
`Contents of ${foundPath}:
|
|
15
18
|
|
|
16
|
-
${readFileSync(
|
|
19
|
+
${readFileSync(foundPath, "utf-8")}`
|
|
17
20
|
);
|
|
18
21
|
}
|
|
19
22
|
currentDir = dirname(currentDir);
|
package/dist/utils/style.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/style.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, readFileSync } from 'fs'\nimport { join, parse, dirname } from 'path'\nimport { memoize } from 'lodash-es'\nimport { getCwd } from './state'\nimport { PROJECT_FILE } from '@constants/product'\n\nconst STYLE_PROMPT =\n 'The codebase follows strict style guidelines shown below. All code changes must strictly adhere to these guidelines to maintain consistency and quality.'\n\nexport const getCodeStyle = memoize((): string => {\n const styles: string[] = []\n let currentDir = getCwd()\n\n while (currentDir !== parse(currentDir).root) {\n const stylePath = join(currentDir, PROJECT_FILE)\n
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,MAAM,OAAO,eAAe;AACrC,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAE7B,MAAM,eACJ;AAEK,MAAM,eAAe,QAAQ,MAAc;AAChD,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa,OAAO;AAExB,SAAO,eAAe,MAAM,UAAU,EAAE,MAAM;AAC5C,UAAM,YAAY,KAAK,YAAY,YAAY;AAC/C,
|
|
4
|
+
"sourcesContent": ["import { existsSync, readFileSync } from 'fs'\nimport { join, parse, dirname } from 'path'\nimport { memoize } from 'lodash-es'\nimport { getCwd } from './state'\nimport { PROJECT_FILE } from '@constants/product'\n\nconst STYLE_PROMPT =\n 'The codebase follows strict style guidelines shown below. All code changes must strictly adhere to these guidelines to maintain consistency and quality.'\n\nexport const getCodeStyle = memoize((): string => {\n const styles: string[] = []\n let currentDir = getCwd()\n\n while (currentDir !== parse(currentDir).root) {\n const stylePath = join(currentDir, PROJECT_FILE)\n const agentsStylePath = join(currentDir, 'AGENTS.md')\n const claudeStylePath = join(currentDir, 'CLAUDE.md')\n const foundPath = existsSync(stylePath)\n ? stylePath\n : existsSync(agentsStylePath)\n ? agentsStylePath\n : existsSync(claudeStylePath)\n ? claudeStylePath\n : null\n if (foundPath) {\n styles.push(\n `Contents of ${foundPath}:\\n\\n${readFileSync(foundPath, 'utf-8')}`,\n )\n }\n currentDir = dirname(currentDir)\n }\n\n if (styles.length === 0) {\n return ''\n }\n\n return `${STYLE_PROMPT}\\n\\n${styles.reverse().join('\\n\\n')}`\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,MAAM,OAAO,eAAe;AACrC,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAE7B,MAAM,eACJ;AAEK,MAAM,eAAe,QAAQ,MAAc;AAChD,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa,OAAO;AAExB,SAAO,eAAe,MAAM,UAAU,EAAE,MAAM;AAC5C,UAAM,YAAY,KAAK,YAAY,YAAY;AAC/C,UAAM,kBAAkB,KAAK,YAAY,WAAW;AACpD,UAAM,kBAAkB,KAAK,YAAY,WAAW;AACpD,UAAM,YAAY,WAAW,SAAS,IAClC,YACA,WAAW,eAAe,IACxB,kBACA,WAAW,eAAe,IACxB,kBACA;AACR,QAAI,WAAW;AACb,aAAO;AAAA,QACL,eAAe,SAAS;AAAA;AAAA,EAAQ,aAAa,WAAW,OAAO,CAAC;AAAA,MAClE;AAAA,IACF;AACA,iBAAa,QAAQ,UAAU;AAAA,EACjC;AAEA,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,YAAY;AAAA;AAAA,EAAO,OAAO,QAAQ,EAAE,KAAK,MAAM,CAAC;AAC5D,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/teamConfig.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from "./config.js";
|
|
6
6
|
import { debug as debugLogger } from "./debugLogger.js";
|
|
7
7
|
import { safeParseJSON } from "./json.js";
|
|
8
|
+
import { ensureProxyBypass, hasSystemProxy } from "./envConfig.js";
|
|
8
9
|
function interpolateEnvVars(value) {
|
|
9
10
|
return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
10
11
|
const envValue = process.env[varName.trim()];
|
|
@@ -58,18 +59,21 @@ function convertTeamMcpConfig(teamConfig) {
|
|
|
58
59
|
enabled: teamConfig.enabled ?? true
|
|
59
60
|
};
|
|
60
61
|
}
|
|
62
|
+
const env = teamConfig.env ? ensureProxyBypass(interpolateEnvVarsInObject(teamConfig.env)) : hasSystemProxy() ? { no_proxy: "*", NO_PROXY: "*" } : void 0;
|
|
61
63
|
return {
|
|
62
64
|
type: "stdio",
|
|
63
65
|
command: interpolateEnvVars(teamConfig.command || ""),
|
|
64
66
|
args: (teamConfig.args || []).map((arg) => interpolateEnvVars(arg)),
|
|
65
|
-
env
|
|
67
|
+
env,
|
|
66
68
|
enabled: teamConfig.enabled ?? true
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
async function fetchTeamConfig(url) {
|
|
70
72
|
debugLogger.state("TEAM_CONFIG_FETCH_START", { url });
|
|
71
73
|
try {
|
|
72
|
-
const response = await fetch(url
|
|
74
|
+
const response = await fetch(url, {
|
|
75
|
+
signal: AbortSignal.timeout(3e4)
|
|
76
|
+
});
|
|
73
77
|
if (!response.ok) {
|
|
74
78
|
throw new Error(
|
|
75
79
|
`Failed to fetch config: ${response.status} ${response.statusText}`
|
|
@@ -288,16 +292,19 @@ async function installPlugins(pluginNames, targetDir) {
|
|
|
288
292
|
const { join } = await import("path");
|
|
289
293
|
const { homedir } = await import("os");
|
|
290
294
|
const installDir = targetDir || join(homedir(), ".minto", "plugins");
|
|
291
|
-
for (const
|
|
295
|
+
for (const pluginSpec of pluginNames) {
|
|
296
|
+
const atIndex = pluginSpec.indexOf("@");
|
|
297
|
+
const pluginName = atIndex !== -1 ? pluginSpec.slice(0, atIndex) : pluginSpec;
|
|
298
|
+
const marketplaceName = atIndex !== -1 ? pluginSpec.slice(atIndex + 1) : void 0;
|
|
292
299
|
try {
|
|
293
300
|
debugLogger.state("TEAM_CONFIG_INSTALL_PLUGIN", {
|
|
294
301
|
pluginName,
|
|
302
|
+
marketplace: marketplaceName,
|
|
295
303
|
targetDir: installDir
|
|
296
304
|
});
|
|
297
305
|
await installPluginFromMarketplace(
|
|
298
306
|
pluginName,
|
|
299
|
-
|
|
300
|
-
// Search all marketplaces
|
|
307
|
+
marketplaceName,
|
|
301
308
|
join(installDir, pluginName)
|
|
302
309
|
);
|
|
303
310
|
installed++;
|
|
@@ -314,21 +321,23 @@ async function installPlugins(pluginNames, targetDir) {
|
|
|
314
321
|
}
|
|
315
322
|
return { installed, failed, errors };
|
|
316
323
|
}
|
|
317
|
-
async function installRemoteAgents(agentUrls) {
|
|
324
|
+
async function installRemoteAgents(agentUrls, targetDir) {
|
|
318
325
|
let installed = 0;
|
|
319
326
|
let failed = 0;
|
|
320
327
|
const errors = [];
|
|
321
328
|
const { join } = await import("path");
|
|
322
329
|
const { homedir } = await import("os");
|
|
323
330
|
const { writeFileSync, mkdirSync, existsSync: existsSync2 } = await import("fs");
|
|
324
|
-
const agentsDir = join(homedir(), ".minto", "agents");
|
|
331
|
+
const agentsDir = targetDir || join(homedir(), ".minto", "agents");
|
|
325
332
|
if (!existsSync2(agentsDir)) {
|
|
326
333
|
mkdirSync(agentsDir, { recursive: true });
|
|
327
334
|
}
|
|
328
335
|
for (const url of agentUrls) {
|
|
329
336
|
try {
|
|
330
337
|
debugLogger.state("TEAM_CONFIG_DOWNLOAD_AGENT", { url });
|
|
331
|
-
const response = await fetch(url
|
|
338
|
+
const response = await fetch(url, {
|
|
339
|
+
signal: AbortSignal.timeout(3e4)
|
|
340
|
+
});
|
|
332
341
|
if (!response.ok) {
|
|
333
342
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
334
343
|
}
|
|
@@ -353,14 +362,14 @@ async function installRemoteAgents(agentUrls) {
|
|
|
353
362
|
}
|
|
354
363
|
return { installed, failed, errors };
|
|
355
364
|
}
|
|
356
|
-
async function installInlineAgents(agents) {
|
|
365
|
+
async function installInlineAgents(agents, targetDir) {
|
|
357
366
|
let installed = 0;
|
|
358
367
|
let failed = 0;
|
|
359
368
|
const errors = [];
|
|
360
369
|
const { join } = await import("path");
|
|
361
370
|
const { homedir } = await import("os");
|
|
362
371
|
const { writeFileSync, mkdirSync, existsSync: existsSync2 } = await import("fs");
|
|
363
|
-
const agentsDir = join(homedir(), ".minto", "agents");
|
|
372
|
+
const agentsDir = targetDir || join(homedir(), ".minto", "agents");
|
|
364
373
|
if (!existsSync2(agentsDir)) {
|
|
365
374
|
mkdirSync(agentsDir, { recursive: true });
|
|
366
375
|
}
|
|
@@ -400,17 +409,17 @@ ${agent.systemPrompt}
|
|
|
400
409
|
}
|
|
401
410
|
return { installed, failed, errors };
|
|
402
411
|
}
|
|
403
|
-
async function installTeamHooks(hooks) {
|
|
404
|
-
const { join } = await import("path");
|
|
412
|
+
async function installTeamHooks(hooks, targetPath) {
|
|
413
|
+
const { join, dirname } = await import("path");
|
|
405
414
|
const { homedir } = await import("os");
|
|
406
415
|
const { writeFileSync, mkdirSync, existsSync: existsSync2, readFileSync: readFileSync2 } = await import("fs");
|
|
407
416
|
try {
|
|
408
417
|
debugLogger.state("TEAM_CONFIG_INSTALL_HOOKS", {});
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
418
|
+
const hooksPath = targetPath || join(homedir(), ".minto", "hooks.json");
|
|
419
|
+
const hooksDir = dirname(hooksPath);
|
|
420
|
+
if (!existsSync2(hooksDir)) {
|
|
421
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
412
422
|
}
|
|
413
|
-
const hooksPath = join(mintoDir, "hooks.json");
|
|
414
423
|
const hooksConfig = {
|
|
415
424
|
description: "Team-configured hooks",
|
|
416
425
|
hooks: {}
|
|
@@ -461,6 +470,141 @@ async function installTeamHooks(hooks) {
|
|
|
461
470
|
return { installed: false, error: errorMsg };
|
|
462
471
|
}
|
|
463
472
|
}
|
|
473
|
+
async function installInlineSkills(skills, targetDir) {
|
|
474
|
+
let installed = 0;
|
|
475
|
+
let failed = 0;
|
|
476
|
+
const errors = [];
|
|
477
|
+
const { join } = await import("path");
|
|
478
|
+
const { homedir } = await import("os");
|
|
479
|
+
const { writeFileSync, mkdirSync, existsSync: existsSync2 } = await import("fs");
|
|
480
|
+
const skillsDir = targetDir || join(homedir(), ".minto", "skills");
|
|
481
|
+
if (!existsSync2(skillsDir)) {
|
|
482
|
+
mkdirSync(skillsDir, { recursive: true });
|
|
483
|
+
}
|
|
484
|
+
for (const skill of skills) {
|
|
485
|
+
try {
|
|
486
|
+
debugLogger.state("TEAM_CONFIG_INSTALL_SKILL", { name: skill.name });
|
|
487
|
+
const frontmatterLines = [
|
|
488
|
+
`name: ${skill.name}`,
|
|
489
|
+
`description: "${skill.description.replace(/"/g, '\\"')}"`
|
|
490
|
+
];
|
|
491
|
+
if (skill.argumentHint) {
|
|
492
|
+
frontmatterLines.push(`argument-hint: "${skill.argumentHint}"`);
|
|
493
|
+
}
|
|
494
|
+
if (skill.disableModelInvocation !== void 0) {
|
|
495
|
+
frontmatterLines.push(
|
|
496
|
+
`disable-model-invocation: ${skill.disableModelInvocation}`
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
if (skill.userInvocable !== void 0) {
|
|
500
|
+
frontmatterLines.push(`user-invocable: ${skill.userInvocable}`);
|
|
501
|
+
}
|
|
502
|
+
if (skill.allowedTools && skill.allowedTools.length > 0) {
|
|
503
|
+
frontmatterLines.push(
|
|
504
|
+
`allowed-tools: ${JSON.stringify(skill.allowedTools)}`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
if (skill.model) {
|
|
508
|
+
frontmatterLines.push(`model: ${skill.model}`);
|
|
509
|
+
}
|
|
510
|
+
if (skill.context) {
|
|
511
|
+
frontmatterLines.push(`context: "${skill.context}"`);
|
|
512
|
+
}
|
|
513
|
+
if (skill.agent) {
|
|
514
|
+
frontmatterLines.push(`agent: "${skill.agent}"`);
|
|
515
|
+
}
|
|
516
|
+
const content = `---
|
|
517
|
+
${frontmatterLines.join("\n")}
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
${skill.content}
|
|
521
|
+
`;
|
|
522
|
+
const filename = `${skill.name}.md`;
|
|
523
|
+
const targetPath = join(skillsDir, filename);
|
|
524
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
525
|
+
installed++;
|
|
526
|
+
debugLogger.state("TEAM_CONFIG_INSTALL_SKILL_SUCCESS", {
|
|
527
|
+
name: skill.name,
|
|
528
|
+
targetPath
|
|
529
|
+
});
|
|
530
|
+
} catch (error) {
|
|
531
|
+
failed++;
|
|
532
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
533
|
+
errors.push(`${skill.name}: ${errorMsg}`);
|
|
534
|
+
debugLogger.error("TEAM_CONFIG_INSTALL_SKILL_ERROR", {
|
|
535
|
+
name: skill.name,
|
|
536
|
+
error: errorMsg
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return { installed, failed, errors };
|
|
541
|
+
}
|
|
542
|
+
async function installInlineCommands(commands, targetDir) {
|
|
543
|
+
let installed = 0;
|
|
544
|
+
let failed = 0;
|
|
545
|
+
const errors = [];
|
|
546
|
+
const { join } = await import("path");
|
|
547
|
+
const { homedir } = await import("os");
|
|
548
|
+
const { writeFileSync, mkdirSync, existsSync: existsSync2 } = await import("fs");
|
|
549
|
+
const commandsDir = targetDir || join(homedir(), ".minto", "commands");
|
|
550
|
+
if (!existsSync2(commandsDir)) {
|
|
551
|
+
mkdirSync(commandsDir, { recursive: true });
|
|
552
|
+
}
|
|
553
|
+
for (const cmd of commands) {
|
|
554
|
+
try {
|
|
555
|
+
debugLogger.state("TEAM_CONFIG_INSTALL_COMMAND", { name: cmd.name });
|
|
556
|
+
const frontmatterLines = [`name: ${cmd.name}`];
|
|
557
|
+
if (cmd.description) {
|
|
558
|
+
frontmatterLines.push(
|
|
559
|
+
`description: "${cmd.description.replace(/"/g, '\\"')}"`
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
if (cmd.aliases && cmd.aliases.length > 0) {
|
|
563
|
+
frontmatterLines.push(`aliases: ${JSON.stringify(cmd.aliases)}`);
|
|
564
|
+
}
|
|
565
|
+
if (cmd.enabled !== void 0) {
|
|
566
|
+
frontmatterLines.push(`enabled: ${cmd.enabled}`);
|
|
567
|
+
}
|
|
568
|
+
if (cmd.hidden !== void 0) {
|
|
569
|
+
frontmatterLines.push(`hidden: ${cmd.hidden}`);
|
|
570
|
+
}
|
|
571
|
+
if (cmd.progressMessage) {
|
|
572
|
+
frontmatterLines.push(`progressMessage: "${cmd.progressMessage}"`);
|
|
573
|
+
}
|
|
574
|
+
if (cmd.argNames && cmd.argNames.length > 0) {
|
|
575
|
+
frontmatterLines.push(`argNames: ${JSON.stringify(cmd.argNames)}`);
|
|
576
|
+
}
|
|
577
|
+
if (cmd.allowedTools && cmd.allowedTools.length > 0) {
|
|
578
|
+
frontmatterLines.push(
|
|
579
|
+
`allowed-tools: ${JSON.stringify(cmd.allowedTools)}`
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
const content = `---
|
|
583
|
+
${frontmatterLines.join("\n")}
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
${cmd.content}
|
|
587
|
+
`;
|
|
588
|
+
const filename = `${cmd.name}.md`;
|
|
589
|
+
const targetPath = join(commandsDir, filename);
|
|
590
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
591
|
+
installed++;
|
|
592
|
+
debugLogger.state("TEAM_CONFIG_INSTALL_COMMAND_SUCCESS", {
|
|
593
|
+
name: cmd.name,
|
|
594
|
+
targetPath
|
|
595
|
+
});
|
|
596
|
+
} catch (error) {
|
|
597
|
+
failed++;
|
|
598
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
599
|
+
errors.push(`${cmd.name}: ${errorMsg}`);
|
|
600
|
+
debugLogger.error("TEAM_CONFIG_INSTALL_COMMAND_ERROR", {
|
|
601
|
+
name: cmd.name,
|
|
602
|
+
error: errorMsg
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return { installed, failed, errors };
|
|
607
|
+
}
|
|
464
608
|
export {
|
|
465
609
|
addMarketplaces,
|
|
466
610
|
applyTeamConfig,
|
|
@@ -468,6 +612,8 @@ export {
|
|
|
468
612
|
convertTeamModelProfile,
|
|
469
613
|
fetchTeamConfig,
|
|
470
614
|
installInlineAgents,
|
|
615
|
+
installInlineCommands,
|
|
616
|
+
installInlineSkills,
|
|
471
617
|
installPlugins,
|
|
472
618
|
installRemoteAgents,
|
|
473
619
|
installTeamHooks,
|