@iaforged/context-code 2.1.7 → 2.2.4
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/src/Task.js +1 -1
- package/dist/src/commands/login/login.js +1 -1
- package/dist/src/components/ConsoleOAuthFlow.js +1 -1
- package/dist/src/constants/oauth.js +1 -1
- package/dist/src/context/mailbox.js +1 -1
- package/dist/src/context/voice.js +1 -1
- package/dist/src/hooks/useTerminalSize.js +1 -1
- package/dist/src/ink/Ansi.js +1 -1
- package/dist/src/ink/clearTerminal.js +1 -1
- package/dist/src/ink/colorize.js +1 -1
- package/dist/src/ink/components/App.js +1 -1
- package/dist/src/ink/components/Button.js +1 -1
- package/dist/src/ink/components/ClockContext.js +1 -1
- package/dist/src/ink/components/CursorDeclarationContext.js +1 -1
- package/dist/src/ink/components/Link.js +1 -1
- package/dist/src/ink/components/StdinContext.js +1 -1
- package/dist/src/ink/components/TerminalFocusContext.js +1 -1
- package/dist/src/ink/dom.js +1 -1
- package/dist/src/ink/events/keyboard-event.js +1 -1
- package/dist/src/ink/hit-test.js +1 -1
- package/dist/src/ink/hooks/use-animation-frame.js +1 -1
- package/dist/src/ink/hooks/use-app.js +1 -1
- package/dist/src/ink/hooks/use-input.js +1 -1
- package/dist/src/ink/hooks/use-interval.js +1 -1
- package/dist/src/ink/hooks/use-selection.js +1 -1
- package/dist/src/ink/hooks/use-tab-status.js +1 -1
- package/dist/src/ink/hooks/use-terminal-focus.js +1 -1
- package/dist/src/ink/hooks/use-terminal-title.js +1 -1
- package/dist/src/ink/hooks/use-terminal-viewport.js +1 -1
- package/dist/src/ink/ink.js +1 -1
- package/dist/src/ink/layout/yoga.js +1 -1
- package/dist/src/ink/line-width-cache.js +1 -1
- package/dist/src/ink/log-update.js +1 -1
- package/dist/src/ink/measure-text.js +1 -1
- package/dist/src/ink/output.js +1 -1
- package/dist/src/ink/parse-keypress.js +1 -1
- package/dist/src/ink/reconciler.js +1 -1
- package/dist/src/ink/render-border.js +1 -1
- package/dist/src/ink/render-node-to-output.js +1 -1
- package/dist/src/ink/render-to-screen.js +1 -1
- package/dist/src/ink/renderer.js +1 -1
- package/dist/src/ink/root.js +1 -1
- package/dist/src/ink/screen.js +1 -1
- package/dist/src/ink/searchHighlight.js +1 -1
- package/dist/src/ink/selection.js +1 -1
- package/dist/src/ink/squash-text-nodes.js +1 -1
- package/dist/src/ink/stringWidth.js +1 -1
- package/dist/src/ink/tabstops.js +1 -1
- package/dist/src/ink/terminal.js +1 -1
- package/dist/src/ink/termio/osc.js +1 -1
- package/dist/src/ink/termio/parser.js +1 -1
- package/dist/src/ink/termio/tokenize.js +1 -1
- package/dist/src/ink/useTerminalNotification.js +1 -1
- package/dist/src/ink/warn.js +1 -1
- package/dist/src/ink/widest-line.js +1 -1
- package/dist/src/ink/wrap-text.js +1 -1
- package/dist/src/ink/wrapAnsi.js +1 -1
- package/dist/src/native-ts/yoga-layout/index.js +1 -1
- package/dist/src/schemas/hooks.js +1 -1
- package/dist/src/services/SessionMemory/sessionMemoryUtils.js +1 -1
- package/dist/src/services/api/client.js +1 -1
- package/dist/src/services/api/dumpPrompts.js +1 -1
- package/dist/src/services/api/errorUtils.js +1 -1
- package/dist/src/services/api/promptCacheBreakDetection.js +1 -1
- package/dist/src/services/api/withRetry.js +1 -1
- package/dist/src/services/autoDream/consolidationLock.js +1 -1
- package/dist/src/services/mcp/elicitationHandler.js +1 -1
- package/dist/src/services/mcp/mcpStringUtils.js +1 -1
- package/dist/src/services/mcp/oauthPort.js +1 -1
- package/dist/src/services/mcp/vscodeSdkMcp.js +1 -1
- package/dist/src/services/oauth/client.js +1 -1
- package/dist/src/services/oauth/getOauthProfile.js +1 -1
- package/dist/src/services/objetivo/types.js +1 -1
- package/dist/src/services/rateLimitMocking.js +1 -1
- package/dist/src/services/remoteManagedSettings/syncCacheState.js +1 -1
- package/dist/src/skills/bundledSkills.js +1 -1
- package/dist/src/tasks/DreamTask/DreamTask.js +1 -1
- package/dist/src/tools/AgentTool/agentMemory.js +1 -1
- package/dist/src/tools/AgentTool/forkSubagent.js +1 -1
- package/dist/src/tools/BashTool/BashToolResultMessage.js +1 -1
- package/dist/src/tools/BashTool/UI.js +1 -1
- package/dist/src/tools/BashTool/sedEditParser.js +1 -1
- package/dist/src/tools/BashTool/utils.js +1 -1
- package/dist/src/tools/FileReadTool/imageProcessor.js +1 -1
- package/dist/src/tools/FileReadTool/prompt.js +1 -1
- package/dist/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +1 -1
- package/dist/src/tools/ListMcpResourcesTool/UI.js +1 -1
- package/dist/src/tools/MCPTool/MCPTool.js +1 -1
- package/dist/src/tools/MCPTool/UI.js +1 -1
- package/dist/src/tools/McpAuthTool/McpAuthTool.js +1 -1
- package/dist/src/tools/NotebookEditTool/prompt.js +1 -1
- package/dist/src/tools/PowerShellTool/PowerShellTool.js +1 -1
- package/dist/src/tools/PowerShellTool/UI.js +1 -1
- package/dist/src/tools/PowerShellTool/gitSafety.js +1 -1
- package/dist/src/tools/PowerShellTool/modeValidation.js +1 -1
- package/dist/src/tools/PowerShellTool/pathValidation.js +1 -1
- package/dist/src/tools/PowerShellTool/powershellPermissions.js +1 -1
- package/dist/src/tools/PowerShellTool/powershellSecurity.js +1 -1
- package/dist/src/tools/PowerShellTool/prompt.js +1 -1
- package/dist/src/tools/PowerShellTool/readOnlyValidation.js +1 -1
- package/dist/src/tools/REPLTool/constants.js +1 -1
- package/dist/src/tools/REPLTool/primitiveTools.js +1 -1
- package/dist/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +1 -1
- package/dist/src/tools/ReadMcpResourceTool/UI.js +1 -1
- package/dist/src/tools/ScheduleCronTool/prompt.js +1 -1
- package/dist/src/tools/SkillTool/prompt.js +1 -1
- package/dist/src/tools/TodoWriteTool/TodoWriteTool.js +1 -1
- package/dist/src/tools/ToolSearchTool/prompt.js +1 -1
- package/dist/src/tools/WebSearchTool/prompt.js +1 -1
- package/dist/src/tools/shared/gitOperationTracking.js +1 -1
- package/dist/src/types/permissions.js +1 -1
- package/dist/src/utils/Cursor.js +1 -1
- package/dist/src/utils/QueryGuard.js +1 -1
- package/dist/src/utils/Shell.js +1 -1
- package/dist/src/utils/ShellCommand.js +1 -1
- package/dist/src/utils/activityManager.js +1 -1
- package/dist/src/utils/advisor.js +1 -1
- package/dist/src/utils/appleTerminalBackup.js +1 -1
- package/dist/src/utils/argumentSubstitution.js +1 -1
- package/dist/src/utils/authFileDescriptor.js +1 -1
- package/dist/src/utils/autoUpdater.js +1 -1
- package/dist/src/utils/background/remote/preconditions.js +1 -1
- package/dist/src/utils/background/remote/remoteSession.js +1 -1
- package/dist/src/utils/bash/ShellSnapshot.js +1 -1
- package/dist/src/utils/bash/ast.js +1 -1
- package/dist/src/utils/bash/bashParser.js +1 -1
- package/dist/src/utils/bash/bashPipeCommand.js +1 -1
- package/dist/src/utils/bash/parser.js +1 -1
- package/dist/src/utils/bash/shellQuote.js +1 -1
- package/dist/src/utils/bash/shellQuoting.js +1 -1
- package/dist/src/utils/billing.js +1 -1
- package/dist/src/utils/caCerts.js +1 -1
- package/dist/src/utils/claudeInChrome/common.js +1 -1
- package/dist/src/utils/claudeInChrome/setupPortable.js +1 -1
- package/dist/src/utils/claudemd.js +1 -1
- package/dist/src/utils/collapseBackgroundBashNotifications.js +1 -1
- package/dist/src/utils/collapseReadSearch.js +1 -1
- package/dist/src/utils/completionCache.js +1 -1
- package/dist/src/utils/computerUse/common.js +1 -1
- package/dist/src/utils/concurrentSessions.js +1 -1
- package/dist/src/utils/context.js +1 -1
- package/dist/src/utils/cron.js +1 -1
- package/dist/src/utils/cronTasks.js +1 -1
- package/dist/src/utils/cwd.js +1 -1
- package/dist/src/utils/debug.js +1 -1
- package/dist/src/utils/debugFilter.js +1 -1
- package/dist/src/utils/detectRepository.js +1 -1
- package/dist/src/utils/diagLogs.js +1 -1
- package/dist/src/utils/diff.js +1 -1
- package/dist/src/utils/directMemberMessage.js +1 -1
- package/dist/src/utils/doctorDiagnostic.js +1 -1
- package/dist/src/utils/dxt/helpers.js +1 -1
- package/dist/src/utils/dxt/zip.js +1 -1
- package/dist/src/utils/earlyInput.js +1 -1
- package/dist/src/utils/editor.js +1 -1
- package/dist/src/utils/effort.js +1 -1
- package/dist/src/utils/embeddedTools.js +1 -1
- package/dist/src/utils/envDynamic.js +1 -1
- package/dist/src/utils/envUtils.js +1 -1
- package/dist/src/utils/execFileNoThrowPortable.js +1 -1
- package/dist/src/utils/execSyncWrapper.js +1 -1
- package/dist/src/utils/exportRenderer.js +1 -1
- package/dist/src/utils/extraUsage.js +1 -1
- package/dist/src/utils/fastMode.js +1 -1
- package/dist/src/utils/fileOperationAnalytics.js +1 -1
- package/dist/src/utils/fileRead.js +1 -1
- package/dist/src/utils/findExecutable.js +1 -1
- package/dist/src/utils/format.js +1 -1
- package/dist/src/utils/frontmatterParser.js +1 -1
- package/dist/src/utils/fsOperations.js +1 -1
- package/dist/src/utils/fullscreen.js +1 -1
- package/dist/src/utils/genericProcessUtils.js +1 -1
- package/dist/src/utils/getWorktreePaths.js +1 -1
- package/dist/src/utils/git/gitConfigParser.js +1 -1
- package/dist/src/utils/git/gitFilesystem.js +1 -1
- package/dist/src/utils/git/gitignore.js +1 -1
- package/dist/src/utils/gitDiff.js +1 -1
- package/dist/src/utils/gitSettings.js +1 -1
- package/dist/src/utils/glob.js +1 -1
- package/dist/src/utils/gracefulShutdown.js +1 -1
- package/dist/src/utils/groupToolUses.js +1 -1
- package/dist/src/utils/handlePromptSubmit.js +1 -1
- package/dist/src/utils/hash.js +1 -1
- package/dist/src/utils/hooks/fileChangedWatcher.js +1 -1
- package/dist/src/utils/hooks/hooksSettings.js +1 -1
- package/dist/src/utils/hooks/registerSkillHooks.js +1 -1
- package/dist/src/utils/hooks/sessionHooks.js +1 -1
- package/dist/src/utils/http.js +1 -1
- package/dist/src/utils/hyperlink.js +1 -1
- package/dist/src/utils/ide.js +1 -1
- package/dist/src/utils/idePathConversion.js +1 -1
- package/dist/src/utils/imagePaste.js +1 -1
- package/dist/src/utils/imageResizer.js +1 -1
- package/dist/src/utils/imageStore.js +1 -1
- package/dist/src/utils/inProcessTeammateHelpers.js +1 -1
- package/dist/src/utils/ink.js +1 -1
- package/dist/src/utils/jetbrains.js +1 -1
- package/dist/src/utils/json.js +1 -1
- package/dist/src/utils/listSessionsImpl.js +1 -1
- package/dist/src/utils/localInstaller.js +1 -1
- package/dist/src/utils/lockfile.js +1 -1
- package/dist/src/utils/logoV2Utils.js +1 -1
- package/dist/src/utils/markdown.js +1 -1
- package/dist/src/utils/mcp/dateTimeParser.js +1 -1
- package/dist/src/utils/mcpOutputStorage.js +1 -1
- package/dist/src/utils/mcpValidation.js +1 -1
- package/dist/src/utils/memoize.js +1 -1
- package/dist/src/utils/memory/types.js +1 -1
- package/dist/src/utils/memoryFileDetection.js +1 -1
- package/dist/src/utils/messageQueueManager.js +1 -1
- package/dist/src/utils/messages/mappers.js +1 -1
- package/dist/src/utils/messages/systemInit.js +1 -1
- package/dist/src/utils/model/antModels.js +1 -1
- package/dist/src/utils/model/check1mAccess.js +1 -1
- package/dist/src/utils/model/contextWindowUpgradeCheck.js +1 -1
- package/dist/src/utils/model/model.js +1 -1
- package/dist/src/utils/model/modelAllowlist.js +1 -1
- package/dist/src/utils/model/modelCapabilities.js +1 -1
- package/dist/src/utils/model/modelOptions.js +1 -1
- package/dist/src/utils/model/modelStrings.js +1 -1
- package/dist/src/utils/model/providerBaseUrls.js +1 -1
- package/dist/src/utils/model/providerCatalog.js +1 -1
- package/dist/src/utils/model/providerModels.js +1 -1
- package/dist/src/utils/model/providerProfiles.js +1 -1
- package/dist/src/utils/model/providerProfilesDb.js +1 -1
- package/dist/src/utils/model/providerSwitch.js +1 -1
- package/dist/src/utils/model/providers.js +1 -1
- package/dist/src/utils/modelCost.js +1 -1
- package/dist/src/utils/modifiers.js +1 -1
- package/dist/src/utils/mtls.js +1 -1
- package/dist/src/utils/nativeInstaller/download.js +1 -1
- package/dist/src/utils/nativeInstaller/installer.js +1 -1
- package/dist/src/utils/nativeInstaller/packageManagers.js +1 -1
- package/dist/src/utils/nativeInstaller/pidLock.js +1 -1
- package/dist/src/utils/notebook.js +1 -1
- package/dist/src/utils/pasteStore.js +1 -1
- package/dist/src/utils/path.js +1 -1
- package/dist/src/utils/permissions/PermissionMode.js +1 -1
- package/dist/src/utils/permissions/PermissionPromptToolResultSchema.js +1 -1
- package/dist/src/utils/permissions/PermissionUpdate.js +1 -1
- package/dist/src/utils/permissions/PermissionUpdateSchema.js +1 -1
- package/dist/src/utils/permissions/autoModeState.js +1 -1
- package/dist/src/utils/permissions/bypassPermissionsKillswitch.js +1 -1
- package/dist/src/utils/permissions/filesystem.js +1 -1
- package/dist/src/utils/permissions/getNextPermissionMode.js +1 -1
- package/dist/src/utils/permissions/pathValidation.js +1 -1
- package/dist/src/utils/permissions/permissionRuleParser.js +1 -1
- package/dist/src/utils/permissions/permissionsDb.js +1 -1
- package/dist/src/utils/permissions/permissionsLoader.js +1 -1
- package/dist/src/utils/permissions/shellRuleMatching.js +1 -1
- package/dist/src/utils/planModeV2.js +1 -1
- package/dist/src/utils/plans.js +1 -1
- package/dist/src/utils/platform.js +1 -1
- package/dist/src/utils/plugins/addDirPluginSettings.js +1 -1
- package/dist/src/utils/plugins/cacheUtils.js +1 -1
- package/dist/src/utils/plugins/dependencyResolver.js +1 -1
- package/dist/src/utils/plugins/fetchTelemetry.js +1 -1
- package/dist/src/utils/plugins/gitAvailability.js +1 -1
- package/dist/src/utils/plugins/hintRecommendation.js +1 -1
- package/dist/src/utils/plugins/installedPluginsManager.js +1 -1
- package/dist/src/utils/plugins/loadPluginAgents.js +1 -1
- package/dist/src/utils/plugins/loadPluginCommands.js +1 -1
- package/dist/src/utils/plugins/loadPluginHooks.js +1 -1
- package/dist/src/utils/plugins/loadPluginOutputStyles.js +1 -1
- package/dist/src/utils/plugins/lspPluginIntegration.js +1 -1
- package/dist/src/utils/plugins/lspRecommendation.js +1 -1
- package/dist/src/utils/plugins/managedPlugins.js +1 -1
- package/dist/src/utils/plugins/marketplaceHelpers.js +1 -1
- package/dist/src/utils/plugins/marketplaceManager.js +1 -1
- package/dist/src/utils/plugins/mcpPluginIntegration.js +1 -1
- package/dist/src/utils/plugins/mcpbHandler.js +1 -1
- package/dist/src/utils/plugins/officialMarketplaceGcs.js +1 -1
- package/dist/src/utils/plugins/officialMarketplaceStartupCheck.js +1 -1
- package/dist/src/utils/plugins/orphanedPluginFilter.js +1 -1
- package/dist/src/utils/plugins/performStartupChecks.js +1 -1
- package/dist/src/utils/plugins/pluginAutoupdate.js +1 -1
- package/dist/src/utils/plugins/pluginBlocklist.js +1 -1
- package/dist/src/utils/plugins/pluginDirectories.js +1 -1
- package/dist/src/utils/plugins/pluginFlagging.js +1 -1
- package/dist/src/utils/plugins/pluginInstallationHelpers.js +1 -1
- package/dist/src/utils/plugins/pluginLoader.js +1 -1
- package/dist/src/utils/plugins/pluginOptionsStorage.js +1 -1
- package/dist/src/utils/plugins/pluginPolicy.js +1 -1
- package/dist/src/utils/plugins/pluginStartupCheck.js +1 -1
- package/dist/src/utils/plugins/pluginVersioning.js +1 -1
- package/dist/src/utils/plugins/reconciler.js +1 -1
- package/dist/src/utils/plugins/refresh.js +1 -1
- package/dist/src/utils/plugins/schemas.js +1 -1
- package/dist/src/utils/plugins/walkPluginMarkdown.js +1 -1
- package/dist/src/utils/plugins/zipCache.js +1 -1
- package/dist/src/utils/powershell/parser.js +1 -1
- package/dist/src/utils/processUserInput/processBashCommand.js +1 -1
- package/dist/src/utils/processUserInput/processSlashCommand.js +1 -1
- package/dist/src/utils/processUserInput/processTextPrompt.js +1 -1
- package/dist/src/utils/processUserInput/processUserInput.js +1 -1
- package/dist/src/utils/profilerBase.js +1 -1
- package/dist/src/utils/promptCategory.js +1 -1
- package/dist/src/utils/promptEditor.js +1 -1
- package/dist/src/utils/promptShellExecution.js +1 -1
- package/dist/src/utils/proxy.js +1 -1
- package/dist/src/utils/queryHelpers.js +1 -1
- package/dist/src/utils/queryProfiler.js +1 -1
- package/dist/src/utils/queueProcessor.js +1 -1
- package/dist/src/utils/readFileInRange.js +1 -1
- package/dist/src/utils/releaseNotes.js +1 -1
- package/dist/src/utils/renderOptions.js +1 -1
- package/dist/src/utils/ripgrep.js +1 -1
- package/dist/src/utils/sandbox/sandbox-adapter.js +1 -1
- package/dist/src/utils/sdkEventQueue.js +1 -1
- package/dist/src/utils/secureStorage/index.js +1 -1
- package/dist/src/utils/secureStorage/macOsKeychainHelpers.js +1 -1
- package/dist/src/utils/secureStorage/macOsKeychainStorage.js +1 -1
- package/dist/src/utils/secureStorage/plainTextStorage.js +1 -1
- package/dist/src/utils/secureStorage/sqliteStorage.js +1 -1
- package/dist/src/utils/sessionEnvironment.js +1 -1
- package/dist/src/utils/sessionIngressAuth.js +1 -1
- package/dist/src/utils/sessionRestore.js +1 -1
- package/dist/src/utils/sessionStart.js +1 -1
- package/dist/src/utils/sessionTitle.js +1 -1
- package/dist/src/utils/settings/managedPath.js +1 -1
- package/dist/src/utils/settings/mdm/rawRead.js +1 -1
- package/dist/src/utils/settings/mdm/settings.js +1 -1
- package/dist/src/utils/settings/permissionValidation.js +1 -1
- package/dist/src/utils/settings/pluginOnlyPolicy.js +1 -1
- package/dist/src/utils/settings/schemaOutput.js +1 -1
- package/dist/src/utils/settings/settings.js +1 -1
- package/dist/src/utils/settings/types.js +1 -1
- package/dist/src/utils/settings/validateEditTool.js +1 -1
- package/dist/src/utils/settings/validation.js +1 -1
- package/dist/src/utils/shell/bashProvider.js +1 -1
- package/dist/src/utils/shell/powershellDetection.js +1 -1
- package/dist/src/utils/shell/powershellProvider.js +1 -1
- package/dist/src/utils/shell/readOnlyCommandValidation.js +1 -1
- package/dist/src/utils/shell/resolveDefaultShell.js +1 -1
- package/dist/src/utils/shell/shellToolUtils.js +1 -1
- package/dist/src/utils/shell/specPrefix.js +1 -1
- package/dist/src/utils/shellConfig.js +1 -1
- package/dist/src/utils/sideQuestion.js +1 -1
- package/dist/src/utils/skills/skillChangeDetector.js +1 -1
- package/dist/src/utils/slashCommandParsing.js +1 -1
- package/dist/src/utils/sliceAnsi.js +1 -1
- package/dist/src/utils/slowOperations.js +1 -1
- package/dist/src/utils/standaloneAgent.js +1 -1
- package/dist/src/utils/startupProfiler.js +1 -1
- package/dist/src/utils/staticRender.js +1 -1
- package/dist/src/utils/status.js +1 -1
- package/dist/src/utils/statusNoticeDefinitions.js +1 -1
- package/dist/src/utils/suggestions/commandSuggestions.js +1 -1
- package/dist/src/utils/suggestions/directoryCompletion.js +1 -1
- package/dist/src/utils/suggestions/shellHistoryCompletion.js +1 -1
- package/dist/src/utils/suggestions/skillUsageTracking.js +1 -1
- package/dist/src/utils/suggestions/slackChannelSuggestions.js +1 -1
- package/dist/src/utils/swarm/backends/detection.js +1 -1
- package/dist/src/utils/swarm/permissionSync.js +1 -1
- package/dist/src/utils/swarm/reconnection.js +1 -1
- package/dist/src/utils/swarm/spawnUtils.js +1 -91
- package/dist/src/utils/swarm/teammateInit.js +1 -1
- package/dist/src/utils/systemDirectories.js +1 -1
- package/dist/src/utils/systemPrompt.js +1 -1
- package/dist/src/utils/systemTheme.js +1 -1
- package/dist/src/utils/task/TaskOutput.js +1 -1
- package/dist/src/utils/task/diskOutput.js +1 -1
- package/dist/src/utils/tasks.js +1 -1
- package/dist/src/utils/teamDiscovery.js +1 -1
- package/dist/src/utils/teamMemoryOps.js +1 -1
- package/dist/src/utils/teammateMailbox.js +1 -1
- package/dist/src/utils/telemetry/betaSessionTracing.js +1 -1
- package/dist/src/utils/telemetry/bigqueryExporter.js +1 -1
- package/dist/src/utils/telemetry/events.js +1 -1
- package/dist/src/utils/telemetry/instrumentation.js +1 -1
- package/dist/src/utils/telemetry/logger.js +1 -1
- package/dist/src/utils/telemetry/perfettoTracing.js +1 -1
- package/dist/src/utils/telemetry/pluginTelemetry.js +1 -1
- package/dist/src/utils/telemetry/sessionTracing.js +1 -1
- package/dist/src/utils/telemetryAttributes.js +1 -1
- package/dist/src/utils/teleport/api.js +1 -1
- package/dist/src/utils/teleport/environments.js +1 -1
- package/dist/src/utils/teleport/gitBundle.js +1 -1
- package/dist/src/utils/teleport.js +1 -1
- package/dist/src/utils/tempfile.js +1 -1
- package/dist/src/utils/terminal.js +1 -1
- package/dist/src/utils/terminalPanel.js +1 -1
- package/dist/src/utils/textHighlighting.js +1 -1
- package/dist/src/utils/theme.js +1 -1
- package/dist/src/utils/themes/bootstrap.js +1 -1
- package/dist/src/utils/themes/loader.js +1 -1
- package/dist/src/utils/thinking.js +1 -1
- package/dist/src/utils/tmuxSocket.js +1 -1
- package/dist/src/utils/tokens.js +1 -1
- package/dist/src/utils/toolPool.js +1 -1
- package/dist/src/utils/toolResultStorage.js +1 -1
- package/dist/src/utils/transcriptSearch.js +1 -1
- package/dist/src/utils/truncate.js +1 -1
- package/dist/src/utils/ultraplan/keyword.js +1 -1
- package/dist/src/utils/unaryLogging.js +1 -1
- package/dist/src/utils/undercover.js +1 -1
- package/dist/src/utils/user.js +1 -1
- package/dist/src/utils/userPromptKeywords.js +1 -1
- package/dist/src/utils/which.js +1 -1
- package/dist/src/utils/windowsPaths.js +1 -1
- package/dist/src/utils/worktree.js +1 -1
- package/dist/src/utils/zodToJsonSchema.js +1 -1
- package/dist/src/vim/operators.js +1 -1
- package/dist/src/vim/textObjects.js +1 -1
- package/dist/src/vim/transitions.js +1 -1
- package/dist/src/voice/voiceModeEnabled.js +1 -1
- package/dist/src/webapp/auth.js +1 -1
- package/dist/src/webapp/tunnel.js +1 -1
- package/dist/src/whatsapp/bridge.js +1 -1
- package/dist/src/whatsapp/mirror.js +1 -1
- package/package.json +41 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"axios";import{createHash as t}from"crypto";import{chmod as r,writeFile as n}from"fs/promises";import{dirname as a,join as
|
|
1
|
+
import e from"axios";import{createHash as t}from"crypto";import{chmod as r,writeFile as n}from"fs/promises";import{dirname as a,join as o}from"path";import{logForDebugging as s}from"../debug.js";import{parseAndValidateManifestFromBytes as i}from"../dxt/helpers.js";import{parseZipModes as c,unzipFile as f}from"../dxt/zip.js";import{errorMessage as g,getErrnoCode as d,isENOENT as l,toError as u}from"../errors.js";import{getFsImplementation as h}from"../fsOperations.js";import{logError as m}from"../log.js";import{getSecureStorage as p}from"../secureStorage/index.js";import{getSettings_DEPRECATED as w,updateSettingsForSource as C}from"../settings/settings.js";import{jsonParse as $,jsonStringify as v}from"../slowOperations.js";import{getSystemDirectories as y}from"../systemDirectories.js";import{classifyFetchError as b,logPluginFetch as M}from"./fetchTelemetry.js";export function isMcpbSource(e){return e.endsWith(".mcpb")||e.endsWith(".dxt")}function isUrl(e){return e.startsWith("http://")||e.startsWith("https://")}function getMcpbCacheDir(e){return o(e,".mcpb-cache")}function getMetadataPath(e,r){const n=t("md5").update(r).digest("hex").substring(0,8);return o(e,`${n}.metadata.json`)}function serverSecretsKey(e,t){return`${e}/${t}`}export function loadMcpServerUserConfig(e,t){try{const r=w(),n=r.pluginConfigs?.[e]?.mcpServers?.[t],a=p().read()?.pluginSecrets?.[serverSecretsKey(e,t)];return n||a?(s(`Loaded user config for ${e}/${t} (settings + secureStorage)`),{...n,...a}):null}catch(r){const n=u(r);return m(n),s(`Failed to load user config for ${e}/${t}: ${r}`,{level:"error"}),null}}export function saveMcpServerUserConfig(e,t,r,n){try{const a={},o={};for(const[e,t]of Object.entries(r))!0===n[e]?.sensitive?o[e]=String(t):a[e]=t;const i=new Set(Object.keys(o)),c=new Set(Object.keys(a)),f=p(),g=serverSecretsKey(e,t),d=f.read()?.pluginSecrets?.[g]??void 0,l=d?Object.fromEntries(Object.entries(d).filter(([e])=>!c.has(e))):void 0,u=l&&d&&Object.keys(l).length!==Object.keys(d).length;if(Object.keys(o).length>0||u){const e=f.read()??{};e.pluginSecrets||(e.pluginSecrets={}),e.pluginSecrets[g]={...l,...o};const t=f.update(e);if(!t.success)throw new Error(`Failed to save sensitive config to secure storage for ${g}`);t.warning&&s(`Server secrets save warning: ${t.warning}`,{level:"warn"}),u&&s(`saveMcpServerUserConfig: scrubbed ${Object.keys(d).length-Object.keys(l).length} stale non-sensitive key(s) from secureStorage for ${g}`)}const h=w(),m=h.pluginConfigs?.[e]?.mcpServers?.[t]??{},$=Object.keys(m).filter(e=>i.has(e));if(Object.keys(a).length>0||$.length>0){h.pluginConfigs||(h.pluginConfigs={}),h.pluginConfigs[e]||(h.pluginConfigs[e]={}),h.pluginConfigs[e].mcpServers||(h.pluginConfigs[e].mcpServers={});const r=Object.fromEntries($.map(e=>[e,void 0]));h.pluginConfigs[e].mcpServers[t]={...a,...r};const n=C("userSettings",h);if(n.error)throw n.error;$.length>0&&s(`saveMcpServerUserConfig: scrubbed ${$.length} plaintext sensitive key(s) from settings.json for ${e}/${t}`)}s(`Saved user config for ${e}/${t} (${Object.keys(a).length} non-sensitive, ${Object.keys(o).length} sensitive)`)}catch(r){const n=u(r);throw m(n),new Error(`Failed to save user configuration for ${e}/${t}: ${n.message}`)}}export function validateUserConfig(e,t){const r=[];for(const[n,a]of Object.entries(t)){const t=e[n];!a.required||void 0!==t&&""!==t?void 0!==t&&""!==t&&("string"===a.type?Array.isArray(t)?a.multiple?t.every(e=>"string"==typeof e)||r.push(`${a.title||n} must be an array of strings`):r.push(`${a.title||n} must be a string, not an array`):"string"!=typeof t&&r.push(`${a.title||n} must be a string`):"number"===a.type&&"number"!=typeof t?r.push(`${a.title||n} must be a number`):"boolean"===a.type&&"boolean"!=typeof t?r.push(`${a.title||n} must be a boolean`):"file"!==a.type&&"directory"!==a.type||"string"==typeof t||r.push(`${a.title||n} must be a path string`),"number"===a.type&&"number"==typeof t&&(void 0!==a.min&&t<a.min&&r.push(`${a.title||n} must be at least ${a.min}`),void 0!==a.max&&t>a.max&&r.push(`${a.title||n} must be at most ${a.max}`))):r.push(`${a.title||n} is required but not provided`)}return{valid:0===r.length,errors:r}}async function generateMcpConfig(e,t,r={}){const{getMcpConfigForManifest:n}=await import("@anthropic-ai/mcpb"),a=await n({manifest:e,extensionPath:t,systemDirs:y(),userConfig:r,pathSeparator:"/"});if(!a){const t=new Error(`Failed to generate MCP server configuration from manifest "${e.name}"`);throw m(t),t}return a}async function loadCacheMetadata(e,t){const r=h(),n=getMetadataPath(e,t);try{const e=await r.readFile(n,{encoding:"utf-8"});return $(e)}catch(e){if("ENOENT"===d(e))return null;const t=u(e);return m(t),s(`Failed to load MCPB cache metadata: ${e}`,{level:"error"}),null}}async function saveCacheMetadata(e,t,r){const a=getMetadataPath(e,t);await h().mkdir(e),await n(a,v(r,null,2),"utf-8")}export async function checkMcpbChanged(e,t){const r=h(),n=getMcpbCacheDir(t),a=await loadCacheMetadata(n,e);if(!a)return!0;try{await r.stat(a.extractedPath)}catch(e){return"ENOENT"===d(e)?s(`MCPB extraction path missing: ${a.extractedPath}`):s(`MCPB extraction path inaccessible: ${a.extractedPath}: ${e}`,{level:"error"}),!0}if(!isUrl(e)){const n=o(t,e);let i;try{i=await r.stat(n)}catch(e){return"ENOENT"===d(e)?s(`MCPB source file missing: ${n}`):s(`MCPB source file inaccessible: ${n}: ${e}`,{level:"error"}),!0}const c=new Date(a.cachedAt).getTime(),f=Math.floor(i.mtimeMs);if(f>c)return s(`MCPB file modified: ${new Date(f)} > ${new Date(c)}`),!0}return!1}export async function loadMcpbFile(d,u,p,w,C,$){const v=h(),y=getMcpbCacheDir(u);await v.mkdir(y),s(`Loading MCPB from source: ${d}`);const x=await loadCacheMetadata(y,d);if(x&&!await checkMcpbChanged(d,u)){s(`Using cached MCPB from ${x.extractedPath} (hash: ${x.contentHash})`);const e=o(x.extractedPath,"manifest.json");let t;try{t=await v.readFile(e,{encoding:"utf-8"})}catch(t){if(l(t)){const t=new Error(`Cached manifest not found: ${e}`);throw m(t),t}throw t}const r=(new TextEncoder).encode(t),n=await i(r);if(n.user_config&&Object.keys(n.user_config).length>0){const e=n.name,t=loadMcpServerUserConfig(p,e),r=C||t||{},a=validateUserConfig(r,n.user_config);if($||!a.valid)return{status:"needs-config",manifest:n,extractedPath:x.extractedPath,contentHash:x.contentHash,configSchema:n.user_config,existingConfig:t||{},validationErrors:a.valid?[]:a.errors};C&&saveMcpServerUserConfig(p,e,C,n.user_config??{});return{manifest:n,mcpConfig:await generateMcpConfig(n,x.extractedPath,r),extractedPath:x.extractedPath,contentHash:x.contentHash}}return{manifest:n,mcpConfig:await generateMcpConfig(n,x.extractedPath),extractedPath:x.extractedPath,contentHash:x.contentHash}}let S,P;if(isUrl(d)){const r=t("md5").update(d).digest("hex").substring(0,8);P=o(y,`${r}.mcpb`),S=await async function(t,r,a){s(`Downloading MCPB from ${t}`),a&&a(`Downloading ${t}...`);const o=performance.now();let i=!1;try{const c=await e.get(t,{timeout:12e4,responseType:"arraybuffer",maxRedirects:5,onDownloadProgress:e=>{if(e.total&&a){const t=Math.round(e.loaded/e.total*100);a(`Downloading... ${t}%`)}}}),f=new Uint8Array(c.data);return M("mcpb",t,"success",performance.now()-o),i=!0,await n(r,Buffer.from(f)),s(`Downloaded ${f.length} bytes to ${r}`),a&&a("Download complete"),f}catch(e){i||M("mcpb",t,"failure",performance.now()-o,b(e));const r=g(e),n=new Error(`Failed to download MCPB file from ${t}: ${r}`);throw m(n),n}}(d,P,w)}else{const e=o(u,d);w&&w(`Loading ${d}...`);try{S=await v.readFileBytes(e),P=e}catch(t){if(l(t)){const t=new Error(`MCPB file not found: ${e}`);throw m(t),t}throw t}}const j=(O=S,t("sha256").update(O).digest("hex").substring(0,16));var O;s(`MCPB content hash: ${j}`),w&&w("Extracting MCPB archive...");const k=await f(Buffer.from(S)),E=c(S),B=k["manifest.json"];if(!B){const e=new Error("No manifest.json found in MCPB file");throw m(e),e}const D=await i(B);if(s(`MCPB manifest: ${D.name} v${D.version} by ${D.author.name}`),!D.server){const e=new Error(`MCPB manifest for "${D.name}" does not define a server configuration`);throw m(e),e}const U=o(y,j);if(await async function(e,t,i,c){c&&c("Extracting files..."),await h().mkdir(t);let f=0;const g=Object.entries(e).filter(([e])=>!e.endsWith("/")),d=g.length;for(const[e,s]of g){const g=o(t,e),l=a(g);if(l!==t&&await h().mkdir(l),e.endsWith(".json")||e.endsWith(".js")||e.endsWith(".ts")||e.endsWith(".txt")||e.endsWith(".md")||e.endsWith(".yml")||e.endsWith(".yaml")){const e=(new TextDecoder).decode(s);await n(g,e,"utf-8")}else await n(g,Buffer.from(s));const u=i[e];u&&73&u&&await r(g,511&u).catch(()=>{}),f++,c&&f%10==0&&c(`Extracted ${f}/${d} files`)}s(`Extracted ${f} files to ${t}`),c&&c(`Extraction complete (${f} files)`)}(k,U,E,w),D.user_config&&Object.keys(D.user_config).length>0){const e=D.name,t=loadMcpServerUserConfig(p,e),r=C||t||{},n=validateUserConfig(r,D.user_config);if(!n.valid){const e={source:d,contentHash:j,extractedPath:U,cachedAt:(new Date).toISOString(),lastChecked:(new Date).toISOString()};return await saveCacheMetadata(y,d,e),{status:"needs-config",manifest:D,extractedPath:U,contentHash:j,configSchema:D.user_config,existingConfig:t||{},validationErrors:n.errors}}C&&saveMcpServerUserConfig(p,e,C,D.user_config??{}),w&&w("Generating MCP server configuration...");const a=await generateMcpConfig(D,U,r),o={source:d,contentHash:j,extractedPath:U,cachedAt:(new Date).toISOString(),lastChecked:(new Date).toISOString()};return await saveCacheMetadata(y,d,o),{manifest:D,mcpConfig:a,extractedPath:U,contentHash:j}}w&&w("Generating MCP server configuration...");const H=await generateMcpConfig(D,U),W={source:d,contentHash:j,extractedPath:U,cachedAt:(new Date).toISOString(),lastChecked:(new Date).toISOString()};return await saveCacheMetadata(y,d,W),s(`Successfully loaded MCPB: ${D.name} (extracted to ${U})`),{manifest:D,mcpConfig:H,extractedPath:U,contentHash:j}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import t from"axios";import{chmod as e,mkdir as r,readFile as i,rename as s,rm as a,writeFile as o}from"fs/promises";import{dirname as c,join as n,resolve as f,sep as l}from"path";import{waitForScrollIdle as p}from"../../bootstrap/state.js";import{logEvent as u}from"../../services/analytics/index.js";import{logForDebugging as m}from"../debug.js";import{parseZipModes as d,unzipFile as h}from"../dxt/zip.js";import{errorMessage as E,getErrnoCode as w}from"../errors.js";const y="https://downloads.claude.ai/claude-code-releases/plugins/claude-plugins-official",g="marketplaces/claude-plugins-official/";export async function fetchOfficialMarketplaceFromGcs(w,_){const O=f(_),v=f(w);if(v!==O&&!v.startsWith(O+l))return m(`fetchOfficialMarketplaceFromGcs: refusing path outside cache dir: ${w}`,{level:"error"}),null;await p();const $=performance.now();let b,N,k,x="failed";try{const f=await t.get(`${y}/latest`,{responseType:"text",timeout:1e4});if(b=String(f.data).trim(),!b)throw new Error("latest pointer returned empty body");const l=n(w,".gcs-sha");if(await i(l,"utf8").then(t=>t.trim(),()=>null)===b)return x="noop",b;const p=await t.get(`${y}/${b}.zip`,{responseType:"arraybuffer",timeout:6e4}),u=Buffer.from(p.data);N=u.length;const m=await h(u),E=d(u),_=`${w}.staging`;await a(_,{recursive:!0,force:!0}),await r(_,{recursive:!0});for(const[t,i]of Object.entries(m)){if(!t.startsWith(g))continue;const s=t.slice(37);if(!s||s.endsWith("/"))continue;const a=n(_,s);await r(c(a),{recursive:!0}),await o(a,i);const f=E[t];f&&73&f&&await e(a,511&f).catch(()=>{})}return await o(n(_,".gcs-sha"),b),await a(w,{recursive:!0,force:!0}),await s(_,w),x="updated",b}catch(t){return k=classifyGcsError(t),m(`Official marketplace GCS fetch failed: ${E(t)}`,{level:"warn"}),null}finally{u("tengu_plugin_remote_fetch",{source:"marketplace_gcs",host:"downloads.claude.ai",is_official:!0,outcome:x,duration_ms:Math.round(performance.now()-$),...void 0!==N&&{bytes:N},...b&&{sha:b},...k&&{error_kind:k}})}}const _=new Set(["ENOSPC","EACCES","EPERM","EXDEV","EBUSY","ENOENT","ENOTDIR","EROFS","EMFILE","ENAMETOOLONG"]);export function classifyGcsError(e){if(t.isAxiosError(e))return"ECONNABORTED"===e.code?"timeout":e.response?`http_${e.response.status}`:"network";const r=w(e);if(r&&/^E[A-Z]+$/.test(r)&&!r.startsWith("ERR_"))return _.has(r)?`fs_${r}`:"fs_other";if("number"==typeof e?.code)return"zip_parse";const i=E(e);return/unzip|invalid zip|central directory/i.test(i)?"zip_parse":/empty body/.test(i)?"empty_latest":"other"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as a}from"path";import{getFeatureValue_CACHED_MAY_BE_STALE as t}from"../../services/analytics/growthbook.js";import{logEvent as l}from"../../services/analytics/index.js";import{getGlobalConfig as e,saveGlobalConfig as i}from"../config.js";import{logForDebugging as o}from"../debug.js";import{isEnvTruthy as c}from"../envUtils.js";import{toError as n}from"../errors.js";import{logError as
|
|
1
|
+
import{join as a}from"path";import{getFeatureValue_CACHED_MAY_BE_STALE as t}from"../../services/analytics/growthbook.js";import{logEvent as l}from"../../services/analytics/index.js";import{getGlobalConfig as e,saveGlobalConfig as i}from"../config.js";import{logForDebugging as o}from"../debug.js";import{isEnvTruthy as c}from"../envUtils.js";import{toError as n}from"../errors.js";import{logError as r}from"../log.js";import{checkGitAvailable as s,markGitUnavailable as f}from"./gitAvailability.js";import{isSourceAllowedByPolicy as p}from"./marketplaceHelpers.js";import{addMarketplaceSource as u,getMarketplacesCacheDir as k,loadKnownMarketplacesConfig as d,saveKnownMarketplacesConfig as A}from"./marketplaceManager.js";import{OFFICIAL_MARKETPLACE_NAME as _,OFFICIAL_MARKETPLACE_SOURCE as m}from"./officialMarketplace.js";import{fetchOfficialMarketplaceFromGcs as I}from"./officialMarketplaceGcs.js";export function isOfficialMarketplaceAutoInstallDisabled(){return c(process.env.CONTEXT_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL)||c(process.env.CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL)}export const RETRY_CONFIG={MAX_ATTEMPTS:10,INITIAL_DELAY_MS:36e5,BACKOFF_MULTIPLIER:2,MAX_DELAY_MS:6048e5};function calculateNextRetryDelay(a){const t=RETRY_CONFIG.INITIAL_DELAY_MS*Math.pow(RETRY_CONFIG.BACKOFF_MULTIPLIER,a);return Math.min(t,RETRY_CONFIG.MAX_DELAY_MS)}export async function checkAndInstallOfficialMarketplace(){const c=e();if(!function(a){if(!a.officialMarketplaceAutoInstallAttempted)return!0;if(a.officialMarketplaceAutoInstalled)return!1;const t=a.officialMarketplaceAutoInstallFailReason,l=a.officialMarketplaceAutoInstallRetryCount||0,e=a.officialMarketplaceAutoInstallNextRetryTime,i=Date.now();return!(l>=RETRY_CONFIG.MAX_ATTEMPTS||"policy_blocked"===t||e&&i<e||"unknown"!==t&&"git_unavailable"!==t&&"gcs_unavailable"!==t&&void 0!==t)}(c)){const a=c.officialMarketplaceAutoInstallFailReason??"already_attempted";return o(`Official marketplace auto-install skipped: ${a}`),{installed:!1,skipped:!0,reason:a}}try{if(isOfficialMarketplaceAutoInstallDisabled())return o("Official marketplace auto-install disabled via env var, skipping"),i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!1,officialMarketplaceAutoInstallFailReason:"policy_blocked"})),l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,policy_blocked:!0}),{installed:!1,skipped:!0,reason:"policy_blocked"};if((await d())[_])return o(`Official marketplace '${_}' already installed, skipping`),i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!0})),{installed:!1,skipped:!0,reason:"already_installed"};if(!p(m))return o("Official marketplace blocked by enterprise policy, skipping"),i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!1,officialMarketplaceAutoInstallFailReason:"policy_blocked"})),l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,policy_blocked:!0}),{installed:!1,skipped:!0,reason:"policy_blocked"};const e=k(),f=a(e,_);if(null!==await I(f,e)){const a=await d();return a[_]={source:m,installLocation:f,lastUpdated:(new Date).toISOString()},await A(a),i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!0,officialMarketplaceAutoInstallFailReason:void 0,officialMarketplaceAutoInstallRetryCount:void 0,officialMarketplaceAutoInstallLastAttemptTime:void 0,officialMarketplaceAutoInstallNextRetryTime:void 0})),l("tengu_official_marketplace_auto_install",{installed:!0,skipped:!1,via_gcs:!0}),{installed:!0,skipped:!1}}if(!t("tengu_plugin_official_mkt_git_fallback",!0)){o("Official marketplace GCS failed; git fallback disabled by flag — skipping install");const a=(c.officialMarketplaceAutoInstallRetryCount||0)+1,t=Date.now(),e=t+calculateNextRetryDelay(a);return i(l=>({...l,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!1,officialMarketplaceAutoInstallFailReason:"gcs_unavailable",officialMarketplaceAutoInstallRetryCount:a,officialMarketplaceAutoInstallLastAttemptTime:t,officialMarketplaceAutoInstallNextRetryTime:e})),l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,gcs_unavailable:!0,retry_count:a}),{installed:!1,skipped:!0,reason:"gcs_unavailable"}}if(!await s()){o("Git not available, skipping official marketplace auto-install");const a=(c.officialMarketplaceAutoInstallRetryCount||0)+1,t=Date.now(),e=calculateNextRetryDelay(a),s=t+e;let f=!1;try{i(l=>({...l,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!1,officialMarketplaceAutoInstallFailReason:"git_unavailable",officialMarketplaceAutoInstallRetryCount:a,officialMarketplaceAutoInstallLastAttemptTime:t,officialMarketplaceAutoInstallNextRetryTime:s}))}catch(a){f=!0;const t=n(a);r(t),o(`Failed to save marketplace auto-install git_unavailable state: ${a}`,{level:"error"})}return l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,git_unavailable:!0,retry_count:a}),{installed:!1,skipped:!0,reason:"git_unavailable",configSaveFailed:f}}o("Attempting to auto-install official marketplace"),await u(m),o("Successfully auto-installed official marketplace");const M=c.officialMarketplaceAutoInstallRetryCount||0;return i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!0,officialMarketplaceAutoInstallFailReason:void 0,officialMarketplaceAutoInstallRetryCount:void 0,officialMarketplaceAutoInstallLastAttemptTime:void 0,officialMarketplaceAutoInstallNextRetryTime:void 0})),l("tengu_official_marketplace_auto_install",{installed:!0,skipped:!1,retry_count:M}),{installed:!0,skipped:!1}}catch(a){const t=a instanceof Error?a.message:String(a);if(t.includes("xcrun: error:"))return f(),o("Official marketplace auto-install: git is a non-functional macOS xcrun shim, treating as git_unavailable"),l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,git_unavailable:!0,macos_xcrun_shim:!0}),{installed:!1,skipped:!0,reason:"git_unavailable"};o(`Failed to auto-install official marketplace: ${t}`,{level:"error"}),r(n(a));const e=(c.officialMarketplaceAutoInstallRetryCount||0)+1,s=Date.now(),p=calculateNextRetryDelay(e),u=s+p;let k=!1;try{i(a=>({...a,officialMarketplaceAutoInstallAttempted:!0,officialMarketplaceAutoInstalled:!1,officialMarketplaceAutoInstallFailReason:"unknown",officialMarketplaceAutoInstallRetryCount:e,officialMarketplaceAutoInstallLastAttemptTime:s,officialMarketplaceAutoInstallNextRetryTime:u}))}catch(a){k=!0;const t=n(a);r(t),o(`Failed to save marketplace auto-install failure state: ${a}`,{level:"error"})}return l("tengu_official_marketplace_auto_install",{installed:!1,skipped:!0,failed:!0,retry_count:e}),{installed:!1,skipped:!0,reason:"unknown",configSaveFailed:k}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname as r,isAbsolute as o,join as
|
|
1
|
+
import{dirname as r,isAbsolute as o,join as n,normalize as t,relative as e,sep as i}from"path";import{ripGrep as a}from"../ripgrep.js";import{getPluginsDirectory as l}from"./pluginDirectories.js";let c=null;export async function getGlobExclusionsForPluginCache(s){const u=t(n(l(),"cache"));if(s&&!function(r,o){const n=normalizeForCompare(r),t=normalizeForCompare(o);return n===t||n===i||t===i||n.startsWith(t+i)||t.startsWith(n+i)}(s,u))return[];if(null!==c)return c;try{const n=await a(["--files","--hidden","--no-ignore","--max-depth","4","--glob",".orphaned_at"],u,(new AbortController).signal);return c=n.map(n=>{const t=r(n);return`!**/${(o(t)?e(u,t):t).replace(/\\/g,"/")}/**`}),c}catch{return c=[],c}}export function clearPluginCacheExclusions(){c=null}function normalizeForCompare(r){const o=t(r);return"win32"===process.platform?o.toLowerCase():o}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{performBackgroundPluginInstallations as
|
|
1
|
+
import{performBackgroundPluginInstallations as r}from"../../services/plugins/PluginInstallationManager.js";import{checkHasTrustDialogAccepted as t}from"../config.js";import{logForDebugging as e}from"../debug.js";import{clearMarketplacesCache as i,registerSeedMarketplaces as n}from"./marketplaceManager.js";import{clearPluginCache as a}from"./pluginLoader.js";export async function performStartupChecks(s){if(e("performStartupChecks called"),t())try{e("Starting background plugin installations");await n()&&(i(),a("performStartupChecks: seed marketplaces changed"),s(r=>r.plugins.needsRefresh?r:{...r,plugins:{...r.plugins,needsRefresh:!0}})),await r(s)}catch(r){e(`Error initiating background plugin installations: ${r}`)}else e("Trust not accepted for current directory - skipping plugin installations")}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{updatePluginOp as e}from"../../services/plugins/pluginOperations.js";import{shouldSkipPluginAutoupdate as t}from"../config.js";import{logForDebugging as a}from"../debug.js";import{errorMessage as n}from"../errors.js";import{logError as r}from"../log.js";import{getPendingUpdatesDetails as l,hasPendingUpdates as
|
|
1
|
+
import{updatePluginOp as e}from"../../services/plugins/pluginOperations.js";import{shouldSkipPluginAutoupdate as t}from"../config.js";import{logForDebugging as a}from"../debug.js";import{errorMessage as n}from"../errors.js";import{logError as r}from"../log.js";import{getPendingUpdatesDetails as l,hasPendingUpdates as o,isInstallationRelevantToCurrentProject as u,loadInstalledPluginsFromDisk as i}from"./installedPluginsManager.js";import{getDeclaredMarketplaces as s,loadKnownMarketplacesConfig as p,refreshMarketplace as c}from"./marketplaceManager.js";import{parsePluginIdentifier as d}from"./pluginIdentifier.js";import{isMarketplaceAutoUpdate as f}from"./schemas.js";let g=null,m=null;export function onPluginsAutoUpdated(e){return g=e,null!==m&&m.length>0&&(e(m),m=null),()=>{g=null}}export function getAutoUpdatedPluginNames(){return o()?l().map(e=>d(e.pluginId).name):[]}export async function updatePluginsForMarketplaces(t){const r=i(),l=Object.keys(r.plugins);if(0===l.length)return[];return(await Promise.allSettled(l.map(async l=>{const{marketplace:o}=d(l);if(!o||!t.has(o.toLowerCase()))return null;const i=r.plugins[l];if(!i||0===i.length)return null;const s=i.filter(u);return 0===s.length?null:async function(t,r){let l=!1;for(const{scope:o}of r)try{const n=await e(t,o);n.success&&!n.alreadyUpToDate?(l=!0,a(`Plugin autoupdate: updated ${t} from ${n.oldVersion} to ${n.newVersion}`)):n.alreadyUpToDate||a(`Plugin autoupdate: failed to update ${t}: ${n.message}`,{level:"warn"})}catch(e){a(`Plugin autoupdate: error updating ${t}: ${n(e)}`,{level:"warn"})}return l?t:null}(l,s)}))).filter(e=>"fulfilled"===e.status&&null!==e.value).map(e=>e.value)}export function autoUpdateMarketplacesAndPluginsInBackground(){(async()=>{if(t())a("Plugin autoupdate: skipped (auto-updater disabled)");else try{const e=await async function(){const e=await p(),t=s(),a=new Set;for(const[n,r]of Object.entries(e)){const e=t[n]?.autoUpdate;(void 0!==e?e:f(n,r))&&a.add(n.toLowerCase())}return a}();if(0===e.size)return;const t=(await Promise.allSettled(Array.from(e).map(async e=>{try{await c(e,void 0,{disableCredentialHelper:!0})}catch(t){a(`Plugin autoupdate: failed to refresh marketplace ${e}: ${n(t)}`,{level:"warn"})}}))).filter(e=>"rejected"===e.status);t.length>0&&a(`Plugin autoupdate: ${t.length} marketplace refresh(es) failed`,{level:"warn"}),a("Plugin autoupdate: checking installed plugins");const r=await async function(e){return updatePluginsForMarketplaces(e)}(e);r.length>0&&(g?g(r):m=r)}catch(e){r(e)}})()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{uninstallPluginOp as e}from"../../services/plugins/pluginOperations.js";import{logForDebugging as
|
|
1
|
+
import{uninstallPluginOp as e}from"../../services/plugins/pluginOperations.js";import{logForDebugging as t}from"../debug.js";import{errorMessage as o}from"../errors.js";import{loadInstalledPluginsV2 as n}from"./installedPluginsManager.js";import{getMarketplace as s,loadKnownMarketplacesConfigSafe as i}from"./marketplaceManager.js";import{addFlaggedPlugin as r,getFlaggedPlugins as c,loadFlaggedPlugins as l}from"./pluginFlagging.js";export function detectDelistedPlugins(e,t,o){const n=new Set(t.plugins.map(e=>e.name)),s=`@${o}`,i=[];for(const t of Object.keys(e.plugins)){if(!t.endsWith(s))continue;const e=t.slice(0,-s.length);n.has(e)||i.push(t)}return i}export async function detectAndUninstallDelistedPlugins(){await l();const a=n(),p=c(),u=await i(),f=[];for(const n of Object.keys(u))try{const i=await s(n);if(!i.forceRemoveDeletedPlugins)continue;const c=detectDelistedPlugins(a,i,n);for(const n of c){if(n in p)continue;const s=a.plugins[n]??[];if(s.some(e=>"user"===e.scope||"project"===e.scope||"local"===e.scope)){for(const i of s){const{scope:s}=i;if("user"===s||"project"===s||"local"===s)try{await e(n,s)}catch(e){t(`Failed to auto-uninstall delisted plugin ${n} from ${s}: ${o(e)}`,{level:"error"})}}await r(n),f.push(n)}}}catch(e){t(`Failed to check for delisted plugins in "${n}": ${o(e)}`,{level:"warn"})}return f}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdirSync as t}from"fs";import{readdir as r,rm as e,stat as
|
|
1
|
+
import{mkdirSync as t}from"fs";import{readdir as r,rm as e,stat as o}from"fs/promises";import{delimiter as i,join as n}from"path";import{getUseCoworkPlugins as s}from"../../bootstrap/state.js";import{logForDebugging as a}from"../debug.js";import{getClaudeConfigHomeDir as c,isEnvTruthy as p}from"../envUtils.js";import{errorMessage as u,isFsInaccessible as D}from"../errors.js";import{formatFileSize as l}from"../format.js";import{expandTilde as _}from"../permissions/pathValidation.js";const f="cowork_plugins";export function getPluginsDirectory(){const t=process.env.CONTEXT_CODE_PLUGIN_CACHE_DIR??process.env.CLAUDE_CODE_PLUGIN_CACHE_DIR;return t?_(t):n(c(),s()||p(process.env.CONTEXT_CODE_USE_COWORK_PLUGINS)||p(process.env.CLAUDE_CODE_USE_COWORK_PLUGINS)?f:"plugins")}export function getPluginSeedDirs(){const t=process.env.CONTEXT_CODE_PLUGIN_SEED_DIR??process.env.CLAUDE_CODE_PLUGIN_SEED_DIR;return t?t.split(i).filter(Boolean).map(_):[]}export function pluginDataDirPath(t){return n(getPluginsDirectory(),"data",function(t){return t.replace(/[^a-zA-Z0-9\-_]/g,"-")}(t))}export function getPluginDataDir(r){const e=pluginDataDirPath(r);return t(e,{recursive:!0}),e}export async function getPluginDataDirSize(t){const e=pluginDataDirPath(t);let i=0;const walk=async t=>{for(const e of await r(t,{withFileTypes:!0})){const r=n(t,e.name);if(e.isDirectory())await walk(r);else try{i+=(await o(r)).size}catch{}}};try{await walk(e)}catch(t){if(D(t))return null;throw t}return 0===i?null:{bytes:i,human:l(i)}}export async function deletePluginDataDir(t){const r=pluginDataDirPath(t);try{await e(r,{recursive:!0,force:!0})}catch(t){a(`Failed to delete plugin data dir ${r}: ${u(t)}`,{level:"warn"})}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomBytes as t}from"crypto";import{readFile as e,rename as n,unlink as
|
|
1
|
+
import{randomBytes as t}from"crypto";import{readFile as e,rename as n,unlink as o,writeFile as i}from"fs/promises";import{join as r}from"path";import{logForDebugging as a}from"../debug.js";import{getFsImplementation as s}from"../fsOperations.js";import{logError as g}from"../log.js";import{jsonParse as l,jsonStringify as c}from"../slowOperations.js";import{getPluginsDirectory as u}from"./pluginDirectories.js";let f=null;function getFlaggedPluginsPath(){return r(u(),"flagged-plugins.json")}async function readFromDisk(){try{return function(t){const e=l(t);if("object"!=typeof e||null===e||!("plugins"in e)||"object"!=typeof e.plugins||null===e.plugins)return{};const n=e.plugins,o={};for(const[t,e]of Object.entries(n))if(e&&"object"==typeof e&&"flaggedAt"in e&&"string"==typeof e.flaggedAt){const n={flaggedAt:e.flaggedAt};"seenAt"in e&&"string"==typeof e.seenAt&&(n.seenAt=e.seenAt),o[t]=n}return o}(await e(getFlaggedPluginsPath(),{encoding:"utf-8"}))}catch{return{}}}async function writeToDisk(e){const r=getFlaggedPluginsPath(),a=`${r}.${t(8).toString("hex")}.tmp`;try{await s().mkdir(u());const t=c({plugins:e},null,2);await i(a,t,{encoding:"utf-8",mode:384}),await n(a,r),f=e}catch(t){g(t);try{await o(a)}catch{}}}export async function loadFlaggedPlugins(){const t=await readFromDisk(),e=Date.now();let n=!1;for(const[o,i]of Object.entries(t))i.seenAt&&e-new Date(i.seenAt).getTime()>=1728e5&&(delete t[o],n=!0);f=t,n&&await writeToDisk(t)}export function getFlaggedPlugins(){return f??{}}export async function addFlaggedPlugin(t){null===f&&(f=await readFromDisk());const e={...f,[t]:{flaggedAt:(new Date).toISOString()}};await writeToDisk(e),a(`Flagged plugin: ${t}`)}export async function markFlaggedPluginsSeen(t){null===f&&(f=await readFromDisk());const e=(new Date).toISOString();let n=!1;const o={...f};for(const i of t){const t=o[i];t&&!t.seenAt&&(o[i]={...t,seenAt:e},n=!0)}n&&await writeToDisk(o)}export async function removeFlaggedPlugin(t){if(null===f&&(f=await readFromDisk()),!(t in f))return;const{[t]:e,...n}=f;f=n,await writeToDisk(n)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomBytes as e}from"crypto";import{rename as t,rm as
|
|
1
|
+
import{randomBytes as e}from"crypto";import{rename as t,rm as n}from"fs/promises";import{dirname as r,join as a,resolve as o,sep as i}from"path";import{logEvent as s}from"../../services/analytics/index.js";import{getCwd as l}from"../cwd.js";import{toError as c}from"../errors.js";import{getFsImplementation as p}from"../fsOperations.js";import{logError as u}from"../log.js";import{getSettingsForSource as m,updateSettingsForSource as d}from"../settings/settings.js";import{buildPluginTelemetryFields as g}from"../telemetry/pluginTelemetry.js";import{clearAllCaches as f}from"./cacheUtils.js";import{formatDependencyCountSuffix as y,getEnabledPluginIdsForScope as h,resolveDependencyClosure as k}from"./dependencyResolver.js";import{addInstalledPlugin as w,getGitCommitSha as b}from"./installedPluginsManager.js";import{getManagedPluginNames as $}from"./managedPlugins.js";import{getMarketplaceCacheOnly as P,getPluginById as j}from"./marketplaceManager.js";import{isOfficialMarketplaceName as v,parsePluginIdentifier as I,scopeToSettingSource as C}from"./pluginIdentifier.js";import{cachePlugin as R,getVersionedCachePath as x,getVersionedZipCachePath as D}from"./pluginLoader.js";import{isPluginBlockedByPolicy as O}from"./pluginPolicy.js";import{calculatePluginVersion as _}from"./pluginVersioning.js";import{isLocalPluginSource as N}from"./schemas.js";import{convertDirectoryToZipInPlace as L,isPluginZipCacheEnabled as S}from"./zipCache.js";export function getCurrentTimestamp(){return(new Date).toISOString()}export function validatePathWithinBase(e,t){const n=o(e,t),r=o(e)+i;if(!n.startsWith(r)&&n!==o(e))throw new Error(`Path traversal detected: "${t}" would escape the base directory`);return n}export async function cacheAndRegisterPlugin(o,s,l="user",c,u){const m="string"==typeof s.source&&u?u:s.source,d=await R(m,{manifest:s}),g=u||d.path,f=d.gitCommitSha??await b(g),y=getCurrentTimestamp(),h=await _(o,s.source,d.manifest,g,s.version,d.gitCommitSha),k=x(o,h);let $=d.path;if(d.path!==k){await p().mkdir(r(k)),await n(k,{recursive:!0,force:!0});const o=d.path.endsWith(i)?d.path:d.path+i;if(k.startsWith(o)){const n=a(r(d.path),`.claude-plugin-temp-${Date.now()}-${e(4).toString("hex")}`);await t(d.path,n),await p().mkdir(r(k)),await t(n,k)}else await t(d.path,k);$=k}if(S()){const e=D(o,h);await L($,e),$=e}return w(o,{version:h,installedAt:y,lastUpdated:y,installPath:$,gitCommitSha:f},l,c),$}export function registerPluginInstallation(e,t="user",n){const r=getCurrentTimestamp();w(e.pluginId,{version:e.version||"unknown",installedAt:r,lastUpdated:r,installPath:e.installPath},t,n)}export function parsePluginId(e){const t=e.split("@");return 2===t.length&&t[0]&&t[1]?{name:t[0],marketplace:t[1]}:null}export function formatResolutionError(e){switch(e.reason){case"cycle":return`Dependency cycle: ${e.chain.join(" → ")}`;case"cross-marketplace":{const t=I(e.dependency).marketplace,n=t?`marketplace "${t}"`:"a different marketplace",r=t?` Add "${t}" to allowCrossMarketplaceDependenciesOn in the ROOT marketplace's marketplace.json (the marketplace of the plugin you're installing — only its allowlist applies; no transitive trust).`:"";return`Dependency "${e.dependency}" (required by ${e.requiredBy}) is in ${n}, which is not in the allowlist — cross-marketplace dependencies are blocked by default. Install it manually first.${r}`}case"not-found":{const{marketplace:t}=I(e.missing);return t?`Dependency "${e.missing}" (required by ${e.requiredBy}) not found. Is the "${t}" marketplace added?`:`Dependency "${e.missing}" (required by ${e.requiredBy}) not found in any configured marketplace`}}}export async function installResolvedPlugin({pluginId:e,entry:t,scope:n,marketplaceInstallLocation:r}){const a=C(n);if(O(e))return{ok:!1,reason:"blocked-by-policy",pluginName:t.name};const o=new Map;if(N(t.source)&&!r)return{ok:!1,reason:"local-source-no-location",pluginName:t.name};r&&o.set(e,{entry:t,marketplaceInstallLocation:r});const i=I(e).marketplace,s=new Set((i?(await P(i))?.allowCrossMarketplaceDependenciesOn:void 0)??[]),c=await k(e,async n=>{if(o.has(n))return o.get(n).entry;if(n===e)return t;const r=await j(n);return r&&o.set(n,r),r?.entry??null},h(a),s);if(!c.ok)return{ok:!1,reason:"resolution-failed",resolution:c};for(const n of c.closure)if(n!==e&&O(n))return{ok:!1,reason:"dependency-blocked-by-policy",pluginName:t.name,blockedDependency:n};const p={};for(const e of c.closure)p[e]=!0;const{error:u}=d(a,{enabledPlugins:{...m(a)?.enabledPlugins,...p}});if(u)return{ok:!1,reason:"settings-write-failed",message:u.message};const g="user"!==n?l():void 0;for(const r of c.closure){let a,i=o.get(r);if(!i&&r===e){const e=(await j(r))?.marketplaceInstallLocation;e&&(i={entry:t,marketplaceInstallLocation:e})}if(!i)continue;const{source:s}=i.entry;N(s)&&(a=validatePathWithinBase(i.marketplaceInstallLocation,s)),await cacheAndRegisterPlugin(r,i.entry,n,g,a)}f();const w=y(c.closure.filter(t=>t!==e));return{ok:!0,closure:c.closure,depNote:w}}export async function installPluginFromMarketplace({pluginId:e,entry:t,marketplaceName:n,scope:r="user",trigger:a="user"}){try{const o=await j(e),i=o?.marketplaceInstallLocation,l=await installResolvedPlugin({pluginId:e,entry:t,scope:r,marketplaceInstallLocation:i});if(!l.ok)switch(l.reason){case"local-source-no-location":return{success:!1,error:`Cannot install local plugin "${l.pluginName}" without marketplace install location`};case"settings-write-failed":return{success:!1,error:`Failed to update settings: ${l.message}`};case"resolution-failed":return{success:!1,error:formatResolutionError(l.resolution)};case"blocked-by-policy":return{success:!1,error:`Plugin "${l.pluginName}" is blocked by your organization's policy and cannot be installed`};case"dependency-blocked-by-policy":return{success:!1,error:`Cannot install "${l.pluginName}": dependency "${l.blockedDependency}" is blocked by your organization's policy`}}return s("tengu_plugin_installed",{_PROTO_plugin_name:t.name,_PROTO_marketplace_name:n,plugin_id:v(n)?e:"third-party",trigger:a,install_source:"hint"===a?"ui-suggestion":"ui-discover",...g(t.name,n,$()),...t.version&&{version:t.version}}),{success:!0,message:`✓ Installed ${t.name}${l.depNote}. Run /reload-plugins to activate.`}}catch(e){const t=e instanceof Error?e.message:String(e);return u(c(e)),{success:!1,error:`Failed to install: ${t}`}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{copyFile as e,readdir as t,readFile as a,readlink as n,realpath as o,rename as s,rm as r,rmdir as i,stat as l,symlink as c}from"fs/promises";import u from"lodash-es/memoize.js";import{basename as m,dirname as p,join as f,relative as h,resolve as d,sep as g}from"path";import{getInlinePlugins as y}from"../../bootstrap/state.js";import{BUILTIN_MARKETPLACE_NAME as P,getBuiltinPlugins as w}from"../../plugins/builtinPlugins.js";import{logForDebugging as $}from"../debug.js";import{isEnvTruthy as k}from"../envUtils.js";import{errorMessage as v,getErrnoPath as b,isENOENT as S,isFsInaccessible as C,toError as E}from"../errors.js";import{execFileNoThrow as A,execFileNoThrowWithCwd as j}from"../execFileNoThrow.js";import{pathExists as x}from"../file.js";import{getFsImplementation as F}from"../fsOperations.js";import{gitExe as O}from"../git.js";import{lazySchema as N}from"../lazySchema.js";import{logError as I}from"../log.js";import{getSettings_DEPRECATED as _}from"../settings/settings.js";import{clearPluginSettingsBase as T,getPluginSettingsBase as L,resetSettingsCache as D,setPluginSettingsBase as M}from"../settings/settingsCache.js";import{SettingsSchema as V}from"../settings/types.js";import{jsonParse as Z,jsonStringify as U}from"../slowOperations.js";import{getAddDirEnabledPlugins as z}from"./addDirPluginSettings.js";import{verifyAndDemote as H}from"./dependencyResolver.js";import{classifyFetchError as R,logPluginFetch as B}from"./fetchTelemetry.js";import{checkGitAvailable as G}from"./gitAvailability.js";import{getInMemoryInstalledPlugins as W}from"./installedPluginsManager.js";import{getManagedPluginNames as J}from"./managedPlugins.js";import{formatSourceForDisplay as K,getBlockedMarketplaces as X,getStrictKnownMarketplaces as q,isSourceAllowedByPolicy as Y,isSourceInBlocklist as Q}from"./marketplaceHelpers.js";import{getMarketplaceCacheOnly as ee,getPluginByIdCacheOnly as te,loadKnownMarketplacesConfigSafe as ae}from"./marketplaceManager.js";import{getPluginSeedDirs as ne,getPluginsDirectory as oe}from"./pluginDirectories.js";import{parsePluginIdentifier as se}from"./pluginIdentifier.js";import{validatePathWithinBase as re}from"./pluginInstallationHelpers.js";import{calculatePluginVersion as ie}from"./pluginVersioning.js";import{PluginHooksSchema as le,PluginIdSchema as ce,PluginManifestSchema as ue}from"./schemas.js";import{convertDirectoryToZipInPlace as me,extractZipToDirectory as pe,getSessionPluginCachePath as fe,isPluginZipCacheEnabled as he}from"./zipCache.js";export function getPluginCachePath(){return f(oe(),"cache")}export function getVersionedCachePathIn(e,t,a){const{name:n,marketplace:o}=se(t),s=(o||"unknown").replace(/[^a-zA-Z0-9\-_]/g,"-"),r=(n||t).replace(/[^a-zA-Z0-9\-_]/g,"-"),i=a.replace(/[^a-zA-Z0-9\-_.]/g,"-");return f(e,"cache",s,r,i)}export function getVersionedCachePath(e,t){return getVersionedCachePathIn(oe(),e,t)}export function getVersionedZipCachePath(e,t){return`${getVersionedCachePath(e,t)}.zip`}async function probeSeedCache(e,a){for(const n of ne()){const o=getVersionedCachePathIn(n,e,a);try{if((await t(o)).length>0)return o}catch{}}return null}export async function probeSeedCacheAnyVersion(e){for(const a of ne()){const n=p(getVersionedCachePathIn(a,e,"_"));try{const e=await t(n);if(1!==e.length)continue;const a=f(n,e[0]);if((await t(a)).length>0)return a}catch{}}return null}export function getLegacyCachePath(e){const t=getPluginCachePath();return f(t,e.replace(/[^a-zA-Z0-9\-_]/g,"-"))}export async function resolvePluginPath(e,t){if(t){const a=getVersionedCachePath(e,t);if(await x(a))return a}const a=getLegacyCachePath(se(e).name||e);return await x(a)?a:t?getVersionedCachePath(e,t):a}export async function copyDir(a,s){await F().mkdir(s);const r=await t(a,{withFileTypes:!0});for(const t of r){const r=f(a,t.name),i=f(s,t.name);if(t.isDirectory())await copyDir(r,i);else if(t.isFile())await e(r,i);else if(t.isSymbolicLink()){const e=await n(r);let t,l;try{t=await o(r)}catch{await c(e,i);continue}try{l=await o(a)}catch{l=a}const u=l.endsWith(g)?l:l+g;if(t.startsWith(u)||t===l){const e=h(l,t),a=f(s,e),n=h(p(i),a);await c(n,i)}else await c(t,i)}}}export async function copyPluginToVersionedCache(e,a,n,o,s){const l=he(),c=getVersionedCachePath(a,n),u=getVersionedZipCachePath(a,n);if(l){if(await x(u))return $(`Plugin ${a} version ${n} already cached at ${u}`),u}else if(await x(c)){if((await t(c)).length>0)return $(`Plugin ${a} version ${n} already cached at ${c}`),c;$(`Removing empty cache directory for ${a} at ${c}`),await i(c)}const m=await probeSeedCache(a,n);if(m)return $(`Using seed cache for ${a}@${n} at ${m}`),m;if(await F().mkdir(p(c)),o&&"string"==typeof o.source&&s){const e=re(s,o.source);$(`Copying source directory ${o.source} for plugin ${a}`);try{await copyDir(e,c)}catch(t){if(S(t)&&b(t)===e)throw new Error(`Plugin source directory not found: ${e} (from entry.source: ${o.source})`);throw t}}else $(`Copying plugin ${a} to versioned cache (fallback to full copy)`),await copyDir(e,c);const h=f(c,".git");if(await r(h,{recursive:!0,force:!0}),0===(await t(c)).length)throw new Error(`Failed to copy plugin ${a} to versioned cache: destination is empty after copy`);return l?(await me(c,u),$(`Successfully cached plugin ${a} as ZIP at ${u}`),u):($(`Successfully cached plugin ${a} at ${c}`),c)}function validateGitUrl(e){try{const t=new URL(e);if(!["https:","http:","file:"].includes(t.protocol)&&!/^git@[a-zA-Z0-9.-]+:/.test(e))throw new Error(`Invalid git URL protocol: ${t.protocol}. Only HTTPS, HTTP, file:// and SSH (git@) URLs are supported.`);return e}catch{if(/^git@[a-zA-Z0-9.-]+:/.test(e))return e;throw new Error(`Invalid git URL: ${e}`)}}export async function installFromNpm(e,t,a={}){const n=f(oe(),"npm-cache");await F().mkdir(n);const o=a.version?`${e}@${a.version}`:e,s=f(n,"node_modules",e);if(!await x(s)){$(`Installing npm package ${o} to cache`);const e=["install",o,"--prefix",n];a.registry&&e.push("--registry",a.registry);const t=await A("npm",e,{useCwd:!1});if(0!==t.code)throw new Error(`Failed to install npm package: ${t.stderr}`)}await copyDir(s,t),$(`Copied npm package ${e} from cache to ${t}`)}export async function gitClone(e,t,a,n){const o=["clone","--depth","1","--recurse-submodules","--shallow-submodules"];a&&o.push("--branch",a),n&&o.push("--no-checkout"),o.push(e,t);const s=performance.now(),r=await A(O(),o);if(0!==r.code)throw B("plugin_clone",e,"failure",performance.now()-s,R(r.stderr)),new Error(`Failed to clone repository: ${r.stderr}`);if(n){if(0!==(await j(O(),["fetch","--depth","1","origin",n],{cwd:t})).code){$(`Shallow fetch of SHA ${n} failed, falling back to unshallow fetch`);const a=await j(O(),["fetch","--unshallow"],{cwd:t});if(0!==a.code)throw B("plugin_clone",e,"failure",performance.now()-s,R(a.stderr)),new Error(`Failed to fetch commit ${n}: ${a.stderr}`)}const a=await j(O(),["checkout",n],{cwd:t});if(0!==a.code)throw B("plugin_clone",e,"failure",performance.now()-s,R(a.stderr)),new Error(`Failed to checkout commit ${n}: ${a.stderr}`)}B("plugin_clone",e,"success",performance.now()-s)}async function installFromGit(e,t,a,n){const o=validateGitUrl(e);await gitClone(o,t,a,n),$(`Cloned repository from ${o}${a?` (ref: ${a})`:""} to ${t}`)}export async function installFromGitSubdir(e,t,a,n,o){if(!await G())throw new Error("git-subdir plugin source requires git to be installed and on PATH. Install git (version 2.25 or later for sparse-checkout cone mode) and try again.");const i=function(e){return/^[a-zA-Z0-9-_.]+\/[a-zA-Z0-9-_.]+$/.test(e)?k(process.env.CONTEXT_CODE_REMOTE)||k(process.env.CLAUDE_CODE_REMOTE)?`https://github.com/${e}.git`:`git@github.com:${e}.git`:validateGitUrl(e)}(e),l=`${t}.clone`,c=["clone","--depth","1","--filter=tree:0","--no-checkout"];n&&c.push("--branch",n),c.push(i,l);const u=await A(O(),c);if(0!==u.code)throw new Error(`Failed to clone repository for git-subdir source: ${u.stderr}`);try{const r=await j(O(),["sparse-checkout","set","--cone","--",a],{cwd:l});if(0!==r.code)throw new Error(`git sparse-checkout set failed (git >= 2.25 required for cone mode): ${r.stderr}`);let c;if(o){if(0!==(await j(O(),["fetch","--depth","1","origin",o],{cwd:l})).code){$(`Shallow fetch of SHA ${o} failed for git-subdir, falling back to unshallow fetch`);const e=await j(O(),["fetch","--unshallow"],{cwd:l});if(0!==e.code)throw new Error(`Failed to fetch commit ${o}: ${e.stderr}`)}const e=await j(O(),["checkout",o],{cwd:l});if(0!==e.code)throw new Error(`Failed to checkout commit ${o}: ${e.stderr}`);c=o}else{const[e,t]=await Promise.all([j(O(),["checkout","HEAD"],{cwd:l}),j(O(),["rev-parse","HEAD"],{cwd:l})]);if(0!==e.code)throw new Error(`git checkout after sparse-checkout failed: ${e.stderr}`);0===t.code&&(c=t.stdout.trim())}const u=re(l,a);try{await s(u,t)}catch(e){if(S(e))throw new Error(`Subdirectory '${a}' not found in repository ${i}${n?` (ref: ${n})`:""}. Check that the path is correct and exists at the specified ref/sha.`);throw e}return $(`Extracted subdir ${a} from ${i}${n?` ref=${n}`:""}${c?` sha=${c}`:""} to ${t}`),c}finally{await r(l,{recursive:!0,force:!0})}}export function generateTemporaryCacheNameForPlugin(e){const t=Date.now(),a=Math.random().toString(36).substring(2,8);let n;if("string"==typeof e)n="local";else switch(e.source){case"npm":n="npm";break;case"pip":n="pip";break;case"github":n="github";break;case"url":n="git";break;case"git-subdir":n="subdir";break;default:n="unknown"}return`temp_${n}_${t}_${a}`}export async function cachePlugin(e,t){const n=getPluginCachePath();await F().mkdir(n);const o=generateTemporaryCacheNameForPlugin(e),i=f(n,o);let l,c=!1;try{if($(`Caching plugin from source: ${U(e)} to temporary path ${i}`),c=!0,"string"==typeof e)await async function(e,t){if(!await x(e))throw new Error(`Source path does not exist: ${e}`);await copyDir(e,t);const a=f(t,".git");await r(a,{recursive:!0,force:!0})}(e,i);else switch(e.source){case"npm":await installFromNpm(e.package,i,{registry:e.registry,version:e.version});break;case"github":await async function(e,t,a,n){if(!/^[a-zA-Z0-9-_.]+\/[a-zA-Z0-9-_.]+$/.test(e))throw new Error(`Invalid GitHub repository format: ${e}. Expected format: owner/repo`);return installFromGit(k(process.env.CONTEXT_CODE_REMOTE)||k(process.env.CLAUDE_CODE_REMOTE)?`https://github.com/${e}.git`:`git@github.com:${e}.git`,t,a,n)}(e.repo,i,e.ref,e.sha);break;case"url":await installFromGit(e.url,i,e.ref,e.sha);break;case"git-subdir":l=await installFromGitSubdir(e.url,i,e.path,e.ref,e.sha);break;case"pip":throw new Error("Python package plugins are not yet supported");default:throw new Error("Unsupported plugin source type")}}catch(e){if(c&&await x(i)){$(`Cleaning up failed installation at ${i}`);try{await r(i,{recursive:!0,force:!0})}catch(e){$(`Failed to clean up installation: ${e}`,{level:"error"})}}throw e}const u=f(i,".claude-plugin","plugin.json"),m=f(i,"plugin.json");let p;if(await x(u))try{const e=await a(u,{encoding:"utf-8"}),t=Z(e),n=ue().safeParse(t);if(!n.success){const e=n.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw $(`Invalid manifest at ${u}: ${e}`,{level:"error"}),new Error(`Plugin has an invalid manifest file at ${u}. Validation errors: ${e}`)}p=n.data}catch(e){if(e instanceof Error&&e.message.includes("invalid manifest file"))throw e;const t=v(e);throw $(`Failed to parse manifest at ${u}: ${t}`,{level:"error"}),new Error(`Plugin has a corrupt manifest file at ${u}. JSON parse error: ${t}`)}else if(await x(m))try{const e=await a(m,{encoding:"utf-8"}),t=Z(e),n=ue().safeParse(t);if(!n.success){const e=n.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw $(`Invalid legacy manifest at ${m}: ${e}`,{level:"error"}),new Error(`Plugin has an invalid manifest file at ${m}. Validation errors: ${e}`)}p=n.data}catch(e){if(e instanceof Error&&e.message.includes("invalid manifest file"))throw e;const t=v(e);throw $(`Failed to parse legacy manifest at ${m}: ${t}`,{level:"error"}),new Error(`Plugin has a corrupt manifest file at ${m}. JSON parse error: ${t}`)}else p=t?.manifest||{name:o,description:`Plugin cached from ${"string"==typeof e?e:e.source}`};const h=p.name.replace(/[^a-zA-Z0-9-_]/g,"-"),d=f(n,h);return await x(d)&&($(`Removing old cached version at ${d}`),await r(d,{recursive:!0,force:!0})),await s(i,d),$(`Successfully cached plugin ${p.name} to ${d}`),{path:d,manifest:p,...l&&{gitCommitSha:l}}}export async function loadPluginManifest(e,t,n){if(!await x(e))return{name:t,description:`Plugin from ${n}`};try{const n=await a(e,{encoding:"utf-8"}),o=Z(n),s=ue().safeParse(o);if(s.success)return s.data;const r=s.error.issues.map(e=>e.path.length>0?`${e.path.join(".")}: ${e.message}`:e.message).join(", ");throw $(`Plugin ${t} has an invalid manifest file at ${e}. Validation errors: ${r}`,{level:"error"}),new Error(`Plugin ${t} has an invalid manifest file at ${e}.\n\nValidation errors: ${r}`)}catch(a){if(a instanceof Error&&a.message.includes("invalid manifest file"))throw a;const n=v(a);throw $(`Plugin ${t} has a corrupt manifest file at ${e}. Parse error: ${n}`,{level:"error"}),new Error(`Plugin ${t} has a corrupt manifest file at ${e}.\n\nJSON parse error: ${n}`)}}async function loadPluginHooks(e,t){if(!await x(e))throw new Error(`Hooks file not found at ${e} for plugin ${t}. If the manifest declares hooks, the file must exist.`);const n=await a(e,{encoding:"utf-8"}),o=Z(n);return le().parse(o).hooks}async function validatePluginPaths(e,t,a,n,o,s,r,i){const l=await Promise.all(e.map(async e=>{const a=f(t,e);return{relPath:e,fullPath:a,exists:await x(a)}})),c=[];for(const{relPath:e,fullPath:t,exists:u}of l)u?c.push(t):($(`${s} path ${e} ${r} not found at ${t} for ${a}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${t} for ${a}`)),i.push({type:"path-not-found",source:n,plugin:a,path:t,component:o}));return c}export async function createPluginFromPath(e,t,n,s,r=!0){const i=[],l=f(e,".claude-plugin","plugin.json"),c=await loadPluginManifest(l,s,t),u={name:c.name,manifest:c,path:e,source:t,repository:t,enabled:n},[m,p,h,d]=await Promise.all([!c.commands&&x(f(e,"commands")),!c.agents&&x(f(e,"agents")),!c.skills&&x(f(e,"skills")),!c.outputStyles&&x(f(e,"output-styles"))]),g=f(e,"commands");if(m&&(u.commandsPath=g),c.commands){const a=Object.values(c.commands)[0];if("object"==typeof c.commands&&!Array.isArray(c.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={},n=[],o=Object.entries(c.commands),s=await Promise.all(o.map(async([t,a])=>{if(!a||"object"!=typeof a)return{commandName:t,metadata:a,kind:"skip"};if(a.source){const n=f(e,a.source);return{commandName:t,metadata:a,kind:"source",fullPath:n,exists:await x(n)}}return a.content?{commandName:t,metadata:a,kind:"content"}:{commandName:t,metadata:a,kind:"skip"}}));for(const e of s)"skip"!==e.kind&&("content"!==e.kind?e.exists?(n.push(e.fullPath),a[e.commandName]=e.metadata):($(`Command ${e.commandName} path ${e.metadata.source} specified in manifest but not found at ${e.fullPath} for ${c.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${e.fullPath} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:e.fullPath,component:"commands"})):a[e.commandName]=e.metadata);n.length>0&&(u.commandsPaths=n),Object.keys(a).length>0&&(u.commandsMetadata=a)}else{const a=Array.isArray(c.commands)?c.commands:[c.commands],n=await Promise.all(a.map(async t=>{if("string"!=typeof t)return{cmdPath:t,kind:"invalid"};const a=f(e,t);return{cmdPath:t,kind:"path",fullPath:a,exists:await x(a)}})),o=[];for(const e of n)"invalid"!==e.kind?e.exists?o.push(e.fullPath):($(`Command path ${e.cmdPath} specified in manifest but not found at ${e.fullPath} for ${c.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${e.fullPath} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:e.fullPath,component:"commands"})):$(`Unexpected command format in manifest for ${c.name}`,{level:"error"});o.length>0&&(u.commandsPaths=o)}}const y=f(e,"agents");if(p&&(u.agentsPath=y),c.agents){const a=Array.isArray(c.agents)?c.agents:[c.agents],n=await validatePluginPaths(a,e,c.name,t,"agents","Agent","specified in manifest but",i);n.length>0&&(u.agentsPaths=n)}const P=f(e,"skills");if(h&&(u.skillsPath=P),c.skills){const a=Array.isArray(c.skills)?c.skills:[c.skills],n=await validatePluginPaths(a,e,c.name,t,"skills","Skill","specified in manifest but",i);n.length>0&&(u.skillsPaths=n)}const w=f(e,"output-styles");if(d&&(u.outputStylesPath=w),c.outputStyles){const a=Array.isArray(c.outputStyles)?c.outputStyles:[c.outputStyles],n=await validatePluginPaths(a,e,c.name,t,"output-styles","Output style","specified in manifest but",i);n.length>0&&(u.outputStylesPaths=n)}let k;const b=new Set,S=f(e,"hooks","hooks.json");if(await x(S))try{k=await loadPluginHooks(S,c.name);try{b.add(await o(S))}catch{b.add(S)}$(`Loaded hooks from standard location for plugin ${c.name}: ${S}`)}catch(e){const a=v(e);$(`Failed to load hooks for ${c.name}: ${a}`,{level:"error"}),I(E(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:S,reason:a})}if(c.hooks){const a=Array.isArray(c.hooks)?c.hooks:[c.hooks];for(const n of a)if("string"==typeof n){const a=f(e,n);if(!await x(a)){$(`Hooks file ${n} specified in manifest but not found at ${a} for ${c.name}`,{level:"error"}),I(new Error(`Plugin component file not found: ${a} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:a,component:"hooks"});continue}let s;try{s=await o(a)}catch{s=a}if(b.has(s)){if($(`Skipping duplicate hooks file for plugin ${c.name}: ${n} (resolves to already-loaded file: ${s})`),r){const e=`Duplicate hooks file detected: ${n} resolves to already-loaded file ${s}. The standard hooks/hooks.json is loaded automatically, so manifest.hooks should only reference additional hook files.`;I(new Error(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:e})}continue}try{const o=await loadPluginHooks(a,c.name);try{k=mergeHooksSettings(k,o),b.add(s),$(`Loaded and merged hooks from manifest for plugin ${c.name}: ${n}`)}catch(e){const o=v(e);$(`Failed to merge hooks from ${n} for ${c.name}: ${o}`,{level:"error"}),I(E(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:`Failed to merge: ${o}`})}}catch(e){const o=v(e);$(`Failed to load hooks from ${n} for ${c.name}: ${o}`,{level:"error"}),I(E(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:o})}}else"object"==typeof n&&(k=mergeHooksSettings(k,n))}k&&(u.hooksConfig=k);const A=await async function(e,t){const n=f(e,"settings.json");try{const e=await a(n,{encoding:"utf-8"}),s=Z(e);if("object"==typeof(o=s)&&null!==o&&!Array.isArray(o)){const e=parsePluginSettings(s);if(e)return $(`Loaded settings from settings.json for plugin ${t.name}`),e}}catch(e){C(e)||$(`Failed to parse settings.json for plugin ${t.name}: ${e}`,{level:"warn"})}var o;if(t.settings){const e=parsePluginSettings(t.settings);if(e)return $(`Loaded settings from manifest for plugin ${t.name}`),e}}(e,c);return A&&(u.settings=A),{plugin:u,errors:i}}const de=N(()=>V().pick({agent:!0}).strip());function parsePluginSettings(e){const t=de().safeParse(e);if(!t.success)return;const a=t.data;return 0!==Object.keys(a).length?a:void 0}function mergeHooksSettings(e,t){if(!e)return t;const a={...e};for(const[e,n]of Object.entries(t))a[e]?a[e]=[...a[e]||[],...n]:a[e]=n;return a}async function loadPluginsFromMarketplaces({cacheOnly:e}){const t=_(),a={...z(),...t.enabledPlugins||{}},n=[],o=[],s=Object.entries(a).filter(([e,t])=>{if(!ce().safeParse(e).success||void 0===t)return!1;const{marketplace:a}=se(e);return a!==P}),i=await ae(),c=q(),u=X(),m=null!==c||null!==u&&u.length>0,p=new Set(s.map(([e])=>se(e).marketplace).filter(e=>!!e)),h=new Map;await Promise.all([...p].map(async e=>{h.set(e,await ee(e))}));const d=W(),g=await Promise.allSettled(s.map(async([t,a])=>{const{name:n,marketplace:s}=se(t),u=i[s];if(!u&&m)return o.push({type:"marketplace-blocked-by-policy",source:t,plugin:n,marketplace:s,blockedByBlocklist:null===c,allowedSources:(c??[]).map(e=>K(e))}),null;if(u&&!Y(u.source)){const e=Q(u.source),a=q()||[];return o.push({type:"marketplace-blocked-by-policy",source:t,plugin:n,marketplace:s,blockedByBlocklist:e,allowedSources:e?[]:a.map(e=>K(e))}),null}let p=null;const g=h.get(s);if(g&&u){const e=g.plugins.find(e=>e.name===n);e&&(p={entry:e,marketplaceInstallLocation:u.installLocation})}else p=await te(t);if(!p)return o.push({type:"plugin-not-found",source:t,pluginId:n,marketplace:s}),null;const y=d.plugins[t]?.[0];return e?async function(e,t,a,n,o,s){let r;if("string"==typeof e.source){let n;try{n=(await l(t)).isDirectory()?t:f(t,"..")}catch{return o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:t}),null}r=f(n,e.source)}else{if(!s||!await x(s))return o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:s??"(not recorded)"}),null;r=s}if(he()&&r.endsWith(".zip")){const n=await fe(),s=f(n,a.replace(/[^a-zA-Z0-9@\-_]/g,"-"));try{await pe(r,s),r=s}catch(t){return $(`Failed to extract plugin ZIP ${r}: ${t}`,{level:"error"}),o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:r}),null}}return finishLoadingPluginFromPath(e,a,n,o,r)}(p.entry,p.marketplaceInstallLocation,t,!0===a,o,y?.installPath):async function(e,t,a,n,o,s){let i;if($(`Loading plugin ${e.name} from source: ${U(e.source)}`),"string"==typeof e.source){const n=(await l(t)).isDirectory()?t:f(t,".."),s=f(n,e.source);if(!await x(s)){const e=new Error(`Plugin path not found: ${s}`);return $(`Plugin path not found: ${s}`,{level:"error"}),I(e),o.push({type:"generic-error",source:a,error:`Plugin directory not found at path: ${s}. Check that the marketplace entry has the correct path.`}),null}try{const t=f(s,".claude-plugin","plugin.json");let o;try{o=await loadPluginManifest(t,e.name,e.source)}catch{}const r=await ie(a,e.source,o,n,e.version);i=await copyPluginToVersionedCache(s,a,r,e,n),$(`Resolved local plugin ${e.name} to versioned cache: ${i}`)}catch(t){const a=v(t);$(`Failed to copy plugin ${e.name} to versioned cache: ${a}. Using marketplace path.`,{level:"warn"}),i=s}}else try{const t=await ie(a,e.source,void 0,void 0,s??e.version,"sha"in e.source?e.source.sha:void 0),n=getVersionedCachePath(a,t),o=getVersionedZipCachePath(a,t);if(he()&&await x(o))$(`Using versioned cached plugin ZIP ${e.name} from ${o}`),i=o;else if(await x(n))$(`Using versioned cached plugin ${e.name} from ${n}`),i=n;else{const n=await probeSeedCache(a,t)??("unknown"===t?await probeSeedCacheAnyVersion(a):null);if(n)i=n,$(`Using seed cache for external plugin ${e.name} at ${n}`);else{const n=await cachePlugin(e.source,{manifest:{name:e.name}}),o="unknown"!==t?t:await ie(a,e.source,n.manifest,n.path,s??e.version,n.gitCommitSha);i=await copyPluginToVersionedCache(n.path,a,o,e,void 0),n.path!==i&&await r(n.path,{recursive:!0,force:!0})}}}catch(t){const n=v(t);return $(`Failed to cache plugin ${e.name}: ${n}`,{level:"error"}),I(E(t)),o.push({type:"generic-error",source:a,error:`Failed to download/cache plugin ${e.name}: ${n}`}),null}if(he()&&i.endsWith(".zip")){const t=await fe(),n=f(t,a.replace(/[^a-zA-Z0-9@\-_]/g,"-"));try{await pe(i,n),$(`Extracted plugin ZIP to session dir: ${n}`),i=n}catch(e){throw $(`Failed to extract plugin ZIP ${i}, deleting corrupt file: ${e}`),await r(i,{force:!0}).catch(()=>{}),e}}return finishLoadingPluginFromPath(e,a,n,o,i)}(p.entry,p.marketplaceInstallLocation,t,!0===a,o,y?.version)}));for(const[e,t]of g.entries())if("fulfilled"===t.status&&t.value)n.push(t.value);else if("rejected"===t.status){const a=E(t.reason);I(a);const n=s[e][0];o.push({type:"generic-error",source:n,plugin:n.split("@")[0],error:a.message})}return{plugins:n,errors:o}}async function finishLoadingPluginFromPath(e,t,a,n,o){const s=[],r=f(o,".claude-plugin","plugin.json"),i=await x(r),{plugin:l,errors:c}=await createPluginFromPath(o,t,a,e.name,e.strict??!0);if(s.push(...c),"object"==typeof e.source&&"sha"in e.source&&e.source.sha&&(l.sha=e.source.sha),i){if(!e.strict&&i&&(e.commands||e.agents||e.skills||e.hooks||e.outputStyles)){const a=new Error(`Plugin ${e.name} has both plugin.json and marketplace manifest entries for commands/agents/skills/hooks/outputStyles. This is a conflict.`);return $(`Plugin ${e.name} has both plugin.json and marketplace manifest entries for commands/agents/skills/hooks/outputStyles. This is a conflict.`,{level:"error"}),I(a),n.push({type:"generic-error",source:t,error:`Plugin ${e.name} has conflicting manifests: both plugin.json and marketplace entry specify components. Set strict: true in marketplace entry or remove component specs from one location.`}),null}if(i){if(e.commands){const a=Object.values(e.commands)[0];if("object"==typeof e.commands&&!Array.isArray(e.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={...l.commandsMetadata||{}},n=[],r=Object.entries(e.commands),i=await Promise.all(r.map(async([e,t])=>{if(!t||"object"!=typeof t||!t.source)return{commandName:e,metadata:t,skip:!0};const a=f(o,t.source);return{commandName:e,metadata:t,skip:!1,fullPath:a,exists:await x(a)}}));for(const o of i)o.skip||(o.exists?(n.push(o.fullPath),a[o.commandName]=o.metadata):($(`Command ${o.commandName} path ${o.metadata.source} from marketplace entry not found at ${o.fullPath} for ${e.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${o.fullPath} for ${e.name}`)),s.push({type:"path-not-found",source:t,plugin:e.name,path:o.fullPath,component:"commands"})));n.length>0&&(l.commandsPaths=[...l.commandsPaths||[],...n],l.commandsMetadata=a)}else{const a=Array.isArray(e.commands)?e.commands:[e.commands],n=await Promise.all(a.map(async e=>{if("string"!=typeof e)return{cmdPath:e,kind:"invalid"};const t=f(o,e);return{cmdPath:e,kind:"path",fullPath:t,exists:await x(t)}})),r=[];for(const a of n)"invalid"!==a.kind?a.exists?r.push(a.fullPath):($(`Command path ${a.cmdPath} from marketplace entry not found at ${a.fullPath} for ${e.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${a.fullPath} for ${e.name}`)),s.push({type:"path-not-found",source:t,plugin:e.name,path:a.fullPath,component:"commands"})):$(`Unexpected command format in marketplace entry for ${e.name}`,{level:"error"});r.length>0&&(l.commandsPaths=[...l.commandsPaths||[],...r])}}if(e.agents){const a=Array.isArray(e.agents)?e.agents:[e.agents],n=await validatePluginPaths(a,o,e.name,t,"agents","Agent","from marketplace entry",s);n.length>0&&(l.agentsPaths=[...l.agentsPaths||[],...n])}if(e.skills){const a=Array.isArray(e.skills)?e.skills:[e.skills],n=await validatePluginPaths(a,o,e.name,t,"skills","Skill","from marketplace entry",s);n.length>0&&(l.skillsPaths=[...l.skillsPaths||[],...n])}if(e.outputStyles){const a=Array.isArray(e.outputStyles)?e.outputStyles:[e.outputStyles],n=await validatePluginPaths(a,o,e.name,t,"output-styles","Output style","from marketplace entry",s);n.length>0&&(l.outputStylesPaths=[...l.outputStylesPaths||[],...n])}e.hooks&&(l.hooksConfig={...l.hooksConfig||{},...e.hooks})}}else{if(l.manifest={...e,id:void 0,source:void 0,strict:void 0},l.name=l.manifest.name,e.commands){const a=Object.values(e.commands)[0];if("object"==typeof e.commands&&!Array.isArray(e.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={},n=[],r=Object.entries(e.commands),i=await Promise.all(r.map(async([e,t])=>{if(!t||"object"!=typeof t||!t.source)return{commandName:e,metadata:t,skip:!0};const a=f(o,t.source);return{commandName:e,metadata:t,skip:!1,fullPath:a,exists:await x(a)}}));for(const o of i)o.skip||(o.exists?(n.push(o.fullPath),a[o.commandName]=o.metadata):($(`Command ${o.commandName} path ${o.metadata.source} from marketplace entry not found at ${o.fullPath} for ${e.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${o.fullPath} for ${e.name}`)),s.push({type:"path-not-found",source:t,plugin:e.name,path:o.fullPath,component:"commands"})));n.length>0&&(l.commandsPaths=n,l.commandsMetadata=a)}else{const a=Array.isArray(e.commands)?e.commands:[e.commands],n=await Promise.all(a.map(async e=>{if("string"!=typeof e)return{cmdPath:e,kind:"invalid"};const t=f(o,e);return{cmdPath:e,kind:"path",fullPath:t,exists:await x(t)}})),r=[];for(const a of n)"invalid"!==a.kind?a.exists?r.push(a.fullPath):($(`Command path ${a.cmdPath} from marketplace entry not found at ${a.fullPath} for ${e.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${a.fullPath} for ${e.name}`)),s.push({type:"path-not-found",source:t,plugin:e.name,path:a.fullPath,component:"commands"})):$(`Unexpected command format in marketplace entry for ${e.name}`,{level:"error"});r.length>0&&(l.commandsPaths=r)}}if(e.agents){const a=Array.isArray(e.agents)?e.agents:[e.agents],n=await validatePluginPaths(a,o,e.name,t,"agents","Agent","from marketplace entry",s);n.length>0&&(l.agentsPaths=n)}if(e.skills){$(`Processing ${Array.isArray(e.skills)?e.skills.length:1} skill paths for plugin ${e.name}`);const a=Array.isArray(e.skills)?e.skills:[e.skills],n=await Promise.all(a.map(async e=>{const t=f(o,e);return{skillPath:e,fullPath:t,exists:await x(t)}})),r=[];for(const{skillPath:a,fullPath:o,exists:i}of n)$(`Checking skill path: ${a} -> ${o} (exists: ${i})`),i?r.push(o):($(`Skill path ${a} from marketplace entry not found at ${o} for ${e.name}`,{level:"warn"}),I(new Error(`Plugin component file not found: ${o} for ${e.name}`)),s.push({type:"path-not-found",source:t,plugin:e.name,path:o,component:"skills"}));$(`Found ${r.length} valid skill paths for plugin ${e.name}, setting skillsPaths`),r.length>0&&(l.skillsPaths=r)}else $(`Plugin ${e.name} has no entry.skills defined`);if(e.outputStyles){const a=Array.isArray(e.outputStyles)?e.outputStyles:[e.outputStyles],n=await validatePluginPaths(a,o,e.name,t,"output-styles","Output style","from marketplace entry",s);n.length>0&&(l.outputStylesPaths=n)}e.hooks&&(l.hooksConfig=e.hooks)}return n.push(...s),l}async function loadSessionOnlyPlugins(e){if(0===e.length)return{plugins:[],errors:[]};const t=[],a=[];for(const[n,o]of e.entries())try{const e=d(o);if(!await x(e)){$(`Plugin path does not exist: ${e}, skipping`,{level:"warn"}),a.push({type:"path-not-found",source:`inline[${n}]`,path:e,component:"commands"});continue}const s=m(e),{plugin:r,errors:i}=await createPluginFromPath(e,`${s}@inline`,!0,s);r.source=`${r.name}@inline`,r.repository=`${r.name}@inline`,t.push(r),a.push(...i),$(`Loaded inline plugin from path: ${r.name}`)}catch(e){const t=v(e);$(`Failed to load session plugin from ${o}: ${t}`,{level:"warn"}),a.push({type:"generic-error",source:`inline[${n}]`,error:`Failed to load plugin: ${t}`})}return t.length>0&&$(`Loaded ${t.length} session-only plugins from --plugin-dir`),{plugins:t,errors:a}}export function mergePluginSources(e){const t=[],a=e.managedNames,n=e.session.filter(e=>!a?.has(e.name)||($(`Plugin "${e.name}" from --plugin-dir is blocked by managed settings`,{level:"warn"}),t.push({type:"generic-error",source:e.source,plugin:e.name,error:`--plugin-dir copy of "${e.name}" ignored: plugin is locked by managed settings`}),!1)),o=new Set(n.map(e=>e.name)),s=e.marketplace.filter(e=>!o.has(e.name)||($(`Plugin "${e.name}" from --plugin-dir overrides installed version`),!1));return{plugins:[...n,...s,...e.builtin],errors:t}}export const loadAllPlugins=u(async()=>{const e=await assemblePluginLoadResult(()=>loadPluginsFromMarketplaces({cacheOnly:!1}));return loadAllPluginsCacheOnly.cache?.set(void 0,Promise.resolve(e)),e});export const loadAllPluginsCacheOnly=u(async()=>k(process.env.CONTEXT_CODE_SYNC_PLUGIN_INSTALL)||k(process.env.CLAUDE_CODE_SYNC_PLUGIN_INSTALL)?loadAllPlugins():assemblePluginLoadResult(()=>loadPluginsFromMarketplaces({cacheOnly:!0})));async function assemblePluginLoadResult(e){const t=y(),[a,n]=await Promise.all([e(),t.length>0?loadSessionOnlyPlugins(t):Promise.resolve({plugins:[],errors:[]})]),o=w(),{plugins:s,errors:r}=mergePluginSources({session:n.plugins,marketplace:a.plugins,builtin:[...o.enabled,...o.disabled],managedNames:J()}),i=[...a.errors,...n.errors,...r],{demoted:l,errors:c}=H(s);for(const e of s)l.has(e.source)&&(e.enabled=!1);i.push(...c);const u=s.filter(e=>e.enabled);return $(`Found ${s.length} plugins (${u.length} enabled, ${s.length-u.length} disabled)`),cachePluginSettings(u),{enabled:u,disabled:s.filter(e=>!e.enabled),errors:i}}export function clearPluginCache(e){e&&$(`clearPluginCache: invalidating loadAllPlugins cache (${e})`),loadAllPlugins.cache?.clear?.(),loadAllPluginsCacheOnly.cache?.clear?.(),void 0!==L()&&D(),T()}export function cachePluginSettings(e){const t=function(e){let t;for(const a of e)if(a.settings){t||(t={});for(const[e,n]of Object.entries(a.settings))e in t&&$(`Plugin "${a.name}" overrides setting "${e}" (previously set by another plugin)`),t[e]=n}return t}(e);M(t),t&&Object.keys(t).length>0&&(D(),$(`Cached plugin settings with keys: ${Object.keys(t).join(", ")}`))}
|
|
1
|
+
import{copyFile as e,readdir as t,readFile as a,readlink as n,realpath as o,rename as r,rm as s,rmdir as i,stat as l,symlink as c}from"fs/promises";import u from"lodash-es/memoize.js";import{basename as m,dirname as p,join as f,relative as h,resolve as d,sep as g}from"path";import{getInlinePlugins as y}from"../../bootstrap/state.js";import{BUILTIN_MARKETPLACE_NAME as w,getBuiltinPlugins as $}from"../../plugins/builtinPlugins.js";import{logForDebugging as P}from"../debug.js";import{isEnvTruthy as k}from"../envUtils.js";import{errorMessage as v,getErrnoPath as b,isENOENT as j,isFsInaccessible as S,toError as C}from"../errors.js";import{execFileNoThrow as A,execFileNoThrowWithCwd as E}from"../execFileNoThrow.js";import{pathExists as x}from"../file.js";import{getFsImplementation as F}from"../fsOperations.js";import{gitExe as O}from"../git.js";import{lazySchema as _}from"../lazySchema.js";import{logError as N}from"../log.js";import{getSettings_DEPRECATED as L}from"../settings/settings.js";import{clearPluginSettingsBase as T,getPluginSettingsBase as I,resetSettingsCache as D,setPluginSettingsBase as V}from"../settings/settingsCache.js";import{SettingsSchema as U}from"../settings/types.js";import{jsonParse as Z,jsonStringify as z}from"../slowOperations.js";import{getAddDirEnabledPlugins as H}from"./addDirPluginSettings.js";import{verifyAndDemote as M}from"./dependencyResolver.js";import{classifyFetchError as R,logPluginFetch as G}from"./fetchTelemetry.js";import{checkGitAvailable as B}from"./gitAvailability.js";import{getInMemoryInstalledPlugins as W}from"./installedPluginsManager.js";import{getManagedPluginNames as J}from"./managedPlugins.js";import{formatSourceForDisplay as X,getBlockedMarketplaces as q,getStrictKnownMarketplaces as Y,isSourceAllowedByPolicy as K,isSourceInBlocklist as Q}from"./marketplaceHelpers.js";import{getMarketplaceCacheOnly as ee,getPluginByIdCacheOnly as te,loadKnownMarketplacesConfigSafe as ae}from"./marketplaceManager.js";import{getPluginSeedDirs as ne,getPluginsDirectory as oe}from"./pluginDirectories.js";import{parsePluginIdentifier as re}from"./pluginIdentifier.js";import{validatePathWithinBase as se}from"./pluginInstallationHelpers.js";import{calculatePluginVersion as ie}from"./pluginVersioning.js";import{PluginHooksSchema as le,PluginIdSchema as ce,PluginManifestSchema as ue}from"./schemas.js";import{convertDirectoryToZipInPlace as me,extractZipToDirectory as pe,getSessionPluginCachePath as fe,isPluginZipCacheEnabled as he}from"./zipCache.js";export function getPluginCachePath(){return f(oe(),"cache")}export function getVersionedCachePathIn(e,t,a){const{name:n,marketplace:o}=re(t),r=(o||"unknown").replace(/[^a-zA-Z0-9\-_]/g,"-"),s=(n||t).replace(/[^a-zA-Z0-9\-_]/g,"-"),i=a.replace(/[^a-zA-Z0-9\-_.]/g,"-");return f(e,"cache",r,s,i)}export function getVersionedCachePath(e,t){return getVersionedCachePathIn(oe(),e,t)}export function getVersionedZipCachePath(e,t){return`${getVersionedCachePath(e,t)}.zip`}async function probeSeedCache(e,a){for(const n of ne()){const o=getVersionedCachePathIn(n,e,a);try{if((await t(o)).length>0)return o}catch{}}return null}export async function probeSeedCacheAnyVersion(e){for(const a of ne()){const n=p(getVersionedCachePathIn(a,e,"_"));try{const e=await t(n);if(1!==e.length)continue;const a=f(n,e[0]);if((await t(a)).length>0)return a}catch{}}return null}export function getLegacyCachePath(e){const t=getPluginCachePath();return f(t,e.replace(/[^a-zA-Z0-9\-_]/g,"-"))}export async function resolvePluginPath(e,t){if(t){const a=getVersionedCachePath(e,t);if(await x(a))return a}const a=getLegacyCachePath(re(e).name||e);return await x(a)?a:t?getVersionedCachePath(e,t):a}export async function copyDir(a,r){await F().mkdir(r);const s=await t(a,{withFileTypes:!0});for(const t of s){const s=f(a,t.name),i=f(r,t.name);if(t.isDirectory())await copyDir(s,i);else if(t.isFile())await e(s,i);else if(t.isSymbolicLink()){const e=await n(s);let t,l;try{t=await o(s)}catch{await c(e,i);continue}try{l=await o(a)}catch{l=a}const u=l.endsWith(g)?l:l+g;if(t.startsWith(u)||t===l){const e=h(l,t),a=f(r,e),n=h(p(i),a);await c(n,i)}else await c(t,i)}}}export async function copyPluginToVersionedCache(e,a,n,o,r){const l=he(),c=getVersionedCachePath(a,n),u=getVersionedZipCachePath(a,n);if(l){if(await x(u))return P(`Plugin ${a} version ${n} already cached at ${u}`),u}else if(await x(c)){if((await t(c)).length>0)return P(`Plugin ${a} version ${n} already cached at ${c}`),c;P(`Removing empty cache directory for ${a} at ${c}`),await i(c)}const m=await probeSeedCache(a,n);if(m)return P(`Using seed cache for ${a}@${n} at ${m}`),m;if(await F().mkdir(p(c)),o&&"string"==typeof o.source&&r){const e=se(r,o.source);P(`Copying source directory ${o.source} for plugin ${a}`);try{await copyDir(e,c)}catch(t){if(j(t)&&b(t)===e)throw new Error(`Plugin source directory not found: ${e} (from entry.source: ${o.source})`);throw t}}else P(`Copying plugin ${a} to versioned cache (fallback to full copy)`),await copyDir(e,c);const h=f(c,".git");await s(h,{recursive:!0,force:!0});if(0===(await t(c)).length)throw new Error(`Failed to copy plugin ${a} to versioned cache: destination is empty after copy`);return l?(await me(c,u),P(`Successfully cached plugin ${a} as ZIP at ${u}`),u):(P(`Successfully cached plugin ${a} at ${c}`),c)}function validateGitUrl(e){try{const t=new URL(e);if(!["https:","http:","file:"].includes(t.protocol)&&!/^git@[a-zA-Z0-9.-]+:/.test(e))throw new Error(`Invalid git URL protocol: ${t.protocol}. Only HTTPS, HTTP, file:// and SSH (git@) URLs are supported.`);return e}catch{if(/^git@[a-zA-Z0-9.-]+:/.test(e))return e;throw new Error(`Invalid git URL: ${e}`)}}export async function installFromNpm(e,t,a={}){const n=f(oe(),"npm-cache");await F().mkdir(n);const o=a.version?`${e}@${a.version}`:e,r=f(n,"node_modules",e);if(!await x(r)){P(`Installing npm package ${o} to cache`);const e=["install",o,"--prefix",n];a.registry&&e.push("--registry",a.registry);const t=await A("npm",e,{useCwd:!1});if(0!==t.code)throw new Error(`Failed to install npm package: ${t.stderr}`)}await copyDir(r,t),P(`Copied npm package ${e} from cache to ${t}`)}export async function gitClone(e,t,a,n){const o=["clone","--depth","1","--recurse-submodules","--shallow-submodules"];a&&o.push("--branch",a),n&&o.push("--no-checkout"),o.push(e,t);const r=performance.now(),s=await A(O(),o);if(0!==s.code)throw G("plugin_clone",e,"failure",performance.now()-r,R(s.stderr)),new Error(`Failed to clone repository: ${s.stderr}`);if(n){if(0!==(await E(O(),["fetch","--depth","1","origin",n],{cwd:t})).code){P(`Shallow fetch of SHA ${n} failed, falling back to unshallow fetch`);const a=await E(O(),["fetch","--unshallow"],{cwd:t});if(0!==a.code)throw G("plugin_clone",e,"failure",performance.now()-r,R(a.stderr)),new Error(`Failed to fetch commit ${n}: ${a.stderr}`)}const a=await E(O(),["checkout",n],{cwd:t});if(0!==a.code)throw G("plugin_clone",e,"failure",performance.now()-r,R(a.stderr)),new Error(`Failed to checkout commit ${n}: ${a.stderr}`)}G("plugin_clone",e,"success",performance.now()-r)}async function installFromGit(e,t,a,n){const o=validateGitUrl(e);await gitClone(o,t,a,n);P(`Cloned repository from ${o}${a?` (ref: ${a})`:""} to ${t}`)}export async function installFromGitSubdir(e,t,a,n,o){if(!await B())throw new Error("git-subdir plugin source requires git to be installed and on PATH. Install git (version 2.25 or later for sparse-checkout cone mode) and try again.");const i=function(e){return/^[a-zA-Z0-9-_.]+\/[a-zA-Z0-9-_.]+$/.test(e)?k(process.env.CONTEXT_CODE_REMOTE)||k(process.env.CLAUDE_CODE_REMOTE)?`https://github.com/${e}.git`:`git@github.com:${e}.git`:validateGitUrl(e)}(e),l=`${t}.clone`,c=["clone","--depth","1","--filter=tree:0","--no-checkout"];n&&c.push("--branch",n),c.push(i,l);const u=await A(O(),c);if(0!==u.code)throw new Error(`Failed to clone repository for git-subdir source: ${u.stderr}`);try{const e=await E(O(),["sparse-checkout","set","--cone","--",a],{cwd:l});if(0!==e.code)throw new Error(`git sparse-checkout set failed (git >= 2.25 required for cone mode): ${e.stderr}`);let s;if(o){if(0!==(await E(O(),["fetch","--depth","1","origin",o],{cwd:l})).code){P(`Shallow fetch of SHA ${o} failed for git-subdir, falling back to unshallow fetch`);const e=await E(O(),["fetch","--unshallow"],{cwd:l});if(0!==e.code)throw new Error(`Failed to fetch commit ${o}: ${e.stderr}`)}const e=await E(O(),["checkout",o],{cwd:l});if(0!==e.code)throw new Error(`Failed to checkout commit ${o}: ${e.stderr}`);s=o}else{const[e,t]=await Promise.all([E(O(),["checkout","HEAD"],{cwd:l}),E(O(),["rev-parse","HEAD"],{cwd:l})]);if(0!==e.code)throw new Error(`git checkout after sparse-checkout failed: ${e.stderr}`);0===t.code&&(s=t.stdout.trim())}const c=se(l,a);try{await r(c,t)}catch(e){if(j(e))throw new Error(`Subdirectory '${a}' not found in repository ${i}${n?` (ref: ${n})`:""}. Check that the path is correct and exists at the specified ref/sha.`);throw e}const u=n?` ref=${n}`:"";return P(`Extracted subdir ${a} from ${i}${u}${s?` sha=${s}`:""} to ${t}`),s}finally{await s(l,{recursive:!0,force:!0})}}export function generateTemporaryCacheNameForPlugin(e){const t=Date.now(),a=Math.random().toString(36).substring(2,8);let n;if("string"==typeof e)n="local";else switch(e.source){case"npm":n="npm";break;case"pip":n="pip";break;case"github":n="github";break;case"url":n="git";break;case"git-subdir":n="subdir";break;default:n="unknown"}return`temp_${n}_${t}_${a}`}export async function cachePlugin(e,t){const n=getPluginCachePath();await F().mkdir(n);const o=generateTemporaryCacheNameForPlugin(e),i=f(n,o);let l,c=!1;try{if(P(`Caching plugin from source: ${z(e)} to temporary path ${i}`),c=!0,"string"==typeof e)await async function(e,t){if(!await x(e))throw new Error(`Source path does not exist: ${e}`);await copyDir(e,t);const a=f(t,".git");await s(a,{recursive:!0,force:!0})}(e,i);else switch(e.source){case"npm":await installFromNpm(e.package,i,{registry:e.registry,version:e.version});break;case"github":await async function(e,t,a,n){if(!/^[a-zA-Z0-9-_.]+\/[a-zA-Z0-9-_.]+$/.test(e))throw new Error(`Invalid GitHub repository format: ${e}. Expected format: owner/repo`);return installFromGit(k(process.env.CONTEXT_CODE_REMOTE)||k(process.env.CLAUDE_CODE_REMOTE)?`https://github.com/${e}.git`:`git@github.com:${e}.git`,t,a,n)}(e.repo,i,e.ref,e.sha);break;case"url":await installFromGit(e.url,i,e.ref,e.sha);break;case"git-subdir":l=await installFromGitSubdir(e.url,i,e.path,e.ref,e.sha);break;case"pip":throw new Error("Python package plugins are not yet supported");default:throw new Error("Unsupported plugin source type")}}catch(e){if(c&&await x(i)){P(`Cleaning up failed installation at ${i}`);try{await s(i,{recursive:!0,force:!0})}catch(e){P(`Failed to clean up installation: ${e}`,{level:"error"})}}throw e}const u=f(i,".claude-plugin","plugin.json"),m=f(i,"plugin.json");let p;if(await x(u))try{const e=await a(u,{encoding:"utf-8"}),t=Z(e),n=ue().safeParse(t);if(!n.success){const e=n.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw P(`Invalid manifest at ${u}: ${e}`,{level:"error"}),new Error(`Plugin has an invalid manifest file at ${u}. Validation errors: ${e}`)}p=n.data}catch(e){if(e instanceof Error&&e.message.includes("invalid manifest file"))throw e;const t=v(e);throw P(`Failed to parse manifest at ${u}: ${t}`,{level:"error"}),new Error(`Plugin has a corrupt manifest file at ${u}. JSON parse error: ${t}`)}else if(await x(m))try{const e=await a(m,{encoding:"utf-8"}),t=Z(e),n=ue().safeParse(t);if(!n.success){const e=n.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw P(`Invalid legacy manifest at ${m}: ${e}`,{level:"error"}),new Error(`Plugin has an invalid manifest file at ${m}. Validation errors: ${e}`)}p=n.data}catch(e){if(e instanceof Error&&e.message.includes("invalid manifest file"))throw e;const t=v(e);throw P(`Failed to parse legacy manifest at ${m}: ${t}`,{level:"error"}),new Error(`Plugin has a corrupt manifest file at ${m}. JSON parse error: ${t}`)}else p=t?.manifest||{name:o,description:`Plugin cached from ${"string"==typeof e?e:e.source}`};const h=p.name.replace(/[^a-zA-Z0-9-_]/g,"-"),d=f(n,h);return await x(d)&&(P(`Removing old cached version at ${d}`),await s(d,{recursive:!0,force:!0})),await r(i,d),P(`Successfully cached plugin ${p.name} to ${d}`),{path:d,manifest:p,...l&&{gitCommitSha:l}}}export async function loadPluginManifest(e,t,n){if(!await x(e))return{name:t,description:`Plugin from ${n}`};try{const n=await a(e,{encoding:"utf-8"}),o=Z(n),r=ue().safeParse(o);if(r.success)return r.data;const s=r.error.issues.map(e=>e.path.length>0?`${e.path.join(".")}: ${e.message}`:e.message).join(", ");throw P(`Plugin ${t} has an invalid manifest file at ${e}. Validation errors: ${s}`,{level:"error"}),new Error(`Plugin ${t} has an invalid manifest file at ${e}.\n\nValidation errors: ${s}`)}catch(a){if(a instanceof Error&&a.message.includes("invalid manifest file"))throw a;const n=v(a);throw P(`Plugin ${t} has a corrupt manifest file at ${e}. Parse error: ${n}`,{level:"error"}),new Error(`Plugin ${t} has a corrupt manifest file at ${e}.\n\nJSON parse error: ${n}`)}}async function loadPluginHooks(e,t){if(!await x(e))throw new Error(`Hooks file not found at ${e} for plugin ${t}. If the manifest declares hooks, the file must exist.`);const n=await a(e,{encoding:"utf-8"}),o=Z(n);return le().parse(o).hooks}async function validatePluginPaths(e,t,a,n,o,r,s,i){const l=await Promise.all(e.map(async e=>{const a=f(t,e);return{relPath:e,fullPath:a,exists:await x(a)}})),c=[];for(const{relPath:e,fullPath:t,exists:u}of l)u?c.push(t):(P(`${r} path ${e} ${s} not found at ${t} for ${a}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${t} for ${a}`)),i.push({type:"path-not-found",source:n,plugin:a,path:t,component:o}));return c}export async function createPluginFromPath(e,t,n,r,s=!0){const i=[],l=f(e,".claude-plugin","plugin.json"),c=await loadPluginManifest(l,r,t),u={name:c.name,manifest:c,path:e,source:t,repository:t,enabled:n},[m,p,h,d]=await Promise.all([!c.commands&&x(f(e,"commands")),!c.agents&&x(f(e,"agents")),!c.skills&&x(f(e,"skills")),!c.outputStyles&&x(f(e,"output-styles"))]),g=f(e,"commands");if(m&&(u.commandsPath=g),c.commands){const a=Object.values(c.commands)[0];if("object"==typeof c.commands&&!Array.isArray(c.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={},n=[],o=Object.entries(c.commands),r=await Promise.all(o.map(async([t,a])=>{if(!a||"object"!=typeof a)return{commandName:t,metadata:a,kind:"skip"};if(a.source){const n=f(e,a.source);return{commandName:t,metadata:a,kind:"source",fullPath:n,exists:await x(n)}}return a.content?{commandName:t,metadata:a,kind:"content"}:{commandName:t,metadata:a,kind:"skip"}}));for(const e of r)"skip"!==e.kind&&("content"!==e.kind?e.exists?(n.push(e.fullPath),a[e.commandName]=e.metadata):(P(`Command ${e.commandName} path ${e.metadata.source} specified in manifest but not found at ${e.fullPath} for ${c.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${e.fullPath} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:e.fullPath,component:"commands"})):a[e.commandName]=e.metadata);n.length>0&&(u.commandsPaths=n),Object.keys(a).length>0&&(u.commandsMetadata=a)}else{const a=Array.isArray(c.commands)?c.commands:[c.commands],n=await Promise.all(a.map(async t=>{if("string"!=typeof t)return{cmdPath:t,kind:"invalid"};const a=f(e,t);return{cmdPath:t,kind:"path",fullPath:a,exists:await x(a)}})),o=[];for(const e of n)"invalid"!==e.kind?e.exists?o.push(e.fullPath):(P(`Command path ${e.cmdPath} specified in manifest but not found at ${e.fullPath} for ${c.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${e.fullPath} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:e.fullPath,component:"commands"})):P(`Unexpected command format in manifest for ${c.name}`,{level:"error"});o.length>0&&(u.commandsPaths=o)}}const y=f(e,"agents");if(p&&(u.agentsPath=y),c.agents){const a=Array.isArray(c.agents)?c.agents:[c.agents],n=await validatePluginPaths(a,e,c.name,t,"agents","Agent","specified in manifest but",i);n.length>0&&(u.agentsPaths=n)}const w=f(e,"skills");if(h&&(u.skillsPath=w),c.skills){const a=Array.isArray(c.skills)?c.skills:[c.skills],n=await validatePluginPaths(a,e,c.name,t,"skills","Skill","specified in manifest but",i);n.length>0&&(u.skillsPaths=n)}const $=f(e,"output-styles");if(d&&(u.outputStylesPath=$),c.outputStyles){const a=Array.isArray(c.outputStyles)?c.outputStyles:[c.outputStyles],n=await validatePluginPaths(a,e,c.name,t,"output-styles","Output style","specified in manifest but",i);n.length>0&&(u.outputStylesPaths=n)}let k;const b=new Set,j=f(e,"hooks","hooks.json");if(await x(j))try{k=await loadPluginHooks(j,c.name);try{b.add(await o(j))}catch{b.add(j)}P(`Loaded hooks from standard location for plugin ${c.name}: ${j}`)}catch(e){const a=v(e);P(`Failed to load hooks for ${c.name}: ${a}`,{level:"error"}),N(C(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:j,reason:a})}if(c.hooks){const a=Array.isArray(c.hooks)?c.hooks:[c.hooks];for(const n of a)if("string"==typeof n){const a=f(e,n);if(!await x(a)){P(`Hooks file ${n} specified in manifest but not found at ${a} for ${c.name}`,{level:"error"}),N(new Error(`Plugin component file not found: ${a} for ${c.name}`)),i.push({type:"path-not-found",source:t,plugin:c.name,path:a,component:"hooks"});continue}let r;try{r=await o(a)}catch{r=a}if(b.has(r)){if(P(`Skipping duplicate hooks file for plugin ${c.name}: ${n} (resolves to already-loaded file: ${r})`),s){const e=`Duplicate hooks file detected: ${n} resolves to already-loaded file ${r}. The standard hooks/hooks.json is loaded automatically, so manifest.hooks should only reference additional hook files.`;N(new Error(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:e})}continue}try{const e=await loadPluginHooks(a,c.name);try{k=mergeHooksSettings(k,e),b.add(r),P(`Loaded and merged hooks from manifest for plugin ${c.name}: ${n}`)}catch(e){const o=v(e);P(`Failed to merge hooks from ${n} for ${c.name}: ${o}`,{level:"error"}),N(C(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:`Failed to merge: ${o}`})}}catch(e){const o=v(e);P(`Failed to load hooks from ${n} for ${c.name}: ${o}`,{level:"error"}),N(C(e)),i.push({type:"hook-load-failed",source:t,plugin:c.name,hookPath:a,reason:o})}}else"object"==typeof n&&(k=mergeHooksSettings(k,n))}k&&(u.hooksConfig=k);const A=await async function(e,t){const n=f(e,"settings.json");try{const e=await a(n,{encoding:"utf-8"}),r=Z(e);if("object"==typeof(o=r)&&null!==o&&!Array.isArray(o)){const e=parsePluginSettings(r);if(e)return P(`Loaded settings from settings.json for plugin ${t.name}`),e}}catch(e){S(e)||P(`Failed to parse settings.json for plugin ${t.name}: ${e}`,{level:"warn"})}var o;if(t.settings){const e=parsePluginSettings(t.settings);if(e)return P(`Loaded settings from manifest for plugin ${t.name}`),e}return}(e,c);return A&&(u.settings=A),{plugin:u,errors:i}}const de=_(()=>U().pick({agent:!0}).strip());function parsePluginSettings(e){const t=de().safeParse(e);if(!t.success)return;const a=t.data;return 0!==Object.keys(a).length?a:void 0}function mergeHooksSettings(e,t){if(!e)return t;const a={...e};for(const[e,n]of Object.entries(t))a[e]?a[e]=[...a[e]||[],...n]:a[e]=n;return a}async function loadPluginsFromMarketplaces({cacheOnly:e}){const t=L(),a={...H(),...t.enabledPlugins||{}},n=[],o=[],r=Object.entries(a).filter(([e,t])=>{if(!ce().safeParse(e).success||void 0===t)return!1;const{marketplace:a}=re(e);return a!==w}),i=await ae(),c=Y(),u=q(),m=null!==c||null!==u&&u.length>0,p=new Set(r.map(([e])=>re(e).marketplace).filter(e=>!!e)),h=new Map;await Promise.all([...p].map(async e=>{h.set(e,await ee(e))}));const d=W(),g=await Promise.allSettled(r.map(async([t,a])=>{const{name:n,marketplace:r}=re(t),u=i[r];if(!u&&m)return o.push({type:"marketplace-blocked-by-policy",source:t,plugin:n,marketplace:r,blockedByBlocklist:null===c,allowedSources:(c??[]).map(e=>X(e))}),null;if(u&&!K(u.source)){const e=Q(u.source),a=Y()||[];return o.push({type:"marketplace-blocked-by-policy",source:t,plugin:n,marketplace:r,blockedByBlocklist:e,allowedSources:e?[]:a.map(e=>X(e))}),null}let p=null;const g=h.get(r);if(g&&u){const e=g.plugins.find(e=>e.name===n);e&&(p={entry:e,marketplaceInstallLocation:u.installLocation})}else p=await te(t);if(!p)return o.push({type:"plugin-not-found",source:t,pluginId:n,marketplace:r}),null;const y=d.plugins[t]?.[0];return e?async function(e,t,a,n,o,r){let s;if("string"==typeof e.source){let n;try{n=(await l(t)).isDirectory()?t:f(t,"..")}catch{return o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:t}),null}s=f(n,e.source)}else{if(!r||!await x(r))return o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:r??"(not recorded)"}),null;s=r}if(he()&&s.endsWith(".zip")){const t=await fe(),n=f(t,a.replace(/[^a-zA-Z0-9@\-_]/g,"-"));try{await pe(s,n),s=n}catch(t){return P(`Failed to extract plugin ZIP ${s}: ${t}`,{level:"error"}),o.push({type:"plugin-cache-miss",source:a,plugin:e.name,installPath:s}),null}}return finishLoadingPluginFromPath(e,a,n,o,s)}(p.entry,p.marketplaceInstallLocation,t,!0===a,o,y?.installPath):async function(e,t,a,n,o,r){let i;if(P(`Loading plugin ${e.name} from source: ${z(e.source)}`),"string"==typeof e.source){const n=(await l(t)).isDirectory()?t:f(t,".."),r=f(n,e.source);if(!await x(r)){const e=new Error(`Plugin path not found: ${r}`);return P(`Plugin path not found: ${r}`,{level:"error"}),N(e),o.push({type:"generic-error",source:a,error:`Plugin directory not found at path: ${r}. Check that the marketplace entry has the correct path.`}),null}try{const t=f(r,".claude-plugin","plugin.json");let o;try{o=await loadPluginManifest(t,e.name,e.source)}catch{}const s=await ie(a,e.source,o,n,e.version);i=await copyPluginToVersionedCache(r,a,s,e,n),P(`Resolved local plugin ${e.name} to versioned cache: ${i}`)}catch(t){const a=v(t);P(`Failed to copy plugin ${e.name} to versioned cache: ${a}. Using marketplace path.`,{level:"warn"}),i=r}}else try{const t=await ie(a,e.source,void 0,void 0,r??e.version,"sha"in e.source?e.source.sha:void 0),n=getVersionedCachePath(a,t),o=getVersionedZipCachePath(a,t);if(he()&&await x(o))P(`Using versioned cached plugin ZIP ${e.name} from ${o}`),i=o;else if(await x(n))P(`Using versioned cached plugin ${e.name} from ${n}`),i=n;else{const n=await probeSeedCache(a,t)??("unknown"===t?await probeSeedCacheAnyVersion(a):null);if(n)i=n,P(`Using seed cache for external plugin ${e.name} at ${n}`);else{const n=await cachePlugin(e.source,{manifest:{name:e.name}}),o="unknown"!==t?t:await ie(a,e.source,n.manifest,n.path,r??e.version,n.gitCommitSha);i=await copyPluginToVersionedCache(n.path,a,o,e,void 0),n.path!==i&&await s(n.path,{recursive:!0,force:!0})}}}catch(t){const n=v(t);return P(`Failed to cache plugin ${e.name}: ${n}`,{level:"error"}),N(C(t)),o.push({type:"generic-error",source:a,error:`Failed to download/cache plugin ${e.name}: ${n}`}),null}if(he()&&i.endsWith(".zip")){const e=await fe(),t=f(e,a.replace(/[^a-zA-Z0-9@\-_]/g,"-"));try{await pe(i,t),P(`Extracted plugin ZIP to session dir: ${t}`),i=t}catch(e){throw P(`Failed to extract plugin ZIP ${i}, deleting corrupt file: ${e}`),await s(i,{force:!0}).catch(()=>{}),e}}return finishLoadingPluginFromPath(e,a,n,o,i)}(p.entry,p.marketplaceInstallLocation,t,!0===a,o,y?.version)}));for(const[e,t]of g.entries())if("fulfilled"===t.status&&t.value)n.push(t.value);else if("rejected"===t.status){const a=C(t.reason);N(a);const n=r[e][0];o.push({type:"generic-error",source:n,plugin:n.split("@")[0],error:a.message})}return{plugins:n,errors:o}}async function finishLoadingPluginFromPath(e,t,a,n,o){const r=[],s=f(o,".claude-plugin","plugin.json"),i=await x(s),{plugin:l,errors:c}=await createPluginFromPath(o,t,a,e.name,e.strict??!0);if(r.push(...c),"object"==typeof e.source&&"sha"in e.source&&e.source.sha&&(l.sha=e.source.sha),i){if(!e.strict&&i&&(e.commands||e.agents||e.skills||e.hooks||e.outputStyles)){const a=new Error(`Plugin ${e.name} has both plugin.json and marketplace manifest entries for commands/agents/skills/hooks/outputStyles. This is a conflict.`);return P(`Plugin ${e.name} has both plugin.json and marketplace manifest entries for commands/agents/skills/hooks/outputStyles. This is a conflict.`,{level:"error"}),N(a),n.push({type:"generic-error",source:t,error:`Plugin ${e.name} has conflicting manifests: both plugin.json and marketplace entry specify components. Set strict: true in marketplace entry or remove component specs from one location.`}),null}if(i){if(e.commands){const a=Object.values(e.commands)[0];if("object"==typeof e.commands&&!Array.isArray(e.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={...l.commandsMetadata||{}},n=[],s=Object.entries(e.commands),i=await Promise.all(s.map(async([e,t])=>{if(!t||"object"!=typeof t||!t.source)return{commandName:e,metadata:t,skip:!0};const a=f(o,t.source);return{commandName:e,metadata:t,skip:!1,fullPath:a,exists:await x(a)}}));for(const o of i)o.skip||(o.exists?(n.push(o.fullPath),a[o.commandName]=o.metadata):(P(`Command ${o.commandName} path ${o.metadata.source} from marketplace entry not found at ${o.fullPath} for ${e.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${o.fullPath} for ${e.name}`)),r.push({type:"path-not-found",source:t,plugin:e.name,path:o.fullPath,component:"commands"})));n.length>0&&(l.commandsPaths=[...l.commandsPaths||[],...n],l.commandsMetadata=a)}else{const a=Array.isArray(e.commands)?e.commands:[e.commands],n=await Promise.all(a.map(async e=>{if("string"!=typeof e)return{cmdPath:e,kind:"invalid"};const t=f(o,e);return{cmdPath:e,kind:"path",fullPath:t,exists:await x(t)}})),s=[];for(const a of n)"invalid"!==a.kind?a.exists?s.push(a.fullPath):(P(`Command path ${a.cmdPath} from marketplace entry not found at ${a.fullPath} for ${e.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${a.fullPath} for ${e.name}`)),r.push({type:"path-not-found",source:t,plugin:e.name,path:a.fullPath,component:"commands"})):P(`Unexpected command format in marketplace entry for ${e.name}`,{level:"error"});s.length>0&&(l.commandsPaths=[...l.commandsPaths||[],...s])}}if(e.agents){const a=Array.isArray(e.agents)?e.agents:[e.agents],n=await validatePluginPaths(a,o,e.name,t,"agents","Agent","from marketplace entry",r);n.length>0&&(l.agentsPaths=[...l.agentsPaths||[],...n])}if(e.skills){const a=Array.isArray(e.skills)?e.skills:[e.skills],n=await validatePluginPaths(a,o,e.name,t,"skills","Skill","from marketplace entry",r);n.length>0&&(l.skillsPaths=[...l.skillsPaths||[],...n])}if(e.outputStyles){const a=Array.isArray(e.outputStyles)?e.outputStyles:[e.outputStyles],n=await validatePluginPaths(a,o,e.name,t,"output-styles","Output style","from marketplace entry",r);n.length>0&&(l.outputStylesPaths=[...l.outputStylesPaths||[],...n])}e.hooks&&(l.hooksConfig={...l.hooksConfig||{},...e.hooks})}}else{if(l.manifest={...e,id:void 0,source:void 0,strict:void 0},l.name=l.manifest.name,e.commands){const a=Object.values(e.commands)[0];if("object"==typeof e.commands&&!Array.isArray(e.commands)&&a&&"object"==typeof a&&("source"in a||"content"in a)){const a={},n=[],s=Object.entries(e.commands),i=await Promise.all(s.map(async([e,t])=>{if(!t||"object"!=typeof t||!t.source)return{commandName:e,metadata:t,skip:!0};const a=f(o,t.source);return{commandName:e,metadata:t,skip:!1,fullPath:a,exists:await x(a)}}));for(const o of i)o.skip||(o.exists?(n.push(o.fullPath),a[o.commandName]=o.metadata):(P(`Command ${o.commandName} path ${o.metadata.source} from marketplace entry not found at ${o.fullPath} for ${e.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${o.fullPath} for ${e.name}`)),r.push({type:"path-not-found",source:t,plugin:e.name,path:o.fullPath,component:"commands"})));n.length>0&&(l.commandsPaths=n,l.commandsMetadata=a)}else{const a=Array.isArray(e.commands)?e.commands:[e.commands],n=await Promise.all(a.map(async e=>{if("string"!=typeof e)return{cmdPath:e,kind:"invalid"};const t=f(o,e);return{cmdPath:e,kind:"path",fullPath:t,exists:await x(t)}})),s=[];for(const a of n)"invalid"!==a.kind?a.exists?s.push(a.fullPath):(P(`Command path ${a.cmdPath} from marketplace entry not found at ${a.fullPath} for ${e.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${a.fullPath} for ${e.name}`)),r.push({type:"path-not-found",source:t,plugin:e.name,path:a.fullPath,component:"commands"})):P(`Unexpected command format in marketplace entry for ${e.name}`,{level:"error"});s.length>0&&(l.commandsPaths=s)}}if(e.agents){const a=Array.isArray(e.agents)?e.agents:[e.agents],n=await validatePluginPaths(a,o,e.name,t,"agents","Agent","from marketplace entry",r);n.length>0&&(l.agentsPaths=n)}if(e.skills){P(`Processing ${Array.isArray(e.skills)?e.skills.length:1} skill paths for plugin ${e.name}`);const a=Array.isArray(e.skills)?e.skills:[e.skills],n=await Promise.all(a.map(async e=>{const t=f(o,e);return{skillPath:e,fullPath:t,exists:await x(t)}})),s=[];for(const{skillPath:a,fullPath:o,exists:i}of n)P(`Checking skill path: ${a} -> ${o} (exists: ${i})`),i?s.push(o):(P(`Skill path ${a} from marketplace entry not found at ${o} for ${e.name}`,{level:"warn"}),N(new Error(`Plugin component file not found: ${o} for ${e.name}`)),r.push({type:"path-not-found",source:t,plugin:e.name,path:o,component:"skills"}));P(`Found ${s.length} valid skill paths for plugin ${e.name}, setting skillsPaths`),s.length>0&&(l.skillsPaths=s)}else P(`Plugin ${e.name} has no entry.skills defined`);if(e.outputStyles){const a=Array.isArray(e.outputStyles)?e.outputStyles:[e.outputStyles],n=await validatePluginPaths(a,o,e.name,t,"output-styles","Output style","from marketplace entry",r);n.length>0&&(l.outputStylesPaths=n)}e.hooks&&(l.hooksConfig=e.hooks)}return n.push(...r),l}async function loadSessionOnlyPlugins(e){if(0===e.length)return{plugins:[],errors:[]};const t=[],a=[];for(const[n,o]of e.entries())try{const e=d(o);if(!await x(e)){P(`Plugin path does not exist: ${e}, skipping`,{level:"warn"}),a.push({type:"path-not-found",source:`inline[${n}]`,path:e,component:"commands"});continue}const r=m(e),{plugin:s,errors:i}=await createPluginFromPath(e,`${r}@inline`,!0,r);s.source=`${s.name}@inline`,s.repository=`${s.name}@inline`,t.push(s),a.push(...i),P(`Loaded inline plugin from path: ${s.name}`)}catch(e){const t=v(e);P(`Failed to load session plugin from ${o}: ${t}`,{level:"warn"}),a.push({type:"generic-error",source:`inline[${n}]`,error:`Failed to load plugin: ${t}`})}return t.length>0&&P(`Loaded ${t.length} session-only plugins from --plugin-dir`),{plugins:t,errors:a}}export function mergePluginSources(e){const t=[],a=e.managedNames,n=e.session.filter(e=>!a?.has(e.name)||(P(`Plugin "${e.name}" from --plugin-dir is blocked by managed settings`,{level:"warn"}),t.push({type:"generic-error",source:e.source,plugin:e.name,error:`--plugin-dir copy of "${e.name}" ignored: plugin is locked by managed settings`}),!1)),o=new Set(n.map(e=>e.name)),r=e.marketplace.filter(e=>!o.has(e.name)||(P(`Plugin "${e.name}" from --plugin-dir overrides installed version`),!1));return{plugins:[...n,...r,...e.builtin],errors:t}}export const loadAllPlugins=u(async()=>{const e=await assemblePluginLoadResult(()=>loadPluginsFromMarketplaces({cacheOnly:!1}));return loadAllPluginsCacheOnly.cache?.set(void 0,Promise.resolve(e)),e});export const loadAllPluginsCacheOnly=u(async()=>k(process.env.CONTEXT_CODE_SYNC_PLUGIN_INSTALL)||k(process.env.CLAUDE_CODE_SYNC_PLUGIN_INSTALL)?loadAllPlugins():assemblePluginLoadResult(()=>loadPluginsFromMarketplaces({cacheOnly:!0})));async function assemblePluginLoadResult(e){const t=y(),[a,n]=await Promise.all([e(),t.length>0?loadSessionOnlyPlugins(t):Promise.resolve({plugins:[],errors:[]})]),o=$(),{plugins:r,errors:s}=mergePluginSources({session:n.plugins,marketplace:a.plugins,builtin:[...o.enabled,...o.disabled],managedNames:J()}),i=[...a.errors,...n.errors,...s],{demoted:l,errors:c}=M(r);for(const e of r)l.has(e.source)&&(e.enabled=!1);i.push(...c);const u=r.filter(e=>e.enabled);return P(`Found ${r.length} plugins (${u.length} enabled, ${r.length-u.length} disabled)`),cachePluginSettings(u),{enabled:u,disabled:r.filter(e=>!e.enabled),errors:i}}export function clearPluginCache(e){e&&P(`clearPluginCache: invalidating loadAllPlugins cache (${e})`),loadAllPlugins.cache?.clear?.(),loadAllPluginsCacheOnly.cache?.clear?.(),void 0!==I()&&D(),T()}export function cachePluginSettings(e){const t=function(e){let t;for(const a of e)if(a.settings){t||(t={});for(const[e,n]of Object.entries(a.settings))e in t&&P(`Plugin "${a.name}" overrides setting "${e}" (previously set by another plugin)`),t[e]=n}return t}(e);V(t),t&&Object.keys(t).length>0&&(D(),P(`Cached plugin settings with keys: ${Object.keys(t).join(", ")}`))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"lodash-es/memoize.js";import{logForDebugging as t}from"../debug.js";import{logError as n}from"../log.js";import{getSecureStorage as i}from"../secureStorage/index.js";import{getSettings_DEPRECATED as r,updateSettingsForSource as s}from"../settings/settings.js";import{validateUserConfig as o}from"./mcpbHandler.js";import{getPluginDataDir as
|
|
1
|
+
import e from"lodash-es/memoize.js";import{logForDebugging as t}from"../debug.js";import{logError as n}from"../log.js";import{getSecureStorage as i}from"../secureStorage/index.js";import{getSettings_DEPRECATED as r,updateSettingsForSource as s}from"../settings/settings.js";import{validateUserConfig as o}from"./mcpbHandler.js";import{getPluginDataDir as l}from"./pluginDirectories.js";export function getPluginStorageId(e){return e.source}export const loadPluginOptions=e(e=>{const t=r(),n=t.pluginConfigs?.[e]?.options??{},s=i();return{...n,...s.read()?.pluginSecrets?.[e]??{}}});export function clearPluginOptionsCache(){loadPluginOptions.cache?.clear?.()}export function savePluginOptions(e,o,l){const c={},g={};for(const[e,t]of Object.entries(o))!0===l[e]?.sensitive?g[e]=String(t):c[e]=t;const u=new Set(Object.keys(g)),a=new Set(Object.keys(c)),p=i(),f=p.read()?.pluginSecrets?.[e]??void 0,d=f?Object.fromEntries(Object.entries(f).filter(([e])=>!a.has(e))):void 0,O=d&&f&&Object.keys(d).length!==Object.keys(f).length;if(Object.keys(g).length>0||O){const i=p.read()??{};i.pluginSecrets||(i.pluginSecrets={}),i.pluginSecrets[e]={...d,...g};const r=p.update(i);if(!r.success){const t=new Error(`Failed to save sensitive plugin options for ${e} to secure storage`);throw n(t),t}r.warning&&t(`Plugin secrets save warning: ${r.warning}`,{level:"warn"})}const b=r(),m=b.pluginConfigs?.[e]?.options??{},h=Object.keys(m).filter(e=>u.has(e));if(Object.keys(c).length>0||h.length>0){b.pluginConfigs||(b.pluginConfigs={}),b.pluginConfigs[e]||(b.pluginConfigs[e]={});const t=Object.fromEntries(h.map(e=>[e,void 0]));b.pluginConfigs[e].options={...c,...t};const i=s("userSettings",b);if(i.error)throw n(i.error),new Error(`Failed to save plugin options for ${e}: ${i.error.message}`)}clearPluginOptionsCache()}export function deletePluginOptions(e){const n=r();if(n.pluginConfigs?.[e]){const n={[e]:void 0},{error:i}=s("userSettings",{pluginConfigs:n});i&&t(`deletePluginOptions: failed to clear settings.pluginConfigs[${e}]: ${i.message}`,{level:"warn"})}const o=i(),l=o.read();if(l?.pluginSecrets){const n=`${e}/`,i=Object.entries(l.pluginSecrets).filter(([t])=>t!==e&&!t.startsWith(n));if(i.length!==Object.keys(l.pluginSecrets).length){o.update({...l,pluginSecrets:i.length>0?Object.fromEntries(i):void 0}).success||t(`deletePluginOptions: failed to clear pluginSecrets for ${e} from keychain`,{level:"warn"})}}clearPluginOptionsCache()}export function getUnconfiguredOptions(e){const t=e.manifest.userConfig;if(!t||0===Object.keys(t).length)return{};const n=loadPluginOptions(getPluginStorageId(e));if(o(n,t).valid)return{};const i={};for(const[e,r]of Object.entries(t)){o({[e]:n[e]},{[e]:r}).valid||(i[e]=r)}return i}export function substitutePluginVariables(e,t){const normalize=e=>"win32"===process.platform?e.replace(/\\/g,"/"):e;let n=e.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g,()=>normalize(t.path));if(t.source){const e=t.source;n=n.replace(/\$\{CLAUDE_PLUGIN_DATA\}/g,()=>normalize(l(e)))}return n}export function substituteUserConfigVariables(e,t){return e.replace(/\$\{user_config\.([^}]+)\}/g,(e,n)=>{const i=t[n];if(void 0===i)throw new Error(`Missing required user configuration value: ${n}. This should have been validated before variable substitution.`);return String(i)})}export function substituteUserConfigInContent(e,t,n){return e.replace(/\$\{user_config\.([^}]+)\}/g,(e,i)=>{if(!0===n[i]?.sensitive)return`[sensitive option '${i}' not available in skill content]`;const r=t[i];return void 0===r?e:String(r)})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getSettingsForSource as t}from"../settings/settings.js";export function isPluginBlockedByPolicy(
|
|
1
|
+
import{getSettingsForSource as t}from"../settings/settings.js";export function isPluginBlockedByPolicy(i){const n=t("policySettings")?.enabledPlugins;return!1===n?.[i]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"path";import{getCwd as n}from"../cwd.js";import{logForDebugging as t}from"../debug.js";import{logError as s}from"../log.js";import{getInitialSettings as
|
|
1
|
+
import{join as e}from"path";import{getCwd as n}from"../cwd.js";import{logForDebugging as t}from"../debug.js";import{logError as s}from"../log.js";import{getInitialSettings as o,getSettingsForSource as i,updateSettingsForSource as r}from"../settings/settings.js";import{getAddDirEnabledPlugins as l}from"./addDirPluginSettings.js";import{getInMemoryInstalledPlugins as c,migrateFromEnabledPlugins as a}from"./installedPluginsManager.js";import{getPluginById as u}from"./marketplaceManager.js";import{SETTING_SOURCE_TO_SCOPE as p,scopeToSettingSource as g}from"./pluginIdentifier.js";import{cacheAndRegisterPlugin as f,registerPluginInstallation as d}from"./pluginInstallationHelpers.js";import{isLocalPluginSource as m}from"./schemas.js";export async function checkEnabledPlugins(){const e=o(),n=[],t=l();for(const[e,s]of Object.entries(t))e.includes("@")&&s&&n.push(e);if(e.enabledPlugins)for(const[t,s]of Object.entries(e.enabledPlugins)){if(!t.includes("@"))continue;const e=n.indexOf(t);s?-1===e&&n.push(t):-1!==e&&n.splice(e,1)}return n}export function getPluginEditableScopes(){const e=new Map,n=l();for(const[t,s]of Object.entries(n))t.includes("@")&&(!0===s?e.set(t,"flag"):!1===s&&e.delete(t));const s=[{scope:"managed",source:"policySettings"},{scope:"user",source:"userSettings"},{scope:"project",source:"projectSettings"},{scope:"local",source:"localSettings"},{scope:"flag",source:"flagSettings"}];for(const{scope:o,source:r}of s){const s=i(r);if(s?.enabledPlugins)for(const[i,l]of Object.entries(s.enabledPlugins))i.includes("@")&&(i in n&&n[i]!==l&&t(`Plugin ${i} from --add-dir (${n[i]}) overridden by ${r} (${l})`),!0===l?e.set(i,o):!1===l&&e.delete(i))}return t(`Found ${e.size} enabled plugins with scopes: ${Array.from(e.entries()).map(([e,n])=>`${e}(${n})`).join(", ")}`),e}export function isPersistableScope(e){return"flag"!==e}export function settingSourceToScope(e){return p[e]}export async function getInstalledPlugins(){a().catch(e=>{s(e)});const e=c(),n=Object.keys(e.plugins);return t(`Found ${n.length} installed plugins`),n}export async function findMissingPlugins(e){try{const n=await getInstalledPlugins(),s=e.filter(e=>!n.includes(e)),o=await Promise.all(s.map(async e=>{try{const n=await u(e);return{pluginId:e,found:null!=n}}catch(n){return t(`Failed to check plugin ${e} in marketplace: ${n}`),{pluginId:e,found:!1}}}));return o.filter(({found:e})=>e).map(({pluginId:e})=>e)}catch(e){return s(e),[]}}export async function installSelectedPlugins(t,o,l="user"){const c="user"!==l?n():void 0,a=g(l),p=i(a),P={...p?.enabledPlugins},h=[],j=[];for(let n=0;n<t.length;n++){const i=t[n];if(i){o&&o(i,n+1,t.length);try{const n=await u(i);if(!n){j.push({name:i,error:"Plugin not found in any marketplace"});continue}const{entry:t,marketplaceInstallLocation:s}=n;m(t.source)?d({pluginId:i,installPath:e(s,t.source),version:t.version},l,c):await f(i,t,l,c),P[i]=!0,h.push(i)}catch(e){const n=e instanceof Error?e.message:String(e);j.push({name:i,error:n}),s(e)}}}return r(a,{...p,enabledPlugins:P}),{installed:h,failed:j}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as r}from"crypto";import{logForDebugging as
|
|
1
|
+
import{createHash as r}from"crypto";import{logForDebugging as n}from"../debug.js";import{getHeadForDir as t}from"../git/gitFilesystem.js";export async function calculatePluginVersion(t,i,e,o,s,u){if(e?.version)return n(`Using manifest version for ${t}: ${e.version}`),e.version;if(s)return n(`Using provided version for ${t}: ${s}`),s;if(u){const e=u.substring(0,12);if("object"==typeof i&&"git-subdir"===i.source){const o=i.path.replace(/\\/g,"/").replace(/^\.\//,"").replace(/\/+$/,""),s=`${e}-${r("sha256").update(o).digest("hex").substring(0,8)}`;return n(`Using git-subdir SHA+path version for ${t}: ${s} (path=${o})`),s}return n(`Using pre-resolved git SHA for ${t}: ${e}`),e}if(o){const r=await getGitCommitSha(o);if(r){const i=r.substring(0,12);return n(`Using git SHA for ${t}: ${i}`),i}}return n(`No version found for ${t}, using 'unknown'`),"unknown"}export function getGitCommitSha(r){return t(r)}export function getVersionFromPath(r){const n=r.split("/").filter(Boolean),t=n.findIndex((r,t)=>"cache"===r&&"plugins"===n[t-1]);if(-1===t)return null;const i=n.slice(t+1);return i.length>=3&&i[2]||null}export function isVersionedPath(r){return null!==getVersionFromPath(r)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"lodash-es/isEqual.js";import{isAbsolute as
|
|
1
|
+
import e from"lodash-es/isEqual.js";import{isAbsolute as t,resolve as o}from"path";import{getOriginalCwd as r}from"../../bootstrap/state.js";import{logForDebugging as a}from"../debug.js";import{errorMessage as s}from"../errors.js";import{pathExists as n}from"../file.js";import{findCanonicalGitRoot as i}from"../git.js";import{logError as c}from"../log.js";import{addMarketplaceSource as p,getDeclaredMarketplaces as l,loadKnownMarketplacesConfig as u}from"./marketplaceManager.js";import{isLocalMarketplaceSource as m}from"./schemas.js";export function diffMarketplaces(t,o,r){const a=[],s=[],n=[];for(const[i,c]of Object.entries(t)){const t=o[i],p=normalizeSource(c.source,r?.projectRoot);t?c.sourceIsFallback||e(p,t.source)?n.push(i):s.push({name:i,declaredSource:p,materializedSource:t.source}):a.push(i)}return{missing:a,sourceChanged:s,upToDate:n}}export async function reconcileMarketplaces(e){const t=l();if(0===Object.keys(t).length)return{installed:[],updated:[],failed:[],upToDate:[],skipped:[]};let o;try{o=await u()}catch(e){c(e),o={}}const i=diffMarketplaces(t,o,{projectRoot:r()}),d=[...i.missing.map(e=>({name:e,source:normalizeSource(t[e].source),action:"install"})),...i.sourceChanged.map(({name:e,declaredSource:t})=>({name:e,source:t,action:"update"}))],f=[],h=[];for(const t of d)e?.skip?.(t.name,t.source)?f.push(t.name):"update"!==t.action||!m(t.source)||await n(t.source.path)?h.push(t):(a(`[reconcile] '${t.name}' declared path does not exist; keeping materialized entry`),f.push(t.name));if(0===h.length)return{installed:[],updated:[],failed:[],upToDate:i.upToDate,skipped:f};a(`[reconcile] ${h.length} marketplace(s): ${h.map(e=>`${e.name}(${e.action})`).join(", ")}`);const g=[],j=[],k=[];for(let t=0;t<h.length;t++){const{name:o,source:r,action:a}=h[t];e?.onProgress?.({type:"installing",name:o,action:a,index:t+1,total:h.length});try{const t=await p(r);"install"===a?g.push(o):j.push(o),e?.onProgress?.({type:"installed",name:o,alreadyMaterialized:t.alreadyMaterialized})}catch(t){const r=s(t);k.push({name:o,error:r}),e?.onProgress?.({type:"failed",name:o,error:r}),c(t)}}return{installed:g,updated:j,failed:k,upToDate:i.upToDate,skipped:f}}function normalizeSource(e,a){if(("directory"===e.source||"file"===e.source)&&!t(e.path)){const t=a??r(),s=i(t);return{...e,path:o(s??t,e.path)}}return e}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getOriginalCwd as e}from"../../bootstrap/state.js";import{reinitializeLspServerManager as r}from"../../services/lsp/manager.js";import{getAgentDefinitionsWithOverrides as
|
|
1
|
+
import{getOriginalCwd as e}from"../../bootstrap/state.js";import{reinitializeLspServerManager as r}from"../../services/lsp/manager.js";import{getAgentDefinitionsWithOverrides as o}from"../../tools/AgentTool/loadAgentsDir.js";import{logForDebugging as n}from"../debug.js";import{errorMessage as t}from"../errors.js";import{logError as s}from"../log.js";import{clearAllCaches as i}from"./cacheUtils.js";import{getPluginCommands as l}from"./loadPluginCommands.js";import{loadPluginHooks as a}from"./loadPluginHooks.js";import{loadPluginLspServers as c}from"./lspPluginIntegration.js";import{loadPluginMcpServers as g}from"./mcpPluginIntegration.js";import{clearPluginCacheExclusions as m}from"./orphanedPluginFilter.js";import{loadAllPlugins as u}from"./pluginLoader.js";export async function refreshActivePlugins(p){n("refreshActivePlugins: clearing all plugin caches"),i(),m();const f=await u(),[d,h]=await Promise.all([l(),o(e())]),{enabled:j,disabled:P,errors:y}=f,[b,v]=await Promise.all([Promise.all(j.map(async e=>{if(e.mcpServers)return Object.keys(e.mcpServers).length;const r=await g(e,y);return r&&(e.mcpServers=r),r?Object.keys(r).length:0})),Promise.all(j.map(async e=>{if(e.lspServers)return Object.keys(e.lspServers).length;const r=await c(e,y);return r&&(e.lspServers=r),r?Object.keys(r).length:0}))]),k=b.reduce((e,r)=>e+r,0),$=v.reduce((e,r)=>e+r,0);p(e=>({...e,plugins:{...e.plugins,enabled:j,disabled:P,commands:d,errors:mergePluginErrors(e.plugins.errors,y),needsRefresh:!1},agentDefinitions:h,mcp:{...e.mcp,pluginReconnectKey:e.mcp.pluginReconnectKey+1}})),r();let A=!1;try{await a()}catch(e){A=!0,s(e),n(`refreshActivePlugins: loadPluginHooks failed: ${t(e)}`)}const S=j.reduce((e,r)=>r.hooksConfig?e+Object.values(r.hooksConfig).reduce((e,r)=>e+(r?.reduce((e,r)=>e+r.hooks.length,0)??0),0):e,0);return n(`refreshActivePlugins: ${j.length} enabled, ${d.length} commands, ${h.allAgents.length} agents, ${S} hooks, ${k} MCP, ${$} LSP`),{enabled_count:j.length,disabled_count:P.length,command_count:d.length,agent_count:h.allAgents.length,hook_count:S,mcp_count:k,lsp_count:$,error_count:y.length+(A?1:0),agentDefinitions:h,pluginCommands:d}}function mergePluginErrors(e,r){const o=e.filter(e=>"lsp-manager"===e.source||e.source.startsWith("plugin:")),n=new Set(r.map(errorKey));return[...o.filter(e=>!n.has(errorKey(e))),...r]}function errorKey(e){return"generic-error"===e.type?`generic-error:${e.source}:${e.error}`:`${e.type}:${e.source}`}
|