@within-7/minto 0.1.5 → 0.1.6
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/commands/agents/AgentsCommand.js +2342 -0
- package/dist/commands/agents/AgentsCommand.js.map +7 -0
- package/dist/commands/agents/constants.js +58 -0
- package/dist/commands/agents/constants.js.map +7 -0
- package/dist/commands/agents/index.js +37 -0
- package/dist/commands/agents/index.js.map +7 -0
- package/dist/commands/agents/types.js +10 -0
- package/dist/commands/agents/types.js.map +7 -0
- package/dist/commands/agents/utils/fileOperations.js +185 -0
- package/dist/commands/agents/utils/fileOperations.js.map +7 -0
- package/dist/commands/agents/utils/index.js +21 -0
- package/dist/commands/agents/utils/index.js.map +7 -0
- package/dist/commands/bug.js +2 -2
- package/dist/commands/bug.js.map +2 -2
- package/dist/commands/compact.js +5 -5
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/ctx_viz.js +55 -22
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/mcp-interactive.js +11 -11
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +94 -32
- package/dist/commands/model.js.map +3 -3
- package/dist/commands/plugin/AddMarketplaceForm.js +49 -21
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +38 -26
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +24 -8
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +3 -1
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +16 -7
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +84 -39
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +7 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +16 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +4 -2
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +12 -6
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +14 -5
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin/example-usage.js.map +2 -2
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +226 -46
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/refreshCommands.js +6 -3
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +2 -1
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/setup.js +19 -5
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/terminalSetup.js +2 -2
- package/dist/commands/terminalSetup.js.map +1 -1
- package/dist/commands.js +14 -30
- package/dist/commands.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +10 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +5 -1
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/Config.js +17 -4
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/CustomSelect/select-option.js +4 -1
- package/dist/components/CustomSelect/select-option.js.map +2 -2
- package/dist/components/Help.js +6 -8
- package/dist/components/Help.js.map +2 -2
- package/dist/components/Logo.js +1 -1
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +2030 -0
- package/dist/components/ModelSelector/ModelSelector.js.map +7 -0
- package/dist/components/ModelSelector/ScreenContainer.js +27 -0
- package/dist/components/ModelSelector/ScreenContainer.js.map +7 -0
- package/dist/components/ModelSelector/constants.js +37 -0
- package/dist/components/ModelSelector/constants.js.map +7 -0
- package/dist/components/ModelSelector/hooks/index.js +5 -0
- package/dist/components/ModelSelector/hooks/index.js.map +7 -0
- package/dist/components/ModelSelector/hooks/useEscapeNavigation.js +21 -0
- package/dist/components/ModelSelector/hooks/useEscapeNavigation.js.map +7 -0
- package/dist/components/ModelSelector/index.js +17 -0
- package/dist/components/ModelSelector/index.js.map +7 -0
- package/dist/components/ModelSelector/types.js +1 -0
- package/dist/components/ModelSelector/types.js.map +7 -0
- package/dist/components/PressEnterToContinue.js +1 -1
- package/dist/components/PressEnterToContinue.js.map +2 -2
- package/dist/components/ProjectOnboarding.js +1 -1
- package/dist/components/ProjectOnboarding.js.map +2 -2
- package/dist/components/PromptInput.js +88 -37
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/QuitSummary.js +17 -10
- package/dist/components/QuitSummary.js.map +2 -2
- package/dist/components/SentryErrorBoundary.js.map +2 -2
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js.map +1 -1
- package/dist/components/TodoItem.js.map +1 -1
- package/dist/components/binary-feedback/BinaryFeedbackOption.js +1 -3
- package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +2 -2
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +1 -1
- package/dist/components/messages/AssistantToolUseMessage.js +3 -1
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/TaskProgressMessage.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/utils.js.map +2 -2
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +2 -2
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +2 -2
- package/dist/components/permissions/hooks.js.map +2 -2
- package/dist/constants/modelCapabilities.js +1 -1
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/prompts.js.map +1 -1
- package/dist/constants/timing.js +34 -0
- package/dist/constants/timing.js.map +7 -0
- package/dist/entrypoints/cli.js +128 -33
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/entrypoints/mcp.js +13 -18
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useCancelRequest.js.map +1 -1
- package/dist/hooks/useHistorySearch.js.map +2 -2
- package/dist/hooks/useLogStartupTime.js.map +2 -2
- package/dist/hooks/usePermissionRequestLogging.js.map +2 -2
- package/dist/hooks/useTextInput.js.map +1 -1
- package/dist/hooks/useUnifiedCompletion.js +493 -394
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/index.js.map +2 -2
- package/dist/permissions.js +4 -7
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +6 -1
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +72 -36
- package/dist/screens/REPL.js.map +2 -2
- package/dist/screens/ResumeConversation.js +2 -1
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/adapters/base.js.map +2 -2
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +3 -1
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/claude.js +327 -328
- package/dist/services/claude.js.map +2 -2
- package/dist/services/customCommands.js +6 -1
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/fileFreshness.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +20 -7
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +6 -12
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/mcpClient.js +29 -2
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/mentionProcessor.js +23 -10
- package/dist/services/mentionProcessor.js.map +2 -2
- package/dist/services/modelAdapterFactory.js.map +2 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +109 -72
- package/dist/services/openai.js.map +3 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +14 -8
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js.map +1 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +1 -4
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +4 -1
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js +3 -1
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/SkillTool/SkillTool.js +12 -6
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +14 -5
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/ThinkTool/ThinkTool.js +6 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +23 -3
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +6 -3
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js +3 -1
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/searchProviders.js +15 -6
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools.js +4 -1
- package/dist/tools.js.map +2 -2
- package/dist/types/core.js +1 -0
- package/dist/types/core.js.map +7 -0
- package/dist/types/hooks.js +1 -4
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js +8 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/plugin.js +9 -6
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/BackgroundShellManager.js +76 -10
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/PersistentShell.js +7 -2
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/advancedFuzzyMatcher.js +4 -1
- package/dist/utils/advancedFuzzyMatcher.js.map +2 -2
- package/dist/utils/agentLoader.js +69 -35
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentStorage.js.map +2 -2
- package/dist/utils/async.js +163 -0
- package/dist/utils/async.js.map +7 -0
- package/dist/utils/autoUpdater.js +8 -2
- package/dist/utils/autoUpdater.js.map +2 -2
- package/dist/utils/commands.js +23 -11
- package/dist/utils/commands.js.map +2 -2
- package/dist/utils/commonUnixCommands.js +3 -1
- package/dist/utils/commonUnixCommands.js.map +2 -2
- package/dist/utils/compressionMode.js.map +2 -2
- package/dist/utils/config.js +30 -14
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +82 -0
- package/dist/utils/envConfig.js.map +7 -0
- package/dist/utils/errorHandling.js +89 -0
- package/dist/utils/errorHandling.js.map +7 -0
- package/dist/utils/expertChatStorage.js.map +2 -2
- package/dist/utils/fuzzyMatcher.js +13 -7
- package/dist/utils/fuzzyMatcher.js.map +2 -2
- package/dist/utils/hookManager.js +14 -4
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/log.js.map +2 -2
- package/dist/utils/marketplaceManager.js +44 -9
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messageContextManager.js.map +1 -1
- package/dist/utils/messages.js +6 -3
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +3 -1
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +3 -15
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +41 -13
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/pluginRegistry.js.map +2 -2
- package/dist/utils/pluginValidator.js +71 -49
- package/dist/utils/pluginValidator.js.map +2 -2
- package/dist/utils/ptyCompat.js.map +2 -2
- package/dist/utils/roundConverter.js.map +2 -2
- package/dist/utils/secureFile.js +43 -14
- package/dist/utils/secureFile.js.map +2 -2
- package/dist/utils/sessionState.js.map +2 -2
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/teamConfig.js +7 -4
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/theme.js.map +2 -2
- package/dist/utils/thinking.js.map +2 -2
- package/dist/utils/unaryLogging.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/secureFile.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, unlinkSync, renameSync } from 'node:fs'\nimport { join, dirname, normalize, resolve, extname, relative, isAbsolute } from 'node:path'\nimport { homedir } from 'node:os'\n\n/**\n * \u5B89\u5168\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u670D\u52A1\n * \u89E3\u51B3\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u4E2D\u7F3A\u5C11\u9002\u5F53\u9A8C\u8BC1\u548C\u9519\u8BEF\u5904\u7406\u7684\u95EE\u9898\n */\nexport class SecureFileService {\n private static instance: SecureFileService\n private allowedBasePaths: Set<string>\n private maxFileSize: number\n private allowedExtensions: Set<string>\n\n private constructor() {\n // \u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\n this.allowedBasePaths = new Set([\n process.cwd(),\n homedir(),\n '/tmp',\n '/var/tmp'\n ])\n \n // \u9ED8\u8BA4\u6700\u5927\u6587\u4EF6\u5927\u5C0F (10MB)\n this.maxFileSize = 10 * 1024 * 1024\n \n // \u5141\u8BB8\u7684\u6587\u4EF6\u6269\u5C55\u540D\n this.allowedExtensions = new Set([\n '.txt', '.md', '.json', '.js', '.ts', '.tsx', '.jsx',\n '.yaml', '.yml', '.toml', '.ini', '.env', '.log',\n '.html', '.css', '.scss', '.less', '.xml', '.csv',\n '.py', '.go', '.rs', '.java', '.cpp', '.c', '.h',\n '.sh', '.bash', '.zsh', '.fish', '.ps1', '.bat',\n '.dockerfile', '.gitignore', '.npmignore', '.eslintignore'\n ])\n }\n\n public static getInstance(): SecureFileService {\n if (!SecureFileService.instance) {\n SecureFileService.instance = new SecureFileService()\n }\n return SecureFileService.instance\n }\n\n /**\n * \u9A8C\u8BC1\u6587\u4EF6\u8DEF\u5F84\u662F\u5426\u5B89\u5168\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u9A8C\u8BC1\u7ED3\u679C\n */\n public validateFilePath(filePath: string): { isValid: boolean; normalizedPath: string; error?: string } {\n try {\n // \u89C4\u8303\u5316\u8DEF\u5F84\n const normalizedPath = normalize(filePath)\n \n // \u68C0\u67E5\u8DEF\u5F84\u957F\u5EA6\n if (normalizedPath.length > 4096) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path too long (max 4096 characters)'\n }\n }\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u8DEF\u5F84\u904D\u5386\u5B57\u7B26\n if (normalizedPath.includes('..') || normalizedPath.includes('~')) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path contains traversal characters'\n }\n }\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u53EF\u7591\u7684\u5B57\u7B26\u5E8F\u5217\n const suspiciousPatterns = [\n /\\.\\./, // \u7236\u76EE\u5F55\n /~/, // \u7528\u6237\u76EE\u5F55\n /\\$\\{/, // \u73AF\u5883\u53D8\u91CF\n /`/, // \u547D\u4EE4\u6267\u884C\n /\\|/, // \u7BA1\u9053\u7B26\n /;/, // \u547D\u4EE4\u5206\u9694\u7B26\n /&/, // \u540E\u53F0\u6267\u884C\n />/, // \u8F93\u51FA\u91CD\u5B9A\u5411\n /</, // \u8F93\u5165\u91CD\u5B9A\u5411\n ]\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(normalizedPath)) {\n return {\n isValid: false,\n normalizedPath,\n error: `Path contains suspicious pattern: ${pattern}`\n }\n }\n }\n\n // \u89E3\u6790\u4E3A\u7EDD\u5BF9\u8DEF\u5F84\n const absolutePath = resolve(normalizedPath)\n \n // \u68C0\u67E5\u662F\u5426\u5728\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\u4E2D\n const isInAllowedPath = Array.from(this.allowedBasePaths).some(basePath => {\n const base = resolve(basePath)\n const rel = relative(base, absolutePath)\n if (!rel || rel === '') return true\n if (rel.startsWith('..')) return false\n if (isAbsolute(rel)) return false\n return true\n })\n\n if (!isInAllowedPath) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path is outside allowed directories'\n }\n }\n\n return { isValid: true, normalizedPath: absolutePath }\n } catch (error) {\n return {\n isValid: false,\n normalizedPath: filePath,\n error: `Path validation failed: ${error instanceof Error ? error.message : String(error)}`\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u6587\u4EF6\u662F\u5426\u5B58\u5728\n */\n public safeExists(filePath: string): boolean {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return false\n }\n\n try {\n return existsSync(validation.normalizedPath)\n } catch (error) {\n return false\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u8BFB\u53D6\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @param options \u8BFB\u53D6\u9009\u9879\n * @returns \u8BFB\u53D6\u7ED3\u679C\n */\n public safeReadFile(\n filePath: string, \n options: { \n encoding?: BufferEncoding; \n maxFileSize?: number;\n allowedExtensions?: string[];\n checkFileExtension?: boolean;\n } = {}\n ): { success: boolean; content?: string | Buffer; error?: string; stats?: any } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n \n // \u68C0\u67E5\u6587\u4EF6\u6269\u5C55\u540D\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.checkFileExtension !== false) {\n const ext = extname(normalizedPath).toLowerCase()\n const allowedExts = options.allowedExtensions || \n Array.from(this.allowedExtensions)\n \n if (allowedExts.length > 0 && !allowedExts.includes(ext)) {\n return { \n success: false, \n error: `File extension '${ext}' is not allowed` \n }\n }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n // \u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\n const stats = statSync(normalizedPath)\n const maxSize = options.maxFileSize || this.maxFileSize\n \n // \u68C0\u67E5\u6587\u4EF6\u5927\u5C0F\n if (stats.size > maxSize) {\n return { \n success: false, \n error: `File too large (${stats.size} bytes, max ${maxSize} bytes)` \n }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u7C7B\u578B\n if (!stats.isFile()) {\n return { success: false, error: 'Path is not a file' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u6743\u9650\n if ((stats.mode & parseInt('400', 8)) === 0) { // \u68C0\u67E5\u8BFB\u6743\u9650\n return { success: false, error: 'No read permission' }\n }\n\n // \u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\n const content = readFileSync(normalizedPath, {\n encoding: options.encoding || 'utf8'\n })\n\n return { \n success: true, \n content,\n stats: {\n size: stats.size,\n mtime: stats.mtime,\n atime: stats.atime,\n mode: stats.mode\n }\n }\n } catch (error) {\n return { \n success: false, \n error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5199\u5165\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @param content \u6587\u4EF6\u5185\u5BB9\n * @param options \u5199\u5165\u9009\u9879\n * @returns \u5199\u5165\u7ED3\u679C\n */\n public safeWriteFile(\n filePath: string, \n content: string | Buffer, \n options: { \n encoding?: BufferEncoding; \n createDirectory?: boolean;\n atomic?: boolean;\n mode?: number;\n allowedExtensions?: string[];\n checkFileExtension?: boolean;\n maxSize?: number;\n } = {}\n ): { success: boolean; error?: string } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n \n // \u68C0\u67E5\u6587\u4EF6\u6269\u5C55\u540D\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.checkFileExtension !== false) {\n const ext = extname(normalizedPath).toLowerCase()\n const allowedExts = options.allowedExtensions || \n Array.from(this.allowedExtensions)\n \n if (allowedExts.length > 0 && !allowedExts.includes(ext)) {\n return { \n success: false, \n error: `File extension '${ext}' is not allowed` \n }\n }\n }\n\n // \u68C0\u67E5\u5185\u5BB9\u5927\u5C0F\n const contentSize = typeof content === 'string' ? \n Buffer.byteLength(content, options.encoding as BufferEncoding || 'utf8') : \n content.length\n \n const maxSize = options.maxSize || this.maxFileSize\n if (contentSize > maxSize) {\n return { \n success: false, \n error: `Content too large (${contentSize} bytes, max ${maxSize} bytes)` \n }\n }\n\n // \u521B\u5EFA\u76EE\u5F55\uFF08\u5982\u679C\u9700\u8981\uFF09\n if (options.createDirectory) {\n const dir = dirname(normalizedPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o755 })\n }\n }\n\n // \u539F\u5B50\u5199\u5165\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.atomic) {\n const tempPath = `${normalizedPath}.tmp.${Date.now()}`\n \n try {\n // \u5199\u5165\u4E34\u65F6\u6587\u4EF6\n writeFileSync(tempPath, content, {\n encoding: options.encoding as BufferEncoding || 'utf8',\n mode: options.mode || 0o644\n })\n \n // \u91CD\u547D\u540D\u4E3A\u76EE\u6807\u6587\u4EF6\n renameSync(tempPath, normalizedPath)\n } catch (renameError) {\n // \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n try {\n if (existsSync(tempPath)) {\n unlinkSync(tempPath)\n }\n } catch {\n // \u5FFD\u7565\u6E05\u7406\u9519\u8BEF\n }\n throw renameError\n }\n } else {\n // \u76F4\u63A5\u5199\u5165\n writeFileSync(normalizedPath, content, {\n encoding: options.encoding as BufferEncoding || 'utf8',\n mode: options.mode || 0o644\n })\n }\n\n return { success: true }\n } catch (error) {\n return { \n success: false, \n error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5220\u9664\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u5220\u9664\u7ED3\u679C\n */\n public safeDeleteFile(filePath: string): { success: boolean; error?: string } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n \n // \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u7C7B\u578B\n const stats = statSync(normalizedPath)\n if (!stats.isFile()) {\n return { success: false, error: 'Path is not a file' }\n }\n\n // \u68C0\u67E5\u5199\u6743\u9650\n if ((stats.mode & parseInt('200', 8)) === 0) {\n return { success: false, error: 'No write permission' }\n }\n\n // \u5B89\u5168\u5220\u9664\n unlinkSync(normalizedPath)\n return { success: true }\n } catch (error) {\n return { \n success: false, \n error: `Failed to delete file: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u521B\u5EFA\u76EE\u5F55\n * @param dirPath \u76EE\u5F55\u8DEF\u5F84\n * @param mode \u76EE\u5F55\u6743\u9650\n * @returns \u521B\u5EFA\u7ED3\u679C\n */\n public safeCreateDirectory(dirPath: string, mode: number = 0o755): { success: boolean; error?: string } {\n const validation = this.validateFilePath(dirPath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n \n if (existsSync(normalizedPath)) {\n const stats = statSync(normalizedPath)\n if (!stats.isDirectory()) {\n return { success: false, error: 'Path already exists and is not a directory' }\n }\n return { success: true }\n }\n\n mkdirSync(normalizedPath, { recursive: true, mode })\n return { success: true }\n } catch (error) {\n return { \n success: false, \n error: `Failed to create directory: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u6587\u4EF6\u4FE1\u606F\n */\n public safeGetFileInfo(filePath: string): { \n success: boolean; \n stats?: { \n size: number; \n isFile: boolean; \n isDirectory: boolean; \n mode: number; \n atime: Date; \n mtime: Date; \n ctime: Date; \n }; \n error?: string \n } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n \n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n const stats = statSync(normalizedPath)\n \n return {\n success: true,\n stats: {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n mode: stats.mode,\n atime: stats.atime,\n mtime: stats.mtime,\n ctime: stats.ctime\n }\n }\n } catch (error) {\n return { \n success: false, \n error: `Failed to get file info: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u6DFB\u52A0\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\n * @param basePath \u57FA\u7840\u8DEF\u5F84\n */\n public addAllowedBasePath(basePath: string): { success: boolean; error?: string } {\n try {\n const normalized = normalize(resolve(basePath))\n \n // \u9A8C\u8BC1\u8DEF\u5F84\u662F\u5426\u5B58\u5728\n if (!existsSync(normalized)) {\n return { success: false, error: 'Base path does not exist' }\n }\n\n this.allowedBasePaths.add(normalized)\n return { success: true }\n } catch (error) {\n return { \n success: false, \n error: `Failed to add base path: ${error instanceof Error ? error.message : String(error)}` \n }\n }\n }\n\n /**\n * \u8BBE\u7F6E\u6700\u5927\u6587\u4EF6\u5927\u5C0F\n * @param maxSize \u6700\u5927\u6587\u4EF6\u5927\u5C0F\uFF08\u5B57\u8282\uFF09\n */\n public setMaxFileSize(maxSize: number): void {\n this.maxFileSize = maxSize\n }\n\n /**\n * \u6DFB\u52A0\u5141\u8BB8\u7684\u6587\u4EF6\u6269\u5C55\u540D\n * @param extensions \u6587\u4EF6\u6269\u5C55\u540D\u6570\u7EC4\n */\n public addAllowedExtensions(extensions: string[]): void {\n extensions.forEach(ext => {\n if (!ext.startsWith('.')) {\n ext = '.' + ext\n }\n this.allowedExtensions.add(ext.toLowerCase())\n })\n }\n\n /**\n * \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5728\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\u4E2D\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u662F\u5426\u5141\u8BB8\n */\n public isPathAllowed(filePath: string): boolean {\n const validation = this.validateFilePath(filePath)\n return validation.isValid\n }\n\n /**\n * \u9A8C\u8BC1\u6587\u4EF6\u540D\u5B89\u5168\u6027\n * @param filename \u6587\u4EF6\u540D\n * @returns \u9A8C\u8BC1\u7ED3\u679C\n */\n public validateFileName(filename: string): { isValid: boolean; error?: string } {\n // \u68C0\u67E5\u6587\u4EF6\u540D\u957F\u5EA6\n if (filename.length === 0) {\n return { isValid: false, error: 'Filename cannot be empty' }\n }\n\n if (filename.length > 255) {\n return { isValid: false, error: 'Filename too long (max 255 characters)' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u540D\u5B57\u7B26\n const invalidChars = /[<>:\"/\\\\|?*\\x00-\\x1F]/\n if (invalidChars.test(filename)) {\n return { isValid: false, error: 'Filename contains invalid characters' }\n }\n\n // \u68C0\u67E5\u4FDD\u7559\u6587\u4EF6\u540D\n const reservedNames = [\n 'CON', 'PRN', 'AUX', 'NUL',\n 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'\n ]\n\n const baseName = filename.split('.')[0].toUpperCase()\n if (reservedNames.includes(baseName)) {\n return { isValid: false, error: 'Filename is reserved' }\n }\n\n // \u68C0\u67E5\u662F\u5426\u4EE5\u70B9\u5F00\u5934\u6216\u7ED3\u5C3E\n if (filename.startsWith('.') || filename.endsWith('.')) {\n return { isValid: false, error: 'Filename cannot start or end with a dot' }\n }\n\n // \u68C0\u67E5\u662F\u5426\u4EE5\u7A7A\u683C\u5F00\u5934\u6216\u7ED3\u5C3E\n if (filename.startsWith(' ') || filename.endsWith(' ')) {\n return { isValid: false, error: 'Filename cannot start or end with spaces' }\n }\n\n return { isValid: true }\n }\n}\n\n// \u5BFC\u51FA\u5355\u4F8B\u5B9E\u4F8B\nexport const secureFileService = SecureFileService.getInstance()\n"],
|
|
5
|
-
"mappings": "AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n statSync,\n unlinkSync,\n renameSync,\n} from 'node:fs'\nimport {\n join,\n dirname,\n normalize,\n resolve,\n extname,\n relative,\n isAbsolute,\n} from 'node:path'\nimport { homedir } from 'node:os'\n\n/**\n * \u5B89\u5168\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u670D\u52A1\n * \u89E3\u51B3\u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u4E2D\u7F3A\u5C11\u9002\u5F53\u9A8C\u8BC1\u548C\u9519\u8BEF\u5904\u7406\u7684\u95EE\u9898\n */\nexport class SecureFileService {\n private static instance: SecureFileService\n private allowedBasePaths: Set<string>\n private maxFileSize: number\n private allowedExtensions: Set<string>\n\n private constructor() {\n // \u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\n this.allowedBasePaths = new Set([\n process.cwd(),\n homedir(),\n '/tmp',\n '/var/tmp',\n ])\n\n // \u9ED8\u8BA4\u6700\u5927\u6587\u4EF6\u5927\u5C0F (10MB)\n this.maxFileSize = 10 * 1024 * 1024\n\n // \u5141\u8BB8\u7684\u6587\u4EF6\u6269\u5C55\u540D\n this.allowedExtensions = new Set([\n '.txt',\n '.md',\n '.json',\n '.js',\n '.ts',\n '.tsx',\n '.jsx',\n '.yaml',\n '.yml',\n '.toml',\n '.ini',\n '.env',\n '.log',\n '.html',\n '.css',\n '.scss',\n '.less',\n '.xml',\n '.csv',\n '.py',\n '.go',\n '.rs',\n '.java',\n '.cpp',\n '.c',\n '.h',\n '.sh',\n '.bash',\n '.zsh',\n '.fish',\n '.ps1',\n '.bat',\n '.dockerfile',\n '.gitignore',\n '.npmignore',\n '.eslintignore',\n ])\n }\n\n public static getInstance(): SecureFileService {\n if (!SecureFileService.instance) {\n SecureFileService.instance = new SecureFileService()\n }\n return SecureFileService.instance\n }\n\n /**\n * \u9A8C\u8BC1\u6587\u4EF6\u8DEF\u5F84\u662F\u5426\u5B89\u5168\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u9A8C\u8BC1\u7ED3\u679C\n */\n public validateFilePath(filePath: string): {\n isValid: boolean\n normalizedPath: string\n error?: string\n } {\n try {\n // \u89C4\u8303\u5316\u8DEF\u5F84\n const normalizedPath = normalize(filePath)\n\n // \u68C0\u67E5\u8DEF\u5F84\u957F\u5EA6\n if (normalizedPath.length > 4096) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path too long (max 4096 characters)',\n }\n }\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u8DEF\u5F84\u904D\u5386\u5B57\u7B26\n if (normalizedPath.includes('..') || normalizedPath.includes('~')) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path contains traversal characters',\n }\n }\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u53EF\u7591\u7684\u5B57\u7B26\u5E8F\u5217\n const suspiciousPatterns = [\n /\\.\\./, // \u7236\u76EE\u5F55\n /~/, // \u7528\u6237\u76EE\u5F55\n /\\$\\{/, // \u73AF\u5883\u53D8\u91CF\n /`/, // \u547D\u4EE4\u6267\u884C\n /\\|/, // \u7BA1\u9053\u7B26\n /;/, // \u547D\u4EE4\u5206\u9694\u7B26\n /&/, // \u540E\u53F0\u6267\u884C\n />/, // \u8F93\u51FA\u91CD\u5B9A\u5411\n /</, // \u8F93\u5165\u91CD\u5B9A\u5411\n ]\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(normalizedPath)) {\n return {\n isValid: false,\n normalizedPath,\n error: `Path contains suspicious pattern: ${pattern}`,\n }\n }\n }\n\n // \u89E3\u6790\u4E3A\u7EDD\u5BF9\u8DEF\u5F84\n const absolutePath = resolve(normalizedPath)\n\n // \u68C0\u67E5\u662F\u5426\u5728\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\u4E2D\n const isInAllowedPath = Array.from(this.allowedBasePaths).some(\n basePath => {\n const base = resolve(basePath)\n const rel = relative(base, absolutePath)\n if (!rel || rel === '') return true\n if (rel.startsWith('..')) return false\n if (isAbsolute(rel)) return false\n return true\n },\n )\n\n if (!isInAllowedPath) {\n return {\n isValid: false,\n normalizedPath,\n error: 'Path is outside allowed directories',\n }\n }\n\n return { isValid: true, normalizedPath: absolutePath }\n } catch (error) {\n return {\n isValid: false,\n normalizedPath: filePath,\n error: `Path validation failed: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u6587\u4EF6\u662F\u5426\u5B58\u5728\n */\n public safeExists(filePath: string): boolean {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return false\n }\n\n try {\n return existsSync(validation.normalizedPath)\n } catch (error) {\n return false\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u8BFB\u53D6\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @param options \u8BFB\u53D6\u9009\u9879\n * @returns \u8BFB\u53D6\u7ED3\u679C\n */\n public safeReadFile(\n filePath: string,\n options: {\n encoding?: BufferEncoding\n maxFileSize?: number\n allowedExtensions?: string[]\n checkFileExtension?: boolean\n } = {},\n ): {\n success: boolean\n content?: string | Buffer\n error?: string\n stats?: any\n } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n\n // \u68C0\u67E5\u6587\u4EF6\u6269\u5C55\u540D\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.checkFileExtension !== false) {\n const ext = extname(normalizedPath).toLowerCase()\n const allowedExts =\n options.allowedExtensions || Array.from(this.allowedExtensions)\n\n if (allowedExts.length > 0 && !allowedExts.includes(ext)) {\n return {\n success: false,\n error: `File extension '${ext}' is not allowed`,\n }\n }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n // \u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\n const stats = statSync(normalizedPath)\n const maxSize = options.maxFileSize || this.maxFileSize\n\n // \u68C0\u67E5\u6587\u4EF6\u5927\u5C0F\n if (stats.size > maxSize) {\n return {\n success: false,\n error: `File too large (${stats.size} bytes, max ${maxSize} bytes)`,\n }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u7C7B\u578B\n if (!stats.isFile()) {\n return { success: false, error: 'Path is not a file' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u6743\u9650\n if ((stats.mode & parseInt('400', 8)) === 0) {\n // \u68C0\u67E5\u8BFB\u6743\u9650\n return { success: false, error: 'No read permission' }\n }\n\n // \u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\n const content = readFileSync(normalizedPath, {\n encoding: options.encoding || 'utf8',\n })\n\n return {\n success: true,\n content,\n stats: {\n size: stats.size,\n mtime: stats.mtime,\n atime: stats.atime,\n mode: stats.mode,\n },\n }\n } catch (error) {\n return {\n success: false,\n error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5199\u5165\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @param content \u6587\u4EF6\u5185\u5BB9\n * @param options \u5199\u5165\u9009\u9879\n * @returns \u5199\u5165\u7ED3\u679C\n */\n public safeWriteFile(\n filePath: string,\n content: string | Buffer,\n options: {\n encoding?: BufferEncoding\n createDirectory?: boolean\n atomic?: boolean\n mode?: number\n allowedExtensions?: string[]\n checkFileExtension?: boolean\n maxSize?: number\n } = {},\n ): { success: boolean; error?: string } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n\n // \u68C0\u67E5\u6587\u4EF6\u6269\u5C55\u540D\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.checkFileExtension !== false) {\n const ext = extname(normalizedPath).toLowerCase()\n const allowedExts =\n options.allowedExtensions || Array.from(this.allowedExtensions)\n\n if (allowedExts.length > 0 && !allowedExts.includes(ext)) {\n return {\n success: false,\n error: `File extension '${ext}' is not allowed`,\n }\n }\n }\n\n // \u68C0\u67E5\u5185\u5BB9\u5927\u5C0F\n const contentSize =\n typeof content === 'string'\n ? Buffer.byteLength(\n content,\n (options.encoding as BufferEncoding) || 'utf8',\n )\n : content.length\n\n const maxSize = options.maxSize || this.maxFileSize\n if (contentSize > maxSize) {\n return {\n success: false,\n error: `Content too large (${contentSize} bytes, max ${maxSize} bytes)`,\n }\n }\n\n // \u521B\u5EFA\u76EE\u5F55\uFF08\u5982\u679C\u9700\u8981\uFF09\n if (options.createDirectory) {\n const dir = dirname(normalizedPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o755 })\n }\n }\n\n // \u539F\u5B50\u5199\u5165\uFF08\u5982\u679C\u542F\u7528\uFF09\n if (options.atomic) {\n const tempPath = `${normalizedPath}.tmp.${Date.now()}`\n\n try {\n // \u5199\u5165\u4E34\u65F6\u6587\u4EF6\n writeFileSync(tempPath, content, {\n encoding: (options.encoding as BufferEncoding) || 'utf8',\n mode: options.mode || 0o644,\n })\n\n // \u91CD\u547D\u540D\u4E3A\u76EE\u6807\u6587\u4EF6\n renameSync(tempPath, normalizedPath)\n } catch (renameError) {\n // \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n try {\n if (existsSync(tempPath)) {\n unlinkSync(tempPath)\n }\n } catch {\n // \u5FFD\u7565\u6E05\u7406\u9519\u8BEF\n }\n throw renameError\n }\n } else {\n // \u76F4\u63A5\u5199\u5165\n writeFileSync(normalizedPath, content, {\n encoding: (options.encoding as BufferEncoding) || 'utf8',\n mode: options.mode || 0o644,\n })\n }\n\n return { success: true }\n } catch (error) {\n return {\n success: false,\n error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5220\u9664\u6587\u4EF6\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u5220\u9664\u7ED3\u679C\n */\n public safeDeleteFile(filePath: string): {\n success: boolean\n error?: string\n } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n\n // \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u7C7B\u578B\n const stats = statSync(normalizedPath)\n if (!stats.isFile()) {\n return { success: false, error: 'Path is not a file' }\n }\n\n // \u68C0\u67E5\u5199\u6743\u9650\n if ((stats.mode & parseInt('200', 8)) === 0) {\n return { success: false, error: 'No write permission' }\n }\n\n // \u5B89\u5168\u5220\u9664\n unlinkSync(normalizedPath)\n return { success: true }\n } catch (error) {\n return {\n success: false,\n error: `Failed to delete file: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u521B\u5EFA\u76EE\u5F55\n * @param dirPath \u76EE\u5F55\u8DEF\u5F84\n * @param mode \u76EE\u5F55\u6743\u9650\n * @returns \u521B\u5EFA\u7ED3\u679C\n */\n public safeCreateDirectory(\n dirPath: string,\n mode: number = 0o755,\n ): { success: boolean; error?: string } {\n const validation = this.validateFilePath(dirPath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n\n if (existsSync(normalizedPath)) {\n const stats = statSync(normalizedPath)\n if (!stats.isDirectory()) {\n return {\n success: false,\n error: 'Path already exists and is not a directory',\n }\n }\n return { success: true }\n }\n\n mkdirSync(normalizedPath, { recursive: true, mode })\n return { success: true }\n } catch (error) {\n return {\n success: false,\n error: `Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u6587\u4EF6\u4FE1\u606F\n */\n public safeGetFileInfo(filePath: string): {\n success: boolean\n stats?: {\n size: number\n isFile: boolean\n isDirectory: boolean\n mode: number\n atime: Date\n mtime: Date\n ctime: Date\n }\n error?: string\n } {\n const validation = this.validateFilePath(filePath)\n if (!validation.isValid) {\n return { success: false, error: validation.error }\n }\n\n try {\n const normalizedPath = validation.normalizedPath\n\n if (!existsSync(normalizedPath)) {\n return { success: false, error: 'File does not exist' }\n }\n\n const stats = statSync(normalizedPath)\n\n return {\n success: true,\n stats: {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n mode: stats.mode,\n atime: stats.atime,\n mtime: stats.mtime,\n ctime: stats.ctime,\n },\n }\n } catch (error) {\n return {\n success: false,\n error: `Failed to get file info: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u6DFB\u52A0\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\n * @param basePath \u57FA\u7840\u8DEF\u5F84\n */\n public addAllowedBasePath(basePath: string): {\n success: boolean\n error?: string\n } {\n try {\n const normalized = normalize(resolve(basePath))\n\n // \u9A8C\u8BC1\u8DEF\u5F84\u662F\u5426\u5B58\u5728\n if (!existsSync(normalized)) {\n return { success: false, error: 'Base path does not exist' }\n }\n\n this.allowedBasePaths.add(normalized)\n return { success: true }\n } catch (error) {\n return {\n success: false,\n error: `Failed to add base path: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n }\n\n /**\n * \u8BBE\u7F6E\u6700\u5927\u6587\u4EF6\u5927\u5C0F\n * @param maxSize \u6700\u5927\u6587\u4EF6\u5927\u5C0F\uFF08\u5B57\u8282\uFF09\n */\n public setMaxFileSize(maxSize: number): void {\n this.maxFileSize = maxSize\n }\n\n /**\n * \u6DFB\u52A0\u5141\u8BB8\u7684\u6587\u4EF6\u6269\u5C55\u540D\n * @param extensions \u6587\u4EF6\u6269\u5C55\u540D\u6570\u7EC4\n */\n public addAllowedExtensions(extensions: string[]): void {\n extensions.forEach(ext => {\n if (!ext.startsWith('.')) {\n ext = '.' + ext\n }\n this.allowedExtensions.add(ext.toLowerCase())\n })\n }\n\n /**\n * \u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5728\u5141\u8BB8\u7684\u57FA\u7840\u8DEF\u5F84\u4E2D\n * @param filePath \u6587\u4EF6\u8DEF\u5F84\n * @returns \u662F\u5426\u5141\u8BB8\n */\n public isPathAllowed(filePath: string): boolean {\n const validation = this.validateFilePath(filePath)\n return validation.isValid\n }\n\n /**\n * \u9A8C\u8BC1\u6587\u4EF6\u540D\u5B89\u5168\u6027\n * @param filename \u6587\u4EF6\u540D\n * @returns \u9A8C\u8BC1\u7ED3\u679C\n */\n public validateFileName(filename: string): {\n isValid: boolean\n error?: string\n } {\n // \u68C0\u67E5\u6587\u4EF6\u540D\u957F\u5EA6\n if (filename.length === 0) {\n return { isValid: false, error: 'Filename cannot be empty' }\n }\n\n if (filename.length > 255) {\n return { isValid: false, error: 'Filename too long (max 255 characters)' }\n }\n\n // \u68C0\u67E5\u6587\u4EF6\u540D\u5B57\u7B26\n const invalidChars = /[<>:\"/\\\\|?*\\x00-\\x1F]/\n if (invalidChars.test(filename)) {\n return { isValid: false, error: 'Filename contains invalid characters' }\n }\n\n // \u68C0\u67E5\u4FDD\u7559\u6587\u4EF6\u540D\n const reservedNames = [\n 'CON',\n 'PRN',\n 'AUX',\n 'NUL',\n 'COM1',\n 'COM2',\n 'COM3',\n 'COM4',\n 'COM5',\n 'COM6',\n 'COM7',\n 'COM8',\n 'COM9',\n 'LPT1',\n 'LPT2',\n 'LPT3',\n 'LPT4',\n 'LPT5',\n 'LPT6',\n 'LPT7',\n 'LPT8',\n 'LPT9',\n ]\n\n const baseName = filename.split('.')[0].toUpperCase()\n if (reservedNames.includes(baseName)) {\n return { isValid: false, error: 'Filename is reserved' }\n }\n\n // \u68C0\u67E5\u662F\u5426\u4EE5\u70B9\u5F00\u5934\u6216\u7ED3\u5C3E\n if (filename.startsWith('.') || filename.endsWith('.')) {\n return {\n isValid: false,\n error: 'Filename cannot start or end with a dot',\n }\n }\n\n // \u68C0\u67E5\u662F\u5426\u4EE5\u7A7A\u683C\u5F00\u5934\u6216\u7ED3\u5C3E\n if (filename.startsWith(' ') || filename.endsWith(' ')) {\n return {\n isValid: false,\n error: 'Filename cannot start or end with spaces',\n }\n }\n\n return { isValid: true }\n }\n}\n\n// \u5BFC\u51FA\u5355\u4F8B\u5B9E\u4F8B\nexport const secureFileService = SecureFileService.getInstance()\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/sessionState.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["type SessionState = {\n modelErrors: Record<string, unknown>\n currentError: string | null\n}\n\nconst isDebug =\n process.argv.includes('--debug') ||\n process.argv.includes('-d') ||\n process.env.DEBUG === 'true'\n\nconst sessionState: SessionState = {\n modelErrors: {},\n currentError: null,\n} as const\n\nfunction setSessionState<K extends keyof SessionState>(\n key: K,\n value: SessionState[K],\n): void\nfunction setSessionState(partialState: Partial<SessionState>): void\nfunction setSessionState(\n keyOrState: keyof SessionState | Partial<SessionState>,\n value?: any,\n): void {\n if (typeof keyOrState === 'string') {\n sessionState[keyOrState] = value\n } else {\n Object.assign(sessionState, keyOrState)\n }\n}\n\nfunction getSessionState(): SessionState\nfunction getSessionState<K extends keyof SessionState>(key: K): SessionState[K]\nfunction getSessionState<K extends keyof SessionState>(key?: K) {\n return key === undefined ? sessionState : sessionState[key]\n}\n\nexport type { SessionState }\nexport { setSessionState, getSessionState }\nexport default sessionState\n"],
|
|
5
|
+
"mappings": "AAKA,MAAM,UACJ,QAAQ,KAAK,SAAS,SAAS,KAC/B,QAAQ,KAAK,SAAS,IAAI,KAC1B,QAAQ,IAAI,UAAU;AAExB,MAAM,eAA6B;AAAA,EACjC,aAAa,CAAC;AAAA,EACd,cAAc;AAChB;AAOA,SAAS,gBACP,YACA,OACM;AACN,MAAI,OAAO,eAAe,UAAU;AAClC,iBAAa,UAAU,IAAI;AAAA,EAC7B,OAAO;AACL,WAAO,OAAO,cAAc,UAAU;AAAA,EACxC;AACF;AAIA,SAAS,gBAA8C,KAAS;AAC9D,SAAO,QAAQ,SAAY,eAAe,aAAa,GAAG;AAC5D;AAIA,IAAO,uBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -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.\n * Loads metadata first (name, description) for performance,\n * then lazy-loads full content when needed.\n */\n\nimport { readFileSync } from 'fs'\nimport matter from 'gray-matter'\nimport { LoadedSkill } from '../types/plugin'\nimport { loadAllPlugins } from './pluginLoader'\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 * Load all skills from all installed plugins\n * Uses progressive disclosure - only loads metadata (name, description)\n * Content is lazy-loaded when needed\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 skills: 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 skills.push(skill)\n }\n }\n\n // Build cache map for fast lookups\n skillsCache = new Map()\n for (const skill of skills) {\n skillsCache.set(skill.name, skill)\n }\n\n return skills\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 }
|
|
5
|
-
"mappings": "AAQA,SAAS,oBAAoB;AAC7B,OAAO,YAAY;AAEnB,SAAS,sBAAsB;AAM/B,IAAI,cAA+C;AAMnD,MAAM,eAAe,oBAAI,IAAoB;AAOtC,SAAS,gBAA+B;AAE7C,MAAI,gBAAgB,MAAM;AACxB,WAAO,MAAM,KAAK,YAAY,OAAO,CAAC;AAAA,EACxC;AAEA,QAAM,SAAwB,CAAC;AAC/B,QAAM,UAAU,eAAe;AAG/B,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,QAAS;AAErB,eAAW,SAAS,OAAO,QAAQ;AACjC,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAGA,gBAAc,oBAAI,IAAI;AACtB,aAAW,SAAS,QAAQ;AAC1B,gBAAY,IAAI,MAAM,MAAM,KAAK;AAAA,EACnC;AAEA,SAAO;AACT;AAMO,SAAS,SAAS,MAAuC;AAE9D,MAAI,gBAAgB,MAAM;AACxB,kBAAc;AAAA,EAChB;AAEA,SAAO,aAAa,IAAI,IAAI;AAC9B;AAMA,eAAsB,iBAAiB,OAAqC;AAE1E,MAAI,aAAa,IAAI,MAAM,IAAI,GAAG;AAChC,WAAO,aAAa,IAAI,MAAM,IAAI;AAAA,EACpC;AAGA,MAAI,MAAM,OAAO,SAAS;AACxB,iBAAa,IAAI,MAAM,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO,MAAM,OAAO;AAAA,EACtB;AAGA,MAAI;AACF,UAAM,cAAc,aAAa,MAAM,UAAU,OAAO;AACxD,UAAM,EAAE,QAAQ,IAAI,OAAO,WAAW;AACtC,UAAM,iBAAiB,QAAQ,KAAK;AAGpC,iBAAa,IAAI,MAAM,MAAM,cAAc;AAG3C,UAAM,OAAO,UAAU;AAEvB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,qCAAqC,MAAM,IAAI,MAC7C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,aAAa,OAA8B;AACzD,QAAM,YAAY,cAAc;AAChC,QAAM,aAAa,MAAM,YAAY;AAErC,SAAO,UAAU;AAAA,IACf,
|
|
4
|
+
"sourcesContent": ["/**\n * Skill Loader\n *\n * Progressive disclosure system for loading skills from plugins.\n * Loads metadata first (name, description) for performance,\n * then lazy-loads full content when needed.\n */\n\nimport { readFileSync } from 'fs'\nimport matter from 'gray-matter'\nimport { LoadedSkill } from '../types/plugin'\nimport { loadAllPlugins } from './pluginLoader'\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 * Load all skills from all installed plugins\n * Uses progressive disclosure - only loads metadata (name, description)\n * Content is lazy-loaded when needed\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 skills: 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 skills.push(skill)\n }\n }\n\n // Build cache map for fast lookups\n skillsCache = new Map()\n for (const skill of skills) {\n skillsCache.set(skill.name, skill)\n }\n\n return skills\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": "AAQA,SAAS,oBAAoB;AAC7B,OAAO,YAAY;AAEnB,SAAS,sBAAsB;AAM/B,IAAI,cAA+C;AAMnD,MAAM,eAAe,oBAAI,IAAoB;AAOtC,SAAS,gBAA+B;AAE7C,MAAI,gBAAgB,MAAM;AACxB,WAAO,MAAM,KAAK,YAAY,OAAO,CAAC;AAAA,EACxC;AAEA,QAAM,SAAwB,CAAC;AAC/B,QAAM,UAAU,eAAe;AAG/B,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,QAAS;AAErB,eAAW,SAAS,OAAO,QAAQ;AACjC,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAGA,gBAAc,oBAAI,IAAI;AACtB,aAAW,SAAS,QAAQ;AAC1B,gBAAY,IAAI,MAAM,MAAM,KAAK;AAAA,EACnC;AAEA,SAAO;AACT;AAMO,SAAS,SAAS,MAAuC;AAE9D,MAAI,gBAAgB,MAAM;AACxB,kBAAc;AAAA,EAChB;AAEA,SAAO,aAAa,IAAI,IAAI;AAC9B;AAMA,eAAsB,iBAAiB,OAAqC;AAE1E,MAAI,aAAa,IAAI,MAAM,IAAI,GAAG;AAChC,WAAO,aAAa,IAAI,MAAM,IAAI;AAAA,EACpC;AAGA,MAAI,MAAM,OAAO,SAAS;AACxB,iBAAa,IAAI,MAAM,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO,MAAM,OAAO;AAAA,EACtB;AAGA,MAAI;AACF,UAAM,cAAc,aAAa,MAAM,UAAU,OAAO;AACxD,UAAM,EAAE,QAAQ,IAAI,OAAO,WAAW;AACtC,UAAM,iBAAiB,QAAQ,KAAK;AAGpC,iBAAa,IAAI,MAAM,MAAM,cAAc;AAG3C,UAAM,OAAO,UAAU;AAEvB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,qCAAqC,MAAM,IAAI,MAC7C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,aAAa,OAA8B;AACzD,QAAM,YAAY,cAAc;AAChC,QAAM,aAAa,MAAM,YAAY;AAErC,SAAO,UAAU;AAAA,IACf,WACE,MAAM,KAAK,YAAY,EAAE,SAAS,UAAU,KAC5C,MAAM,OAAO,YAAY,YAAY,EAAE,SAAS,UAAU,KAC1D,MAAM,WAAW,YAAY,EAAE,SAAS,UAAU;AAAA,EACtD;AACF;AAKO,SAAS,kBAAkB,YAAmC;AACnE,QAAM,YAAY,cAAc;AAChC,SAAO,UAAU,OAAO,WAAS,MAAM,eAAe,UAAU;AAClE;AAKO,SAAS,mBAAyB;AACvC,gBAAc;AACd,eAAa,MAAM;AACrB;AAKO,SAAS,gBAAwB;AACtC,QAAM,SAAS,cAAc;AAC7B,SAAO,OAAO;AAChB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/teamConfig.js
CHANGED
|
@@ -137,9 +137,7 @@ function applyTeamConfig(teamConfig, strategy = "merge") {
|
|
|
137
137
|
const settingsUpdated = [];
|
|
138
138
|
if (teamConfig.models?.profiles) {
|
|
139
139
|
const existingProfiles = globalConfig.modelProfiles || [];
|
|
140
|
-
const existingModelNames = new Set(
|
|
141
|
-
existingProfiles.map((p) => p.modelName)
|
|
142
|
-
);
|
|
140
|
+
const existingModelNames = new Set(existingProfiles.map((p) => p.modelName));
|
|
143
141
|
for (const teamProfile of teamConfig.models.profiles) {
|
|
144
142
|
const runtimeProfile = convertTeamModelProfile(teamProfile);
|
|
145
143
|
if (strategy === "skip-existing" && existingModelNames.has(runtimeProfile.modelName)) {
|
|
@@ -168,7 +166,12 @@ function applyTeamConfig(teamConfig, strategy = "merge") {
|
|
|
168
166
|
}
|
|
169
167
|
if (teamConfig.models?.pointers) {
|
|
170
168
|
globalConfig.modelPointers = {
|
|
171
|
-
...globalConfig.modelPointers || {
|
|
169
|
+
...globalConfig.modelPointers || {
|
|
170
|
+
main: "",
|
|
171
|
+
task: "",
|
|
172
|
+
reasoning: "",
|
|
173
|
+
quick: ""
|
|
174
|
+
},
|
|
172
175
|
...teamConfig.models.pointers
|
|
173
176
|
};
|
|
174
177
|
settingsUpdated.push("modelPointers");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/teamConfig.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Team Configuration System\n *\n * Enables teams to share a unified Minto configuration via remote URLs.\n * Supports environment variable interpolation and flexible configuration merging.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport {\n getGlobalConfig,\n saveGlobalConfig,\n ModelProfile,\n ModelPointers,\n McpServerConfig,\n ProviderType,\n} from './config'\nimport { debug as debugLogger } from './debugLogger'\nimport { safeParseJSON } from './json'\n\n/**\n * Team configuration schema\n * Represents a shareable configuration template for teams\n */\nexport type TeamConfig = {\n version: '1.0'\n name: string // Configuration name (e.g., \"Acme Inc. Default Config\")\n description?: string // Optional description\n\n // Model Configuration\n models?: {\n profiles?: TeamModelProfile[]\n pointers?: Partial<ModelPointers> // Default model pointers\n defaultModel?: string // Default model name\n }\n\n // MCP Server Configuration\n mcpServers?: Record<string, TeamMcpServerConfig>\n\n // Plugin Marketplace Configuration\n plugins?: {\n // Plugin marketplace URLs (marketplace.json)\n marketplaces?: string[]\n // Specific plugins to install from marketplaces\n install?: string[] // Plugin names to install\n }\n\n // Global Settings\n settings?: {\n theme?: 'dark' | 'light'\n verbose?: boolean\n compressionMode?: 'business' | 'code'\n thinking?: boolean\n proxy?: string\n stream?: boolean\n }\n\n // Instructions for users\n postInstallInstructions?: string\n}\n\n/**\n * Model profile template with environment variable support\n */\nexport type TeamModelProfile = {\n name: string\n provider: ProviderType\n modelName: string\n baseURL?: string\n apiKey: string // Can be env var like \"${ANTHROPIC_API_KEY}\"\n maxTokens: number\n contextLength: number\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal'\n isActive?: boolean\n}\n\n/**\n * MCP server config with env var support\n */\nexport type TeamMcpServerConfig = {\n type?: 'stdio' | 'sse'\n command?: string // For stdio\n args?: string[] // For stdio, supports env vars like \"${HOME}/.local/bin/mcp-server\"\n url?: string // For SSE\n env?: Record<string, string> // Env vars, supports interpolation\n enabled?: boolean\n}\n\n/**\n * Interpolate environment variables in a string\n * Supports ${VAR_NAME} syntax\n */\nexport function interpolateEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName.trim()]\n if (envValue === undefined) {\n debugLogger.warn('ENV_VAR_NOT_FOUND', {\n varName,\n original: match,\n })\n // Keep the placeholder if env var not found\n return match\n }\n return envValue\n })\n}\n\n/**\n * Recursively interpolate env vars in an object\n */\nexport function interpolateEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return interpolateEnvVars(obj) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => interpolateEnvVarsInObject(item)) as T\n }\n\n if (obj && typeof obj === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = interpolateEnvVarsInObject(value)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Convert team model profile to runtime model profile\n */\nexport function convertTeamModelProfile(\n teamProfile: TeamModelProfile,\n): ModelProfile {\n const now = Date.now()\n\n return {\n name: teamProfile.name,\n provider: teamProfile.provider,\n modelName: teamProfile.modelName,\n baseURL: teamProfile.baseURL,\n apiKey: interpolateEnvVars(teamProfile.apiKey),\n maxTokens: teamProfile.maxTokens,\n contextLength: teamProfile.contextLength,\n reasoningEffort: teamProfile.reasoningEffort,\n isActive: teamProfile.isActive ?? true,\n createdAt: now,\n lastUsed: now,\n }\n}\n\n/**\n * Convert team MCP config to runtime MCP config\n */\nexport function convertTeamMcpConfig(\n teamConfig: TeamMcpServerConfig,\n): McpServerConfig {\n if (teamConfig.type === 'sse') {\n return {\n type: 'sse',\n url: interpolateEnvVars(teamConfig.url || ''),\n enabled: teamConfig.enabled ?? true,\n }\n }\n\n // Default to stdio\n return {\n type: 'stdio',\n command: interpolateEnvVars(teamConfig.command || ''),\n args: (teamConfig.args || []).map(arg => interpolateEnvVars(arg)),\n env: teamConfig.env\n ? interpolateEnvVarsInObject(teamConfig.env)\n : undefined,\n enabled: teamConfig.enabled ?? true,\n }\n}\n\n/**\n * Fetch team configuration from a URL\n */\nexport async function fetchTeamConfig(url: string): Promise<TeamConfig> {\n debugLogger.state('TEAM_CONFIG_FETCH_START', { url })\n\n try {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n )\n }\n\n const configText = await response.text()\n const config = JSON.parse(configText) as TeamConfig\n\n // Validate version\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_FETCH_SUCCESS', {\n url,\n configName: config.name,\n hasModels: !!config.models,\n hasMcpServers: !!config.mcpServers,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_FETCH_ERROR', {\n url,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Load team configuration from a local file\n */\nexport function loadTeamConfigFromFile(filePath: string): TeamConfig {\n debugLogger.state('TEAM_CONFIG_LOAD_FILE', { filePath })\n\n if (!existsSync(filePath)) {\n throw new Error(`Configuration file not found: ${filePath}`)\n }\n\n try {\n const configText = readFileSync(filePath, 'utf-8')\n const config = safeParseJSON(configText) as TeamConfig\n\n if (!config) {\n throw new Error('Invalid JSON in configuration file')\n }\n\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_LOAD_FILE_SUCCESS', {\n filePath,\n configName: config.name,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_LOAD_FILE_ERROR', {\n filePath,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Merge strategy for configuration\n */\nexport type MergeStrategy = 'replace' | 'merge' | 'skip-existing'\n\n/**\n * Apply team configuration to global config\n */\nexport function applyTeamConfig(\n teamConfig: TeamConfig,\n strategy: MergeStrategy = 'merge',\n): {\n applied: boolean\n modelsAdded: number\n mcpServersAdded: number\n settingsUpdated: string[]\n} {\n debugLogger.state('TEAM_CONFIG_APPLY_START', {\n configName: teamConfig.name,\n strategy,\n })\n\n const globalConfig = getGlobalConfig()\n let modelsAdded = 0\n let mcpServersAdded = 0\n const settingsUpdated: string[] = []\n\n // Apply model profiles\n if (teamConfig.models?.profiles) {\n const existingProfiles = globalConfig.modelProfiles || []\n const existingModelNames = new Set(\n existingProfiles.map(p => p.modelName),\n )\n\n for (const teamProfile of teamConfig.models.profiles) {\n const runtimeProfile = convertTeamModelProfile(teamProfile)\n\n if (strategy === 'skip-existing' && existingModelNames.has(runtimeProfile.modelName)) {\n debugLogger.state('TEAM_CONFIG_SKIP_MODEL', {\n modelName: runtimeProfile.modelName,\n reason: 'already_exists',\n })\n continue\n }\n\n if (strategy === 'replace') {\n // Remove existing profile with same modelName\n const index = existingProfiles.findIndex(\n p => p.modelName === runtimeProfile.modelName,\n )\n if (index !== -1) {\n existingProfiles.splice(index, 1)\n }\n }\n\n existingProfiles.push(runtimeProfile)\n modelsAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MODEL', {\n modelName: runtimeProfile.modelName,\n provider: runtimeProfile.provider,\n })\n }\n\n globalConfig.modelProfiles = existingProfiles\n }\n\n // Apply model pointers\n if (teamConfig.models?.pointers) {\n globalConfig.modelPointers = {\n ...(globalConfig.modelPointers || { main: '', task: '', reasoning: '', quick: '' }),\n ...teamConfig.models.pointers,\n }\n settingsUpdated.push('modelPointers')\n }\n\n // Apply default model\n if (teamConfig.models?.defaultModel) {\n globalConfig.defaultModelName = teamConfig.models.defaultModel\n settingsUpdated.push('defaultModelName')\n }\n\n // Apply MCP servers\n if (teamConfig.mcpServers) {\n const existingMcpServers = globalConfig.mcpServers || {}\n const existingServerNames = new Set(Object.keys(existingMcpServers))\n\n for (const [serverName, teamMcpConfig] of Object.entries(\n teamConfig.mcpServers,\n )) {\n if (strategy === 'skip-existing' && existingServerNames.has(serverName)) {\n debugLogger.state('TEAM_CONFIG_SKIP_MCP', {\n serverName,\n reason: 'already_exists',\n })\n continue\n }\n\n const runtimeMcpConfig = convertTeamMcpConfig(teamMcpConfig)\n existingMcpServers[serverName] = runtimeMcpConfig\n mcpServersAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MCP', {\n serverName,\n type: runtimeMcpConfig.type || 'stdio',\n })\n }\n\n globalConfig.mcpServers = existingMcpServers\n }\n\n // Apply global settings\n if (teamConfig.settings) {\n const { settings } = teamConfig\n\n if (settings.theme !== undefined) {\n globalConfig.theme = settings.theme\n settingsUpdated.push('theme')\n }\n\n if (settings.verbose !== undefined) {\n globalConfig.verbose = settings.verbose\n settingsUpdated.push('verbose')\n }\n\n if (settings.compressionMode !== undefined) {\n globalConfig.compressionMode = settings.compressionMode\n settingsUpdated.push('compressionMode')\n }\n\n if (settings.thinking !== undefined) {\n globalConfig.thinking = settings.thinking\n settingsUpdated.push('thinking')\n }\n\n if (settings.proxy !== undefined) {\n globalConfig.proxy = settings.proxy\n settingsUpdated.push('proxy')\n }\n\n if (settings.stream !== undefined) {\n globalConfig.stream = settings.stream\n settingsUpdated.push('stream')\n }\n }\n\n // Save updated config\n saveGlobalConfig(globalConfig)\n\n debugLogger.state('TEAM_CONFIG_APPLY_SUCCESS', {\n configName: teamConfig.name,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated: settingsUpdated.join(', '),\n })\n\n return {\n applied: true,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated,\n }\n}\n\n/**\n * Add marketplaces from URLs\n */\nexport async function addMarketplaces(\n marketplaceUrls: string[],\n): Promise<{ added: number; failed: number; errors: string[] }> {\n let added = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager\n const { addMarketplace } = await import('./marketplaceManager')\n\n for (const url of marketplaceUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE', { url })\n\n await addMarketplace(url)\n added++\n\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE_SUCCESS', { url })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_ADD_MARKETPLACE_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { added, failed, errors }\n}\n\n/**\n * Install plugins from marketplaces\n */\nexport async function installPlugins(\n pluginNames: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager and path utilities\n const { installPluginFromMarketplace } = await import('./marketplaceManager')\n const { join } = await import('path')\n const { homedir } = await import('os')\n\n // Default target: ~/.minto/plugins\n const installDir = targetDir || join(homedir(), '.minto', 'plugins')\n\n for (const pluginName of pluginNames) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN', {\n pluginName,\n targetDir: installDir,\n })\n\n await installPluginFromMarketplace(\n pluginName,\n undefined, // Search all marketplaces\n join(installDir, pluginName),\n )\n\n installed++\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN_SUCCESS', { pluginName })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${pluginName}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_PLUGIN_ERROR', {\n pluginName,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Team Configuration System\n *\n * Enables teams to share a unified Minto configuration via remote URLs.\n * Supports environment variable interpolation and flexible configuration merging.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport {\n getGlobalConfig,\n saveGlobalConfig,\n ModelProfile,\n ModelPointers,\n McpServerConfig,\n ProviderType,\n} from './config'\nimport { debug as debugLogger } from './debugLogger'\nimport { safeParseJSON } from './json'\n\n/**\n * Team configuration schema\n * Represents a shareable configuration template for teams\n */\nexport type TeamConfig = {\n version: '1.0'\n name: string // Configuration name (e.g., \"Acme Inc. Default Config\")\n description?: string // Optional description\n\n // Model Configuration\n models?: {\n profiles?: TeamModelProfile[]\n pointers?: Partial<ModelPointers> // Default model pointers\n defaultModel?: string // Default model name\n }\n\n // MCP Server Configuration\n mcpServers?: Record<string, TeamMcpServerConfig>\n\n // Plugin Marketplace Configuration\n plugins?: {\n // Plugin marketplace URLs (marketplace.json)\n marketplaces?: string[]\n // Specific plugins to install from marketplaces\n install?: string[] // Plugin names to install\n }\n\n // Global Settings\n settings?: {\n theme?: 'dark' | 'light'\n verbose?: boolean\n compressionMode?: 'business' | 'code'\n thinking?: boolean\n proxy?: string\n stream?: boolean\n }\n\n // Instructions for users\n postInstallInstructions?: string\n}\n\n/**\n * Model profile template with environment variable support\n */\nexport type TeamModelProfile = {\n name: string\n provider: ProviderType\n modelName: string\n baseURL?: string\n apiKey: string // Can be env var like \"${ANTHROPIC_API_KEY}\"\n maxTokens: number\n contextLength: number\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal'\n isActive?: boolean\n}\n\n/**\n * MCP server config with env var support\n */\nexport type TeamMcpServerConfig = {\n type?: 'stdio' | 'sse'\n command?: string // For stdio\n args?: string[] // For stdio, supports env vars like \"${HOME}/.local/bin/mcp-server\"\n url?: string // For SSE\n env?: Record<string, string> // Env vars, supports interpolation\n enabled?: boolean\n}\n\n/**\n * Interpolate environment variables in a string\n * Supports ${VAR_NAME} syntax\n */\nexport function interpolateEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName.trim()]\n if (envValue === undefined) {\n debugLogger.warn('ENV_VAR_NOT_FOUND', {\n varName,\n original: match,\n })\n // Keep the placeholder if env var not found\n return match\n }\n return envValue\n })\n}\n\n/**\n * Recursively interpolate env vars in an object\n */\nexport function interpolateEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return interpolateEnvVars(obj) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => interpolateEnvVarsInObject(item)) as T\n }\n\n if (obj && typeof obj === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = interpolateEnvVarsInObject(value)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Convert team model profile to runtime model profile\n */\nexport function convertTeamModelProfile(\n teamProfile: TeamModelProfile,\n): ModelProfile {\n const now = Date.now()\n\n return {\n name: teamProfile.name,\n provider: teamProfile.provider,\n modelName: teamProfile.modelName,\n baseURL: teamProfile.baseURL,\n apiKey: interpolateEnvVars(teamProfile.apiKey),\n maxTokens: teamProfile.maxTokens,\n contextLength: teamProfile.contextLength,\n reasoningEffort: teamProfile.reasoningEffort,\n isActive: teamProfile.isActive ?? true,\n createdAt: now,\n lastUsed: now,\n }\n}\n\n/**\n * Convert team MCP config to runtime MCP config\n */\nexport function convertTeamMcpConfig(\n teamConfig: TeamMcpServerConfig,\n): McpServerConfig {\n if (teamConfig.type === 'sse') {\n return {\n type: 'sse',\n url: interpolateEnvVars(teamConfig.url || ''),\n enabled: teamConfig.enabled ?? true,\n }\n }\n\n // Default to stdio\n return {\n type: 'stdio',\n command: interpolateEnvVars(teamConfig.command || ''),\n args: (teamConfig.args || []).map(arg => interpolateEnvVars(arg)),\n env: teamConfig.env\n ? interpolateEnvVarsInObject(teamConfig.env)\n : undefined,\n enabled: teamConfig.enabled ?? true,\n }\n}\n\n/**\n * Fetch team configuration from a URL\n */\nexport async function fetchTeamConfig(url: string): Promise<TeamConfig> {\n debugLogger.state('TEAM_CONFIG_FETCH_START', { url })\n\n try {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n )\n }\n\n const configText = await response.text()\n const config = JSON.parse(configText) as TeamConfig\n\n // Validate version\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_FETCH_SUCCESS', {\n url,\n configName: config.name,\n hasModels: !!config.models,\n hasMcpServers: !!config.mcpServers,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_FETCH_ERROR', {\n url,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Load team configuration from a local file\n */\nexport function loadTeamConfigFromFile(filePath: string): TeamConfig {\n debugLogger.state('TEAM_CONFIG_LOAD_FILE', { filePath })\n\n if (!existsSync(filePath)) {\n throw new Error(`Configuration file not found: ${filePath}`)\n }\n\n try {\n const configText = readFileSync(filePath, 'utf-8')\n const config = safeParseJSON(configText) as TeamConfig\n\n if (!config) {\n throw new Error('Invalid JSON in configuration file')\n }\n\n if (config.version !== '1.0') {\n throw new Error(\n `Unsupported config version: ${config.version}. Expected 1.0`,\n )\n }\n\n debugLogger.state('TEAM_CONFIG_LOAD_FILE_SUCCESS', {\n filePath,\n configName: config.name,\n })\n\n return config\n } catch (error) {\n debugLogger.error('TEAM_CONFIG_LOAD_FILE_ERROR', {\n filePath,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/**\n * Merge strategy for configuration\n */\nexport type MergeStrategy = 'replace' | 'merge' | 'skip-existing'\n\n/**\n * Apply team configuration to global config\n */\nexport function applyTeamConfig(\n teamConfig: TeamConfig,\n strategy: MergeStrategy = 'merge',\n): {\n applied: boolean\n modelsAdded: number\n mcpServersAdded: number\n settingsUpdated: string[]\n} {\n debugLogger.state('TEAM_CONFIG_APPLY_START', {\n configName: teamConfig.name,\n strategy,\n })\n\n const globalConfig = getGlobalConfig()\n let modelsAdded = 0\n let mcpServersAdded = 0\n const settingsUpdated: string[] = []\n\n // Apply model profiles\n if (teamConfig.models?.profiles) {\n const existingProfiles = globalConfig.modelProfiles || []\n const existingModelNames = new Set(existingProfiles.map(p => p.modelName))\n\n for (const teamProfile of teamConfig.models.profiles) {\n const runtimeProfile = convertTeamModelProfile(teamProfile)\n\n if (\n strategy === 'skip-existing' &&\n existingModelNames.has(runtimeProfile.modelName)\n ) {\n debugLogger.state('TEAM_CONFIG_SKIP_MODEL', {\n modelName: runtimeProfile.modelName,\n reason: 'already_exists',\n })\n continue\n }\n\n if (strategy === 'replace') {\n // Remove existing profile with same modelName\n const index = existingProfiles.findIndex(\n p => p.modelName === runtimeProfile.modelName,\n )\n if (index !== -1) {\n existingProfiles.splice(index, 1)\n }\n }\n\n existingProfiles.push(runtimeProfile)\n modelsAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MODEL', {\n modelName: runtimeProfile.modelName,\n provider: runtimeProfile.provider,\n })\n }\n\n globalConfig.modelProfiles = existingProfiles\n }\n\n // Apply model pointers\n if (teamConfig.models?.pointers) {\n globalConfig.modelPointers = {\n ...(globalConfig.modelPointers || {\n main: '',\n task: '',\n reasoning: '',\n quick: '',\n }),\n ...teamConfig.models.pointers,\n }\n settingsUpdated.push('modelPointers')\n }\n\n // Apply default model\n if (teamConfig.models?.defaultModel) {\n globalConfig.defaultModelName = teamConfig.models.defaultModel\n settingsUpdated.push('defaultModelName')\n }\n\n // Apply MCP servers\n if (teamConfig.mcpServers) {\n const existingMcpServers = globalConfig.mcpServers || {}\n const existingServerNames = new Set(Object.keys(existingMcpServers))\n\n for (const [serverName, teamMcpConfig] of Object.entries(\n teamConfig.mcpServers,\n )) {\n if (strategy === 'skip-existing' && existingServerNames.has(serverName)) {\n debugLogger.state('TEAM_CONFIG_SKIP_MCP', {\n serverName,\n reason: 'already_exists',\n })\n continue\n }\n\n const runtimeMcpConfig = convertTeamMcpConfig(teamMcpConfig)\n existingMcpServers[serverName] = runtimeMcpConfig\n mcpServersAdded++\n\n debugLogger.state('TEAM_CONFIG_ADD_MCP', {\n serverName,\n type: runtimeMcpConfig.type || 'stdio',\n })\n }\n\n globalConfig.mcpServers = existingMcpServers\n }\n\n // Apply global settings\n if (teamConfig.settings) {\n const { settings } = teamConfig\n\n if (settings.theme !== undefined) {\n globalConfig.theme = settings.theme\n settingsUpdated.push('theme')\n }\n\n if (settings.verbose !== undefined) {\n globalConfig.verbose = settings.verbose\n settingsUpdated.push('verbose')\n }\n\n if (settings.compressionMode !== undefined) {\n globalConfig.compressionMode = settings.compressionMode\n settingsUpdated.push('compressionMode')\n }\n\n if (settings.thinking !== undefined) {\n globalConfig.thinking = settings.thinking\n settingsUpdated.push('thinking')\n }\n\n if (settings.proxy !== undefined) {\n globalConfig.proxy = settings.proxy\n settingsUpdated.push('proxy')\n }\n\n if (settings.stream !== undefined) {\n globalConfig.stream = settings.stream\n settingsUpdated.push('stream')\n }\n }\n\n // Save updated config\n saveGlobalConfig(globalConfig)\n\n debugLogger.state('TEAM_CONFIG_APPLY_SUCCESS', {\n configName: teamConfig.name,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated: settingsUpdated.join(', '),\n })\n\n return {\n applied: true,\n modelsAdded,\n mcpServersAdded,\n settingsUpdated,\n }\n}\n\n/**\n * Add marketplaces from URLs\n */\nexport async function addMarketplaces(\n marketplaceUrls: string[],\n): Promise<{ added: number; failed: number; errors: string[] }> {\n let added = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager\n const { addMarketplace } = await import('./marketplaceManager')\n\n for (const url of marketplaceUrls) {\n try {\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE', { url })\n\n await addMarketplace(url)\n added++\n\n debugLogger.state('TEAM_CONFIG_ADD_MARKETPLACE_SUCCESS', { url })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${url}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_ADD_MARKETPLACE_ERROR', {\n url,\n error: errorMsg,\n })\n }\n }\n\n return { added, failed, errors }\n}\n\n/**\n * Install plugins from marketplaces\n */\nexport async function installPlugins(\n pluginNames: string[],\n targetDir?: string,\n): Promise<{ installed: number; failed: number; errors: string[] }> {\n let installed = 0\n let failed = 0\n const errors: string[] = []\n\n // Import marketplace manager and path utilities\n const { installPluginFromMarketplace } = await import('./marketplaceManager')\n const { join } = await import('path')\n const { homedir } = await import('os')\n\n // Default target: ~/.minto/plugins\n const installDir = targetDir || join(homedir(), '.minto', 'plugins')\n\n for (const pluginName of pluginNames) {\n try {\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN', {\n pluginName,\n targetDir: installDir,\n })\n\n await installPluginFromMarketplace(\n pluginName,\n undefined, // Search all marketplaces\n join(installDir, pluginName),\n )\n\n installed++\n debugLogger.state('TEAM_CONFIG_INSTALL_PLUGIN_SUCCESS', { pluginName })\n } catch (error) {\n failed++\n const errorMsg = error instanceof Error ? error.message : String(error)\n errors.push(`${pluginName}: ${errorMsg}`)\n\n debugLogger.error('TEAM_CONFIG_INSTALL_PLUGIN_ERROR', {\n pluginName,\n error: errorMsg,\n })\n }\n }\n\n return { installed, failed, errors }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/utils/theme.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/theme.ts"],
|
|
4
|
-
"sourcesContent": ["import { getGlobalConfig } from './config'\n\nexport interface Theme {\n bashBorder: string\n minto: string\n noting: string\n permission: string\n secondaryBorder: string\n text: string\n secondaryText: string\n suggestion: string\n success: string\n error: string\n warning: string\n primary: string\n secondary: string\n diff: {\n added: string\n removed: string\n addedDimmed: string\n removedDimmed: string\n }\n // Additional color properties used in components\n brand: string\n dimmedText: string\n mutedText: string\n secondaryTextNew: string\n selectionBg: string\n info: string\n dim: string\n primaryText: string\n}\n\nconst lightTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#e9c61aff',\n secondaryBorder: '#999',\n text: '#000',\n secondaryText: '#666',\n suggestion: '#32e98aff',\n success: '#2c7a39',\n error: '#ab2b3f',\n warning: '#966c1e',\n primary: '#000',\n secondary: '#666',\n diff: {\n added: '#69db7c',\n removed: '#ffa8b4',\n addedDimmed: '#c7e1cb',\n removedDimmed: '#fdd2d8',\n },\n brand: '#D4BBFF',\n dimmedText: '#888',\n mutedText: '#999',\n secondaryTextNew: '#666',\n selectionBg: '#3C3C3C',\n info: '#3399ff',\n dim: '#aaa',\n primaryText: '#000',\n}\n\nconst lightDaltonizedTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#3366ff',\n secondaryBorder: '#999',\n text: '#000',\n secondaryText: '#666',\n suggestion: '#3366ff',\n success: '#006699',\n error: '#cc0000',\n warning: '#ff9900',\n primary: '#000',\n secondary: '#666',\n diff: {\n added: '#99ccff',\n removed: '#ffcccc',\n addedDimmed: '#d1e7fd',\n removedDimmed: '#ffe9e9',\n },\n brand: '#3366ff',\n dimmedText: '#888',\n mutedText: '#999',\n secondaryTextNew: '#666',\n selectionBg: '#3C3C3C',\n info: '#3366ff',\n dim: '#aaa',\n primaryText: '#000',\n}\n\nconst darkTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#b1b9f9',\n secondaryBorder: '#888',\n text: '#fff',\n secondaryText: '#999',\n suggestion: '#b1b9f9',\n success: '#4eba65',\n error: '#ff6b80',\n warning: '#ffc107',\n primary: '#fff',\n secondary: '#999',\n diff: {\n added: '#225c2b',\n removed: '#7a2936',\n addedDimmed: '#47584a',\n removedDimmed: '#69484d',\n },\n brand: '#D4BBFF',\n dimmedText: '#666',\n mutedText: '#555',\n secondaryTextNew: '#999',\n selectionBg: '#3C3C3C',\n info: '#5DADE2',\n dim: '#444',\n primaryText: '#fff',\n}\n\nconst darkDaltonizedTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#99ccff',\n secondaryBorder: '#888',\n text: '#fff',\n secondaryText: '#999',\n suggestion: '#99ccff',\n success: '#3399ff',\n error: '#ff6666',\n warning: '#ffcc00',\n primary: '#fff',\n secondary: '#999',\n diff: {\n added: '#004466',\n removed: '#660000',\n addedDimmed: '#3e515b',\n removedDimmed: '#3e2c2c',\n },\n brand: '#99ccff',\n dimmedText: '#666',\n mutedText: '#555',\n secondaryTextNew: '#999',\n selectionBg: '#3C3C3C',\n info: '#99ccff',\n dim: '#444',\n primaryText: '#fff',\n}\n\nexport type ThemeNames
|
|
5
|
-
"mappings": "AAAA,SAAS,uBAAuB;AAiChC,MAAM,aAAoB;AAAA,EACxB,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,uBAA8B;AAAA,EAClC,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,YAAmB;AAAA,EACvB,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,sBAA6B;AAAA,EACjC,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;
|
|
4
|
+
"sourcesContent": ["import { getGlobalConfig } from './config'\n\nexport interface Theme {\n bashBorder: string\n minto: string\n noting: string\n permission: string\n secondaryBorder: string\n text: string\n secondaryText: string\n suggestion: string\n success: string\n error: string\n warning: string\n primary: string\n secondary: string\n diff: {\n added: string\n removed: string\n addedDimmed: string\n removedDimmed: string\n }\n // Additional color properties used in components\n brand: string\n dimmedText: string\n mutedText: string\n secondaryTextNew: string\n selectionBg: string\n info: string\n dim: string\n primaryText: string\n}\n\nconst lightTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#e9c61aff',\n secondaryBorder: '#999',\n text: '#000',\n secondaryText: '#666',\n suggestion: '#32e98aff',\n success: '#2c7a39',\n error: '#ab2b3f',\n warning: '#966c1e',\n primary: '#000',\n secondary: '#666',\n diff: {\n added: '#69db7c',\n removed: '#ffa8b4',\n addedDimmed: '#c7e1cb',\n removedDimmed: '#fdd2d8',\n },\n brand: '#D4BBFF',\n dimmedText: '#888',\n mutedText: '#999',\n secondaryTextNew: '#666',\n selectionBg: '#3C3C3C',\n info: '#3399ff',\n dim: '#aaa',\n primaryText: '#000',\n}\n\nconst lightDaltonizedTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#3366ff',\n secondaryBorder: '#999',\n text: '#000',\n secondaryText: '#666',\n suggestion: '#3366ff',\n success: '#006699',\n error: '#cc0000',\n warning: '#ff9900',\n primary: '#000',\n secondary: '#666',\n diff: {\n added: '#99ccff',\n removed: '#ffcccc',\n addedDimmed: '#d1e7fd',\n removedDimmed: '#ffe9e9',\n },\n brand: '#3366ff',\n dimmedText: '#888',\n mutedText: '#999',\n secondaryTextNew: '#666',\n selectionBg: '#3C3C3C',\n info: '#3366ff',\n dim: '#aaa',\n primaryText: '#000',\n}\n\nconst darkTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#b1b9f9',\n secondaryBorder: '#888',\n text: '#fff',\n secondaryText: '#999',\n suggestion: '#b1b9f9',\n success: '#4eba65',\n error: '#ff6b80',\n warning: '#ffc107',\n primary: '#fff',\n secondary: '#999',\n diff: {\n added: '#225c2b',\n removed: '#7a2936',\n addedDimmed: '#47584a',\n removedDimmed: '#69484d',\n },\n brand: '#D4BBFF',\n dimmedText: '#666',\n mutedText: '#555',\n secondaryTextNew: '#999',\n selectionBg: '#3C3C3C',\n info: '#5DADE2',\n dim: '#444',\n primaryText: '#fff',\n}\n\nconst darkDaltonizedTheme: Theme = {\n bashBorder: '#FF6E57',\n minto: '#FFC233',\n noting: '#222222',\n permission: '#99ccff',\n secondaryBorder: '#888',\n text: '#fff',\n secondaryText: '#999',\n suggestion: '#99ccff',\n success: '#3399ff',\n error: '#ff6666',\n warning: '#ffcc00',\n primary: '#fff',\n secondary: '#999',\n diff: {\n added: '#004466',\n removed: '#660000',\n addedDimmed: '#3e515b',\n removedDimmed: '#3e2c2c',\n },\n brand: '#99ccff',\n dimmedText: '#666',\n mutedText: '#555',\n secondaryTextNew: '#999',\n selectionBg: '#3C3C3C',\n info: '#99ccff',\n dim: '#444',\n primaryText: '#fff',\n}\n\nexport type ThemeNames =\n | 'dark'\n | 'light'\n | 'light-daltonized'\n | 'dark-daltonized'\n\nexport function getTheme(overrideTheme?: ThemeNames): Theme {\n const config = getGlobalConfig()\n switch (overrideTheme ?? config.theme) {\n case 'light':\n return lightTheme\n case 'light-daltonized':\n return lightDaltonizedTheme\n case 'dark-daltonized':\n return darkDaltonizedTheme\n default:\n return darkTheme\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,uBAAuB;AAiChC,MAAM,aAAoB;AAAA,EACxB,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,uBAA8B;AAAA,EAClC,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,YAAmB;AAAA,EACvB,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAEA,MAAM,sBAA6B;AAAA,EACjC,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AACf;AAQO,SAAS,SAAS,eAAmC;AAC1D,QAAM,SAAS,gBAAgB;AAC/B,UAAQ,iBAAiB,OAAO,OAAO;AAAA,IACrC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/thinking.ts"],
|
|
4
|
-
"sourcesContent": ["import { last } from 'lodash-es'\nimport type { Message } from '@query'\nimport { getLastAssistantMessageId } from './messages'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { USE_BEDROCK, USE_VERTEX, getModelManager } from './model'\n\nexport async function getMaxThinkingTokens(\n messages: Message[],\n): Promise<number> {\n if (process.env.MAX_THINKING_TOKENS) {\n const tokens = parseInt(process.env.MAX_THINKING_TOKENS, 10)\n return tokens\n }\n\n if (await ThinkTool.isEnabled()) {\n return 0\n }\n\n const lastMessage = last(messages)\n if (\n lastMessage?.type !== 'user' ||\n typeof lastMessage.message.content !== 'string'\n ) {\n return 0\n }\n\n const content = lastMessage.message.content.toLowerCase()\n if (\n content.includes('think harder') ||\n content.includes('think intensely') ||\n content.includes('think longer') ||\n content.includes('think really hard') ||\n content.includes('think super hard') ||\n content.includes('think very hard') ||\n content.includes('ultrathink')\n ) {\n return 32_000 - 1\n }\n\n if (\n content.includes('think about it') ||\n content.includes('think a lot') ||\n content.includes('think hard') ||\n content.includes('think more') ||\n content.includes('megathink')\n ) {\n return 10_000\n }\n\n if (content.includes('think')) {\n return 4_000\n }\n\n return 0\n}\n\nexport async function getReasoningEffort(\n modelProfile: any,\n messages: Message[],\n): Promise<'low' | 'medium' | 'high' | null> {\n const thinkingTokens = await getMaxThinkingTokens(messages)\n\n // Get reasoning effort from ModelProfile first, then fallback to config\n let reasoningEffort: 'low' | 'medium' | 'high' | undefined\n if (modelProfile?.reasoningEffort) {\n reasoningEffort = modelProfile.reasoningEffort\n } else {\n // \uD83D\uDD27 Fix: Use ModelManager fallback instead of legacy config\n const modelManager = getModelManager()\n const fallbackProfile = modelManager.getModel('main')\n reasoningEffort
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAkC,uBAAuB;AAEzD,eAAsB,qBACpB,UACiB;AACjB,MAAI,QAAQ,IAAI,qBAAqB;AACnC,UAAM,SAAS,SAAS,QAAQ,IAAI,qBAAqB,EAAE;AAC3D,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,UAAU,UAAU,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,KAAK,QAAQ;AACjC,MACE,aAAa,SAAS,UACtB,OAAO,YAAY,QAAQ,YAAY,UACvC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,YAAY,QAAQ,QAAQ,YAAY;AACxD,MACE,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,kBAAkB,KACnC,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,YAAY,GAC7B;AACA,WAAO,OAAS;AAAA,EAClB;AAEA,MACE,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,aAAa,KAC9B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,WAAW,GAC5B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAsB,mBACpB,cACA,UAC2C;AAC3C,QAAM,iBAAiB,MAAM,qBAAqB,QAAQ;AAG1D,MAAI;AACJ,MAAI,cAAc,iBAAiB;AACjC,sBAAkB,aAAa;AAAA,EACjC,OAAO;AAEL,UAAM,eAAe,gBAAgB;AACrC,UAAM,kBAAkB,aAAa,SAAS,MAAM;AACpD,
|
|
4
|
+
"sourcesContent": ["import { last } from 'lodash-es'\nimport type { Message } from '@query'\nimport { getLastAssistantMessageId } from './messages'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { USE_BEDROCK, USE_VERTEX, getModelManager } from './model'\n\nexport async function getMaxThinkingTokens(\n messages: Message[],\n): Promise<number> {\n if (process.env.MAX_THINKING_TOKENS) {\n const tokens = parseInt(process.env.MAX_THINKING_TOKENS, 10)\n return tokens\n }\n\n if (await ThinkTool.isEnabled()) {\n return 0\n }\n\n const lastMessage = last(messages)\n if (\n lastMessage?.type !== 'user' ||\n typeof lastMessage.message.content !== 'string'\n ) {\n return 0\n }\n\n const content = lastMessage.message.content.toLowerCase()\n if (\n content.includes('think harder') ||\n content.includes('think intensely') ||\n content.includes('think longer') ||\n content.includes('think really hard') ||\n content.includes('think super hard') ||\n content.includes('think very hard') ||\n content.includes('ultrathink')\n ) {\n return 32_000 - 1\n }\n\n if (\n content.includes('think about it') ||\n content.includes('think a lot') ||\n content.includes('think hard') ||\n content.includes('think more') ||\n content.includes('megathink')\n ) {\n return 10_000\n }\n\n if (content.includes('think')) {\n return 4_000\n }\n\n return 0\n}\n\nexport async function getReasoningEffort(\n modelProfile: any,\n messages: Message[],\n): Promise<'low' | 'medium' | 'high' | null> {\n const thinkingTokens = await getMaxThinkingTokens(messages)\n\n // Get reasoning effort from ModelProfile first, then fallback to config\n let reasoningEffort: 'low' | 'medium' | 'high' | undefined\n if (modelProfile?.reasoningEffort) {\n reasoningEffort = modelProfile.reasoningEffort\n } else {\n // \uD83D\uDD27 Fix: Use ModelManager fallback instead of legacy config\n const modelManager = getModelManager()\n const fallbackProfile = modelManager.getModel('main')\n reasoningEffort =\n (fallbackProfile?.reasoningEffort === 'minimal'\n ? 'low'\n : fallbackProfile?.reasoningEffort) || 'medium'\n }\n\n const maxEffort =\n reasoningEffort === 'high'\n ? 2\n : reasoningEffort === 'medium'\n ? 1\n : reasoningEffort === 'low'\n ? 0\n : null\n if (!maxEffort) {\n return null\n }\n\n let effort = 0\n if (thinkingTokens < 10_000) {\n effort = 0\n } else if (thinkingTokens >= 10_000 && thinkingTokens < 30_000) {\n effort = 1\n } else {\n effort = 2\n }\n\n if (effort > maxEffort) {\n return maxEffort === 2 ? 'high' : maxEffort === 1 ? 'medium' : 'low'\n }\n\n return effort === 2 ? 'high' : effort === 1 ? 'medium' : 'low'\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAkC,uBAAuB;AAEzD,eAAsB,qBACpB,UACiB;AACjB,MAAI,QAAQ,IAAI,qBAAqB;AACnC,UAAM,SAAS,SAAS,QAAQ,IAAI,qBAAqB,EAAE;AAC3D,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,UAAU,UAAU,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,KAAK,QAAQ;AACjC,MACE,aAAa,SAAS,UACtB,OAAO,YAAY,QAAQ,YAAY,UACvC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,YAAY,QAAQ,QAAQ,YAAY;AACxD,MACE,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,kBAAkB,KACnC,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,YAAY,GAC7B;AACA,WAAO,OAAS;AAAA,EAClB;AAEA,MACE,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,aAAa,KAC9B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,WAAW,GAC5B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAsB,mBACpB,cACA,UAC2C;AAC3C,QAAM,iBAAiB,MAAM,qBAAqB,QAAQ;AAG1D,MAAI;AACJ,MAAI,cAAc,iBAAiB;AACjC,sBAAkB,aAAa;AAAA,EACjC,OAAO;AAEL,UAAM,eAAe,gBAAgB;AACrC,UAAM,kBAAkB,aAAa,SAAS,MAAM;AACpD,uBACG,iBAAiB,oBAAoB,YAClC,QACA,iBAAiB,oBAAoB;AAAA,EAC7C;AAEA,QAAM,YACJ,oBAAoB,SAChB,IACA,oBAAoB,WAClB,IACA,oBAAoB,QAClB,IACA;AACV,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,MAAI,iBAAiB,KAAQ;AAC3B,aAAS;AAAA,EACX,WAAW,kBAAkB,OAAU,iBAAiB,KAAQ;AAC9D,aAAS;AAAA,EACX,OAAO;AACL,aAAS;AAAA,EACX;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,cAAc,IAAI,SAAS,cAAc,IAAI,WAAW;AAAA,EACjE;AAEA,SAAO,WAAW,IAAI,SAAS,WAAW,IAAI,WAAW;AAC3D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/unaryLogging.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["export type CompletionType =\n | 'str_replace_single'\n | 'write_file_single'\n | 'tool_use_single'\n\ntype LogEvent = {\n completion_type: CompletionType\n event: 'accept' | 'reject' | 'response'\n metadata: {\n language_name: string\n message_id: string\n platform: string\n }\n}\n\nexport function logUnaryEvent(event: LogEvent): void {\n // intentionally no-op\n}\n"],
|
|
5
|
+
"mappings": "AAeO,SAAS,cAAc,OAAuB;AAErD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Application version\n * This file is auto-generated during build process\n */\n\nexport const VERSION = '0.1.
|
|
4
|
+
"sourcesContent": ["/**\n * Application version\n * This file is auto-generated during build process\n */\n\nexport const VERSION = '0.1.6'\nexport const BUILD_DATE = '2025-12-30T04:03:47.920Z'\n"],
|
|
5
5
|
"mappings": "AAKO,MAAM,UAAU;AAChB,MAAM,aAAa;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@within-7/minto",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"bin": {
|
|
5
|
-
"minto": "cli.js"
|
|
6
|
-
"mt": "cli.js"
|
|
5
|
+
"minto": "cli.js"
|
|
7
6
|
},
|
|
8
7
|
"engines": {
|
|
9
8
|
"node": ">=20.0.0"
|
|
@@ -50,6 +49,7 @@
|
|
|
50
49
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
51
50
|
"@types/lodash-es": "^4.17.12",
|
|
52
51
|
"@types/react": "^19.1.8",
|
|
52
|
+
"@within-7/minto": "0.1.5",
|
|
53
53
|
"ansi-escapes": "^7.0.0",
|
|
54
54
|
"chalk": "^5.4.1",
|
|
55
55
|
"cli-highlight": "^2.1.11",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"node-html-parser": "^7.0.1",
|
|
76
76
|
"openai": "^4.104.0",
|
|
77
77
|
"react": "18.3.1",
|
|
78
|
+
"react-devtools-core": "^4.28.5",
|
|
78
79
|
"semver": "^7.7.2",
|
|
79
80
|
"shell-quote": "^1.8.3",
|
|
80
81
|
"signal-exit": "3.0.7",
|
|
@@ -86,8 +87,7 @@
|
|
|
86
87
|
"undici": "^6.22.0",
|
|
87
88
|
"wrap-ansi": "8.1.0",
|
|
88
89
|
"zod": "^3.25.76",
|
|
89
|
-
"zod-to-json-schema": "^3.24.6"
|
|
90
|
-
"react-devtools-core": "^4.28.5"
|
|
90
|
+
"zod-to-json-schema": "^3.24.6"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
93
|
"@types/bun": "latest",
|