@cjhyy/code-shell-core 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -23
- package/dist/agent/agent-definition-registry.d.ts +2 -2
- package/dist/agent/agent-definition-registry.js +47 -10
- package/dist/agent/agent-definition.d.ts +5 -0
- package/dist/agent/agent-definition.js +14 -0
- package/dist/automation/index.d.ts +7 -4
- package/dist/automation/index.js +4 -2
- package/dist/automation/runner.js +3 -1
- package/dist/automation/scheduler.d.ts +57 -1
- package/dist/automation/scheduler.js +123 -23
- package/dist/automation/store.d.ts +6 -2
- package/dist/automation/store.js +7 -3
- package/dist/capabilities/index.d.ts +109 -0
- package/dist/capabilities/index.js +80 -0
- package/dist/capability-control/disabled-lists.d.ts +2 -1
- package/dist/capability-control/disabled-lists.js +3 -5
- package/dist/capability-control/overlay.d.ts +14 -1
- package/dist/capability-control/overlay.js +40 -0
- package/dist/capability-control/service.js +6 -4
- package/dist/cli/agent-server-stdio.d.ts +1 -1
- package/dist/cli/agent-server-stdio.js +66 -6
- package/dist/cli/agent-server-tcp.js +20 -5
- package/dist/context/compaction.d.ts +39 -3
- package/dist/context/compaction.js +151 -39
- package/dist/context/manager.d.ts +20 -4
- package/dist/context/manager.js +42 -7
- package/dist/context/token-counter.js +5 -3
- package/dist/context/tool-result-storage.d.ts +6 -0
- package/dist/context/tool-result-storage.js +25 -4
- package/dist/credentials/access.d.ts +13 -2
- package/dist/credentials/access.js +99 -4
- package/dist/credentials/index.d.ts +3 -2
- package/dist/credentials/index.js +2 -1
- package/dist/credentials/oauth.d.ts +9 -1
- package/dist/credentials/oauth.js +80 -1
- package/dist/credentials/store.d.ts +16 -2
- package/dist/credentials/store.js +33 -11
- package/dist/credentials/types.d.ts +62 -1
- package/dist/credentials/types.js +16 -1
- package/dist/credentials/use-credential-tool.js +15 -1
- package/dist/engine/auxiliary-pipeline.d.ts +40 -0
- package/dist/engine/auxiliary-pipeline.js +181 -0
- package/dist/{settings → engine}/disk-defaults.d.ts +2 -2
- package/dist/{settings → engine}/disk-defaults.js +5 -2
- package/dist/engine/dynamic-tool-defs.d.ts +4 -0
- package/dist/engine/dynamic-tool-defs.js +4 -0
- package/dist/engine/engine.d.ts +272 -184
- package/dist/engine/engine.js +1869 -1864
- package/dist/engine/file-history-hook.d.ts +11 -0
- package/dist/engine/file-history-hook.js +31 -0
- package/dist/engine/goal-judge-context.d.ts +9 -0
- package/dist/engine/goal-judge-context.js +234 -0
- package/dist/engine/injected-context-cache.d.ts +6 -0
- package/dist/engine/injected-context-cache.js +13 -0
- package/dist/engine/input-attachments.d.ts +1 -1
- package/dist/engine/model-facade.d.ts +3 -3
- package/dist/engine/model-facade.js +15 -14
- package/dist/engine/permission-controller.d.ts +55 -0
- package/dist/engine/permission-controller.js +148 -0
- package/dist/engine/prompt-cache-diagnostics.d.ts +58 -0
- package/dist/engine/prompt-cache-diagnostics.js +178 -0
- package/dist/engine/run-accounting.d.ts +41 -0
- package/dist/engine/run-accounting.js +126 -0
- package/dist/engine/run-context.d.ts +44 -0
- package/dist/engine/run-context.js +88 -0
- package/dist/engine/run-environment.d.ts +30 -0
- package/dist/engine/run-environment.js +77 -0
- package/dist/engine/run-finalize.d.ts +58 -0
- package/dist/engine/run-finalize.js +245 -0
- package/dist/engine/run-goal.d.ts +58 -0
- package/dist/engine/run-goal.js +188 -0
- package/dist/engine/run-image-input.d.ts +1 -1
- package/dist/engine/run-image-input.js +5 -3
- package/dist/engine/run-session-open.d.ts +41 -0
- package/dist/engine/run-session-open.js +186 -0
- package/dist/engine/run-setup.d.ts +42 -0
- package/dist/engine/run-setup.js +58 -0
- package/dist/engine/run-tooling.d.ts +125 -0
- package/dist/engine/run-tooling.js +283 -0
- package/dist/engine/run-types.d.ts +139 -0
- package/dist/engine/run-types.js +12 -0
- package/dist/engine/run-workspace.d.ts +50 -0
- package/dist/engine/run-workspace.js +114 -0
- package/dist/engine/session-title.d.ts +2 -1
- package/dist/engine/session-title.js +4 -1
- package/dist/engine/steer-queue.d.ts +1 -1
- package/dist/engine/subagent-spawner.d.ts +32 -0
- package/dist/engine/subagent-spawner.js +287 -0
- package/dist/engine/tool-summary.d.ts +2 -2
- package/dist/engine/tool-summary.js +2 -2
- package/dist/engine/turn-loop.d.ts +67 -10
- package/dist/engine/turn-loop.js +538 -97
- package/dist/engine/types.d.ts +35 -4
- package/dist/engine/types.js +1 -1
- package/dist/{engine/goal.d.ts → goal/lifecycle.d.ts} +80 -6
- package/dist/goal/lifecycle.js +482 -0
- package/dist/hooks/events.d.ts +26 -9
- package/dist/hooks/events.js +0 -3
- package/dist/hooks/goal-stop-hook.d.ts +28 -29
- package/dist/hooks/goal-stop-hook.js +344 -144
- package/dist/hooks/registry.js +4 -1
- package/dist/hooks/shell-runner.d.ts +12 -1
- package/dist/hooks/shell-runner.js +160 -9
- package/dist/index.d.ts +51 -110
- package/dist/index.extension.d.ts +51 -0
- package/dist/index.extension.js +39 -0
- package/dist/index.internal.d.ts +86 -0
- package/dist/index.internal.js +92 -0
- package/dist/index.js +37 -125
- package/dist/links/cli.d.ts +48 -0
- package/dist/links/cli.js +617 -0
- package/dist/links/http.d.ts +40 -0
- package/dist/links/http.js +166 -0
- package/dist/links/index.d.ts +4 -0
- package/dist/links/index.js +3 -0
- package/dist/links/link-action-tool.d.ts +5 -0
- package/dist/links/link-action-tool.js +241 -0
- package/dist/links/providers.d.ts +8 -0
- package/dist/links/providers.js +665 -0
- package/dist/links/types.d.ts +44 -0
- package/dist/llm/client-base.d.ts +7 -0
- package/dist/llm/client-base.js +72 -10
- package/dist/llm/model-pool.d.ts +1 -1
- package/dist/llm/model-pool.js +1 -1
- package/dist/llm/providers/anthropic.d.ts +1 -0
- package/dist/llm/providers/anthropic.js +9 -0
- package/dist/llm/providers/openai.d.ts +1 -0
- package/dist/llm/providers/openai.js +17 -0
- package/dist/llm/types.d.ts +12 -5
- package/dist/model-catalog/index.js +15 -2
- package/dist/model-catalog/resolve.d.ts +13 -1
- package/dist/model-catalog/resolve.js +37 -2
- package/dist/model-catalog/types.d.ts +74 -48
- package/dist/model-catalog/types.js +16 -5
- package/dist/model-catalog/upsert.d.ts +3 -1
- package/dist/model-catalog/upsert.js +9 -0
- package/dist/onboarding.d.ts +0 -1
- package/dist/onboarding.js +1 -22
- package/dist/panel-apps/bindings.d.ts +24 -0
- package/dist/panel-apps/bindings.js +69 -0
- package/dist/panel-apps/github-archive.d.ts +21 -0
- package/dist/panel-apps/github-archive.js +98 -0
- package/dist/panel-apps/index.d.ts +4 -0
- package/dist/panel-apps/index.js +4 -0
- package/dist/panel-apps/installer.d.ts +68 -0
- package/dist/panel-apps/installer.js +622 -0
- package/dist/panel-apps/manifest.d.ts +364 -0
- package/dist/panel-apps/manifest.js +189 -0
- package/dist/panel-apps/paths.d.ts +13 -0
- package/dist/panel-apps/paths.js +38 -0
- package/dist/panel-apps/registry.d.ts +51 -0
- package/dist/panel-apps/registry.js +99 -0
- package/dist/panel-apps/runtime.d.ts +80 -0
- package/dist/panel-apps/runtime.js +154 -0
- package/dist/plugins/gitOps.js +8 -1
- package/dist/plugins/installedPlugins.d.ts +2 -1
- package/dist/plugins/installedPlugins.js +146 -8
- package/dist/plugins/installer/codex/convertAgents.d.ts +4 -1
- package/dist/plugins/installer/codex/convertAgents.js +62 -8
- package/dist/plugins/installer/codex/convertCommands.d.ts +5 -5
- package/dist/plugins/installer/codex/convertCommands.js +35 -12
- package/dist/plugins/installer/codex/convertHooks.d.ts +10 -0
- package/dist/plugins/installer/codex/convertHooks.js +82 -0
- package/dist/plugins/installer/codex/convertSkills.js +41 -6
- package/dist/plugins/installer/install.d.ts +7 -1
- package/dist/plugins/installer/install.js +21 -87
- package/dist/plugins/installer/installFromArchive.d.ts +26 -4
- package/dist/plugins/installer/installFromArchive.js +44 -27
- package/dist/plugins/installer/installFromNpm.d.ts +31 -0
- package/dist/plugins/installer/installFromNpm.js +273 -0
- package/dist/plugins/installer/loadPluginAgents.js +17 -4
- package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
- package/dist/plugins/installer/loadPluginMcp.js +245 -35
- package/dist/plugins/installer/normalizeManifest.d.ts +13 -0
- package/dist/plugins/installer/normalizeManifest.js +306 -0
- package/dist/plugins/installer/npmTar.d.ts +13 -0
- package/dist/plugins/installer/npmTar.js +321 -0
- package/dist/plugins/installer/parseSource.d.ts +11 -0
- package/dist/plugins/installer/parseSource.js +48 -0
- package/dist/plugins/installer/preview.d.ts +101 -0
- package/dist/plugins/installer/preview.js +336 -0
- package/dist/plugins/installer/projectPluginSource.d.ts +14 -0
- package/dist/plugins/installer/projectPluginSource.js +140 -0
- package/dist/plugins/installer/types.d.ts +775 -0
- package/dist/plugins/installer/types.js +100 -0
- package/dist/plugins/installer/unzip.d.ts +11 -0
- package/dist/plugins/installer/unzip.js +123 -9
- package/dist/plugins/installer/update.d.ts +2 -2
- package/dist/plugins/installer/update.js +43 -4
- package/dist/plugins/loadPluginHooks.d.ts +19 -2
- package/dist/plugins/loadPluginHooks.js +97 -86
- package/dist/plugins/pluginAutomationTemplates.d.ts +18 -0
- package/dist/plugins/pluginAutomationTemplates.js +50 -0
- package/dist/plugins/pluginCatalog.d.ts +45 -0
- package/dist/plugins/pluginCatalog.js +87 -0
- package/dist/plugins/pluginCommandHook.d.ts +10 -4
- package/dist/plugins/pluginCommandHook.js +133 -18
- package/dist/plugins/pluginCommandsLoader.d.ts +19 -0
- package/dist/plugins/pluginCommandsLoader.js +181 -7
- package/dist/plugins/pluginContent.d.ts +10 -1
- package/dist/plugins/pluginContent.js +87 -30
- package/dist/plugins/pluginHookApproval.d.ts +30 -0
- package/dist/plugins/pluginHookApproval.js +160 -0
- package/dist/plugins/pluginHookIntegrity.d.ts +69 -0
- package/dist/plugins/pluginHookIntegrity.js +361 -0
- package/dist/plugins/pluginInstaller.js +71 -12
- package/dist/plugins/pluginMcpApproval.d.ts +19 -0
- package/dist/plugins/pluginMcpApproval.js +110 -0
- package/dist/plugins/pluginMcpIntegrity.d.ts +21 -0
- package/dist/plugins/pluginMcpIntegrity.js +74 -0
- package/dist/plugins/types.d.ts +30 -0
- package/dist/plugins/varRewrite.d.ts +9 -5
- package/dist/plugins/varRewrite.js +26 -17
- package/dist/preset/index.d.ts +11 -8
- package/dist/preset/index.js +62 -203
- package/dist/product/define.js +9 -3
- package/dist/product/types.d.ts +0 -2
- package/dist/profile/activation.d.ts +36 -0
- package/dist/profile/activation.js +57 -0
- package/dist/profile/catalog-store.d.ts +77 -0
- package/dist/profile/catalog-store.js +346 -0
- package/dist/profile/catalog.d.ts +54 -0
- package/dist/profile/catalog.js +152 -0
- package/dist/profile/index.d.ts +7 -0
- package/dist/profile/index.js +7 -0
- package/dist/profile/requirements.d.ts +76 -0
- package/dist/profile/requirements.js +117 -0
- package/dist/profile/resolve.d.ts +11 -0
- package/dist/profile/resolve.js +41 -0
- package/dist/profile/store.d.ts +17 -0
- package/dist/profile/store.js +167 -0
- package/dist/profile/types.d.ts +321 -0
- package/dist/profile/types.js +104 -0
- package/dist/prompt/composer.d.ts +46 -7
- package/dist/prompt/composer.js +78 -48
- package/dist/prompt/instruction-scanner.d.ts +6 -5
- package/dist/prompt/instruction-scanner.js +8 -23
- package/dist/prompt/section-loader.d.ts +2 -2
- package/dist/prompt/section-loader.js +7 -4
- package/dist/prompt/sections/browser.md +10 -9
- package/dist/prompt/sections/harness-base.md +9 -0
- package/dist/protocol/chat-session-manager.d.ts +77 -3
- package/dist/protocol/chat-session-manager.js +194 -18
- package/dist/protocol/chat-session.d.ts +72 -9
- package/dist/protocol/chat-session.js +151 -16
- package/dist/protocol/client.d.ts +37 -4
- package/dist/protocol/client.js +118 -6
- package/dist/protocol/index.d.ts +2 -2
- package/dist/protocol/index.js +2 -2
- package/dist/protocol/mobile-remote-types.d.ts +406 -0
- package/dist/protocol/mobile-remote-types.js +1 -0
- package/dist/protocol/server.d.ts +152 -14
- package/dist/protocol/server.js +1574 -229
- package/dist/protocol/types.d.ts +182 -32
- package/dist/protocol/types.js +18 -0
- package/dist/run/ArtifactTracker.d.ts +6 -1
- package/dist/run/ArtifactTracker.js +29 -21
- package/dist/run/EngineRunner.d.ts +2 -0
- package/dist/run/EngineRunner.js +1 -0
- package/dist/run/RunManager.d.ts +26 -0
- package/dist/run/RunManager.js +82 -11
- package/dist/run/factory.d.ts +3 -0
- package/dist/run/factory.js +2 -0
- package/dist/runtime/safe-spawn.d.ts +6 -0
- package/dist/runtime/safe-spawn.js +8 -13
- package/dist/services/auto-dream.d.ts +13 -1
- package/dist/services/auto-dream.js +56 -8
- package/dist/services/dream-consolidation.d.ts +3 -0
- package/dist/services/dream-consolidation.js +14 -2
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/memory-orchestrator.js +6 -2
- package/dist/services/oauth.d.ts +34 -10
- package/dist/services/oauth.js +236 -98
- package/dist/services/session-memory.d.ts +4 -4
- package/dist/services/session-memory.js +13 -10
- package/dist/session/memory.d.ts +26 -7
- package/dist/session/memory.js +79 -21
- package/dist/session/session-manager.d.ts +208 -25
- package/dist/session/session-manager.js +1232 -116
- package/dist/session/session-message.d.ts +22 -0
- package/dist/session/session-message.js +1 -0
- package/dist/session/transcript.d.ts +76 -6
- package/dist/session/transcript.js +278 -7
- package/dist/settings/feature-flags.d.ts +40 -0
- package/dist/settings/feature-flags.js +40 -0
- package/dist/settings/manager.d.ts +39 -1
- package/dist/settings/manager.js +102 -41
- package/dist/settings/migrate-config.js +4 -2
- package/dist/settings/schema.d.ts +511 -177
- package/dist/settings/schema.js +98 -25
- package/dist/skills/scanner.d.ts +6 -2
- package/dist/skills/scanner.js +160 -9
- package/dist/sources/adapter.d.ts +14 -0
- package/dist/sources/adapter.js +7 -0
- package/dist/sources/adapters/local-files.d.ts +10 -0
- package/dist/sources/adapters/local-files.js +127 -0
- package/dist/sources/adapters/mcp-resource.d.ts +17 -0
- package/dist/sources/adapters/mcp-resource.js +41 -0
- package/dist/sources/adapters/mock.d.ts +3 -0
- package/dist/sources/adapters/mock.js +29 -0
- package/dist/sources/binding.d.ts +6 -0
- package/dist/sources/binding.js +24 -0
- package/dist/sources/catalog.d.ts +6 -0
- package/dist/sources/catalog.js +64 -0
- package/dist/sources/context-summary.d.ts +8 -0
- package/dist/sources/context-summary.js +13 -0
- package/dist/sources/credential-status.d.ts +2 -0
- package/dist/sources/credential-status.js +13 -0
- package/dist/sources/index.d.ts +10 -0
- package/dist/sources/index.js +10 -0
- package/dist/sources/resolve.d.ts +28 -0
- package/dist/sources/resolve.js +47 -0
- package/dist/sources/truncate-utf8.d.ts +7 -0
- package/dist/sources/truncate-utf8.js +18 -0
- package/dist/sources/types.d.ts +71 -0
- package/dist/sources/types.js +26 -0
- package/dist/testing/fetch-stub.d.ts +32 -0
- package/dist/testing/fetch-stub.js +24 -0
- package/dist/themes/image.d.ts +18 -0
- package/dist/themes/image.js +117 -0
- package/dist/themes/index.d.ts +4 -0
- package/dist/themes/index.js +4 -0
- package/dist/themes/installer.d.ts +50 -0
- package/dist/themes/installer.js +290 -0
- package/dist/themes/manifest.d.ts +102 -0
- package/dist/themes/manifest.js +86 -0
- package/dist/themes/paths.d.ts +14 -0
- package/dist/themes/paths.js +33 -0
- package/dist/tool-system/browser-bridge.d.ts +53 -11
- package/dist/tool-system/browser-bridge.js +8 -9
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +2 -2
- package/dist/tool-system/builtin/agent-heartbeat.js +20 -6
- package/dist/tool-system/builtin/agent-notifications.d.ts +127 -72
- package/dist/tool-system/builtin/agent-notifications.js +291 -101
- package/dist/tool-system/builtin/agent-output-file.js +1 -3
- package/dist/tool-system/builtin/agent-progress.d.ts +6 -0
- package/dist/tool-system/builtin/agent-progress.js +83 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +38 -2
- package/dist/tool-system/builtin/agent-registry.js +178 -9
- package/dist/tool-system/builtin/agent-transcript-translator.js +1 -1
- package/dist/tool-system/builtin/agent.d.ts +2 -0
- package/dist/tool-system/builtin/agent.js +279 -34
- package/dist/tool-system/builtin/background-jobs.d.ts +63 -7
- package/dist/tool-system/builtin/background-jobs.js +111 -15
- package/dist/tool-system/builtin/background-work.d.ts +12 -1
- package/dist/tool-system/builtin/background-work.js +12 -1
- package/dist/tool-system/builtin/bash.d.ts +3 -5
- package/dist/tool-system/builtin/bash.js +14 -6
- package/dist/tool-system/builtin/browser-tools.d.ts +8 -5
- package/dist/tool-system/builtin/browser-tools.js +89 -23
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +6 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +172 -12
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +14 -10
- package/dist/tool-system/builtin/file-cache.d.ts +2 -0
- package/dist/tool-system/builtin/file-cache.js +4 -0
- package/dist/tool-system/builtin/generate-image.js +17 -10
- package/dist/tool-system/builtin/generate-video.d.ts +4 -0
- package/dist/tool-system/builtin/generate-video.js +164 -28
- package/dist/tool-system/builtin/glob.d.ts +2 -1
- package/dist/tool-system/builtin/glob.js +28 -3
- package/dist/tool-system/builtin/grep.d.ts +1 -0
- package/dist/tool-system/builtin/grep.js +82 -17
- package/dist/tool-system/builtin/image-uploader.js +7 -1
- package/dist/tool-system/builtin/index.d.ts +57 -18
- package/dist/tool-system/builtin/index.js +280 -167
- package/dist/tool-system/builtin/memory.d.ts +6 -0
- package/dist/tool-system/builtin/memory.js +36 -15
- package/dist/tool-system/builtin/panel.d.ts +9 -0
- package/dist/tool-system/builtin/panel.js +314 -0
- package/dist/tool-system/builtin/read.js +5 -1
- package/dist/tool-system/builtin/send-message-to-session.d.ts +6 -0
- package/dist/tool-system/builtin/send-message-to-session.js +67 -0
- package/dist/tool-system/builtin/sources.d.ts +8 -0
- package/dist/tool-system/builtin/sources.js +137 -0
- package/dist/tool-system/builtin/tool-search.js +7 -2
- package/dist/tool-system/builtin/update-automation-memory.js +2 -0
- package/dist/tool-system/builtin/video-providers.d.ts +12 -15
- package/dist/tool-system/builtin/video-providers.js +1 -0
- package/dist/tool-system/builtin/view-image.d.ts +2 -2
- package/dist/tool-system/builtin/web-fetch.js +60 -15
- package/dist/tool-system/builtin/web-search.js +1 -3
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +14 -4
- package/dist/tool-system/capability-module.d.ts +93 -0
- package/dist/tool-system/capability-module.js +53 -0
- package/dist/tool-system/context.d.ts +94 -24
- package/dist/tool-system/executor.js +99 -58
- package/dist/tool-system/external-tool-exposure.d.ts +60 -0
- package/dist/tool-system/external-tool-exposure.js +304 -0
- package/dist/tool-system/mcp-manager.d.ts +17 -1
- package/dist/tool-system/mcp-manager.js +72 -7
- package/dist/tool-system/mcp-tool-policy.d.ts +9 -0
- package/dist/tool-system/mcp-tool-policy.js +34 -0
- package/dist/tool-system/panel-bridge.d.ts +53 -0
- package/dist/tool-system/panel-bridge.js +1 -0
- package/dist/tool-system/path-policy.d.ts +19 -0
- package/dist/tool-system/path-policy.js +62 -1
- package/dist/tool-system/permission.d.ts +69 -3
- package/dist/tool-system/permission.js +429 -30
- package/dist/tool-system/registry.d.ts +15 -3
- package/dist/tool-system/registry.js +82 -40
- package/dist/tool-system/sandbox/index.js +3 -8
- package/dist/tool-system/sandbox/seatbelt.js +2 -6
- package/dist/tool-system/session-tool-host.d.ts +139 -0
- package/dist/tool-system/session-tool-host.js +167 -0
- package/dist/tool-system/testing/tool-registry-harness.d.ts +31 -0
- package/dist/tool-system/testing/tool-registry-harness.js +51 -0
- package/dist/tool-system/validation.d.ts +14 -7
- package/dist/tool-system/validation.js +701 -7
- package/dist/types.d.ts +201 -20
- package/dist/{cc-orchestrator → utils}/cwd-normalize.d.ts +1 -0
- package/dist/{cc-orchestrator → utils}/cwd-normalize.js +1 -0
- package/dist/utils/file-mutex.d.ts +65 -0
- package/dist/utils/file-mutex.js +145 -0
- package/dist/utils/json.d.ts +2 -4
- package/dist/utils/json.js +2 -4
- package/dist/utils/lockfile.d.ts +30 -1
- package/dist/utils/lockfile.js +2 -2
- package/dist/utils/secret-scrubber.d.ts +8 -0
- package/dist/utils/secret-scrubber.js +227 -0
- package/dist/utils/toolDisplay.js +1 -1
- package/package.json +20 -5
- package/THIRD_PARTY_NOTICES.md +0 -206
- package/dist/arena/arena.d.ts +0 -43
- package/dist/arena/arena.js +0 -333
- package/dist/arena/context/context-tools.d.ts +0 -16
- package/dist/arena/context/context-tools.js +0 -272
- package/dist/arena/context/within-root.d.ts +0 -7
- package/dist/arena/context/within-root.js +0 -15
- package/dist/arena/detect-mode.d.ts +0 -20
- package/dist/arena/detect-mode.js +0 -78
- package/dist/arena/digest-builder.d.ts +0 -25
- package/dist/arena/digest-builder.js +0 -120
- package/dist/arena/index.d.ts +0 -29
- package/dist/arena/index.js +0 -29
- package/dist/arena/iterate/convergence.d.ts +0 -25
- package/dist/arena/iterate/convergence.js +0 -103
- package/dist/arena/iterate/formats/index.d.ts +0 -22
- package/dist/arena/iterate/formats/index.js +0 -283
- package/dist/arena/iterate/index.d.ts +0 -11
- package/dist/arena/iterate/index.js +0 -9
- package/dist/arena/iterate/iterative-arena.d.ts +0 -23
- package/dist/arena/iterate/iterative-arena.js +0 -237
- package/dist/arena/iterate/parse.d.ts +0 -42
- package/dist/arena/iterate/parse.js +0 -123
- package/dist/arena/iterate/phases/argue.d.ts +0 -22
- package/dist/arena/iterate/phases/argue.js +0 -165
- package/dist/arena/iterate/phases/revise.d.ts +0 -16
- package/dist/arena/iterate/phases/revise.js +0 -62
- package/dist/arena/iterate/phases/tournament.d.ts +0 -34
- package/dist/arena/iterate/phases/tournament.js +0 -113
- package/dist/arena/iterate/tools/web-tools.d.ts +0 -13
- package/dist/arena/iterate/tools/web-tools.js +0 -54
- package/dist/arena/iterate/types.d.ts +0 -152
- package/dist/arena/iterate/types.js +0 -8
- package/dist/arena/ledger.d.ts +0 -47
- package/dist/arena/ledger.js +0 -159
- package/dist/arena/lenses/architecture.d.ts +0 -5
- package/dist/arena/lenses/architecture.js +0 -22
- package/dist/arena/lenses/engineering.d.ts +0 -5
- package/dist/arena/lenses/engineering.js +0 -22
- package/dist/arena/lenses/general.d.ts +0 -5
- package/dist/arena/lenses/general.js +0 -20
- package/dist/arena/lenses/index.d.ts +0 -16
- package/dist/arena/lenses/index.js +0 -47
- package/dist/arena/lenses/product.d.ts +0 -5
- package/dist/arena/lenses/product.js +0 -22
- package/dist/arena/model-presets.d.ts +0 -23
- package/dist/arena/model-presets.js +0 -44
- package/dist/arena/phases/adjudication.d.ts +0 -24
- package/dist/arena/phases/adjudication.js +0 -141
- package/dist/arena/phases/build-consensus.d.ts +0 -29
- package/dist/arena/phases/build-consensus.js +0 -83
- package/dist/arena/phases/claim-registry.d.ts +0 -26
- package/dist/arena/phases/claim-registry.js +0 -60
- package/dist/arena/phases/cross-review.d.ts +0 -45
- package/dist/arena/phases/cross-review.js +0 -218
- package/dist/arena/phases/debate-rounds.d.ts +0 -27
- package/dist/arena/phases/debate-rounds.js +0 -159
- package/dist/arena/phases/participant-research.d.ts +0 -38
- package/dist/arena/phases/participant-research.js +0 -314
- package/dist/arena/phases/planning-detail-expansion.d.ts +0 -38
- package/dist/arena/phases/planning-detail-expansion.js +0 -119
- package/dist/arena/planner.d.ts +0 -27
- package/dist/arena/planner.js +0 -311
- package/dist/arena/providers/docs.d.ts +0 -7
- package/dist/arena/providers/docs.js +0 -111
- package/dist/arena/providers/git.d.ts +0 -8
- package/dist/arena/providers/git.js +0 -174
- package/dist/arena/providers/index.d.ts +0 -32
- package/dist/arena/providers/index.js +0 -132
- package/dist/arena/providers/none.d.ts +0 -7
- package/dist/arena/providers/none.js +0 -11
- package/dist/arena/providers/repo.d.ts +0 -7
- package/dist/arena/providers/repo.js +0 -258
- package/dist/arena/render/session.d.ts +0 -17
- package/dist/arena/render/session.js +0 -190
- package/dist/arena/render/terminal.d.ts +0 -34
- package/dist/arena/render/terminal.js +0 -286
- package/dist/arena/strategies/discussion.d.ts +0 -25
- package/dist/arena/strategies/discussion.js +0 -143
- package/dist/arena/strategies/index.d.ts +0 -15
- package/dist/arena/strategies/index.js +0 -28
- package/dist/arena/strategies/language-wrapper.d.ts +0 -17
- package/dist/arena/strategies/language-wrapper.js +0 -102
- package/dist/arena/strategies/lens-wrapper.d.ts +0 -16
- package/dist/arena/strategies/lens-wrapper.js +0 -236
- package/dist/arena/strategies/planning.d.ts +0 -30
- package/dist/arena/strategies/planning.js +0 -225
- package/dist/arena/strategies/review.d.ts +0 -26
- package/dist/arena/strategies/review.js +0 -168
- package/dist/arena/strategies/utils.d.ts +0 -36
- package/dist/arena/strategies/utils.js +0 -603
- package/dist/arena/tools/selector.d.ts +0 -17
- package/dist/arena/tools/selector.js +0 -61
- package/dist/arena/transitions.d.ts +0 -53
- package/dist/arena/transitions.js +0 -97
- package/dist/arena/types.d.ts +0 -514
- package/dist/arena/types.js +0 -27
- package/dist/cc-orchestrator/agent-adapter.d.ts +0 -54
- package/dist/cc-orchestrator/agent-adapter.js +0 -143
- package/dist/cc-orchestrator/cc-capability.d.ts +0 -19
- package/dist/cc-orchestrator/cc-capability.js +0 -53
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +0 -24
- package/dist/cc-orchestrator/codex-session-discovery.js +0 -191
- package/dist/cc-orchestrator/codex-session-history.d.ts +0 -38
- package/dist/cc-orchestrator/codex-session-history.js +0 -247
- package/dist/cc-orchestrator/external-agent-bindings.d.ts +0 -27
- package/dist/cc-orchestrator/external-agent-bindings.js +0 -150
- package/dist/cc-orchestrator/external-agent-changes.d.ts +0 -19
- package/dist/cc-orchestrator/external-agent-changes.js +0 -231
- package/dist/cc-orchestrator/external-agent-driver.d.ts +0 -19
- package/dist/cc-orchestrator/external-agent-driver.js +0 -284
- package/dist/cc-orchestrator/external-agent-session-store.d.ts +0 -23
- package/dist/cc-orchestrator/external-agent-session-store.js +0 -146
- package/dist/cc-orchestrator/index.d.ts +0 -8
- package/dist/cc-orchestrator/index.js +0 -8
- package/dist/cc-orchestrator/relevance-judge.d.ts +0 -15
- package/dist/cc-orchestrator/relevance-judge.js +0 -29
- package/dist/cc-orchestrator/session-discovery.d.ts +0 -46
- package/dist/cc-orchestrator/session-discovery.js +0 -125
- package/dist/cc-orchestrator/session-history.d.ts +0 -54
- package/dist/cc-orchestrator/session-history.js +0 -150
- package/dist/cron/cron-runtime.d.ts +0 -2
- package/dist/cron/cron-runtime.js +0 -2
- package/dist/cron/cron-store.d.ts +0 -2
- package/dist/cron/cron-store.js +0 -2
- package/dist/cron/scheduler.d.ts +0 -7
- package/dist/cron/scheduler.js +0 -7
- package/dist/engine/goal.js +0 -206
- package/dist/external-agents/config.d.ts +0 -2
- package/dist/external-agents/config.js +0 -15
- package/dist/external-agents/types.d.ts +0 -31
- package/dist/git/parse-log.d.ts +0 -13
- package/dist/git/parse-log.js +0 -21
- package/dist/git/utils.d.ts +0 -49
- package/dist/git/utils.js +0 -161
- package/dist/git/worktree/crud.d.ts +0 -69
- package/dist/git/worktree/crud.js +0 -206
- package/dist/git/worktree/diff.d.ts +0 -14
- package/dist/git/worktree/diff.js +0 -82
- package/dist/git/worktree/git-exec.d.ts +0 -7
- package/dist/git/worktree/git-exec.js +0 -51
- package/dist/git/worktree/index.d.ts +0 -5
- package/dist/git/worktree/index.js +0 -5
- package/dist/git/worktree/query.d.ts +0 -42
- package/dist/git/worktree/query.js +0 -121
- package/dist/git/worktree/slug.d.ts +0 -11
- package/dist/git/worktree/slug.js +0 -58
- package/dist/git/worktree.d.ts +0 -1
- package/dist/git/worktree.js +0 -5
- package/dist/lsp/client.d.ts +0 -41
- package/dist/lsp/client.js +0 -186
- package/dist/lsp/manager.d.ts +0 -40
- package/dist/lsp/manager.js +0 -155
- package/dist/lsp/root-path.d.ts +0 -9
- package/dist/lsp/root-path.js +0 -12
- package/dist/lsp/servers.d.ts +0 -16
- package/dist/lsp/servers.js +0 -60
- package/dist/prompt/sections/coding.md +0 -35
- package/dist/quota/credentials.d.ts +0 -3
- package/dist/quota/credentials.js +0 -80
- package/dist/quota/index.d.ts +0 -36
- package/dist/quota/index.js +0 -155
- package/dist/quota/types.d.ts +0 -48
- package/dist/quota/types.js +0 -13
- package/dist/review/review-prompt.d.ts +0 -28
- package/dist/review/review-prompt.js +0 -81
- package/dist/state.d.ts +0 -160
- package/dist/state.js +0 -267
- package/dist/tool-system/builtin/apply-patch/applier.d.ts +0 -26
- package/dist/tool-system/builtin/apply-patch/applier.js +0 -308
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +0 -10
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +0 -30
- package/dist/tool-system/builtin/apply-patch/index.d.ts +0 -20
- package/dist/tool-system/builtin/apply-patch/index.js +0 -105
- package/dist/tool-system/builtin/apply-patch/parser.d.ts +0 -17
- package/dist/tool-system/builtin/apply-patch/parser.js +0 -212
- package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +0 -18
- package/dist/tool-system/builtin/apply-patch/seek-sequence.js +0 -123
- package/dist/tool-system/builtin/apply-patch/types.d.ts +0 -49
- package/dist/tool-system/builtin/apply-patch/types.js +0 -13
- package/dist/tool-system/builtin/arena.d.ts +0 -31
- package/dist/tool-system/builtin/arena.js +0 -415
- package/dist/tool-system/builtin/brief.d.ts +0 -6
- package/dist/tool-system/builtin/brief.js +0 -41
- package/dist/tool-system/builtin/check-quota.d.ts +0 -15
- package/dist/tool-system/builtin/check-quota.js +0 -34
- package/dist/tool-system/builtin/drive-claude-code.d.ts +0 -51
- package/dist/tool-system/builtin/drive-claude-code.js +0 -698
- package/dist/tool-system/builtin/lsp.d.ts +0 -7
- package/dist/tool-system/builtin/lsp.js +0 -144
- package/dist/tool-system/builtin/notebook-edit.d.ts +0 -7
- package/dist/tool-system/builtin/notebook-edit.js +0 -127
- package/dist/tool-system/builtin/worktree.d.ts +0 -11
- package/dist/tool-system/builtin/worktree.js +0 -345
- /package/dist/{external-agents → links}/types.js +0 -0
- /package/dist/{engine/session-usage.d.ts → session/usage.d.ts} +0 -0
- /package/dist/{engine/session-usage.js → session/usage.js} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { mkdtemp, mkdir, open, readFile, rm, stat } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { valid as validSemver } from "semver";
|
|
6
|
+
import { findPluginRoot, normalizePluginName } from "./installFromArchive.js";
|
|
7
|
+
import { installPluginFromPath } from "./install.js";
|
|
8
|
+
import { gunzipNpmTarball, extractNpmTar, MAX_NPM_TARBALL_BYTES } from "./npmTar.js";
|
|
9
|
+
import { PluginInstallError } from "./types.js";
|
|
10
|
+
export const NPM_PUBLIC_REGISTRY = "https://registry.npmjs.org";
|
|
11
|
+
export const MAX_NPM_METADATA_BYTES = 4 * 1024 * 1024;
|
|
12
|
+
const NPM_FETCH_TIMEOUT_MS = 30_000;
|
|
13
|
+
const MAX_NPM_PACKAGE_JSON_BYTES = 1024 * 1024;
|
|
14
|
+
function assertRegistryUrl(raw, label) {
|
|
15
|
+
let url;
|
|
16
|
+
try {
|
|
17
|
+
url = new URL(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
throw new PluginInstallError(`${label} is not a valid URL`);
|
|
21
|
+
}
|
|
22
|
+
if (url.protocol !== "https:" ||
|
|
23
|
+
url.hostname !== "registry.npmjs.org" ||
|
|
24
|
+
url.port !== "" ||
|
|
25
|
+
url.username !== "" ||
|
|
26
|
+
url.password !== "" ||
|
|
27
|
+
url.search !== "" ||
|
|
28
|
+
url.hash !== "") {
|
|
29
|
+
throw new PluginInstallError(`${label} must use the fixed public registry.npmjs.org origin`);
|
|
30
|
+
}
|
|
31
|
+
return url;
|
|
32
|
+
}
|
|
33
|
+
function assertSelfContained(document) {
|
|
34
|
+
const dependencyFields = [
|
|
35
|
+
"dependencies",
|
|
36
|
+
"optionalDependencies",
|
|
37
|
+
"peerDependencies",
|
|
38
|
+
"bundledDependencies",
|
|
39
|
+
"bundleDependencies",
|
|
40
|
+
];
|
|
41
|
+
for (const field of dependencyFields) {
|
|
42
|
+
const value = document[field];
|
|
43
|
+
const populated = value === undefined || value === null || value === false
|
|
44
|
+
? false
|
|
45
|
+
: Array.isArray(value)
|
|
46
|
+
? value.length > 0
|
|
47
|
+
: typeof value === "object"
|
|
48
|
+
? Object.keys(value).length > 0
|
|
49
|
+
: true;
|
|
50
|
+
if (populated) {
|
|
51
|
+
throw new PluginInstallError(`npm plugin declares ${field}; Phase A accepts self-contained packages only and never installs dependencies`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function verifyExtractedPackage(packageDir, resolution) {
|
|
56
|
+
const manifestPath = join(packageDir, "package.json");
|
|
57
|
+
let manifestStat;
|
|
58
|
+
try {
|
|
59
|
+
manifestStat = await stat(manifestPath);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw new PluginInstallError("npm tarball is missing package/package.json");
|
|
63
|
+
}
|
|
64
|
+
if (!manifestStat.isFile() || manifestStat.size > MAX_NPM_PACKAGE_JSON_BYTES) {
|
|
65
|
+
throw new PluginInstallError("npm package.json is not a bounded regular file");
|
|
66
|
+
}
|
|
67
|
+
let document;
|
|
68
|
+
try {
|
|
69
|
+
document = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw new PluginInstallError(`npm tarball has malformed package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
73
|
+
}
|
|
74
|
+
if (document.name !== resolution.packageName || document.version !== resolution.resolvedVersion) {
|
|
75
|
+
throw new PluginInstallError("npm tarball package identity does not match the reviewed registry metadata");
|
|
76
|
+
}
|
|
77
|
+
assertSelfContained(document);
|
|
78
|
+
}
|
|
79
|
+
function sha512DigestFromIntegrity(integrity) {
|
|
80
|
+
const token = integrity.split(/\s+/).find((candidate) => candidate.startsWith("sha512-"));
|
|
81
|
+
if (!token)
|
|
82
|
+
throw new PluginInstallError("npm package has no sha512 integrity value");
|
|
83
|
+
const encoded = token.slice("sha512-".length);
|
|
84
|
+
if (!/^[A-Za-z0-9+/]{86}==$/.test(encoded)) {
|
|
85
|
+
throw new PluginInstallError("npm package sha512 integrity value is malformed");
|
|
86
|
+
}
|
|
87
|
+
const digest = Buffer.from(encoded, "base64");
|
|
88
|
+
if (digest.length !== 64 || digest.toString("base64") !== encoded) {
|
|
89
|
+
throw new PluginInstallError("npm package sha512 integrity value is malformed");
|
|
90
|
+
}
|
|
91
|
+
return digest;
|
|
92
|
+
}
|
|
93
|
+
async function checkedFetch(url, accept, fetchImpl) {
|
|
94
|
+
let response;
|
|
95
|
+
try {
|
|
96
|
+
response = await fetchImpl(url, {
|
|
97
|
+
method: "GET",
|
|
98
|
+
redirect: "manual",
|
|
99
|
+
headers: {
|
|
100
|
+
Accept: accept,
|
|
101
|
+
"Accept-Encoding": "identity",
|
|
102
|
+
"User-Agent": "CodeShell-plugin-installer/1",
|
|
103
|
+
},
|
|
104
|
+
signal: AbortSignal.timeout(NPM_FETCH_TIMEOUT_MS),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
throw new PluginInstallError(`public npm registry request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
}
|
|
110
|
+
if (response.status !== 200) {
|
|
111
|
+
throw new PluginInstallError(`public npm registry returned HTTP ${response.status}; redirects and non-success responses are refused`);
|
|
112
|
+
}
|
|
113
|
+
const lengthText = response.headers.get("content-length");
|
|
114
|
+
if (lengthText && (!/^[0-9]+$/.test(lengthText) || !Number.isSafeInteger(Number(lengthText)))) {
|
|
115
|
+
throw new PluginInstallError("public npm registry returned an invalid Content-Length");
|
|
116
|
+
}
|
|
117
|
+
return response;
|
|
118
|
+
}
|
|
119
|
+
async function readBoundedResponse(response, limit, label) {
|
|
120
|
+
const declared = response.headers.get("content-length");
|
|
121
|
+
if (declared && Number(declared) > limit) {
|
|
122
|
+
throw new PluginInstallError(`${label} exceeds ${limit} bytes`);
|
|
123
|
+
}
|
|
124
|
+
if (!response.body)
|
|
125
|
+
throw new PluginInstallError(`${label} response has no body`);
|
|
126
|
+
const chunks = [];
|
|
127
|
+
let total = 0;
|
|
128
|
+
for await (const value of response.body) {
|
|
129
|
+
const chunk = Buffer.from(value);
|
|
130
|
+
total += chunk.length;
|
|
131
|
+
if (total > limit)
|
|
132
|
+
throw new PluginInstallError(`${label} exceeds ${limit} bytes`);
|
|
133
|
+
chunks.push(chunk);
|
|
134
|
+
}
|
|
135
|
+
if (declared && total !== Number(declared)) {
|
|
136
|
+
throw new PluginInstallError(`${label} length does not match Content-Length`);
|
|
137
|
+
}
|
|
138
|
+
return Buffer.concat(chunks, total);
|
|
139
|
+
}
|
|
140
|
+
/** Resolve an exact version or dist-tag to an immutable public-registry snapshot. */
|
|
141
|
+
export async function resolveNpmPlugin(parsed, options = {}) {
|
|
142
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
143
|
+
if (typeof fetchImpl !== "function")
|
|
144
|
+
throw new PluginInstallError("fetch is unavailable");
|
|
145
|
+
const metadataUrl = assertRegistryUrl(`${NPM_PUBLIC_REGISTRY}/${encodeURIComponent(parsed.packageName)}/${encodeURIComponent(parsed.selector)}`, "npm metadata URL");
|
|
146
|
+
const response = await checkedFetch(metadataUrl, "application/json", fetchImpl);
|
|
147
|
+
const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
|
|
148
|
+
if (!contentType.includes("json")) {
|
|
149
|
+
throw new PluginInstallError("public npm registry metadata response is not JSON");
|
|
150
|
+
}
|
|
151
|
+
const body = await readBoundedResponse(response, MAX_NPM_METADATA_BYTES, "npm metadata");
|
|
152
|
+
let document;
|
|
153
|
+
try {
|
|
154
|
+
document = JSON.parse(body.toString("utf8"));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new PluginInstallError(`public npm registry returned malformed metadata: ${error instanceof Error ? error.message : String(error)}`);
|
|
158
|
+
}
|
|
159
|
+
if (document.name !== parsed.packageName) {
|
|
160
|
+
throw new PluginInstallError("npm metadata package name does not match the requested package");
|
|
161
|
+
}
|
|
162
|
+
if (typeof document.version !== "string" || !validSemver(document.version)) {
|
|
163
|
+
throw new PluginInstallError("npm metadata did not resolve to an exact semantic version");
|
|
164
|
+
}
|
|
165
|
+
const resolvedVersion = validSemver(document.version);
|
|
166
|
+
if (parsed.selectorKind === "exact" && resolvedVersion !== parsed.selector) {
|
|
167
|
+
throw new PluginInstallError("npm registry resolved a different version than requested");
|
|
168
|
+
}
|
|
169
|
+
assertSelfContained(document);
|
|
170
|
+
if (typeof document.dist?.tarball !== "string") {
|
|
171
|
+
throw new PluginInstallError("npm metadata has no tarball URL");
|
|
172
|
+
}
|
|
173
|
+
assertRegistryUrl(document.dist.tarball, "npm tarball URL");
|
|
174
|
+
if (typeof document.dist.integrity !== "string") {
|
|
175
|
+
throw new PluginInstallError("npm metadata has no integrity value");
|
|
176
|
+
}
|
|
177
|
+
sha512DigestFromIntegrity(document.dist.integrity);
|
|
178
|
+
return {
|
|
179
|
+
packageName: parsed.packageName,
|
|
180
|
+
requestedSelector: parsed.selector,
|
|
181
|
+
resolvedVersion,
|
|
182
|
+
tarballUrl: document.dist.tarball,
|
|
183
|
+
integrity: document.dist.integrity,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/** Download a tarball with a compressed-byte cap and verify SHA-512 before use. */
|
|
187
|
+
export async function downloadVerifiedNpmTarball(resolution, targetPath, options = {}) {
|
|
188
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
189
|
+
if (typeof fetchImpl !== "function")
|
|
190
|
+
throw new PluginInstallError("fetch is unavailable");
|
|
191
|
+
const url = assertRegistryUrl(resolution.tarballUrl, "npm tarball URL");
|
|
192
|
+
const response = await checkedFetch(url, "application/octet-stream", fetchImpl);
|
|
193
|
+
const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
|
|
194
|
+
if (contentType &&
|
|
195
|
+
!["application/octet-stream", "application/gzip", "application/x-gzip"].some((allowed) => contentType.includes(allowed))) {
|
|
196
|
+
throw new PluginInstallError("npm tarball response has an unexpected Content-Type");
|
|
197
|
+
}
|
|
198
|
+
const contentEncoding = response.headers.get("content-encoding")?.toLowerCase();
|
|
199
|
+
if (contentEncoding && contentEncoding !== "identity") {
|
|
200
|
+
throw new PluginInstallError("npm tarball HTTP content encoding must be identity");
|
|
201
|
+
}
|
|
202
|
+
const declared = response.headers.get("content-length");
|
|
203
|
+
if (declared && Number(declared) > MAX_NPM_TARBALL_BYTES) {
|
|
204
|
+
throw new PluginInstallError(`npm tarball exceeds ${MAX_NPM_TARBALL_BYTES} bytes`);
|
|
205
|
+
}
|
|
206
|
+
if (!response.body)
|
|
207
|
+
throw new PluginInstallError("npm tarball response has no body");
|
|
208
|
+
const hash = createHash("sha512");
|
|
209
|
+
const output = await open(targetPath, "wx", 0o600);
|
|
210
|
+
let total = 0;
|
|
211
|
+
try {
|
|
212
|
+
for await (const value of response.body) {
|
|
213
|
+
const chunk = Buffer.from(value);
|
|
214
|
+
total += chunk.length;
|
|
215
|
+
if (total > MAX_NPM_TARBALL_BYTES) {
|
|
216
|
+
throw new PluginInstallError(`npm tarball exceeds ${MAX_NPM_TARBALL_BYTES} bytes`);
|
|
217
|
+
}
|
|
218
|
+
hash.update(chunk);
|
|
219
|
+
await output.write(chunk);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
await output.close();
|
|
224
|
+
await rm(targetPath, { force: true });
|
|
225
|
+
if (error instanceof PluginInstallError)
|
|
226
|
+
throw error;
|
|
227
|
+
throw new PluginInstallError(`npm tarball download failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
228
|
+
}
|
|
229
|
+
await output.close();
|
|
230
|
+
if (declared && total !== Number(declared)) {
|
|
231
|
+
await rm(targetPath, { force: true });
|
|
232
|
+
throw new PluginInstallError("npm tarball length does not match Content-Length");
|
|
233
|
+
}
|
|
234
|
+
const expected = sha512DigestFromIntegrity(resolution.integrity);
|
|
235
|
+
const actual = hash.digest();
|
|
236
|
+
if (!timingSafeEqual(actual, expected)) {
|
|
237
|
+
await rm(targetPath, { force: true });
|
|
238
|
+
throw new PluginInstallError("npm tarball sha512 integrity check failed");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Install a self-contained plugin from the public npm registry. The resolved
|
|
243
|
+
* exact version is recorded as the source; Phase A deliberately has no npm
|
|
244
|
+
* dependency install, lifecycle execution, private registry, or auto-update.
|
|
245
|
+
*/
|
|
246
|
+
export async function installPluginFromNpm(parsed, name, installedAt, options = {}) {
|
|
247
|
+
if (parsed.kind !== "npm") {
|
|
248
|
+
throw new PluginInstallError("installPluginFromNpm expects an npm source");
|
|
249
|
+
}
|
|
250
|
+
const resolution = await resolveNpmPlugin(parsed, options);
|
|
251
|
+
const resolvedName = normalizePluginName(name ?? parsed.inferredName);
|
|
252
|
+
const temp = await mkdtemp(join(tmpdir(), "cs-tmp-npm-"));
|
|
253
|
+
const tgzPath = join(temp, "package.tgz");
|
|
254
|
+
const tarPath = join(temp, "package.tar");
|
|
255
|
+
const extractPath = join(temp, "extract");
|
|
256
|
+
try {
|
|
257
|
+
await mkdir(extractPath, { mode: 0o700 });
|
|
258
|
+
await downloadVerifiedNpmTarball(resolution, tgzPath, options);
|
|
259
|
+
await gunzipNpmTarball(tgzPath, tarPath);
|
|
260
|
+
await extractNpmTar(tarPath, extractPath);
|
|
261
|
+
const packageDir = join(extractPath, "package");
|
|
262
|
+
await verifyExtractedPackage(packageDir, resolution);
|
|
263
|
+
const root = await findPluginRoot(packageDir);
|
|
264
|
+
const dir = await installPluginFromPath(root, resolvedName, installedAt, {
|
|
265
|
+
source: `npm:${resolution.packageName}@${resolution.resolvedVersion}`,
|
|
266
|
+
version: resolution.resolvedVersion,
|
|
267
|
+
});
|
|
268
|
+
return { dir, name: resolvedName, resolution };
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
await rm(temp, { recursive: true, force: true });
|
|
272
|
+
}
|
|
273
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
1
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, relative, sep } from "node:path";
|
|
3
3
|
import { readInstalledPlugins } from "../installedPlugins.js";
|
|
4
4
|
function pluginNameFromKey(key) {
|
|
5
5
|
const at = key.lastIndexOf("@");
|
|
@@ -19,8 +19,21 @@ export function pluginAgentDirs(disabledPlugins = []) {
|
|
|
19
19
|
// Carry pluginName so a plugin agent's bare skill allowlist
|
|
20
20
|
// (`director-skill`) can be namespaced to `<pluginName>:director-skill`
|
|
21
21
|
// at spawn time — see resolveAgentTypeOverrides.
|
|
22
|
-
if (existsSync(dir))
|
|
23
|
-
|
|
22
|
+
if (!existsSync(dir))
|
|
23
|
+
continue;
|
|
24
|
+
try {
|
|
25
|
+
const installRoot = realpathSync(entry.installPath);
|
|
26
|
+
const resolvedDir = realpathSync(dir);
|
|
27
|
+
const rel = relative(installRoot, resolvedDir);
|
|
28
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
|
|
29
|
+
continue;
|
|
30
|
+
if (statSync(resolvedDir).isDirectory()) {
|
|
31
|
+
out.push({ dir, source: "plugin", pluginName });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Missing, unreadable, or escaping plugin contribution — ignore it.
|
|
36
|
+
}
|
|
24
37
|
}
|
|
25
38
|
}
|
|
26
39
|
return out;
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import type { MCPServerConfig, MCPServerOverride } from "../../types.js";
|
|
2
|
+
export declare function normalizePluginMcpMap(raw: unknown, pluginName: string, alreadyKeyed: boolean): Record<string, MCPServerConfig>;
|
|
3
|
+
/**
|
|
4
|
+
* Read a single plugin's MCP servers, already keyed `<plugin>:<server>`.
|
|
5
|
+
*
|
|
6
|
+
* Two on-disk shapes are supported:
|
|
7
|
+
* - `mcp-servers.json` — the Codex-install product: already keyed + named.
|
|
8
|
+
* - `.mcp.json` — what a CC plugin ships verbatim (Docker's mcp-toolkit etc.).
|
|
9
|
+
* It uses a `{ mcpServers: {...} }` wrapper with bare server names; we unwrap
|
|
10
|
+
* it and apply the `<plugin>:` prefix + `name` so it matches the keyed shape.
|
|
11
|
+
*
|
|
12
|
+
* `mcp-servers.json` wins if both exist. Malformed files yield {} (must not
|
|
13
|
+
* break startup).
|
|
14
|
+
*/
|
|
15
|
+
export declare function readPluginMcp(installPath: string, pluginName: string): Record<string, MCPServerConfig>;
|
|
2
16
|
/**
|
|
3
17
|
* Merge each registered plugin's MCP servers into a copy of `base`.
|
|
4
18
|
* Plugin keys are `<plugin>:<server>`. A key already present in `base`
|
|
@@ -1,24 +1,240 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from "node:path";
|
|
1
|
+
import { lstatSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, relative, sep } from "node:path";
|
|
3
3
|
import { readInstalledPlugins } from "../installedPlugins.js";
|
|
4
|
+
import { pluginMcpApprovalState } from "../pluginMcpIntegrity.js";
|
|
4
5
|
function pluginNameFromKey(key) {
|
|
5
6
|
const at = key.lastIndexOf("@");
|
|
6
7
|
return at > 0 ? key.slice(0, at) : key;
|
|
7
8
|
}
|
|
9
|
+
const MAX_PLUGIN_MCP_CONFIG_BYTES = 1024 * 1024;
|
|
10
|
+
const MAX_PLUGIN_MCP_SERVERS = 64;
|
|
11
|
+
const MAX_SERVER_NAME_LENGTH = 96;
|
|
12
|
+
const MAX_COMMAND_LENGTH = 4096;
|
|
13
|
+
const MAX_URL_LENGTH = 2048;
|
|
14
|
+
const MAX_ARGS = 256;
|
|
15
|
+
const MAX_RECORD_ENTRIES = 128;
|
|
16
|
+
const MAX_VALUE_LENGTH = 8192;
|
|
17
|
+
const SERVER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
18
|
+
const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
19
|
+
const HTTP_HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
20
|
+
const PLUGIN_TRANSPORTS = new Set(["stdio", "sse", "streamable-http"]);
|
|
21
|
+
function readContainedPluginJson(installPath, fileName) {
|
|
22
|
+
try {
|
|
23
|
+
const root = realpathSync(installPath);
|
|
24
|
+
const candidate = join(installPath, fileName);
|
|
25
|
+
const linkInfo = lstatSync(candidate);
|
|
26
|
+
if (linkInfo.isSymbolicLink() ||
|
|
27
|
+
!linkInfo.isFile() ||
|
|
28
|
+
linkInfo.size > MAX_PLUGIN_MCP_CONFIG_BYTES) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const target = realpathSync(candidate);
|
|
32
|
+
const rel = relative(root, target);
|
|
33
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
|
|
34
|
+
return null;
|
|
35
|
+
const info = statSync(target);
|
|
36
|
+
if (!info.isFile() || info.size > MAX_PLUGIN_MCP_CONFIG_BYTES)
|
|
37
|
+
return null;
|
|
38
|
+
return JSON.parse(readFileSync(target, "utf-8"));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function boundedString(value, maxLength) {
|
|
45
|
+
return typeof value === "string" && value.length > 0 && value.length <= maxLength
|
|
46
|
+
? value
|
|
47
|
+
: undefined;
|
|
48
|
+
}
|
|
49
|
+
function boundedStringArray(value, maxItems, maxLength, validate) {
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (!Array.isArray(value) || value.length > maxItems)
|
|
53
|
+
return undefined;
|
|
54
|
+
const items = [];
|
|
55
|
+
for (const item of value) {
|
|
56
|
+
const stringValue = boundedString(item, maxLength);
|
|
57
|
+
if (!stringValue || (validate && !validate(stringValue)))
|
|
58
|
+
return undefined;
|
|
59
|
+
items.push(stringValue);
|
|
60
|
+
}
|
|
61
|
+
return items;
|
|
62
|
+
}
|
|
63
|
+
function boundedStringRecord(value, validateKey, validateValue) {
|
|
64
|
+
if (value === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
67
|
+
return undefined;
|
|
68
|
+
const entries = Object.entries(value);
|
|
69
|
+
if (entries.length > MAX_RECORD_ENTRIES)
|
|
70
|
+
return undefined;
|
|
71
|
+
const result = {};
|
|
72
|
+
for (const [key, item] of entries) {
|
|
73
|
+
if (key.length === 0 ||
|
|
74
|
+
key.length > 256 ||
|
|
75
|
+
key.includes("\0") ||
|
|
76
|
+
(validateKey && !validateKey(key))) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const stringValue = typeof item === "string" && item.length <= MAX_VALUE_LENGTH ? item : undefined;
|
|
80
|
+
if (stringValue === undefined ||
|
|
81
|
+
stringValue.includes("\0") ||
|
|
82
|
+
(validateValue && !validateValue(stringValue))) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
result[key] = stringValue;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
function safeHttpUrl(value) {
|
|
90
|
+
const raw = boundedString(value, MAX_URL_LENGTH);
|
|
91
|
+
if (!raw)
|
|
92
|
+
return undefined;
|
|
93
|
+
try {
|
|
94
|
+
const url = new URL(raw);
|
|
95
|
+
if ((url.protocol !== "http:" && url.protocol !== "https:") ||
|
|
96
|
+
!url.hostname ||
|
|
97
|
+
url.username ||
|
|
98
|
+
url.password) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return raw;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Turn one untrusted plugin MCP declaration into the narrow runtime shape.
|
|
109
|
+
* Unknown fields are dropped; malformed known fields reject the whole server
|
|
110
|
+
* instead of reaching MCPManager and failing during application startup.
|
|
111
|
+
*/
|
|
112
|
+
function normalizePluginMcpServer(raw, key) {
|
|
113
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
114
|
+
return undefined;
|
|
115
|
+
const cfg = raw;
|
|
116
|
+
const transport = cfg.transport === undefined
|
|
117
|
+
? undefined
|
|
118
|
+
: typeof cfg.transport === "string" && PLUGIN_TRANSPORTS.has(cfg.transport)
|
|
119
|
+
? cfg.transport
|
|
120
|
+
: null;
|
|
121
|
+
if (transport === null)
|
|
122
|
+
return undefined;
|
|
123
|
+
const command = cfg.command === undefined ? undefined : boundedString(cfg.command, MAX_COMMAND_LENGTH);
|
|
124
|
+
if (cfg.command !== undefined && !command)
|
|
125
|
+
return undefined;
|
|
126
|
+
if (command?.includes("\0"))
|
|
127
|
+
return undefined;
|
|
128
|
+
const url = cfg.url === undefined ? undefined : safeHttpUrl(cfg.url);
|
|
129
|
+
if (cfg.url !== undefined && !url)
|
|
130
|
+
return undefined;
|
|
131
|
+
const args = boundedStringArray(cfg.args, MAX_ARGS, MAX_VALUE_LENGTH, (item) => {
|
|
132
|
+
return !item.includes("\0");
|
|
133
|
+
});
|
|
134
|
+
if (cfg.args !== undefined && !args)
|
|
135
|
+
return undefined;
|
|
136
|
+
const env = boundedStringRecord(cfg.env, (name) => ENV_NAME_RE.test(name));
|
|
137
|
+
if (cfg.env !== undefined && !env)
|
|
138
|
+
return undefined;
|
|
139
|
+
const headers = boundedStringRecord(cfg.headers, (name) => HTTP_HEADER_NAME_RE.test(name), (value) => !value.includes("\r") && !value.includes("\n"));
|
|
140
|
+
if (cfg.headers !== undefined && !headers)
|
|
141
|
+
return undefined;
|
|
142
|
+
const envHeaders = boundedStringRecord(cfg.envHeaders, (name) => HTTP_HEADER_NAME_RE.test(name), (envName) => ENV_NAME_RE.test(envName));
|
|
143
|
+
if (cfg.envHeaders !== undefined && !envHeaders)
|
|
144
|
+
return undefined;
|
|
145
|
+
const envVars = boundedStringArray(cfg.envVars, MAX_RECORD_ENTRIES, 256, (name) => ENV_NAME_RE.test(name));
|
|
146
|
+
if (cfg.envVars !== undefined && !envVars)
|
|
147
|
+
return undefined;
|
|
148
|
+
const bearerTokenEnvVar = cfg.bearerTokenEnvVar === undefined ? undefined : boundedString(cfg.bearerTokenEnvVar, 256);
|
|
149
|
+
if (cfg.bearerTokenEnvVar !== undefined &&
|
|
150
|
+
(!bearerTokenEnvVar || !ENV_NAME_RE.test(bearerTokenEnvVar))) {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
const credentialRef = cfg.credentialRef === undefined ? undefined : boundedString(cfg.credentialRef, 256);
|
|
154
|
+
if (cfg.credentialRef !== undefined && !credentialRef)
|
|
155
|
+
return undefined;
|
|
156
|
+
if (cfg.enabled !== undefined && typeof cfg.enabled !== "boolean")
|
|
157
|
+
return undefined;
|
|
158
|
+
const allowedToolsRaw = cfg.allowedTools ?? cfg.allowed_tools;
|
|
159
|
+
const disabledToolsRaw = cfg.disabledTools ?? cfg.disabled_tools;
|
|
160
|
+
const allowedTools = boundedStringArray(allowedToolsRaw, 256, 256, (name) => {
|
|
161
|
+
return !name.includes("\0");
|
|
162
|
+
});
|
|
163
|
+
if (allowedToolsRaw !== undefined && !allowedTools)
|
|
164
|
+
return undefined;
|
|
165
|
+
const disabledTools = boundedStringArray(disabledToolsRaw, 256, 256, (name) => {
|
|
166
|
+
return !name.includes("\0");
|
|
167
|
+
});
|
|
168
|
+
if (disabledToolsRaw !== undefined && !disabledTools)
|
|
169
|
+
return undefined;
|
|
170
|
+
const effectiveTransport = transport ?? (url && !command ? "streamable-http" : "stdio");
|
|
171
|
+
if (effectiveTransport === "stdio" && !command)
|
|
172
|
+
return undefined;
|
|
173
|
+
if ((effectiveTransport === "sse" || effectiveTransport === "streamable-http") && !url) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
name: key,
|
|
178
|
+
...(command ? { command } : {}),
|
|
179
|
+
...(args ? { args } : {}),
|
|
180
|
+
...(env ? { env } : {}),
|
|
181
|
+
...(url ? { url } : {}),
|
|
182
|
+
...(transport ? { transport } : {}),
|
|
183
|
+
...(headers ? { headers } : {}),
|
|
184
|
+
...(envVars ? { envVars } : {}),
|
|
185
|
+
...(bearerTokenEnvVar ? { bearerTokenEnvVar } : {}),
|
|
186
|
+
...(envHeaders ? { envHeaders } : {}),
|
|
187
|
+
...(credentialRef ? { credentialRef } : {}),
|
|
188
|
+
...(typeof cfg.enabled === "boolean" ? { enabled: cfg.enabled } : {}),
|
|
189
|
+
...(allowedTools ? { allowedTools } : {}),
|
|
190
|
+
...(disabledTools ? { disabledTools } : {}),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export function normalizePluginMcpMap(raw, pluginName, alreadyKeyed) {
|
|
194
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
195
|
+
return {};
|
|
196
|
+
const entries = Object.entries(raw);
|
|
197
|
+
if (entries.length > MAX_PLUGIN_MCP_SERVERS)
|
|
198
|
+
return {};
|
|
199
|
+
const keyed = {};
|
|
200
|
+
for (const [declaredName, config] of entries) {
|
|
201
|
+
const serverName = alreadyKeyed
|
|
202
|
+
? declaredName.startsWith(`${pluginName}:`)
|
|
203
|
+
? declaredName.slice(pluginName.length + 1)
|
|
204
|
+
: ""
|
|
205
|
+
: declaredName;
|
|
206
|
+
if (serverName.length === 0 ||
|
|
207
|
+
serverName.length > MAX_SERVER_NAME_LENGTH ||
|
|
208
|
+
!SERVER_NAME_RE.test(serverName)) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const key = `${pluginName}:${serverName}`;
|
|
212
|
+
const normalized = normalizePluginMcpServer(config, key);
|
|
213
|
+
if (normalized)
|
|
214
|
+
keyed[key] = normalized;
|
|
215
|
+
}
|
|
216
|
+
return keyed;
|
|
217
|
+
}
|
|
8
218
|
/**
|
|
9
219
|
* Layer a user override's supplement fields onto a plugin server config.
|
|
10
220
|
*
|
|
11
|
-
* Only env/credential fields are picked —
|
|
12
|
-
* deliberately NOT carried, because those are
|
|
13
|
-
* keep coming from the plugin manifest so
|
|
14
|
-
* without the user being stuck on a stale shadow copy.
|
|
15
|
-
* defense-in-depth on top of the schema's `.strict()`,
|
|
16
|
-
* settings file can never smuggle
|
|
221
|
+
* Only the user server/tool policy and env/credential fields are picked —
|
|
222
|
+
* command/args/url/transport are deliberately NOT carried, because those are
|
|
223
|
+
* the plugin's identity and must keep coming from the plugin manifest so an
|
|
224
|
+
* update can change them without the user being stuck on a stale shadow copy.
|
|
225
|
+
* This explicit pick is defense-in-depth on top of the schema's `.strict()`,
|
|
226
|
+
* so a hand-edited settings file can never smuggle identity fields in.
|
|
17
227
|
*/
|
|
18
228
|
function applyOverride(pluginConfig, override) {
|
|
19
229
|
if (!override)
|
|
20
230
|
return pluginConfig;
|
|
21
231
|
const supplement = {};
|
|
232
|
+
if (override.enabled !== undefined)
|
|
233
|
+
supplement.enabled = override.enabled;
|
|
234
|
+
if (override.allowedTools !== undefined)
|
|
235
|
+
supplement.allowedTools = override.allowedTools;
|
|
236
|
+
if (override.disabledTools !== undefined)
|
|
237
|
+
supplement.disabledTools = override.disabledTools;
|
|
22
238
|
if (override.env !== undefined)
|
|
23
239
|
supplement.env = override.env;
|
|
24
240
|
if (override.envVars !== undefined)
|
|
@@ -43,34 +259,25 @@ function applyOverride(pluginConfig, override) {
|
|
|
43
259
|
* `mcp-servers.json` wins if both exist. Malformed files yield {} (must not
|
|
44
260
|
* break startup).
|
|
45
261
|
*/
|
|
46
|
-
function readPluginMcp(installPath, pluginName) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return {};
|
|
54
|
-
}
|
|
262
|
+
export function readPluginMcp(installPath, pluginName) {
|
|
263
|
+
let keyedPresent = false;
|
|
264
|
+
try {
|
|
265
|
+
lstatSync(join(installPath, "mcp-servers.json"));
|
|
266
|
+
keyedPresent = true;
|
|
55
267
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
for (const [serverName, cfg] of Object.entries(servers)) {
|
|
70
|
-
const key = `${pluginName}:${serverName}`;
|
|
71
|
-
keyed[key] = { ...cfg, name: key };
|
|
72
|
-
}
|
|
73
|
-
return keyed;
|
|
268
|
+
catch {
|
|
269
|
+
// Missing: the CC-compatible .mcp.json fallback may be used.
|
|
270
|
+
}
|
|
271
|
+
const keyed = readContainedPluginJson(installPath, "mcp-servers.json");
|
|
272
|
+
if (keyed && typeof keyed === "object" && !Array.isArray(keyed)) {
|
|
273
|
+
return normalizePluginMcpMap(keyed, pluginName, true);
|
|
274
|
+
}
|
|
275
|
+
if (keyedPresent)
|
|
276
|
+
return {};
|
|
277
|
+
const parsed = readContainedPluginJson(installPath, ".mcp.json");
|
|
278
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
279
|
+
const servers = "mcpServers" in parsed ? (parsed.mcpServers ?? {}) : parsed;
|
|
280
|
+
return normalizePluginMcpMap(servers, pluginName, false);
|
|
74
281
|
}
|
|
75
282
|
return {};
|
|
76
283
|
}
|
|
@@ -96,6 +303,9 @@ export function mergePluginMcpServers(base, disabledPlugins = [], overrides = {}
|
|
|
96
303
|
continue;
|
|
97
304
|
for (const entry of entries) {
|
|
98
305
|
const servers = readPluginMcp(entry.installPath, pluginName);
|
|
306
|
+
const approval = pluginMcpApprovalState(entry, Object.keys(servers).length > 0);
|
|
307
|
+
if (approval === "pending" || approval === "changed" || approval === "none")
|
|
308
|
+
continue;
|
|
99
309
|
for (const [k, cfg] of Object.entries(servers)) {
|
|
100
310
|
if (k in merged)
|
|
101
311
|
continue; // user / earlier wins
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CanonicalPluginManifest as CanonicalPluginManifestData } from "./types.js";
|
|
2
|
+
export interface NormalizePluginManifestOptions {
|
|
3
|
+
name: string;
|
|
4
|
+
version?: string;
|
|
5
|
+
format: "cc" | "codex";
|
|
6
|
+
destinationRoot: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Normalize an Agent Plugin into the runtime manifest. Desktop Panel Apps have
|
|
10
|
+
* their own package and installer, so a Plugin declaration cannot contain UI.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizePluginManifest(sourceRoot: string, options: NormalizePluginManifestOptions): Promise<CanonicalPluginManifestData>;
|
|
13
|
+
export declare function readCanonicalPluginManifest(installRoot: string): Promise<CanonicalPluginManifestData | null>;
|