@within-7/minto 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +155 -37
- package/dist/Tool.js +38 -0
- package/dist/Tool.js.map +3 -3
- package/dist/commands/agents/AgentsCommand.js +52 -26
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +1 -1
- package/dist/commands/agents/constants.js.map +1 -1
- package/dist/commands/agents/index.js +1 -1
- package/dist/commands/bug.js +74 -7
- package/dist/commands/bug.js.map +3 -3
- package/dist/commands/clear.js +3 -0
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +37 -0
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/context.js +84 -0
- package/dist/commands/context.js.map +7 -0
- package/dist/commands/ctx_viz.js +18 -10
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/doctor.js.map +2 -2
- package/dist/commands/export.js +156 -0
- package/dist/commands/export.js.map +7 -0
- package/dist/commands/mcp-interactive.js +21 -12
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +6 -5
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +86 -0
- package/dist/commands/permissions.js.map +7 -0
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/sandbox.js +104 -0
- package/dist/commands/sandbox.js.map +7 -0
- package/dist/commands/status.js +58 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/tasks.js +108 -0
- package/dist/commands/tasks.js.map +7 -0
- package/dist/commands/todos.js +123 -0
- package/dist/commands/todos.js.map +7 -0
- package/dist/commands.js +20 -2
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +10 -18
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +78 -29
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/BashStreamingProgress.js +24 -0
- package/dist/components/BashStreamingProgress.js.map +7 -0
- package/dist/components/CollapsibleHint.js +14 -0
- package/dist/components/CollapsibleHint.js.map +7 -0
- package/dist/components/FileEditToolUpdatedMessage.js +1 -1
- package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +137 -0
- package/dist/components/HotkeyHelpPanel.js.map +7 -0
- package/dist/components/Logo.js +5 -5
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/Message.js +23 -7
- package/dist/components/Message.js.map +3 -3
- package/dist/components/ModelConfig.js +16 -3
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +3 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +1 -1
- package/dist/components/Onboarding.js +19 -14
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/ProgressBar.js +74 -0
- package/dist/components/ProgressBar.js.map +7 -0
- package/dist/components/PromptInput.js +156 -46
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RequestStatusIndicator.js +194 -0
- package/dist/components/RequestStatusIndicator.js.map +7 -0
- package/dist/components/Spinner.js +92 -27
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/SpinnerSymbol.js +21 -27
- package/dist/components/SpinnerSymbol.js.map +2 -2
- package/dist/components/StreamingBashOutput.js +9 -8
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/SubagentBlock.js +1 -1
- package/dist/components/SubagentBlock.js.map +1 -1
- package/dist/components/SubagentProgress.js +10 -11
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +16 -13
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TodoChangeBlock.js +1 -1
- package/dist/components/TodoChangeBlock.js.map +2 -2
- package/dist/components/TodoPanel.js +120 -29
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TokenCounter.js +74 -0
- package/dist/components/TokenCounter.js.map +7 -0
- package/dist/components/TokenWarning.js +2 -1
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/TreeConnector.js +25 -0
- package/dist/components/TreeConnector.js.map +7 -0
- package/dist/components/TurnCompletionIndicator.js +18 -0
- package/dist/components/TurnCompletionIndicator.js.map +7 -0
- package/dist/components/messages/AssistantTextMessage.js +5 -2
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantThinkingMessage.js +18 -3
- package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +11 -8
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +53 -0
- package/dist/components/messages/GroupRenderer.js.map +7 -0
- package/dist/components/messages/NestedTasksPreview.js +12 -0
- package/dist/components/messages/NestedTasksPreview.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +92 -0
- package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
- package/dist/components/messages/TaskInModuleView.js +198 -0
- package/dist/components/messages/TaskInModuleView.js.map +7 -0
- package/dist/components/messages/TaskOutputContent.js +53 -0
- package/dist/components/messages/TaskOutputContent.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +1 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
- package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
- package/dist/constants/colors.js +48 -0
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/formatRules.js +102 -0
- package/dist/constants/formatRules.js.map +7 -0
- package/dist/constants/prompts.js +12 -34
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/symbols.js +64 -6
- package/dist/constants/symbols.js.map +2 -2
- package/dist/constants/timing.js +5 -0
- package/dist/constants/timing.js.map +2 -2
- package/dist/core/config/defaults.js +84 -0
- package/dist/core/config/defaults.js.map +7 -0
- package/dist/core/config/index.js +111 -0
- package/dist/core/config/index.js.map +7 -0
- package/dist/core/config/loader.js +221 -0
- package/dist/core/config/loader.js.map +7 -0
- package/dist/core/config/migrations.js +128 -0
- package/dist/core/config/migrations.js.map +7 -0
- package/dist/core/config/schema.js +178 -0
- package/dist/core/config/schema.js.map +7 -0
- package/dist/core/costTracker.js +138 -0
- package/dist/core/costTracker.js.map +7 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +7 -0
- package/dist/core/permissions/auditLog.js +204 -0
- package/dist/core/permissions/auditLog.js.map +7 -0
- package/dist/core/permissions/engine/index.js +3 -0
- package/dist/core/permissions/engine/index.js.map +7 -0
- package/dist/core/permissions/engine/permissionEngine.js +106 -0
- package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
- package/dist/core/permissions/engine/types.js +1 -0
- package/dist/core/permissions/engine/types.js.map +7 -0
- package/dist/core/permissions/index.js +84 -0
- package/dist/core/permissions/index.js.map +7 -0
- package/dist/core/permissions/ruleEngine.js +259 -0
- package/dist/core/permissions/ruleEngine.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
- package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
- package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
- package/dist/core/permissions/rules/index.js +46 -0
- package/dist/core/permissions/rules/index.js.map +7 -0
- package/dist/core/permissions/rules/planModeRule.js +55 -0
- package/dist/core/permissions/rules/planModeRule.js.map +7 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
- package/dist/core/permissions/rules/safeModeRule.js +65 -0
- package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
- package/dist/core/permissions/types.js +127 -0
- package/dist/core/permissions/types.js.map +7 -0
- package/dist/core/tools/executor.js +143 -0
- package/dist/core/tools/executor.js.map +7 -0
- package/dist/core/tools/index.js +15 -0
- package/dist/core/tools/index.js.map +7 -0
- package/dist/core/tools/registry.js +183 -0
- package/dist/core/tools/registry.js.map +7 -0
- package/dist/core/tools/types.js +1 -0
- package/dist/core/tools/types.js.map +7 -0
- package/dist/cost-tracker.js +23 -15
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/cli.js +43 -43
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/entrypoints/mcp.js +12 -4
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/history.js +14 -3
- package/dist/history.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +116 -0
- package/dist/hooks/useAgentTranscripts.js.map +7 -0
- package/dist/hooks/useAnimationSync.js +53 -0
- package/dist/hooks/useAnimationSync.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +4 -2
- package/dist/hooks/useArrowKeyHistory.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +3 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useCancelRequest.js +4 -1
- package/dist/hooks/useCancelRequest.js.map +2 -2
- package/dist/hooks/useExitOnCtrlCD.js +9 -5
- package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
- package/dist/hooks/useHookStatus.js +40 -0
- package/dist/hooks/useHookStatus.js.map +7 -0
- package/dist/hooks/useLogMessages.js +17 -1
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/hooks/useMessageGroups.js +43 -0
- package/dist/hooks/useMessageGroups.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +62 -6
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +69 -0
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.js +347 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/index.js +7 -0
- package/dist/i18n/locales/index.js.map +7 -0
- package/dist/i18n/locales/zh-CN.js +347 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/query.js +175 -17
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +501 -192
- package/dist/screens/REPL.js.map +3 -3
- package/dist/services/adapters/chatCompletions.js +3 -1
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/messageNormalizer.js +354 -0
- package/dist/services/adapters/messageNormalizer.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +6 -3
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/checkpointManager.js +386 -0
- package/dist/services/checkpointManager.js.map +7 -0
- package/dist/services/claude.js +138 -11
- package/dist/services/claude.js.map +3 -3
- package/dist/services/compressionService.js +50 -1
- package/dist/services/compressionService.js.map +2 -2
- package/dist/services/contextMonitor.js +162 -0
- package/dist/services/contextMonitor.js.map +7 -0
- package/dist/services/customCommands.js +60 -41
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/hookExecutor.js +173 -1
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/intelligentCompactor.js +281 -0
- package/dist/services/intelligentCompactor.js.map +7 -0
- package/dist/services/lspConfig.js +109 -0
- package/dist/services/lspConfig.js.map +7 -0
- package/dist/services/mcpClient.js +273 -34
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/modelOrchestrator.js +310 -0
- package/dist/services/modelOrchestrator.js.map +7 -0
- package/dist/services/openai.js +8 -1
- package/dist/services/openai.js.map +2 -2
- package/dist/services/outputStyles.js +138 -0
- package/dist/services/outputStyles.js.map +7 -0
- package/dist/services/plugins/index.js +5 -0
- package/dist/services/plugins/index.js.map +7 -0
- package/dist/services/plugins/lspServers.js +188 -0
- package/dist/services/plugins/lspServers.js.map +7 -0
- package/dist/services/plugins/pluginRuntime.js +229 -0
- package/dist/services/plugins/pluginRuntime.js.map +7 -0
- package/dist/services/plugins/pluginValidation.js +219 -0
- package/dist/services/plugins/pluginValidation.js.map +7 -0
- package/dist/services/plugins/skillMarketplace.js +556 -0
- package/dist/services/plugins/skillMarketplace.js.map +7 -0
- package/dist/services/responseStateManager.js +37 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +300 -0
- package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
- package/dist/services/sandbox/index.js +14 -0
- package/dist/services/sandbox/index.js.map +7 -0
- package/dist/services/sandbox/networkProxy.js +293 -0
- package/dist/services/sandbox/networkProxy.js.map +7 -0
- package/dist/services/sandbox/sandboxController.js +574 -0
- package/dist/services/sandbox/sandboxController.js.map +7 -0
- package/dist/services/sandbox/types.js +50 -0
- package/dist/services/sandbox/types.js.map +7 -0
- package/dist/services/sessionMemory.js +266 -0
- package/dist/services/sessionMemory.js.map +7 -0
- package/dist/services/taskRouter.js +324 -0
- package/dist/services/taskRouter.js.map +7 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BaseTool.js +72 -0
- package/dist/tools/BaseTool.js.map +7 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +60 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/OutputLine.js +54 -0
- package/dist/tools/BashTool/OutputLine.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +192 -3
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +29 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +4 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +36 -7
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
- package/dist/tools/LspTool/LspTool.js +664 -0
- package/dist/tools/LspTool/LspTool.js.map +7 -0
- package/dist/tools/LspTool/prompt.js +27 -0
- package/dist/tools/LspTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +9 -1
- package/dist/tools/MCPTool/MCPTool.js.map +2 -2
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/prompt.js +94 -0
- package/dist/tools/PlanModeTool/prompt.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
- package/dist/tools/SkillTool/SkillTool.js +6 -1
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
- package/dist/tools/SlashCommandTool/prompt.js +35 -0
- package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
- package/dist/tools/TaskOutputTool/prompt.js +15 -0
- package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +302 -104
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +55 -8
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools.js +31 -2
- package/dist/tools.js.map +2 -2
- package/dist/types/hooks.js +4 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/messageGroup.js +36 -0
- package/dist/types/messageGroup.js.map +7 -0
- package/dist/types/plugin.js.map +2 -2
- package/dist/types/thinking.js +1 -0
- package/dist/types/thinking.js.map +7 -0
- package/dist/utils/BackgroundShellManager.js +136 -39
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/MessageBatchBuffer.js +102 -0
- package/dist/utils/MessageBatchBuffer.js.map +7 -0
- package/dist/utils/PersistentShell.js +151 -1
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/agentLoader.js +1 -23
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentTranscripts.js +641 -0
- package/dist/utils/agentTranscripts.js.map +7 -0
- package/dist/utils/animationManager.js +213 -0
- package/dist/utils/animationManager.js.map +7 -0
- package/dist/utils/animationSync.js +110 -0
- package/dist/utils/animationSync.js.map +7 -0
- package/dist/utils/asyncFile.js +215 -0
- package/dist/utils/asyncFile.js.map +7 -0
- package/dist/utils/backgroundAgentManager.js +231 -0
- package/dist/utils/backgroundAgentManager.js.map +7 -0
- package/dist/utils/config.js +63 -7
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/conversationRecovery.js +19 -0
- package/dist/utils/conversationRecovery.js.map +2 -2
- package/dist/utils/exit.js +73 -0
- package/dist/utils/exit.js.map +7 -0
- package/dist/utils/format.js +73 -5
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/generators.js +76 -6
- package/dist/utils/generators.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +149 -0
- package/dist/utils/globalErrorHandler.js.map +7 -0
- package/dist/utils/groupHandlers/index.js +8 -0
- package/dist/utils/groupHandlers/index.js.map +7 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
- package/dist/utils/groupHandlers/taskHandler.js +104 -0
- package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
- package/dist/utils/groupHandlers/types.js +1 -0
- package/dist/utils/groupHandlers/types.js.map +7 -0
- package/dist/utils/logRotation.js +224 -0
- package/dist/utils/logRotation.js.map +7 -0
- package/dist/utils/marketplaceManager.js +3 -5
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memSafety.js +264 -0
- package/dist/utils/memSafety.js.map +7 -0
- package/dist/utils/messageGroupManager.js +274 -0
- package/dist/utils/messageGroupManager.js.map +7 -0
- package/dist/utils/messages.js +13 -4
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +119 -15
- package/dist/utils/model.js.map +3 -3
- package/dist/utils/permissions/filesystem.js +157 -5
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/plan/planMode.js +143 -0
- package/dist/utils/plan/planMode.js.map +7 -0
- package/dist/utils/pluginLoader.js +17 -21
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/ripgrep.js +55 -2
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/sanitizeInput.js +32 -0
- package/dist/utils/sanitizeInput.js.map +7 -0
- package/dist/utils/secureKeyStorage.js +312 -0
- package/dist/utils/secureKeyStorage.js.map +7 -0
- package/dist/utils/session/sessionPlugins.js +67 -0
- package/dist/utils/session/sessionPlugins.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +257 -0
- package/dist/utils/taskDisplayUtils.js.map +7 -0
- package/dist/utils/teamConfig.js +2 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/todoStorage.js +92 -2
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/toolTimeout.js +136 -0
- package/dist/utils/toolTimeout.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +115 -0
- package/dist/utils/tooling/safeRender.js.map +7 -0
- package/dist/utils/userFriendlyError.js +346 -0
- package/dist/utils/userFriendlyError.js.map +7 -0
- package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +14 -4
- package/scripts/postinstall.js +128 -38
- package/dist/commands/agents.js +0 -2086
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/build.js +0 -74
- package/dist/commands/build.js.map +0 -7
- package/dist/commands/compression.js +0 -57
- package/dist/commands/compression.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -40
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/mcp_refresh.js +0 -40
- package/dist/commands/mcp_refresh.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/plugin-interactive.js +0 -446
- package/dist/commands/plugin-interactive.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -2062
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/entrypoints/cli-wrapper.js +0 -61
- package/dist/entrypoints/cli-wrapper.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync, unlinkSync, rmSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import envPaths from "env-paths";
|
|
4
|
+
import { PRODUCT_COMMAND } from "../constants/product.js";
|
|
5
|
+
const paths = envPaths(PRODUCT_COMMAND);
|
|
6
|
+
const DEFAULT_RETENTION_CONFIG = {
|
|
7
|
+
maxAgeDays: 30,
|
|
8
|
+
maxSizeMB: 500,
|
|
9
|
+
// 500MB total
|
|
10
|
+
patterns: ["*.json", "*.txt", "*.log"]
|
|
11
|
+
};
|
|
12
|
+
function matchesPattern(filename, patterns) {
|
|
13
|
+
return patterns.some((pattern) => {
|
|
14
|
+
if (pattern.startsWith("*.")) {
|
|
15
|
+
const ext = pattern.slice(1);
|
|
16
|
+
return filename.endsWith(ext);
|
|
17
|
+
}
|
|
18
|
+
return filename === pattern;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function getLogDirectories() {
|
|
22
|
+
const cacheDir = paths.cache;
|
|
23
|
+
if (!existsSync(cacheDir)) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const entries = readdirSync(cacheDir, { withFileTypes: true });
|
|
28
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => join(cacheDir, entry.name));
|
|
29
|
+
} catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function getLogFiles(dir, patterns) {
|
|
34
|
+
const files = [];
|
|
35
|
+
if (!existsSync(dir)) {
|
|
36
|
+
return files;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
const fullPath = join(dir, entry.name);
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
files.push(...getLogFiles(fullPath, patterns));
|
|
44
|
+
} else if (entry.isFile() && matchesPattern(entry.name, patterns)) {
|
|
45
|
+
try {
|
|
46
|
+
const stats = statSync(fullPath);
|
|
47
|
+
files.push({
|
|
48
|
+
path: fullPath,
|
|
49
|
+
size: stats.size,
|
|
50
|
+
mtime: stats.mtime
|
|
51
|
+
});
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
return files;
|
|
59
|
+
}
|
|
60
|
+
function safeDeleteFile(filePath) {
|
|
61
|
+
try {
|
|
62
|
+
unlinkSync(filePath);
|
|
63
|
+
return true;
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function cleanEmptyDirectories(dir) {
|
|
69
|
+
if (!existsSync(dir)) return;
|
|
70
|
+
try {
|
|
71
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (entry.isDirectory()) {
|
|
74
|
+
cleanEmptyDirectories(join(dir, entry.name));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const remaining = readdirSync(dir);
|
|
78
|
+
if (remaining.length === 0) {
|
|
79
|
+
try {
|
|
80
|
+
rmSync(dir);
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function rotateByAge(files, maxAgeDays) {
|
|
88
|
+
const stats = {
|
|
89
|
+
filesDeleted: 0,
|
|
90
|
+
bytesFreed: 0,
|
|
91
|
+
errors: []
|
|
92
|
+
};
|
|
93
|
+
const cutoffDate = /* @__PURE__ */ new Date();
|
|
94
|
+
cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
if (file.mtime < cutoffDate) {
|
|
97
|
+
if (safeDeleteFile(file.path)) {
|
|
98
|
+
stats.filesDeleted++;
|
|
99
|
+
stats.bytesFreed += file.size;
|
|
100
|
+
} else {
|
|
101
|
+
stats.errors.push(`Failed to delete: ${file.path}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return stats;
|
|
106
|
+
}
|
|
107
|
+
function rotateBySize(files, maxSizeBytes) {
|
|
108
|
+
const stats = {
|
|
109
|
+
filesDeleted: 0,
|
|
110
|
+
bytesFreed: 0,
|
|
111
|
+
errors: []
|
|
112
|
+
};
|
|
113
|
+
const sortedFiles = [...files].sort(
|
|
114
|
+
(a, b) => a.mtime.getTime() - b.mtime.getTime()
|
|
115
|
+
);
|
|
116
|
+
let totalSize = sortedFiles.reduce((sum, f) => sum + f.size, 0);
|
|
117
|
+
for (const file of sortedFiles) {
|
|
118
|
+
if (totalSize <= maxSizeBytes) {
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
if (safeDeleteFile(file.path)) {
|
|
122
|
+
stats.filesDeleted++;
|
|
123
|
+
stats.bytesFreed += file.size;
|
|
124
|
+
totalSize -= file.size;
|
|
125
|
+
} else {
|
|
126
|
+
stats.errors.push(`Failed to delete: ${file.path}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return stats;
|
|
130
|
+
}
|
|
131
|
+
function rotateLogs(config = {}) {
|
|
132
|
+
const finalConfig = { ...DEFAULT_RETENTION_CONFIG, ...config };
|
|
133
|
+
const stats = {
|
|
134
|
+
filesDeleted: 0,
|
|
135
|
+
bytesFreed: 0,
|
|
136
|
+
errors: []
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
const logDirs = getLogDirectories();
|
|
140
|
+
const allFiles = [];
|
|
141
|
+
for (const dir of logDirs) {
|
|
142
|
+
allFiles.push(...getLogFiles(dir, finalConfig.patterns));
|
|
143
|
+
}
|
|
144
|
+
const ageStats = rotateByAge(allFiles, finalConfig.maxAgeDays);
|
|
145
|
+
stats.filesDeleted += ageStats.filesDeleted;
|
|
146
|
+
stats.bytesFreed += ageStats.bytesFreed;
|
|
147
|
+
stats.errors.push(...ageStats.errors);
|
|
148
|
+
const remainingFiles = allFiles.filter((f) => existsSync(f.path));
|
|
149
|
+
if (finalConfig.maxSizeMB > 0) {
|
|
150
|
+
const maxSizeBytes = finalConfig.maxSizeMB * 1024 * 1024;
|
|
151
|
+
const sizeStats = rotateBySize(remainingFiles, maxSizeBytes);
|
|
152
|
+
stats.filesDeleted += sizeStats.filesDeleted;
|
|
153
|
+
stats.bytesFreed += sizeStats.bytesFreed;
|
|
154
|
+
stats.errors.push(...sizeStats.errors);
|
|
155
|
+
}
|
|
156
|
+
for (const dir of logDirs) {
|
|
157
|
+
cleanEmptyDirectories(dir);
|
|
158
|
+
}
|
|
159
|
+
} catch (error) {
|
|
160
|
+
stats.errors.push(
|
|
161
|
+
`Rotation error: ${error instanceof Error ? error.message : String(error)}`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return stats;
|
|
165
|
+
}
|
|
166
|
+
function getLogStats() {
|
|
167
|
+
const logDirs = getLogDirectories();
|
|
168
|
+
const allFiles = [];
|
|
169
|
+
for (const dir of logDirs) {
|
|
170
|
+
allFiles.push(...getLogFiles(dir, DEFAULT_RETENTION_CONFIG.patterns));
|
|
171
|
+
}
|
|
172
|
+
if (allFiles.length === 0) {
|
|
173
|
+
return {
|
|
174
|
+
totalFiles: 0,
|
|
175
|
+
totalSizeBytes: 0,
|
|
176
|
+
oldestFile: null,
|
|
177
|
+
newestFile: null
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const sorted = allFiles.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
|
|
181
|
+
return {
|
|
182
|
+
totalFiles: allFiles.length,
|
|
183
|
+
totalSizeBytes: allFiles.reduce((sum, f) => sum + f.size, 0),
|
|
184
|
+
oldestFile: sorted[0]?.mtime ?? null,
|
|
185
|
+
newestFile: sorted[sorted.length - 1]?.mtime ?? null
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function runLogRotationInBackground(config) {
|
|
189
|
+
setImmediate(() => {
|
|
190
|
+
try {
|
|
191
|
+
const stats = rotateLogs(config);
|
|
192
|
+
if (stats.errors.length > 0 && process.env.VERBOSE === "true") {
|
|
193
|
+
console.warn(`Log rotation had ${stats.errors.length} errors`);
|
|
194
|
+
}
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function shouldRotate(config = {}) {
|
|
200
|
+
const finalConfig = { ...DEFAULT_RETENTION_CONFIG, ...config };
|
|
201
|
+
const stats = getLogStats();
|
|
202
|
+
if (stats.oldestFile) {
|
|
203
|
+
const cutoffDate = /* @__PURE__ */ new Date();
|
|
204
|
+
cutoffDate.setDate(cutoffDate.getDate() - finalConfig.maxAgeDays);
|
|
205
|
+
if (stats.oldestFile < cutoffDate) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (finalConfig.maxSizeMB > 0) {
|
|
210
|
+
const maxSizeBytes = finalConfig.maxSizeMB * 1024 * 1024;
|
|
211
|
+
if (stats.totalSizeBytes > maxSizeBytes) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
export {
|
|
218
|
+
DEFAULT_RETENTION_CONFIG,
|
|
219
|
+
getLogStats,
|
|
220
|
+
rotateLogs,
|
|
221
|
+
runLogRotationInBackground,
|
|
222
|
+
shouldRotate
|
|
223
|
+
};
|
|
224
|
+
//# sourceMappingURL=logRotation.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/logRotation.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Log Rotation Utility\n *\n * Automatically cleans up old log files to prevent disk space exhaustion.\n * Runs in the background and doesn't block the main application.\n */\n\nimport { existsSync, readdirSync, statSync, unlinkSync, rmSync } from 'fs'\nimport { join } from 'path'\nimport envPaths from 'env-paths'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\nconst paths = envPaths(PRODUCT_COMMAND)\n\n/**\n * Log retention configuration\n */\nexport interface LogRetentionConfig {\n /** Maximum age of log files in days */\n maxAgeDays: number\n /** Maximum total size of logs in MB (0 = unlimited) */\n maxSizeMB: number\n /** File patterns to clean (glob-like) */\n patterns: string[]\n}\n\n/**\n * Default retention configuration\n */\nexport const DEFAULT_RETENTION_CONFIG: LogRetentionConfig = {\n maxAgeDays: 30,\n maxSizeMB: 500, // 500MB total\n patterns: ['*.json', '*.txt', '*.log'],\n}\n\n/**\n * Statistics from log rotation\n */\nexport interface RotationStats {\n filesDeleted: number\n bytesFreed: number\n errors: string[]\n}\n\n/**\n * Check if a file matches any of the patterns\n */\nfunction matchesPattern(filename: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n // Simple glob matching for *.ext patterns\n if (pattern.startsWith('*.')) {\n const ext = pattern.slice(1) // Get .ext\n return filename.endsWith(ext)\n }\n return filename === pattern\n })\n}\n\n/**\n * Get all log directories in the cache path\n */\nfunction getLogDirectories(): string[] {\n const cacheDir = paths.cache\n if (!existsSync(cacheDir)) {\n return []\n }\n\n try {\n const entries = readdirSync(cacheDir, { withFileTypes: true })\n return entries\n .filter(entry => entry.isDirectory())\n .map(entry => join(cacheDir, entry.name))\n } catch {\n return []\n }\n}\n\n/**\n * Get all log files in a directory recursively\n */\nfunction getLogFiles(\n dir: string,\n patterns: string[],\n): Array<{ path: string; size: number; mtime: Date }> {\n const files: Array<{ path: string; size: number; mtime: Date }> = []\n\n if (!existsSync(dir)) {\n return files\n }\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name)\n\n if (entry.isDirectory()) {\n // Recurse into subdirectories\n files.push(...getLogFiles(fullPath, patterns))\n } else if (entry.isFile() && matchesPattern(entry.name, patterns)) {\n try {\n const stats = statSync(fullPath)\n files.push({\n path: fullPath,\n size: stats.size,\n mtime: stats.mtime,\n })\n } catch {\n // Skip files we can't stat\n }\n }\n }\n } catch {\n // Skip directories we can't read\n }\n\n return files\n}\n\n/**\n * Delete a file safely\n */\nfunction safeDeleteFile(filePath: string): boolean {\n try {\n unlinkSync(filePath)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Delete empty directories\n */\nfunction cleanEmptyDirectories(dir: string): void {\n if (!existsSync(dir)) return\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true })\n\n // First, clean subdirectories\n for (const entry of entries) {\n if (entry.isDirectory()) {\n cleanEmptyDirectories(join(dir, entry.name))\n }\n }\n\n // Then check if this directory is now empty\n const remaining = readdirSync(dir)\n if (remaining.length === 0) {\n try {\n rmSync(dir)\n } catch {\n // Ignore errors when removing directories\n }\n }\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Rotate logs based on age\n */\nfunction rotateByAge(\n files: Array<{ path: string; size: number; mtime: Date }>,\n maxAgeDays: number,\n): RotationStats {\n const stats: RotationStats = {\n filesDeleted: 0,\n bytesFreed: 0,\n errors: [],\n }\n\n const cutoffDate = new Date()\n cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays)\n\n for (const file of files) {\n if (file.mtime < cutoffDate) {\n if (safeDeleteFile(file.path)) {\n stats.filesDeleted++\n stats.bytesFreed += file.size\n } else {\n stats.errors.push(`Failed to delete: ${file.path}`)\n }\n }\n }\n\n return stats\n}\n\n/**\n * Rotate logs based on total size\n */\nfunction rotateBySize(\n files: Array<{ path: string; size: number; mtime: Date }>,\n maxSizeBytes: number,\n): RotationStats {\n const stats: RotationStats = {\n filesDeleted: 0,\n bytesFreed: 0,\n errors: [],\n }\n\n // Sort by modification time (oldest first)\n const sortedFiles = [...files].sort(\n (a, b) => a.mtime.getTime() - b.mtime.getTime(),\n )\n\n // Calculate total size\n let totalSize = sortedFiles.reduce((sum, f) => sum + f.size, 0)\n\n // Delete oldest files until we're under the limit\n for (const file of sortedFiles) {\n if (totalSize <= maxSizeBytes) {\n break\n }\n\n if (safeDeleteFile(file.path)) {\n stats.filesDeleted++\n stats.bytesFreed += file.size\n totalSize -= file.size\n } else {\n stats.errors.push(`Failed to delete: ${file.path}`)\n }\n }\n\n return stats\n}\n\n/**\n * Perform log rotation\n */\nexport function rotateLogs(\n config: Partial<LogRetentionConfig> = {},\n): RotationStats {\n const finalConfig = { ...DEFAULT_RETENTION_CONFIG, ...config }\n const stats: RotationStats = {\n filesDeleted: 0,\n bytesFreed: 0,\n errors: [],\n }\n\n try {\n // Get all log directories\n const logDirs = getLogDirectories()\n\n // Collect all log files\n const allFiles: Array<{ path: string; size: number; mtime: Date }> = []\n for (const dir of logDirs) {\n allFiles.push(...getLogFiles(dir, finalConfig.patterns))\n }\n\n // Rotate by age first\n const ageStats = rotateByAge(allFiles, finalConfig.maxAgeDays)\n stats.filesDeleted += ageStats.filesDeleted\n stats.bytesFreed += ageStats.bytesFreed\n stats.errors.push(...ageStats.errors)\n\n // Get remaining files (that weren't deleted by age rotation)\n const remainingFiles = allFiles.filter(f => existsSync(f.path))\n\n // Rotate by size if configured\n if (finalConfig.maxSizeMB > 0) {\n const maxSizeBytes = finalConfig.maxSizeMB * 1024 * 1024\n const sizeStats = rotateBySize(remainingFiles, maxSizeBytes)\n stats.filesDeleted += sizeStats.filesDeleted\n stats.bytesFreed += sizeStats.bytesFreed\n stats.errors.push(...sizeStats.errors)\n }\n\n // Clean up empty directories\n for (const dir of logDirs) {\n cleanEmptyDirectories(dir)\n }\n } catch (error) {\n stats.errors.push(\n `Rotation error: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n\n return stats\n}\n\n/**\n * Get current log storage statistics\n */\nexport function getLogStats(): {\n totalFiles: number\n totalSizeBytes: number\n oldestFile: Date | null\n newestFile: Date | null\n} {\n const logDirs = getLogDirectories()\n const allFiles: Array<{ path: string; size: number; mtime: Date }> = []\n\n for (const dir of logDirs) {\n allFiles.push(...getLogFiles(dir, DEFAULT_RETENTION_CONFIG.patterns))\n }\n\n if (allFiles.length === 0) {\n return {\n totalFiles: 0,\n totalSizeBytes: 0,\n oldestFile: null,\n newestFile: null,\n }\n }\n\n const sorted = allFiles.sort((a, b) => a.mtime.getTime() - b.mtime.getTime())\n\n return {\n totalFiles: allFiles.length,\n totalSizeBytes: allFiles.reduce((sum, f) => sum + f.size, 0),\n oldestFile: sorted[0]?.mtime ?? null,\n newestFile: sorted[sorted.length - 1]?.mtime ?? null,\n }\n}\n\n/**\n * Run log rotation in the background\n * This is fire-and-forget and won't block the main application\n */\nexport function runLogRotationInBackground(\n config?: Partial<LogRetentionConfig>,\n): void {\n // Use setImmediate to run after current event loop\n setImmediate(() => {\n try {\n const stats = rotateLogs(config)\n\n // Log rotation runs silently in background\n // Only log errors in verbose mode\n if (stats.errors.length > 0 && process.env.VERBOSE === 'true') {\n console.warn(`Log rotation had ${stats.errors.length} errors`)\n }\n } catch {\n // Silently ignore errors in background rotation\n }\n })\n}\n\n/**\n * Check if rotation is needed based on current stats\n */\nexport function shouldRotate(\n config: Partial<LogRetentionConfig> = {},\n): boolean {\n const finalConfig = { ...DEFAULT_RETENTION_CONFIG, ...config }\n const stats = getLogStats()\n\n // Check if any files are older than retention period\n if (stats.oldestFile) {\n const cutoffDate = new Date()\n cutoffDate.setDate(cutoffDate.getDate() - finalConfig.maxAgeDays)\n if (stats.oldestFile < cutoffDate) {\n return true\n }\n }\n\n // Check if total size exceeds limit\n if (finalConfig.maxSizeMB > 0) {\n const maxSizeBytes = finalConfig.maxSizeMB * 1024 * 1024\n if (stats.totalSizeBytes > maxSizeBytes) {\n return true\n }\n }\n\n return false\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -73,7 +73,7 @@ async function cloneGitRepo(url, ref) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
function loadManifestFromDirectory(dir) {
|
|
76
|
-
const manifestPath = join(dir, ".
|
|
76
|
+
const manifestPath = join(dir, ".minto-plugin", "marketplace.json");
|
|
77
77
|
if (!existsSync(manifestPath)) {
|
|
78
78
|
throw new MarketplaceError(
|
|
79
79
|
`Marketplace manifest not found at ${manifestPath}`,
|
|
@@ -242,10 +242,8 @@ function loadMarketplaceSettings() {
|
|
|
242
242
|
const cwd = getCwd();
|
|
243
243
|
const home = homedir();
|
|
244
244
|
const settingsPaths = [
|
|
245
|
-
{ path: join(cwd, ".minto", "settings.json"), label: "project
|
|
246
|
-
{ path: join(
|
|
247
|
-
{ path: join(home, ".minto", "settings.json"), label: "user .minto" },
|
|
248
|
-
{ path: join(home, ".claude", "settings.json"), label: "user .claude" }
|
|
245
|
+
{ path: join(cwd, ".minto", "settings.json"), label: "project" },
|
|
246
|
+
{ path: join(home, ".minto", "settings.json"), label: "user" }
|
|
249
247
|
];
|
|
250
248
|
for (const { path, label } of settingsPaths) {
|
|
251
249
|
if (existsSync(path)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/marketplaceManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Marketplace Manager\n *\n * Manages plugin marketplaces including registration, updates, and plugin installation\n * from git-based marketplace sources.\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n rmSync,\n cpSync,\n symlinkSync,\n lstatSync,\n} from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { execFileNoThrow } from './execFileNoThrow'\nimport {\n MarketplaceManifest,\n MarketplaceManifestSchema,\n MarketplaceSource,\n RegisteredMarketplace,\n MarketplaceSettings,\n MarketplaceError,\n MarketplaceErrorCode,\n MarketplacePlugin,\n} from '../types/marketplace'\nimport { getCwd } from './state'\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get marketplace registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch (error) {\n console.error('Error loading marketplace registry:', error)\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Clone git repository to temporary location using safe execFile\n */\nasync function cloneGitRepo(url: string, ref?: string): Promise<string> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n // Build git clone arguments safely\n const args = ['clone', '--depth', '1']\n\n if (ref) {\n args.push('--branch', ref)\n }\n\n args.push(url, tempDir)\n\n // Clone repository using safe execFile\n const result = await execFileNoThrow('git', args)\n\n if (result.code !== 0) {\n throw new Error(`Git clone failed: ${result.stderr || result.stdout}`)\n }\n\n return tempDir\n } catch (error) {\n // Clean up on error\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Ignore cleanup errors\n }\n\n throw new MarketplaceError(\n `Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Load marketplace manifest from directory\n */\nfunction loadManifestFromDirectory(dir: string): MarketplaceManifest {\n const manifestPath = join(dir, '.claude-plugin', 'marketplace.json')\n\n if (!existsSync(manifestPath)) {\n throw new MarketplaceError(\n `Marketplace manifest not found at ${manifestPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Validate with Zod schema\n return MarketplaceManifestSchema.parse(data)\n } catch (error) {\n throw new MarketplaceError(\n `Invalid marketplace manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const url = `https://github.com/${repo}.git`\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local path\n */\nfunction loadLocalMarketplace(path: string): MarketplaceManifest {\n const resolvedPath = path.startsWith('/') ? path : join(getCwd(), path)\n return loadManifestFromDirectory(resolvedPath)\n}\n\n/**\n * Parse marketplace source from string input\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { type: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { type: 'github', repo: match[1] }\n }\n }\n\n // Git URL\n if (\n input.startsWith('http://') ||\n input.startsWith('https://') ||\n input.endsWith('.git')\n ) {\n return { type: 'url', url: input }\n }\n\n // Local path\n return { type: 'local', path: input }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string,\n): Promise<RegisteredMarketplace> {\n const source = parseMarketplaceSource(input)\n\n // Fetch manifest based on source type\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new MarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n // Create registered marketplace\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n // Save to registry\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update a marketplace (re-fetch manifest)\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n // Re-fetch manifest\n let manifest: MarketplaceManifest\n\n switch (marketplace.source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(\n marketplace.source.repo,\n marketplace.source.ref,\n )\n break\n case 'url':\n manifest = await fetchUrlMarketplace(\n marketplace.source.url,\n marketplace.source.ref,\n )\n break\n case 'local':\n manifest = loadLocalMarketplace(marketplace.source.path)\n break\n }\n\n // Update in registry\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n const registry = loadRegistry()\n return registry.find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n):\n | {\n marketplace: RegisteredMarketplace\n plugin: MarketplacePlugin\n }\n | undefined {\n const registry = loadRegistry()\n\n // Search in specific marketplace\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n // Search in all marketplaces\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Load marketplace settings with hierarchical priority\n * Priority (highest to lowest):\n * 1. Project .minto/settings.json\n * 2. Project .claude/settings.json (Claude Code compatibility)\n * 3. User ~/.minto/settings.json\n * 4. User ~/.claude/settings.json (Claude Code compatibility)\n */\nexport function loadMarketplaceSettings(): MarketplaceSettings {\n const cwd = getCwd()\n const home = homedir()\n\n // Define search paths in priority order\n const settingsPaths = [\n { path: join(cwd, '.minto', 'settings.json'), label: 'project .minto' },\n { path: join(cwd, '.claude', 'settings.json'), label: 'project .claude' },\n { path: join(home, '.minto', 'settings.json'), label: 'user .minto' },\n { path: join(home, '.claude', 'settings.json'), label: 'user .claude' },\n ]\n\n // Try loading from each path in priority order\n for (const { path, label } of settingsPaths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8')\n const settings = JSON.parse(content)\n // Optional: log which settings file was used for debugging\n // console.log(`Loaded marketplace settings from ${label}: ${path}`)\n return settings\n } catch (error) {\n console.error(\n `Error loading marketplace settings from ${label} (${path}):`,\n error,\n )\n // Continue to next path on error\n }\n }\n }\n\n // No settings found\n return {}\n}\n\n/**\n * Auto-register marketplaces from settings\n */\nexport async function autoRegisterMarketplaces(): Promise<void> {\n const settings = loadMarketplaceSettings()\n\n if (!settings.extraKnownMarketplaces) return\n\n const registry = loadRegistry()\n\n for (const [name, config] of Object.entries(\n settings.extraKnownMarketplaces,\n )) {\n // Skip if already registered\n if (registry.some(m => m.name === name)) continue\n\n try {\n let source: MarketplaceSource\n\n if (config.source.source === 'github' && config.source.repo) {\n source = {\n type: 'github',\n repo: config.source.repo,\n ref: config.source.ref,\n }\n } else if (config.source.source === 'url' && config.source.url) {\n source = { type: 'url', url: config.source.url, ref: config.source.ref }\n } else if (config.source.source === 'local' && config.source.path) {\n source = { type: 'local', path: config.source.path }\n } else {\n continue\n }\n\n // Fetch and register\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n registry.push({\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n })\n } catch (error) {\n console.error(`Error auto-registering marketplace ${name}:`, error)\n }\n }\n\n saveRegistry(registry)\n}\n\n/**\n * Get marketplace repository directory path\n * For cloned marketplaces, returns the temp directory path\n * For local marketplaces, returns the local path\n */\nasync function getMarketplaceRepoPath(\n marketplace: RegisteredMarketplace,\n): Promise<{ path: string; cleanup: boolean }> {\n switch (marketplace.source.type) {\n case 'github': {\n const url = `https://github.com/${marketplace.source.repo}.git`\n const tempDir = await cloneGitRepo(url, marketplace.source.ref)\n return { path: tempDir, cleanup: true }\n }\n case 'url': {\n const tempDir = await cloneGitRepo(\n marketplace.source.url,\n marketplace.source.ref,\n )\n return { path: tempDir, cleanup: true }\n }\n case 'local': {\n const resolvedPath = isAbsolute(marketplace.source.path)\n ? marketplace.source.path\n : resolve(getCwd(), marketplace.source.path)\n\n if (!existsSync(resolvedPath)) {\n throw new MarketplaceError(\n `Local marketplace path does not exist: ${resolvedPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n return { path: resolvedPath, cleanup: false }\n }\n }\n}\n\n/**\n * Copy directory contents recursively\n */\nfunction copyDirectory(sourcePath: string, destPath: string): void {\n try {\n // Create destination directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true })\n }\n\n // Copy recursively, excluding .git directories\n cpSync(sourcePath, destPath, {\n recursive: true,\n filter: src => {\n // Skip .git directories to avoid copying version control history\n return !src.includes('/.git/') && !src.endsWith('/.git')\n },\n })\n } catch (error) {\n throw new MarketplaceError(\n `Failed to copy directory from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Create symlink to directory\n */\nfunction symlinkDirectory(sourcePath: string, destPath: string): void {\n try {\n // Remove destination if it exists\n if (existsSync(destPath)) {\n // Check if it's already a symlink pointing to the right place\n try {\n const stats = lstatSync(destPath)\n if (stats.isSymbolicLink()) {\n // Already a symlink, remove it\n rmSync(destPath, { force: true })\n } else {\n throw new MarketplaceError(\n `Destination path already exists and is not a symlink: ${destPath}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n } catch (error) {\n throw new MarketplaceError(\n `Failed to check existing path: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n } else {\n // Create parent directory\n const parentDir = join(destPath, '..')\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Create symlink\n symlinkSync(sourcePath, destPath, 'dir')\n } catch (error) {\n throw new MarketplaceError(\n `Failed to create symlink from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPluginFromMarketplace(\n pluginName: string,\n marketplaceName?: string,\n targetDir?: string,\n options?: { dev?: boolean },\n): Promise<string> {\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new MarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n\n // Determine installation directory\n const installDir =\n targetDir || join(getCwd(), '.minto', 'plugins', plugin.name)\n\n // Create installation directory\n if (!existsSync(installDir)) {\n mkdirSync(installDir, { recursive: true })\n }\n\n let cleanupMarketplaceRepo = false\n let marketplaceRepoPath: string | undefined\n\n try {\n // Install plugin based on source type\n if (typeof plugin.source === 'string') {\n // Relative path - resolve from marketplace source\n const repoInfo = await getMarketplaceRepoPath(marketplace)\n marketplaceRepoPath = repoInfo.path\n cleanupMarketplaceRepo = repoInfo.cleanup\n\n // Determine base path for relative plugin sources\n const pluginRoot = marketplace.manifest.metadata?.pluginRoot || ''\n const pluginSourcePath = join(\n marketplaceRepoPath,\n pluginRoot,\n plugin.source,\n )\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Plugin source path does not exist: ${pluginSourcePath} (relative path: ${plugin.source})`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // Copy plugin files to installation directory\n copyDirectory(pluginSourcePath, installDir)\n } else if (plugin.source.source === 'github') {\n // GitHub repository - clone directly\n const url = `https://github.com/${plugin.source.repo}.git`\n const tempDir = await cloneGitRepo(url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'url') {\n // Git URL - clone directly\n const tempDir = await cloneGitRepo(plugin.source.url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'local') {\n // Local path - resolve and copy or symlink\n const pluginSourcePath = isAbsolute(plugin.source.path)\n ? plugin.source.path\n : resolve(getCwd(), plugin.source.path)\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Local plugin path does not exist: ${pluginSourcePath}`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // In dev mode, create symlink for easier development\n // In production mode, copy files for isolation\n if (options?.dev) {\n symlinkDirectory(pluginSourcePath, installDir)\n } else {\n copyDirectory(pluginSourcePath, installDir)\n }\n }\n\n // Create marketplace metadata file to track source\n const metadataPath = join(installDir, '.marketplace-meta.json')\n const metadata = {\n marketplace: marketplace.name,\n plugin: plugin.name,\n installedAt: new Date().toISOString(),\n source: plugin.source,\n }\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8')\n\n // Create plugin.json if it doesn't exist (required for plugin discovery)\n const pluginManifestPath = join(installDir, 'plugin.json')\n if (!existsSync(pluginManifestPath)) {\n const pluginManifest = {\n name: plugin.name,\n displayName: plugin.name, // Use name as displayName for marketplace plugins\n version: plugin.version || '1.0.0',\n description: plugin.description || '',\n author: plugin.author,\n license: plugin.license,\n homepage: plugin.homepage,\n repository: plugin.repository,\n keywords: plugin.keywords || [],\n category: plugin.category,\n }\n writeFileSync(\n pluginManifestPath,\n JSON.stringify(pluginManifest, null, 2),\n 'utf-8',\n )\n }\n\n return installDir\n } finally {\n // Clean up marketplace repo if it was cloned\n if (cleanupMarketplaceRepo && marketplaceRepoPath) {\n try {\n rmSync(marketplaceRepoPath, { recursive: true, force: true })\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Marketplace Manager\n *\n * Manages plugin marketplaces including registration, updates, and plugin installation\n * from git-based marketplace sources.\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n rmSync,\n cpSync,\n symlinkSync,\n lstatSync,\n} from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { execFileNoThrow } from './execFileNoThrow'\nimport {\n MarketplaceManifest,\n MarketplaceManifestSchema,\n MarketplaceSource,\n RegisteredMarketplace,\n MarketplaceSettings,\n MarketplaceError,\n MarketplaceErrorCode,\n MarketplacePlugin,\n} from '../types/marketplace'\nimport { getCwd } from './state'\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get marketplace registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch (error) {\n console.error('Error loading marketplace registry:', error)\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Clone git repository to temporary location using safe execFile\n */\nasync function cloneGitRepo(url: string, ref?: string): Promise<string> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n // Build git clone arguments safely\n const args = ['clone', '--depth', '1']\n\n if (ref) {\n args.push('--branch', ref)\n }\n\n args.push(url, tempDir)\n\n // Clone repository using safe execFile\n const result = await execFileNoThrow('git', args)\n\n if (result.code !== 0) {\n throw new Error(`Git clone failed: ${result.stderr || result.stdout}`)\n }\n\n return tempDir\n } catch (error) {\n // Clean up on error\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Ignore cleanup errors\n }\n\n throw new MarketplaceError(\n `Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Load marketplace manifest from directory\n */\nfunction loadManifestFromDirectory(dir: string): MarketplaceManifest {\n const manifestPath = join(dir, '.minto-plugin', 'marketplace.json')\n\n if (!existsSync(manifestPath)) {\n throw new MarketplaceError(\n `Marketplace manifest not found at ${manifestPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Validate with Zod schema\n return MarketplaceManifestSchema.parse(data)\n } catch (error) {\n throw new MarketplaceError(\n `Invalid marketplace manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const url = `https://github.com/${repo}.git`\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local path\n */\nfunction loadLocalMarketplace(path: string): MarketplaceManifest {\n const resolvedPath = path.startsWith('/') ? path : join(getCwd(), path)\n return loadManifestFromDirectory(resolvedPath)\n}\n\n/**\n * Parse marketplace source from string input\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { type: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { type: 'github', repo: match[1] }\n }\n }\n\n // Git URL\n if (\n input.startsWith('http://') ||\n input.startsWith('https://') ||\n input.endsWith('.git')\n ) {\n return { type: 'url', url: input }\n }\n\n // Local path\n return { type: 'local', path: input }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string,\n): Promise<RegisteredMarketplace> {\n const source = parseMarketplaceSource(input)\n\n // Fetch manifest based on source type\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new MarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n // Create registered marketplace\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n // Save to registry\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update a marketplace (re-fetch manifest)\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n // Re-fetch manifest\n let manifest: MarketplaceManifest\n\n switch (marketplace.source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(\n marketplace.source.repo,\n marketplace.source.ref,\n )\n break\n case 'url':\n manifest = await fetchUrlMarketplace(\n marketplace.source.url,\n marketplace.source.ref,\n )\n break\n case 'local':\n manifest = loadLocalMarketplace(marketplace.source.path)\n break\n }\n\n // Update in registry\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n const registry = loadRegistry()\n return registry.find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n):\n | {\n marketplace: RegisteredMarketplace\n plugin: MarketplacePlugin\n }\n | undefined {\n const registry = loadRegistry()\n\n // Search in specific marketplace\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n // Search in all marketplaces\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Load marketplace settings with hierarchical priority\n * Priority (highest to lowest):\n * 1. Project .minto/settings.json\n * 2. User ~/.minto/settings.json\n */\nexport function loadMarketplaceSettings(): MarketplaceSettings {\n const cwd = getCwd()\n const home = homedir()\n\n // Define search paths in priority order\n const settingsPaths = [\n { path: join(cwd, '.minto', 'settings.json'), label: 'project' },\n { path: join(home, '.minto', 'settings.json'), label: 'user' },\n ]\n\n // Try loading from each path in priority order\n for (const { path, label } of settingsPaths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8')\n const settings = JSON.parse(content)\n // Optional: log which settings file was used for debugging\n // console.log(`Loaded marketplace settings from ${label}: ${path}`)\n return settings\n } catch (error) {\n console.error(\n `Error loading marketplace settings from ${label} (${path}):`,\n error,\n )\n // Continue to next path on error\n }\n }\n }\n\n // No settings found\n return {}\n}\n\n/**\n * Auto-register marketplaces from settings\n */\nexport async function autoRegisterMarketplaces(): Promise<void> {\n const settings = loadMarketplaceSettings()\n\n if (!settings.extraKnownMarketplaces) return\n\n const registry = loadRegistry()\n\n for (const [name, config] of Object.entries(\n settings.extraKnownMarketplaces,\n )) {\n // Skip if already registered\n if (registry.some(m => m.name === name)) continue\n\n try {\n let source: MarketplaceSource\n\n if (config.source.source === 'github' && config.source.repo) {\n source = {\n type: 'github',\n repo: config.source.repo,\n ref: config.source.ref,\n }\n } else if (config.source.source === 'url' && config.source.url) {\n source = { type: 'url', url: config.source.url, ref: config.source.ref }\n } else if (config.source.source === 'local' && config.source.path) {\n source = { type: 'local', path: config.source.path }\n } else {\n continue\n }\n\n // Fetch and register\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n registry.push({\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n })\n } catch (error) {\n console.error(`Error auto-registering marketplace ${name}:`, error)\n }\n }\n\n saveRegistry(registry)\n}\n\n/**\n * Get marketplace repository directory path\n * For cloned marketplaces, returns the temp directory path\n * For local marketplaces, returns the local path\n */\nasync function getMarketplaceRepoPath(\n marketplace: RegisteredMarketplace,\n): Promise<{ path: string; cleanup: boolean }> {\n switch (marketplace.source.type) {\n case 'github': {\n const url = `https://github.com/${marketplace.source.repo}.git`\n const tempDir = await cloneGitRepo(url, marketplace.source.ref)\n return { path: tempDir, cleanup: true }\n }\n case 'url': {\n const tempDir = await cloneGitRepo(\n marketplace.source.url,\n marketplace.source.ref,\n )\n return { path: tempDir, cleanup: true }\n }\n case 'local': {\n const resolvedPath = isAbsolute(marketplace.source.path)\n ? marketplace.source.path\n : resolve(getCwd(), marketplace.source.path)\n\n if (!existsSync(resolvedPath)) {\n throw new MarketplaceError(\n `Local marketplace path does not exist: ${resolvedPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n return { path: resolvedPath, cleanup: false }\n }\n }\n}\n\n/**\n * Copy directory contents recursively\n */\nfunction copyDirectory(sourcePath: string, destPath: string): void {\n try {\n // Create destination directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true })\n }\n\n // Copy recursively, excluding .git directories\n cpSync(sourcePath, destPath, {\n recursive: true,\n filter: src => {\n // Skip .git directories to avoid copying version control history\n return !src.includes('/.git/') && !src.endsWith('/.git')\n },\n })\n } catch (error) {\n throw new MarketplaceError(\n `Failed to copy directory from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Create symlink to directory\n */\nfunction symlinkDirectory(sourcePath: string, destPath: string): void {\n try {\n // Remove destination if it exists\n if (existsSync(destPath)) {\n // Check if it's already a symlink pointing to the right place\n try {\n const stats = lstatSync(destPath)\n if (stats.isSymbolicLink()) {\n // Already a symlink, remove it\n rmSync(destPath, { force: true })\n } else {\n throw new MarketplaceError(\n `Destination path already exists and is not a symlink: ${destPath}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n } catch (error) {\n throw new MarketplaceError(\n `Failed to check existing path: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n } else {\n // Create parent directory\n const parentDir = join(destPath, '..')\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Create symlink\n symlinkSync(sourcePath, destPath, 'dir')\n } catch (error) {\n throw new MarketplaceError(\n `Failed to create symlink from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPluginFromMarketplace(\n pluginName: string,\n marketplaceName?: string,\n targetDir?: string,\n options?: { dev?: boolean },\n): Promise<string> {\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new MarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n\n // Determine installation directory\n const installDir =\n targetDir || join(getCwd(), '.minto', 'plugins', plugin.name)\n\n // Create installation directory\n if (!existsSync(installDir)) {\n mkdirSync(installDir, { recursive: true })\n }\n\n let cleanupMarketplaceRepo = false\n let marketplaceRepoPath: string | undefined\n\n try {\n // Install plugin based on source type\n if (typeof plugin.source === 'string') {\n // Relative path - resolve from marketplace source\n const repoInfo = await getMarketplaceRepoPath(marketplace)\n marketplaceRepoPath = repoInfo.path\n cleanupMarketplaceRepo = repoInfo.cleanup\n\n // Determine base path for relative plugin sources\n const pluginRoot = marketplace.manifest.metadata?.pluginRoot || ''\n const pluginSourcePath = join(\n marketplaceRepoPath,\n pluginRoot,\n plugin.source,\n )\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Plugin source path does not exist: ${pluginSourcePath} (relative path: ${plugin.source})`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // Copy plugin files to installation directory\n copyDirectory(pluginSourcePath, installDir)\n } else if (plugin.source.source === 'github') {\n // GitHub repository - clone directly\n const url = `https://github.com/${plugin.source.repo}.git`\n const tempDir = await cloneGitRepo(url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'url') {\n // Git URL - clone directly\n const tempDir = await cloneGitRepo(plugin.source.url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'local') {\n // Local path - resolve and copy or symlink\n const pluginSourcePath = isAbsolute(plugin.source.path)\n ? plugin.source.path\n : resolve(getCwd(), plugin.source.path)\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Local plugin path does not exist: ${pluginSourcePath}`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // In dev mode, create symlink for easier development\n // In production mode, copy files for isolation\n if (options?.dev) {\n symlinkDirectory(pluginSourcePath, installDir)\n } else {\n copyDirectory(pluginSourcePath, installDir)\n }\n }\n\n // Create marketplace metadata file to track source\n const metadataPath = join(installDir, '.marketplace-meta.json')\n const metadata = {\n marketplace: marketplace.name,\n plugin: plugin.name,\n installedAt: new Date().toISOString(),\n source: plugin.source,\n }\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8')\n\n // Create plugin.json if it doesn't exist (required for plugin discovery)\n const pluginManifestPath = join(installDir, 'plugin.json')\n if (!existsSync(pluginManifestPath)) {\n const pluginManifest = {\n name: plugin.name,\n displayName: plugin.name, // Use name as displayName for marketplace plugins\n version: plugin.version || '1.0.0',\n description: plugin.description || '',\n author: plugin.author,\n license: plugin.license,\n homepage: plugin.homepage,\n repository: plugin.repository,\n keywords: plugin.keywords || [],\n category: plugin.category,\n }\n writeFileSync(\n pluginManifestPath,\n JSON.stringify(pluginManifest, null, 2),\n 'utf-8',\n )\n }\n\n return installDir\n } finally {\n // Clean up marketplace repo if it was cloned\n if (cleanupMarketplaceRepo && marketplaceRepoPath) {\n try {\n rmSync(marketplaceRepoPath, { recursive: true, force: true })\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "AAOA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,SAAS,kBAAkB;AAC1C,SAAS,eAAe;AACxB,SAAS,uBAAuB;AAChC;AAAA,EAEE;AAAA,EAIA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,cAAc;AAKvB,SAAS,oBAA4B;AACnC,QAAM,OAAO,QAAQ;AACrB,QAAM,MAAM,KAAK,MAAM,UAAU,cAAc;AAE/C,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACpC;AAEA,SAAO;AACT;AAKA,SAAS,kBAA0B;AACjC,SAAO,KAAK,kBAAkB,GAAG,eAAe;AAClD;AAKA,SAAS,eAAwC;AAC/C,QAAM,eAAe,gBAAgB;AAErC,MAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,cAAc,OAAO;AAClD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,YAAQ,MAAM,uCAAuC,KAAK;AAC1D,WAAO,CAAC;AAAA,EACV;AACF;AAKA,SAAS,aAAa,cAA6C;AACjE,QAAM,eAAe,gBAAgB;AACrC,gBAAc,cAAc,KAAK,UAAU,cAAc,MAAM,CAAC,GAAG,OAAO;AAC5E;AAKA,eAAe,aAAa,KAAa,KAA+B;AACtE,QAAM,UAAU,KAAK,kBAAkB,GAAG,QAAQ,KAAK,IAAI,EAAE,SAAS,CAAC;AACvE,YAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAEtC,MAAI;AAEF,UAAM,OAAO,CAAC,SAAS,WAAW,GAAG;AAErC,QAAI,KAAK;AACP,WAAK,KAAK,YAAY,GAAG;AAAA,IAC3B;AAEA,SAAK,KAAK,KAAK,OAAO;AAGtB,UAAM,SAAS,MAAM,gBAAgB,OAAO,IAAI;AAEhD,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,IAAI,MAAM,qBAAqB,OAAO,UAAU,OAAO,MAAM,EAAE;AAAA,IACvE;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,QAAI;AACF,aAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IAClD,SAAS,cAAc;AAAA,IAEvB;AAEA,UAAM,IAAI;AAAA,MACR,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACrF,qBAAqB;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,0BAA0B,KAAkC;AACnE,QAAM,eAAe,KAAK,KAAK,iBAAiB,kBAAkB;AAElE,MAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,qCAAqC,YAAY;AAAA,MACjD,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,cAAc,OAAO;AAClD,UAAM,OAAO,KAAK,MAAM,OAAO;AAG/B,WAAO,0BAA0B,MAAM,IAAI;AAAA,EAC7C,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACvF,qBAAqB;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,uBACb,MACA,KAC8B;AAC9B,QAAM,MAAM,sBAAsB,IAAI;AACtC,QAAM,UAAU,MAAM,aAAa,KAAK,GAAG;AAE3C,MAAI;AACF,WAAO,0BAA0B,OAAO;AAAA,EAC1C,UAAE;AAEA,QAAI;AACF,aAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IAClD,SAAS,GAAG;AAAA,IAEZ;AAAA,EACF;AACF;AAKA,eAAe,oBACb,KACA,KAC8B;AAC9B,QAAM,UAAU,MAAM,aAAa,KAAK,GAAG;AAE3C,MAAI;AACF,WAAO,0BAA0B,OAAO;AAAA,EAC1C,UAAE;AAEA,QAAI;AACF,aAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IAClD,SAAS,GAAG;AAAA,IAEZ;AAAA,EACF;AACF;AAKA,SAAS,qBAAqB,MAAmC;AAC/D,QAAM,eAAe,KAAK,WAAW,GAAG,IAAI,OAAO,KAAK,OAAO,GAAG,IAAI;AACtE,SAAO,0BAA0B,YAAY;AAC/C;AAKO,SAAS,uBAAuB,OAAkC;AAEvE,MAAI,mBAAmB,KAAK,KAAK,GAAG;AAClC,WAAO,EAAE,MAAM,UAAU,MAAM,MAAM;AAAA,EACvC;AAGA,MAAI,MAAM,SAAS,YAAY,GAAG;AAChC,UAAM,QAAQ,MAAM,MAAM,iCAAiC;AAC3D,QAAI,OAAO;AACT,aAAO,EAAE,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,IAC1C;AAAA,EACF;AAGA,MACE,MAAM,WAAW,SAAS,KAC1B,MAAM,WAAW,UAAU,KAC3B,MAAM,SAAS,MAAM,GACrB;AACA,WAAO,EAAE,MAAM,OAAO,KAAK,MAAM;AAAA,EACnC;AAGA,SAAO,EAAE,MAAM,SAAS,MAAM,MAAM;AACtC;AAKA,eAAsB,eACpB,OACgC;AAChC,QAAM,SAAS,uBAAuB,KAAK;AAG3C,MAAI;AAEJ,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,iBAAW,MAAM,uBAAuB,OAAO,MAAM,OAAO,GAAG;AAC/D;AAAA,IACF,KAAK;AACH,iBAAW,MAAM,oBAAoB,OAAO,KAAK,OAAO,GAAG;AAC3D;AAAA,IACF,KAAK;AACH,iBAAW,qBAAqB,OAAO,IAAI;AAC3C;AAAA,EACJ;AAGA,QAAM,WAAW,aAAa;AAC9B,MAAI,SAAS,KAAK,OAAK,EAAE,SAAS,SAAS,IAAI,GAAG;AAChD,UAAM,IAAI;AAAA,MACR,gBAAgB,SAAS,IAAI;AAAA,MAC7B,qBAAqB;AAAA,MACrB,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,aAAoC;AAAA,IACxC,MAAM,SAAS;AAAA,IACf;AAAA,IACA;AAAA,IACA,aAAa,oBAAI,KAAK;AAAA,IACtB,SAAS;AAAA,EACX;AAGA,WAAS,KAAK,UAAU;AACxB,eAAa,QAAQ;AAErB,SAAO;AACT;AAKO,SAAS,kBAAkB,MAAoB;AACpD,QAAM,WAAW,aAAa;AAC9B,QAAM,WAAW,SAAS,OAAO,OAAK,EAAE,SAAS,IAAI;AAErD,MAAI,SAAS,WAAW,SAAS,QAAQ;AACvC,UAAM,IAAI;AAAA,MACR,gBAAgB,IAAI;AAAA,MACpB,qBAAqB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,eAAa,QAAQ;AACvB;AAKA,eAAsB,kBACpB,MACgC;AAChC,QAAM,WAAW,aAAa;AAC9B,QAAM,cAAc,SAAS,KAAK,OAAK,EAAE,SAAS,IAAI;AAEtD,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI;AAAA,MACR,gBAAgB,IAAI;AAAA,MACpB,qBAAqB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AAEJ,UAAQ,YAAY,OAAO,MAAM;AAAA,IAC/B,KAAK;AACH,iBAAW,MAAM;AAAA,QACf,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,MACrB;AACA;AAAA,IACF,KAAK;AACH,iBAAW,MAAM;AAAA,QACf,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,MACrB;AACA;AAAA,IACF,KAAK;AACH,iBAAW,qBAAqB,YAAY,OAAO,IAAI;AACvD;AAAA,EACJ;AAGA,cAAY,WAAW;AACvB,cAAY,cAAc,oBAAI,KAAK;AAEnC,eAAa,QAAQ;AAErB,SAAO;AACT;AAKO,SAAS,mBAA4C;AAC1D,SAAO,aAAa;AACtB;AAKO,SAAS,eACd,MACmC;AACnC,QAAM,WAAW,aAAa;AAC9B,SAAO,SAAS,KAAK,OAAK,EAAE,SAAS,IAAI;AAC3C;AAKO,SAAS,WACd,YACA,iBAMY;AACZ,QAAM,WAAW,aAAa;AAG9B,MAAI,iBAAiB;AACnB,UAAM,cAAc,SAAS,KAAK,OAAK,EAAE,SAAS,eAAe;AACjE,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,SAAS,YAAY,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU;AAC3E,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,EAAE,aAAa,OAAO;AAAA,EAC/B;AAGA,aAAW,eAAe,UAAU;AAClC,QAAI,CAAC,YAAY,QAAS;AAE1B,UAAM,SAAS,YAAY,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU;AAC3E,QAAI,QAAQ;AACV,aAAO,EAAE,aAAa,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,0BAA+C;AAC7D,QAAM,MAAM,OAAO;AACnB,QAAM,OAAO,QAAQ;AAGrB,QAAM,gBAAgB;AAAA,IACpB,EAAE,MAAM,KAAK,KAAK,UAAU,eAAe,GAAG,OAAO,UAAU;AAAA,IAC/D,EAAE,MAAM,KAAK,MAAM,UAAU,eAAe,GAAG,OAAO,OAAO;AAAA,EAC/D;AAGA,aAAW,EAAE,MAAM,MAAM,KAAK,eAAe;AAC3C,QAAI,WAAW,IAAI,GAAG;AACpB,UAAI;AACF,cAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,cAAM,WAAW,KAAK,MAAM,OAAO;AAGnC,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ;AAAA,UACN,2CAA2C,KAAK,KAAK,IAAI;AAAA,UACzD;AAAA,QACF;AAAA,MAEF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,CAAC;AACV;AAKA,eAAsB,2BAA0C;AAC9D,QAAM,WAAW,wBAAwB;AAEzC,MAAI,CAAC,SAAS,uBAAwB;AAEtC,QAAM,WAAW,aAAa;AAE9B,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO;AAAA,IAClC,SAAS;AAAA,EACX,GAAG;AAED,QAAI,SAAS,KAAK,OAAK,EAAE,SAAS,IAAI,EAAG;AAEzC,QAAI;AACF,UAAI;AAEJ,UAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,MAAM;AAC3D,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM,OAAO,OAAO;AAAA,UACpB,KAAK,OAAO,OAAO;AAAA,QACrB;AAAA,MACF,WAAW,OAAO,OAAO,WAAW,SAAS,OAAO,OAAO,KAAK;AAC9D,iBAAS,EAAE,MAAM,OAAO,KAAK,OAAO,OAAO,KAAK,KAAK,OAAO,OAAO,IAAI;AAAA,MACzE,WAAW,OAAO,OAAO,WAAW,WAAW,OAAO,OAAO,MAAM;AACjE,iBAAS,EAAE,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK;AAAA,MACrD,OAAO;AACL;AAAA,MACF;AAGA,UAAI;AAEJ,cAAQ,OAAO,MAAM;AAAA,QACnB,KAAK;AACH,qBAAW,MAAM,uBAAuB,OAAO,MAAM,OAAO,GAAG;AAC/D;AAAA,QACF,KAAK;AACH,qBAAW,MAAM,oBAAoB,OAAO,KAAK,OAAO,GAAG;AAC3D;AAAA,QACF,KAAK;AACH,qBAAW,qBAAqB,OAAO,IAAI;AAC3C;AAAA,MACJ;AAEA,eAAS,KAAK;AAAA,QACZ,MAAM,SAAS;AAAA,QACf;AAAA,QACA;AAAA,QACA,aAAa,oBAAI,KAAK;AAAA,QACtB,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,sCAAsC,IAAI,KAAK,KAAK;AAAA,IACpE;AAAA,EACF;AAEA,eAAa,QAAQ;AACvB;AAOA,eAAe,uBACb,aAC6C;AAC7C,UAAQ,YAAY,OAAO,MAAM;AAAA,IAC/B,KAAK,UAAU;AACb,YAAM,MAAM,sBAAsB,YAAY,OAAO,IAAI;AACzD,YAAM,UAAU,MAAM,aAAa,KAAK,YAAY,OAAO,GAAG;AAC9D,aAAO,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,IACxC;AAAA,IACA,KAAK,OAAO;AACV,YAAM,UAAU,MAAM;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,MACrB;AACA,aAAO,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,IACxC;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,eAAe,WAAW,YAAY,OAAO,IAAI,IACnD,YAAY,OAAO,OACnB,QAAQ,OAAO,GAAG,YAAY,OAAO,IAAI;AAE7C,UAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,cAAM,IAAI;AAAA,UACR,0CAA0C,YAAY;AAAA,UACtD,qBAAqB;AAAA,QACvB;AAAA,MACF;AAEA,aAAO,EAAE,MAAM,cAAc,SAAS,MAAM;AAAA,IAC9C;AAAA,EACF;AACF;AAKA,SAAS,cAAc,YAAoB,UAAwB;AACjE,MAAI;AAEF,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,gBAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,IACzC;AAGA,WAAO,YAAY,UAAU;AAAA,MAC3B,WAAW;AAAA,MACX,QAAQ,SAAO;AAEb,eAAO,CAAC,IAAI,SAAS,QAAQ,KAAK,CAAC,IAAI,SAAS,OAAO;AAAA,MACzD;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,UAAU,OAAO,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACrH,qBAAqB;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,iBAAiB,YAAoB,UAAwB;AACpE,MAAI;AAEF,QAAI,WAAW,QAAQ,GAAG;AAExB,UAAI;AACF,cAAM,QAAQ,UAAU,QAAQ;AAChC,YAAI,MAAM,eAAe,GAAG;AAE1B,iBAAO,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,QAClC,OAAO;AACL,gBAAM,IAAI;AAAA,YACR,yDAAyD,QAAQ;AAAA,YACjE,qBAAqB;AAAA,UACvB;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,cAAM,IAAI;AAAA,UACR,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACxF,qBAAqB;AAAA,UACrB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,YAAY,KAAK,UAAU,IAAI;AACrC,UAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,kBAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAC1C;AAAA,IACF;AAGA,gBAAY,YAAY,UAAU,KAAK;AAAA,EACzC,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,UAAU,OAAO,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACrH,qBAAqB;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,6BACpB,YACA,iBACA,WACA,SACiB;AACjB,QAAM,QAAQ,WAAW,YAAY,eAAe;AAEpD,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,kBACI,WAAW,UAAU,+BAA+B,eAAe,MACnE,WAAW,UAAU;AAAA,MACzB,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,EAAE,aAAa,OAAO,IAAI;AAGhC,QAAM,aACJ,aAAa,KAAK,OAAO,GAAG,UAAU,WAAW,OAAO,IAAI;AAG9D,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,cAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAEA,MAAI,yBAAyB;AAC7B,MAAI;AAEJ,MAAI;AAEF,QAAI,OAAO,OAAO,WAAW,UAAU;AAErC,YAAM,WAAW,MAAM,uBAAuB,WAAW;AACzD,4BAAsB,SAAS;AAC/B,+BAAyB,SAAS;AAGlC,YAAM,aAAa,YAAY,SAAS,UAAU,cAAc;AAChE,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT;AAEA,UAAI,CAAC,WAAW,gBAAgB,GAAG;AACjC,cAAM,IAAI;AAAA,UACR,sCAAsC,gBAAgB,oBAAoB,OAAO,MAAM;AAAA,UACvF,qBAAqB;AAAA,QACvB;AAAA,MACF;AAGA,oBAAc,kBAAkB,UAAU;AAAA,IAC5C,WAAW,OAAO,OAAO,WAAW,UAAU;AAE5C,YAAM,MAAM,sBAAsB,OAAO,OAAO,IAAI;AACpD,YAAM,UAAU,MAAM,aAAa,KAAK,OAAO,OAAO,GAAG;AAEzD,UAAI;AACF,sBAAc,SAAS,UAAU;AAAA,MACnC,UAAE;AAEA,eAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MAClD;AAAA,IACF,WAAW,OAAO,OAAO,WAAW,OAAO;AAEzC,YAAM,UAAU,MAAM,aAAa,OAAO,OAAO,KAAK,OAAO,OAAO,GAAG;AAEvE,UAAI;AACF,sBAAc,SAAS,UAAU;AAAA,MACnC,UAAE;AAEA,eAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MAClD;AAAA,IACF,WAAW,OAAO,OAAO,WAAW,SAAS;AAE3C,YAAM,mBAAmB,WAAW,OAAO,OAAO,IAAI,IAClD,OAAO,OAAO,OACd,QAAQ,OAAO,GAAG,OAAO,OAAO,IAAI;AAExC,UAAI,CAAC,WAAW,gBAAgB,GAAG;AACjC,cAAM,IAAI;AAAA,UACR,qCAAqC,gBAAgB;AAAA,UACrD,qBAAqB;AAAA,QACvB;AAAA,MACF;AAIA,UAAI,SAAS,KAAK;AAChB,yBAAiB,kBAAkB,UAAU;AAAA,MAC/C,OAAO;AACL,sBAAc,kBAAkB,UAAU;AAAA,MAC5C;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,YAAY,wBAAwB;AAC9D,UAAM,WAAW;AAAA,MACf,aAAa,YAAY;AAAA,MACzB,QAAQ,OAAO;AAAA,MACf,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,QAAQ,OAAO;AAAA,IACjB;AACA,kBAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,OAAO;AAGtE,UAAM,qBAAqB,KAAK,YAAY,aAAa;AACzD,QAAI,CAAC,WAAW,kBAAkB,GAAG;AACnC,YAAM,iBAAiB;AAAA,QACrB,MAAM,OAAO;AAAA,QACb,aAAa,OAAO;AAAA;AAAA,QACpB,SAAS,OAAO,WAAW;AAAA,QAC3B,aAAa,OAAO,eAAe;AAAA,QACnC,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO,YAAY,CAAC;AAAA,QAC9B,UAAU,OAAO;AAAA,MACnB;AACA;AAAA,QACE;AAAA,QACA,KAAK,UAAU,gBAAgB,MAAM,CAAC;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,UAAE;AAEA,QAAI,0BAA0B,qBAAqB;AACjD,UAAI;AACF,eAAO,qBAAqB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MAC9D,SAAS,OAAO;AAAA,MAEhB;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|