@ai-agent-forge/agent-forge 0.86.7 → 0.88.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/CHANGELOG.md +45 -0
- package/README.md +10 -11
- package/dist/artifacts/artifact-store.d.ts.map +1 -1
- package/dist/artifacts/artifact-store.js +9 -5
- package/dist/artifacts/artifact-store.js.map +1 -1
- package/dist/bundle/.build-manifest.json +430 -413
- package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
- package/dist/bundle/chunks/chunk-HLJEVRWP.js +13 -0
- package/dist/bundle/chunks/chunk-YGHQME4V.js +1456 -0
- package/dist/bundle/chunks/image-resize-worker.js +12 -1
- package/dist/bundle/chunks/{virtual-modules-3IZ4MYSQ.js → virtual-modules-KZ5DRH7Q.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +2 -2
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +231 -185
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js +17 -4
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +15 -9
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +14 -7
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +6 -5
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +9 -8
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/plugin-manager-controller.d.ts.map +1 -1
- package/dist/cli/plugin-manager-controller.js +2 -1
- package/dist/cli/plugin-manager-controller.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +8 -5
- package/dist/cli/serve.js.map +1 -1
- package/dist/client/remote-session.d.ts.map +1 -1
- package/dist/client/remote-session.js +16 -9
- package/dist/client/remote-session.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-capability-contract.d.ts +0 -7
- package/dist/core/agent-capability-contract.d.ts.map +1 -1
- package/dist/core/agent-capability-contract.js +72 -68
- package/dist/core/agent-capability-contract.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +5 -4
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +6 -10
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +35 -133
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-context.d.ts.map +1 -1
- package/dist/core/agent-session-context.js +18 -13
- package/dist/core/agent-session-context.js.map +1 -1
- package/dist/core/agent-session-internal.d.ts +0 -6
- package/dist/core/agent-session-internal.d.ts.map +1 -1
- package/dist/core/agent-session-internal.js.map +1 -1
- package/dist/core/agent-session-model.d.ts.map +1 -1
- package/dist/core/agent-session-model.js +2 -1
- package/dist/core/agent-session-model.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +3 -3
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +7 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tools.d.ts.map +1 -1
- package/dist/core/agent-session-tools.js +3 -2
- package/dist/core/agent-session-tools.js.map +1 -1
- package/dist/core/agent-session.d.ts +40 -22
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +147 -67
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js +11 -5
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +9 -6
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +2 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/embedded-sdk.d.ts.map +1 -1
- package/dist/core/embedded-sdk.js +10 -6
- package/dist/core/embedded-sdk.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +9 -4
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/agent-composition.d.ts.map +1 -1
- package/dist/core/extensions/agent-composition.js +26 -19
- package/dist/core/extensions/agent-composition.js.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.js +3 -2
- package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.js +0 -34
- package/dist/core/extensions/bootstrap-compaction-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.js +20 -17
- package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js +2 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.js +4 -3
- package/dist/core/extensions/bootstrap-retry-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-skills.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-skills.js +7 -6
- package/dist/core/extensions/bootstrap-skills.js.map +1 -1
- package/dist/core/extensions/bootstrap-tools.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-tools.js +2 -1
- package/dist/core/extensions/bootstrap-tools.js.map +1 -1
- package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
- package/dist/core/extensions/capability-plugin.js +37 -13
- package/dist/core/extensions/capability-plugin.js.map +1 -1
- package/dist/core/extensions/capability-runtime-events.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-events.js +17 -13
- package/dist/core/extensions/capability-runtime-events.js.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.js +16 -15
- package/dist/core/extensions/capability-runtime-guards.js.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.js +52 -30
- package/dist/core/extensions/capability-runtime-manifest.js.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.js +66 -65
- package/dist/core/extensions/capability-runtime-validation.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +147 -127
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.d.ts.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.js +3 -2
- package/dist/core/extensions/compaction-memory-failure-mode.js.map +1 -1
- package/dist/core/extensions/context-strategy-binding.d.ts.map +1 -1
- package/dist/core/extensions/context-strategy-binding.js +7 -4
- package/dist/core/extensions/context-strategy-binding.js.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.js +290 -279
- package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.js +3 -2
- package/dist/core/extensions/lifecycle-delivery-queue.js.map +1 -1
- package/dist/core/extensions/provider-failover.d.ts +7 -3
- package/dist/core/extensions/provider-failover.d.ts.map +1 -1
- package/dist/core/extensions/provider-failover.js +9 -8
- package/dist/core/extensions/provider-failover.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +6 -6
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +2 -3
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/i18n/index.d.ts +14 -0
- package/dist/core/i18n/index.d.ts.map +1 -0
- package/dist/core/i18n/index.js +67 -0
- package/dist/core/i18n/index.js.map +1 -0
- package/dist/core/i18n/locales/en/example.d.ts +7 -0
- package/dist/core/i18n/locales/en/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/en/example.js +7 -0
- package/dist/core/i18n/locales/en/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.js +229 -0
- package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts +6 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.js +6 -0
- package/dist/core/i18n/locales/zh-cn/common.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js +173 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +582 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js +55 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +455 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js +191 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.js +10 -0
- package/dist/core/i18n/locales/zh-cn/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts +2 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.js +41 -0
- package/dist/core/i18n/locales/zh-cn/index.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +267 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js +67 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js +39 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js +15 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +102 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +286 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js +79 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js +72 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js.map +1 -0
- package/dist/core/keybindings.d.ts +15 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +18 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +5 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/model-config.d.ts +0 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +9 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +11 -7
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-install-host.d.ts.map +1 -1
- package/dist/core/package-install-host.js +4 -3
- package/dist/core/package-install-host.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +15 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-resource-collection.d.ts.map +1 -1
- package/dist/core/package-resource-collection.js +2 -1
- package/dist/core/package-resource-collection.js.map +1 -1
- package/dist/core/package-source.d.ts.map +1 -1
- package/dist/core/package-source.js +3 -2
- package/dist/core/package-source.js.map +1 -1
- package/dist/core/provider-composer.d.ts +2 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +29 -21
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +6 -2
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +15 -5
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/sdk.d.ts +27 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +80 -55
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +5 -2
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +2 -1
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +39 -29
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts.map +1 -1
- package/dist/core/session-storage.js +3 -3
- package/dist/core/session-storage.js.map +1 -1
- package/dist/core/settings-manager.d.ts +20 -20
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +47 -59
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +53 -32
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +25 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +9 -4
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +2 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +6 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/durable/durable-service.d.ts.map +1 -1
- package/dist/durable/durable-service.js +25 -18
- package/dist/durable/durable-service.js.map +1 -1
- package/dist/host/checkpoint-commit.d.ts.map +1 -1
- package/dist/host/checkpoint-commit.js +2 -1
- package/dist/host/checkpoint-commit.js.map +1 -1
- package/dist/host/manual-compaction.d.ts.map +1 -1
- package/dist/host/manual-compaction.js +2 -1
- package/dist/host/manual-compaction.js.map +1 -1
- package/dist/host/output-projection.d.ts +0 -13
- package/dist/host/output-projection.d.ts.map +1 -1
- package/dist/host/output-projection.js +16 -2
- package/dist/host/output-projection.js.map +1 -1
- package/dist/host/summary-retry.d.ts.map +1 -1
- package/dist/host/summary-retry.js +3 -2
- package/dist/host/summary-retry.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +97 -60
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/agents-view.js +18 -15
- package/dist/modes/interactive/components/agents-view.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -5
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +12 -7
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +2 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +6 -5
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +9 -5
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +18 -15
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +2 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.js +5 -4
- package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
- package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-input.js +2 -1
- package/dist/modes/interactive/components/dialog-input.js.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.js +4 -3
- package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +11 -10
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +0 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -10
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +3 -2
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +12 -11
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js +6 -2
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +28 -16
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +10 -9
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.js +22 -13
- package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js +27 -12
- package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.d.ts +60 -0
- package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/queue-manager-selector.js +166 -0
- package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +16 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +43 -31
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -6
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +115 -120
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js +5 -4
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +3 -2
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +4 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +14 -5
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +2 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +11 -4
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +8 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-list.js +7 -6
- package/dist/modes/interactive/components/tree-list.js.map +1 -1
- package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-render.js +28 -23
- package/dist/modes/interactive/components/tree-render.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +9 -7
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +5 -4
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/workflow-view.js +36 -21
- package/dist/modes/interactive/components/workflow-view.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth.js +71 -40
- package/dist/modes/interactive/interactive-auth.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts +1 -0
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +3 -0
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.js +5 -5
- package/dist/modes/interactive/interactive-dialog-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-format.js +34 -18
- package/dist/modes/interactive/interactive-format.js.map +1 -1
- package/dist/modes/interactive/interactive-helpers.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-helpers.js +7 -2
- package/dist/modes/interactive/interactive-helpers.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +350 -279
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.d.ts +9 -0
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +79 -25
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +5 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +26 -23
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +3 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +0 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -14
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +0 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -19
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +28 -13
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/plugins/ecosystem/catalog.d.ts.map +1 -1
- package/dist/plugins/ecosystem/catalog.js +3 -2
- package/dist/plugins/ecosystem/catalog.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +2 -1
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.d.ts.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.js +3 -2
- package/dist/plugins/ecosystem/default-plugin-market.js.map +1 -1
- package/dist/plugins/ecosystem/distribution.d.ts.map +1 -1
- package/dist/plugins/ecosystem/distribution.js +2 -1
- package/dist/plugins/ecosystem/distribution.js.map +1 -1
- package/dist/plugins/ecosystem/installer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/installer.js +3 -2
- package/dist/plugins/ecosystem/installer.js.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.js +20 -17
- package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.js +35 -34
- package/dist/plugins/ecosystem/node-distribution-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.js +35 -34
- package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +9 -8
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.js +4 -3
- package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +44 -5
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.js +10 -9
- package/dist/plugins/ecosystem/node-plugin-trust-root.js.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.js +31 -30
- package/dist/plugins/ecosystem/node-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.js +30 -29
- package/dist/plugins/ecosystem/node-release-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.js +11 -10
- package/dist/plugins/ecosystem/node-tar-writer.js.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.js +21 -20
- package/dist/plugins/ecosystem/node-url-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.js +3 -2
- package/dist/plugins/ecosystem/plugin-acquisition.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
- package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js +2 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js.map +1 -1
- package/dist/plugins/ecosystem/registry.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry.js +35 -32
- package/dist/plugins/ecosystem/registry.js.map +1 -1
- package/dist/plugins/ecosystem/resolver.d.ts.map +1 -1
- package/dist/plugins/ecosystem/resolver.js +3 -2
- package/dist/plugins/ecosystem/resolver.js.map +1 -1
- package/dist/plugins/ecosystem/selection-store.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection-store.js +11 -10
- package/dist/plugins/ecosystem/selection-store.js.map +1 -1
- package/dist/plugins/ecosystem/selection.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection.js +8 -7
- package/dist/plugins/ecosystem/selection.js.map +1 -1
- package/dist/plugins/ecosystem/state.d.ts.map +1 -1
- package/dist/plugins/ecosystem/state.js +24 -23
- package/dist/plugins/ecosystem/state.js.map +1 -1
- package/dist/plugins/ecosystem/updates.d.ts.map +1 -1
- package/dist/plugins/ecosystem/updates.js +5 -4
- package/dist/plugins/ecosystem/updates.js.map +1 -1
- package/dist/plugins/mcp-http.d.ts +0 -17
- package/dist/plugins/mcp-http.d.ts.map +1 -1
- package/dist/plugins/mcp-http.js +30 -7
- package/dist/plugins/mcp-http.js.map +1 -1
- package/dist/plugins/plugin-supervisor.d.ts.map +1 -1
- package/dist/plugins/plugin-supervisor.js +19 -1
- package/dist/plugins/plugin-supervisor.js.map +1 -1
- package/dist/profile/first-roles.d.ts.map +1 -1
- package/dist/profile/first-roles.js +10 -1
- package/dist/profile/first-roles.js.map +1 -1
- package/dist/profile/goal-plugin.d.ts.map +1 -1
- package/dist/profile/goal-plugin.js +24 -5
- package/dist/profile/goal-plugin.js.map +1 -1
- package/dist/profile/identity.d.ts.map +1 -1
- package/dist/profile/identity.js +7 -6
- package/dist/profile/identity.js.map +1 -1
- package/dist/profile/lock.d.ts.map +1 -1
- package/dist/profile/lock.js +15 -1
- package/dist/profile/lock.js.map +1 -1
- package/dist/profile/plan-plugin.d.ts.map +1 -1
- package/dist/profile/plan-plugin.js +26 -13
- package/dist/profile/plan-plugin.js.map +1 -1
- package/dist/profile/plugin-profiles.d.ts.map +1 -1
- package/dist/profile/plugin-profiles.js +2 -1
- package/dist/profile/plugin-profiles.js.map +1 -1
- package/dist/profile/policy-manifest.d.ts.map +1 -1
- package/dist/profile/policy-manifest.js +5 -4
- package/dist/profile/policy-manifest.js.map +1 -1
- package/dist/profile/profile-registry.d.ts +0 -12
- package/dist/profile/profile-registry.d.ts.map +1 -1
- package/dist/profile/profile-registry.js +14 -1
- package/dist/profile/profile-registry.js.map +1 -1
- package/dist/profile/role-catalog.d.ts +0 -1
- package/dist/profile/role-catalog.d.ts.map +1 -1
- package/dist/profile/role-catalog.js +17 -15
- package/dist/profile/role-catalog.js.map +1 -1
- package/dist/profile/role-orchestrator.d.ts.map +1 -1
- package/dist/profile/role-orchestrator.js +8 -7
- package/dist/profile/role-orchestrator.js.map +1 -1
- package/dist/profile/role-runner.d.ts.map +1 -1
- package/dist/profile/role-runner.js +3 -2
- package/dist/profile/role-runner.js.map +1 -1
- package/dist/profile/root-facade.d.ts.map +1 -1
- package/dist/profile/root-facade.js +2 -1
- package/dist/profile/root-facade.js.map +1 -1
- package/dist/profile/skill-discovery-wiring.d.ts.map +1 -1
- package/dist/profile/skill-discovery-wiring.js +7 -2
- package/dist/profile/skill-discovery-wiring.js.map +1 -1
- package/dist/profile/state-store.d.ts.map +1 -1
- package/dist/profile/state-store.js +13 -9
- package/dist/profile/state-store.js.map +1 -1
- package/dist/profile/todo-plugin.d.ts.map +1 -1
- package/dist/profile/todo-plugin.js +9 -4
- package/dist/profile/todo-plugin.js.map +1 -1
- package/dist/profiles/builtin-suites.d.ts +13 -6
- package/dist/profiles/builtin-suites.d.ts.map +1 -1
- package/dist/profiles/builtin-suites.js +15 -6
- package/dist/profiles/builtin-suites.js.map +1 -1
- package/dist/profiles/suite-loader.d.ts +25 -1
- package/dist/profiles/suite-loader.d.ts.map +1 -1
- package/dist/profiles/suite-loader.js +34 -9
- package/dist/profiles/suite-loader.js.map +1 -1
- package/dist/remote/server-entry.d.ts.map +1 -1
- package/dist/remote/server-entry.js +3 -2
- package/dist/remote/server-entry.js.map +1 -1
- package/dist/remote/session-source.d.ts.map +1 -1
- package/dist/remote/session-source.js +8 -4
- package/dist/remote/session-source.js.map +1 -1
- package/dist/share/session-share.d.ts.map +1 -1
- package/dist/share/session-share.js +14 -2
- package/dist/share/session-share.js.map +1 -1
- package/dist/testing/plugin-testkit.d.ts.map +1 -1
- package/dist/testing/plugin-testkit.js +4 -3
- package/dist/testing/plugin-testkit.js.map +1 -1
- package/dist/testing/runtime-delivery-queue.d.ts.map +1 -1
- package/dist/testing/runtime-delivery-queue.js +2 -1
- package/dist/testing/runtime-delivery-queue.js.map +1 -1
- package/dist/testing/session-plugin-testkit.d.ts.map +1 -1
- package/dist/testing/session-plugin-testkit.js +10 -7
- package/dist/testing/session-plugin-testkit.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +2 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +7 -6
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/photon.d.ts +2 -2
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +2 -2
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +9 -8
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +23 -13
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +5 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +1 -3
- package/docs/docs.json +4 -0
- package/docs/index.md +1 -0
- package/docs/keybindings.md +3 -0
- package/docs/mcp.md +103 -0
- package/docs/models.md +14 -22
- package/docs/providers.md +0 -1
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +1 -26
- package/docs/sdk.md +4 -6
- package/docs/settings.md +10 -12
- package/docs/skills.md +1 -9
- package/docs/terminal-setup.md +2 -3
- package/docs/usage.md +7 -6
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/examples/sdk/10-settings.ts +2 -4
- package/examples/sdk/12-full-control.ts +1 -2
- package/package.json +1 -3
- package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
- package/dist/core/extensions/microcompact.d.ts +0 -80
- package/dist/core/extensions/microcompact.d.ts.map +0 -1
- package/dist/core/extensions/microcompact.js +0 -134
- package/dist/core/extensions/microcompact.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,eAAe,EAEf,WAAW,EAGX,gBAAgB,EAEhB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAEhB,MAAM,YAAY,CAAC;AA2KpB,gEAAgE;AAChE,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IACnD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,8FAA8F;IAC9F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,kBAAkB,CAiJrB;AAYD,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C,GAAG,kBAAkB,CA2BrB;AAED,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAC1B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;QACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;KAC5B,EAAE,CAAC;IACJ,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,qFAAqF;IACrF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,mBAAmB,CAgCtB","sourcesContent":["import { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { comparePluginVersionsV1 } from \"./catalog.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostAdapterFactV1,\n\tHostFactsV1,\n\tPluginAdapterManifestV1,\n\tPluginDiagnosticV1,\n\tPluginManifestV1,\n\tPluginResolutionStatusV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n\tResolvedManifestV1,\n\tResolvedPluginV1,\n\tSelectedAdapterV1,\n} from \"./types.ts\";\n\nfunction assertNonEmpty(value: string, label: string): void {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction matchesList<T extends string>(value: string, allowed: readonly T[] | undefined): boolean {\n\treturn (\n\t\tallowed === undefined || (allowed.length > 0 && (allowed.includes(value as T) || allowed.includes(\"any\" as T)))\n\t);\n}\n\nfunction hasAllFeatures(hostFeatures: readonly string[], required: readonly string[] | undefined): string | undefined {\n\tif (required === undefined) return undefined;\n\tconst available = new Set(hostFeatures);\n\treturn required.find((feature) => !available.has(feature));\n}\n\nfunction runtimeVersion(host: HostFactsV1, name: string): string | undefined {\n\treturn host.runtime.find((runtime) => runtime.name === name)?.version;\n}\n\nfunction diagnostic(\n\tcode: PluginDiagnosticV1[\"code\"],\n\tmessage: string,\n\tdetails?: Readonly<Record<string, string>>,\n): PluginDiagnosticV1 {\n\treturn details === undefined ? { code, message } : { code, message, details };\n}\n\nfunction adapterMatches(adapter: PluginAdapterManifestV1, host: HostFactsV1): boolean {\n\treturn (\n\t\tmatchesList(host.os, adapter.os) &&\n\t\tmatchesList(host.arch, adapter.arch) &&\n\t\thasAllFeatures(host.hostFeatures, adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction hostAdapterMatches(\n\tadapter: PluginAdapterManifestV1,\n\thostAdapter: HostAdapterFactV1,\n\thost: HostFactsV1,\n): boolean {\n\treturn (\n\t\thostAdapter.id === adapter.id &&\n\t\thostAdapter.version === adapter.version &&\n\t\tadapterMatches(adapter, host) &&\n\t\t(hostAdapter.os === undefined || hostAdapter.os === host.os || hostAdapter.os === \"any\") &&\n\t\t(hostAdapter.arch === undefined || hostAdapter.arch === host.arch || hostAdapter.arch === \"any\") &&\n\t\thasAllFeatures(hostAdapter.hostFeatures ?? [], adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction selectAdapter(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): { readonly selected?: SelectedAdapterV1; readonly diagnostic?: PluginDiagnosticV1 } | undefined {\n\tconst adapters = manifest.platform?.adapters;\n\tif (adapters === undefined || adapters.length === 0) return undefined;\n\tconst installed = host.adapters ?? [];\n\tconst candidates = adapters\n\t\t.filter((adapter) => adapterMatches(adapter, host))\n\t\t.filter((adapter) => installed.some((hostAdapter) => hostAdapterMatches(adapter, hostAdapter, host)))\n\t\t.sort((left, right) => {\n\t\t\tconst idOrder = left.id.localeCompare(right.id);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(right.version, left.version) : idOrder;\n\t\t});\n\tconst selected = candidates[0];\n\treturn selected === undefined\n\t\t? {\n\t\t\t\tdiagnostic: diagnostic(\n\t\t\t\t\t\"adapter-unavailable\",\n\t\t\t\t\t`No installed adapter satisfies plugin ${manifest.id} on ${host.os}/${host.arch}`,\n\t\t\t\t),\n\t\t\t}\n\t\t: { selected: { id: selected.id, version: selected.version } };\n}\n\nfunction normalizeRefs(refs: readonly CapabilityRefV1[] | undefined): readonly CapabilityRefV1[] {\n\tconst normalized = [...(refs ?? [])].map((ref) => {\n\t\tassertNonEmpty(ref.id, \"capability id\");\n\t\tif (!Number.isSafeInteger(ref.version) || ref.version < 1) {\n\t\t\tthrow new Error(`capability ${ref.id} version must be a positive safe integer`);\n\t\t}\n\t\treturn { id: ref.id, version: ref.version };\n\t});\n\tnormalized.sort((left, right) =>\n\t\tleft.id === right.id ? left.version - right.version : left.id.localeCompare(right.id),\n\t);\n\treturn normalized;\n}\n\nfunction hasCapability(ref: CapabilityRefV1, available: readonly CapabilityRefV1[]): boolean {\n\treturn available.some((candidate) => candidate.id === ref.id && candidate.version === ref.version);\n}\n\nfunction resolvePlatform(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): {\n\treadonly status?: PluginResolutionStatusV1;\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n\treadonly selectedAdapter?: SelectedAdapterV1;\n} {\n\tconst platform = manifest.platform;\n\tif (platform === undefined) return { diagnostics: [] };\n\tif (!matchesList(host.os, platform.os)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Plugin ${manifest.id} does not support host OS ${host.os}`)],\n\t\t};\n\t}\n\tif (!matchesList(host.arch, platform.arch)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"unsupported-architecture\",\n\t\t\t\t\t`Plugin ${manifest.id} does not support host architecture ${host.arch}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst missingFeature = hasAllFeatures(host.hostFeatures, platform.hostFeatures);\n\tif (missingFeature !== undefined) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"missing-host-feature\", `Host feature is missing: ${missingFeature}`, {\n\t\t\t\t\tfeature: missingFeature,\n\t\t\t\t}),\n\t\t\t],\n\t\t};\n\t}\n\tfor (const constraint of platform.runtime ?? []) {\n\t\tconst actual = runtimeVersion(host, constraint.name);\n\t\tif (actual === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\"missing-runtime\", `Required runtime is missing: ${constraint.name}`, {\n\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t(constraint.minVersion !== undefined && comparePluginVersionsV1(actual, constraint.minVersion) < 0) ||\n\t\t\t(constraint.maxVersion !== undefined && comparePluginVersionsV1(actual, constraint.maxVersion) > 0)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\"runtime-version-incompatible\",\n\t\t\t\t\t\t`Runtime ${constraint.name}@${actual} is outside the supported range`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t\t\tactual,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\tconst selected = selectAdapter(manifest, host);\n\tif (selected?.diagnostic !== undefined)\n\t\treturn { status: \"dependency-unavailable\", diagnostics: [selected.diagnostic] };\n\treturn { diagnostics: [], selectedAdapter: selected?.selected };\n}\n\n/** Resolve one installed plugin against concrete host facts. */\nexport function resolvePluginCompatibilityV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly disabled?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version; when omitted, the manifest min/maxHostVersion range is not checked. */\n\treadonly hostVersion?: string;\n}): PluginResolutionV1 {\n\tconst { manifest, host } = input;\n\tassertNonEmpty(manifest.id, \"plugin id\");\n\tassertNonEmpty(manifest.pluginVersion, \"pluginVersion\");\n\tassertNonEmpty(manifest.apiVersion, \"apiVersion\");\n\tconst required = input.required ?? true;\n\tif (input.disabled === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"disabled\",\n\t\t\tdiagnostics: [diagnostic(\"plugin-disabled\", `Plugin ${manifest.id} is disabled`)],\n\t\t};\n\t}\n\tif (manifest.testOnly === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"test-only-plugin\", `Plugin ${manifest.id} is test-only and cannot be selected for production`),\n\t\t\t],\n\t\t};\n\t}\n\tif (![\"windows\", \"macos\", \"linux\"].includes(host.os)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Host OS is unknown: ${host.os}`)],\n\t\t};\n\t}\n\tif (![\"x64\", \"arm64\"].includes(host.arch)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-architecture\", `Host architecture is unknown: ${host.arch}`)],\n\t\t};\n\t}\n\tif (manifest.minHostVersion !== undefined || manifest.maxHostVersion !== undefined) {\n\t\tif (manifest.minHostVersion !== undefined) assertNonEmpty(manifest.minHostVersion, \"minHostVersion\");\n\t\tif (manifest.maxHostVersion !== undefined) assertNonEmpty(manifest.maxHostVersion, \"maxHostVersion\");\n\t\tif (input.hostVersion !== undefined) {\n\t\t\tconst belowFloor =\n\t\t\t\tmanifest.minHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.minHostVersion) < 0;\n\t\t\tconst aboveCeiling =\n\t\t\t\tmanifest.maxHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.maxHostVersion) > 0;\n\t\t\tif (belowFloor || aboveCeiling) {\n\t\t\t\t// The declared compatibility range, rendered human-readably\n\t\t\t\t// (e.g. \">= 1.0.0 and <= 2.0.0\"); a single bound keeps the\n\t\t\t\t// floor-only shape the diagnostics contract pins.\n\t\t\t\tconst requiredRange = [\n\t\t\t\t\tmanifest.minHostVersion !== undefined ? `>= ${manifest.minHostVersion}` : undefined,\n\t\t\t\t\tmanifest.maxHostVersion !== undefined ? `<= ${manifest.maxHostVersion}` : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((bound) => bound !== undefined)\n\t\t\t\t\t.join(\" and \");\n\t\t\t\tconst guidance = belowFloor\n\t\t\t\t\t? `Upgrade the host to at least ${manifest.minHostVersion} to load this plugin.`\n\t\t\t\t\t: `Install a plugin version whose declared host range includes ${input.hostVersion}.`;\n\t\t\t\treturn {\n\t\t\t\t\tpluginId: manifest.id,\n\t\t\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\t\t\trequired,\n\t\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\t\"host-version-incompatible\",\n\t\t\t\t\t\t\t`Plugin ${manifest.id} requires host version ${requiredRange}, but the host is ${input.hostVersion}. ${guidance}`,\n\t\t\t\t\t\t\t{ required: requiredRange, actual: input.hostVersion },\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (manifest.apiVersion !== host.apiVersion) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"version-incompatible\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"api-version-incompatible\",\n\t\t\t\t\t`Plugin requires API ${manifest.apiVersion}, host provides ${host.apiVersion}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst platform = resolvePlatform(manifest, host);\n\tif (platform.status !== undefined) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: platform.status,\n\t\t\tdiagnostics: platform.diagnostics,\n\t\t};\n\t}\n\tconst available = input.availableCapabilities ?? [];\n\tconst dependencyDiagnostics: PluginDiagnosticV1[] = [];\n\tfor (const requirement of manifest.requires ?? []) {\n\t\tif (hasCapability(requirement, available)) continue;\n\t\tdependencyDiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\trequirement.optional === true ? \"optional-capability-unavailable\" : \"missing-capability\",\n\t\t\t\t`Capability ${requirement.id}@${requirement.version} is unavailable`,\n\t\t\t\t{ capability: requirement.id, version: String(requirement.version) },\n\t\t\t),\n\t\t);\n\t}\n\tconst hasRequiredMissing = dependencyDiagnostics.some((item) => item.code === \"missing-capability\");\n\tif (hasRequiredMissing) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"dependency-unavailable\",\n\t\t\tdiagnostics: dependencyDiagnostics,\n\t\t};\n\t}\n\tconst capabilityRefs = normalizeRefs(manifest.capabilityRefs);\n\tconst resolved: ResolvedPluginV1 = {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tcapabilityRefs,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n\treturn {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\trequired,\n\t\tstatus: \"installed-ready\",\n\t\tdiagnostics: dependencyDiagnostics,\n\t\tresolved,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n}\n\nfunction compareResolvedPlugins(left: ResolvedPluginV1, right: ResolvedPluginV1): number {\n\treturn left.pluginId === right.pluginId\n\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t: left.pluginId.localeCompare(right.pluginId);\n}\n\nfunction compareRefs(left: CapabilityRefV1, right: CapabilityRefV1): number {\n\treturn left.id === right.id ? left.version - right.version : left.id.localeCompare(right.id);\n}\n\n/** Build an order-independent identity including adapter and capability refs. */\nexport function buildResolvedManifestV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly ResolvedPluginV1[];\n}): ResolvedManifestV1 {\n\tassertNonEmpty(input.profileId, \"profileId\");\n\tassertNonEmpty(input.profileVersion, \"profileVersion\");\n\tconst plugins = [...input.plugins]\n\t\t.map((plugin) => ({\n\t\t\tpluginId: plugin.pluginId,\n\t\t\tpluginVersion: plugin.pluginVersion,\n\t\t\tcapabilityRefs: normalizeRefs(plugin.capabilityRefs),\n\t\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: { ...plugin.selectedAdapter } }),\n\t\t}))\n\t\t.sort(compareResolvedPlugins);\n\tconst capabilityRefs = plugins\n\t\t.flatMap((plugin) => plugin.capabilityRefs)\n\t\t.sort(compareRefs)\n\t\t.filter(\n\t\t\t(ref, index, all) => index === 0 || all[index - 1]!.id !== ref.id || all[index - 1]!.version !== ref.version,\n\t\t);\n\tconst digestInput = { profileId: input.profileId, profileVersion: input.profileVersion, plugins, capabilityRefs };\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tplugins: Object.freeze(\n\t\t\tplugins.map((plugin) => Object.freeze({ ...plugin, capabilityRefs: Object.freeze(plugin.capabilityRefs) })),\n\t\t),\n\t\tcapabilityRefs: Object.freeze(capabilityRefs),\n\t\tmanifestDigest: stableJsonDigest(digestInput as unknown as Parameters<typeof stableJsonDigest>[0]),\n\t});\n}\n\n/** Resolve all plugins in a Profile; optional unavailable plugins do not block startup. */\nexport function resolvePluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly {\n\t\treadonly manifest: PluginManifestV1;\n\t\treadonly required?: boolean;\n\t\treadonly disabled?: boolean;\n\t}[];\n\treadonly host: HostFactsV1;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version, forwarded to each plugin's min/maxHostVersion range check. */\n\treadonly hostVersion?: string;\n}): ProfileResolutionV1 {\n\tconst plugins = input.plugins\n\t\t.map((candidate) =>\n\t\t\tresolvePluginCompatibilityV1({\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t\thost: input.host,\n\t\t\t\trequired: candidate.required,\n\t\t\t\tdisabled: candidate.disabled,\n\t\t\t\tavailableCapabilities: input.availableCapabilities,\n\t\t\t\thostVersion: input.hostVersion,\n\t\t\t}),\n\t\t)\n\t\t.sort((left, right) =>\n\t\t\tleft.pluginId === right.pluginId\n\t\t\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t\t\t: left.pluginId.localeCompare(right.pluginId),\n\t\t);\n\tconst diagnostics = plugins.flatMap((plugin) => plugin.diagnostics);\n\tconst blocked = plugins.some((plugin) => plugin.required && plugin.status !== \"installed-ready\");\n\tconst resolvedPlugins = plugins.flatMap((plugin) => (plugin.resolved === undefined ? [] : [plugin.resolved]));\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tstatus: blocked ? \"blocked\" : \"ready\",\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\tresolvedManifest: buildResolvedManifestV1({\n\t\t\tprofileId: input.profileId,\n\t\t\tprofileVersion: input.profileVersion,\n\t\t\tplugins: resolvedPlugins,\n\t\t}),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,eAAe,EAEf,WAAW,EAGX,gBAAgB,EAEhB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAEhB,MAAM,YAAY,CAAC;AA4KpB,gEAAgE;AAChE,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IACnD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,8FAA8F;IAC9F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,kBAAkB,CAiJrB;AAYD,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C,GAAG,kBAAkB,CA2BrB;AAED,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAC1B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;QACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;KAC5B,EAAE,CAAC;IACJ,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,qFAAqF;IACrF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,mBAAmB,CAgCtB","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { comparePluginVersionsV1 } from \"./catalog.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostAdapterFactV1,\n\tHostFactsV1,\n\tPluginAdapterManifestV1,\n\tPluginDiagnosticV1,\n\tPluginManifestV1,\n\tPluginResolutionStatusV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n\tResolvedManifestV1,\n\tResolvedPluginV1,\n\tSelectedAdapterV1,\n} from \"./types.ts\";\n\nfunction assertNonEmpty(value: string, label: string): void {\n\tif (typeof value !== \"string\" || value.trim().length === 0)\n\t\tthrow new Error(t(\"{label} must be a non-empty string\", { label }));\n}\n\nfunction matchesList<T extends string>(value: string, allowed: readonly T[] | undefined): boolean {\n\treturn (\n\t\tallowed === undefined || (allowed.length > 0 && (allowed.includes(value as T) || allowed.includes(\"any\" as T)))\n\t);\n}\n\nfunction hasAllFeatures(hostFeatures: readonly string[], required: readonly string[] | undefined): string | undefined {\n\tif (required === undefined) return undefined;\n\tconst available = new Set(hostFeatures);\n\treturn required.find((feature) => !available.has(feature));\n}\n\nfunction runtimeVersion(host: HostFactsV1, name: string): string | undefined {\n\treturn host.runtime.find((runtime) => runtime.name === name)?.version;\n}\n\nfunction diagnostic(\n\tcode: PluginDiagnosticV1[\"code\"],\n\tmessage: string,\n\tdetails?: Readonly<Record<string, string>>,\n): PluginDiagnosticV1 {\n\treturn details === undefined ? { code, message } : { code, message, details };\n}\n\nfunction adapterMatches(adapter: PluginAdapterManifestV1, host: HostFactsV1): boolean {\n\treturn (\n\t\tmatchesList(host.os, adapter.os) &&\n\t\tmatchesList(host.arch, adapter.arch) &&\n\t\thasAllFeatures(host.hostFeatures, adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction hostAdapterMatches(\n\tadapter: PluginAdapterManifestV1,\n\thostAdapter: HostAdapterFactV1,\n\thost: HostFactsV1,\n): boolean {\n\treturn (\n\t\thostAdapter.id === adapter.id &&\n\t\thostAdapter.version === adapter.version &&\n\t\tadapterMatches(adapter, host) &&\n\t\t(hostAdapter.os === undefined || hostAdapter.os === host.os || hostAdapter.os === \"any\") &&\n\t\t(hostAdapter.arch === undefined || hostAdapter.arch === host.arch || hostAdapter.arch === \"any\") &&\n\t\thasAllFeatures(hostAdapter.hostFeatures ?? [], adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction selectAdapter(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): { readonly selected?: SelectedAdapterV1; readonly diagnostic?: PluginDiagnosticV1 } | undefined {\n\tconst adapters = manifest.platform?.adapters;\n\tif (adapters === undefined || adapters.length === 0) return undefined;\n\tconst installed = host.adapters ?? [];\n\tconst candidates = adapters\n\t\t.filter((adapter) => adapterMatches(adapter, host))\n\t\t.filter((adapter) => installed.some((hostAdapter) => hostAdapterMatches(adapter, hostAdapter, host)))\n\t\t.sort((left, right) => {\n\t\t\tconst idOrder = left.id.localeCompare(right.id);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(right.version, left.version) : idOrder;\n\t\t});\n\tconst selected = candidates[0];\n\treturn selected === undefined\n\t\t? {\n\t\t\t\tdiagnostic: diagnostic(\n\t\t\t\t\t\"adapter-unavailable\",\n\t\t\t\t\t`No installed adapter satisfies plugin ${manifest.id} on ${host.os}/${host.arch}`,\n\t\t\t\t),\n\t\t\t}\n\t\t: { selected: { id: selected.id, version: selected.version } };\n}\n\nfunction normalizeRefs(refs: readonly CapabilityRefV1[] | undefined): readonly CapabilityRefV1[] {\n\tconst normalized = [...(refs ?? [])].map((ref) => {\n\t\tassertNonEmpty(ref.id, \"capability id\");\n\t\tif (!Number.isSafeInteger(ref.version) || ref.version < 1) {\n\t\t\tthrow new Error(t(\"capability {id} version must be a positive safe integer\", { id: ref.id }));\n\t\t}\n\t\treturn { id: ref.id, version: ref.version };\n\t});\n\tnormalized.sort((left, right) =>\n\t\tleft.id === right.id ? left.version - right.version : left.id.localeCompare(right.id),\n\t);\n\treturn normalized;\n}\n\nfunction hasCapability(ref: CapabilityRefV1, available: readonly CapabilityRefV1[]): boolean {\n\treturn available.some((candidate) => candidate.id === ref.id && candidate.version === ref.version);\n}\n\nfunction resolvePlatform(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): {\n\treadonly status?: PluginResolutionStatusV1;\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n\treadonly selectedAdapter?: SelectedAdapterV1;\n} {\n\tconst platform = manifest.platform;\n\tif (platform === undefined) return { diagnostics: [] };\n\tif (!matchesList(host.os, platform.os)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Plugin ${manifest.id} does not support host OS ${host.os}`)],\n\t\t};\n\t}\n\tif (!matchesList(host.arch, platform.arch)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"unsupported-architecture\",\n\t\t\t\t\t`Plugin ${manifest.id} does not support host architecture ${host.arch}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst missingFeature = hasAllFeatures(host.hostFeatures, platform.hostFeatures);\n\tif (missingFeature !== undefined) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"missing-host-feature\", `Host feature is missing: ${missingFeature}`, {\n\t\t\t\t\tfeature: missingFeature,\n\t\t\t\t}),\n\t\t\t],\n\t\t};\n\t}\n\tfor (const constraint of platform.runtime ?? []) {\n\t\tconst actual = runtimeVersion(host, constraint.name);\n\t\tif (actual === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\"missing-runtime\", `Required runtime is missing: ${constraint.name}`, {\n\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t(constraint.minVersion !== undefined && comparePluginVersionsV1(actual, constraint.minVersion) < 0) ||\n\t\t\t(constraint.maxVersion !== undefined && comparePluginVersionsV1(actual, constraint.maxVersion) > 0)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\"runtime-version-incompatible\",\n\t\t\t\t\t\t`Runtime ${constraint.name}@${actual} is outside the supported range`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t\t\tactual,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\tconst selected = selectAdapter(manifest, host);\n\tif (selected?.diagnostic !== undefined)\n\t\treturn { status: \"dependency-unavailable\", diagnostics: [selected.diagnostic] };\n\treturn { diagnostics: [], selectedAdapter: selected?.selected };\n}\n\n/** Resolve one installed plugin against concrete host facts. */\nexport function resolvePluginCompatibilityV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly disabled?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version; when omitted, the manifest min/maxHostVersion range is not checked. */\n\treadonly hostVersion?: string;\n}): PluginResolutionV1 {\n\tconst { manifest, host } = input;\n\tassertNonEmpty(manifest.id, \"plugin id\");\n\tassertNonEmpty(manifest.pluginVersion, \"pluginVersion\");\n\tassertNonEmpty(manifest.apiVersion, \"apiVersion\");\n\tconst required = input.required ?? true;\n\tif (input.disabled === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"disabled\",\n\t\t\tdiagnostics: [diagnostic(\"plugin-disabled\", `Plugin ${manifest.id} is disabled`)],\n\t\t};\n\t}\n\tif (manifest.testOnly === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"test-only-plugin\", `Plugin ${manifest.id} is test-only and cannot be selected for production`),\n\t\t\t],\n\t\t};\n\t}\n\tif (![\"windows\", \"macos\", \"linux\"].includes(host.os)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Host OS is unknown: ${host.os}`)],\n\t\t};\n\t}\n\tif (![\"x64\", \"arm64\"].includes(host.arch)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-architecture\", `Host architecture is unknown: ${host.arch}`)],\n\t\t};\n\t}\n\tif (manifest.minHostVersion !== undefined || manifest.maxHostVersion !== undefined) {\n\t\tif (manifest.minHostVersion !== undefined) assertNonEmpty(manifest.minHostVersion, \"minHostVersion\");\n\t\tif (manifest.maxHostVersion !== undefined) assertNonEmpty(manifest.maxHostVersion, \"maxHostVersion\");\n\t\tif (input.hostVersion !== undefined) {\n\t\t\tconst belowFloor =\n\t\t\t\tmanifest.minHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.minHostVersion) < 0;\n\t\t\tconst aboveCeiling =\n\t\t\t\tmanifest.maxHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.maxHostVersion) > 0;\n\t\t\tif (belowFloor || aboveCeiling) {\n\t\t\t\t// The declared compatibility range, rendered human-readably\n\t\t\t\t// (e.g. \">= 1.0.0 and <= 2.0.0\"); a single bound keeps the\n\t\t\t\t// floor-only shape the diagnostics contract pins.\n\t\t\t\tconst requiredRange = [\n\t\t\t\t\tmanifest.minHostVersion !== undefined ? `>= ${manifest.minHostVersion}` : undefined,\n\t\t\t\t\tmanifest.maxHostVersion !== undefined ? `<= ${manifest.maxHostVersion}` : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((bound) => bound !== undefined)\n\t\t\t\t\t.join(\" and \");\n\t\t\t\tconst guidance = belowFloor\n\t\t\t\t\t? `Upgrade the host to at least ${manifest.minHostVersion} to load this plugin.`\n\t\t\t\t\t: `Install a plugin version whose declared host range includes ${input.hostVersion}.`;\n\t\t\t\treturn {\n\t\t\t\t\tpluginId: manifest.id,\n\t\t\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\t\t\trequired,\n\t\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\t\"host-version-incompatible\",\n\t\t\t\t\t\t\t`Plugin ${manifest.id} requires host version ${requiredRange}, but the host is ${input.hostVersion}. ${guidance}`,\n\t\t\t\t\t\t\t{ required: requiredRange, actual: input.hostVersion },\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (manifest.apiVersion !== host.apiVersion) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"version-incompatible\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"api-version-incompatible\",\n\t\t\t\t\t`Plugin requires API ${manifest.apiVersion}, host provides ${host.apiVersion}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst platform = resolvePlatform(manifest, host);\n\tif (platform.status !== undefined) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: platform.status,\n\t\t\tdiagnostics: platform.diagnostics,\n\t\t};\n\t}\n\tconst available = input.availableCapabilities ?? [];\n\tconst dependencyDiagnostics: PluginDiagnosticV1[] = [];\n\tfor (const requirement of manifest.requires ?? []) {\n\t\tif (hasCapability(requirement, available)) continue;\n\t\tdependencyDiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\trequirement.optional === true ? \"optional-capability-unavailable\" : \"missing-capability\",\n\t\t\t\t`Capability ${requirement.id}@${requirement.version} is unavailable`,\n\t\t\t\t{ capability: requirement.id, version: String(requirement.version) },\n\t\t\t),\n\t\t);\n\t}\n\tconst hasRequiredMissing = dependencyDiagnostics.some((item) => item.code === \"missing-capability\");\n\tif (hasRequiredMissing) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"dependency-unavailable\",\n\t\t\tdiagnostics: dependencyDiagnostics,\n\t\t};\n\t}\n\tconst capabilityRefs = normalizeRefs(manifest.capabilityRefs);\n\tconst resolved: ResolvedPluginV1 = {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tcapabilityRefs,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n\treturn {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\trequired,\n\t\tstatus: \"installed-ready\",\n\t\tdiagnostics: dependencyDiagnostics,\n\t\tresolved,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n}\n\nfunction compareResolvedPlugins(left: ResolvedPluginV1, right: ResolvedPluginV1): number {\n\treturn left.pluginId === right.pluginId\n\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t: left.pluginId.localeCompare(right.pluginId);\n}\n\nfunction compareRefs(left: CapabilityRefV1, right: CapabilityRefV1): number {\n\treturn left.id === right.id ? left.version - right.version : left.id.localeCompare(right.id);\n}\n\n/** Build an order-independent identity including adapter and capability refs. */\nexport function buildResolvedManifestV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly ResolvedPluginV1[];\n}): ResolvedManifestV1 {\n\tassertNonEmpty(input.profileId, \"profileId\");\n\tassertNonEmpty(input.profileVersion, \"profileVersion\");\n\tconst plugins = [...input.plugins]\n\t\t.map((plugin) => ({\n\t\t\tpluginId: plugin.pluginId,\n\t\t\tpluginVersion: plugin.pluginVersion,\n\t\t\tcapabilityRefs: normalizeRefs(plugin.capabilityRefs),\n\t\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: { ...plugin.selectedAdapter } }),\n\t\t}))\n\t\t.sort(compareResolvedPlugins);\n\tconst capabilityRefs = plugins\n\t\t.flatMap((plugin) => plugin.capabilityRefs)\n\t\t.sort(compareRefs)\n\t\t.filter(\n\t\t\t(ref, index, all) => index === 0 || all[index - 1]!.id !== ref.id || all[index - 1]!.version !== ref.version,\n\t\t);\n\tconst digestInput = { profileId: input.profileId, profileVersion: input.profileVersion, plugins, capabilityRefs };\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tplugins: Object.freeze(\n\t\t\tplugins.map((plugin) => Object.freeze({ ...plugin, capabilityRefs: Object.freeze(plugin.capabilityRefs) })),\n\t\t),\n\t\tcapabilityRefs: Object.freeze(capabilityRefs),\n\t\tmanifestDigest: stableJsonDigest(digestInput as unknown as Parameters<typeof stableJsonDigest>[0]),\n\t});\n}\n\n/** Resolve all plugins in a Profile; optional unavailable plugins do not block startup. */\nexport function resolvePluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly {\n\t\treadonly manifest: PluginManifestV1;\n\t\treadonly required?: boolean;\n\t\treadonly disabled?: boolean;\n\t}[];\n\treadonly host: HostFactsV1;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version, forwarded to each plugin's min/maxHostVersion range check. */\n\treadonly hostVersion?: string;\n}): ProfileResolutionV1 {\n\tconst plugins = input.plugins\n\t\t.map((candidate) =>\n\t\t\tresolvePluginCompatibilityV1({\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t\thost: input.host,\n\t\t\t\trequired: candidate.required,\n\t\t\t\tdisabled: candidate.disabled,\n\t\t\t\tavailableCapabilities: input.availableCapabilities,\n\t\t\t\thostVersion: input.hostVersion,\n\t\t\t}),\n\t\t)\n\t\t.sort((left, right) =>\n\t\t\tleft.pluginId === right.pluginId\n\t\t\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t\t\t: left.pluginId.localeCompare(right.pluginId),\n\t\t);\n\tconst diagnostics = plugins.flatMap((plugin) => plugin.diagnostics);\n\tconst blocked = plugins.some((plugin) => plugin.required && plugin.status !== \"installed-ready\");\n\tconst resolvedPlugins = plugins.flatMap((plugin) => (plugin.resolved === undefined ? [] : [plugin.resolved]));\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tstatus: blocked ? \"blocked\" : \"ready\",\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\tresolvedManifest: buildResolvedManifestV1({\n\t\t\tprofileId: input.profileId,\n\t\t\tprofileVersion: input.profileVersion,\n\t\t\tplugins: resolvedPlugins,\n\t\t}),\n\t});\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { t } from "../../core/i18n/index.js";
|
|
1
2
|
import { stableJsonDigest } from "../../profile/identity.js";
|
|
2
3
|
import { comparePluginVersionsV1 } from "./catalog.js";
|
|
3
4
|
function assertNonEmpty(value, label) {
|
|
4
5
|
if (typeof value !== "string" || value.trim().length === 0)
|
|
5
|
-
throw new Error(
|
|
6
|
+
throw new Error(t("{label} must be a non-empty string", { label }));
|
|
6
7
|
}
|
|
7
8
|
function matchesList(value, allowed) {
|
|
8
9
|
return (allowed === undefined || (allowed.length > 0 && (allowed.includes(value) || allowed.includes("any"))));
|
|
@@ -55,7 +56,7 @@ function normalizeRefs(refs) {
|
|
|
55
56
|
const normalized = [...(refs ?? [])].map((ref) => {
|
|
56
57
|
assertNonEmpty(ref.id, "capability id");
|
|
57
58
|
if (!Number.isSafeInteger(ref.version) || ref.version < 1) {
|
|
58
|
-
throw new Error(
|
|
59
|
+
throw new Error(t("capability {id} version must be a positive safe integer", { id: ref.id }));
|
|
59
60
|
}
|
|
60
61
|
return { id: ref.id, version: ref.version };
|
|
61
62
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { comparePluginVersionsV1 } from \"./catalog.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostAdapterFactV1,\n\tHostFactsV1,\n\tPluginAdapterManifestV1,\n\tPluginDiagnosticV1,\n\tPluginManifestV1,\n\tPluginResolutionStatusV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n\tResolvedManifestV1,\n\tResolvedPluginV1,\n\tSelectedAdapterV1,\n} from \"./types.ts\";\n\nfunction assertNonEmpty(value: string, label: string): void {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction matchesList<T extends string>(value: string, allowed: readonly T[] | undefined): boolean {\n\treturn (\n\t\tallowed === undefined || (allowed.length > 0 && (allowed.includes(value as T) || allowed.includes(\"any\" as T)))\n\t);\n}\n\nfunction hasAllFeatures(hostFeatures: readonly string[], required: readonly string[] | undefined): string | undefined {\n\tif (required === undefined) return undefined;\n\tconst available = new Set(hostFeatures);\n\treturn required.find((feature) => !available.has(feature));\n}\n\nfunction runtimeVersion(host: HostFactsV1, name: string): string | undefined {\n\treturn host.runtime.find((runtime) => runtime.name === name)?.version;\n}\n\nfunction diagnostic(\n\tcode: PluginDiagnosticV1[\"code\"],\n\tmessage: string,\n\tdetails?: Readonly<Record<string, string>>,\n): PluginDiagnosticV1 {\n\treturn details === undefined ? { code, message } : { code, message, details };\n}\n\nfunction adapterMatches(adapter: PluginAdapterManifestV1, host: HostFactsV1): boolean {\n\treturn (\n\t\tmatchesList(host.os, adapter.os) &&\n\t\tmatchesList(host.arch, adapter.arch) &&\n\t\thasAllFeatures(host.hostFeatures, adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction hostAdapterMatches(\n\tadapter: PluginAdapterManifestV1,\n\thostAdapter: HostAdapterFactV1,\n\thost: HostFactsV1,\n): boolean {\n\treturn (\n\t\thostAdapter.id === adapter.id &&\n\t\thostAdapter.version === adapter.version &&\n\t\tadapterMatches(adapter, host) &&\n\t\t(hostAdapter.os === undefined || hostAdapter.os === host.os || hostAdapter.os === \"any\") &&\n\t\t(hostAdapter.arch === undefined || hostAdapter.arch === host.arch || hostAdapter.arch === \"any\") &&\n\t\thasAllFeatures(hostAdapter.hostFeatures ?? [], adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction selectAdapter(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): { readonly selected?: SelectedAdapterV1; readonly diagnostic?: PluginDiagnosticV1 } | undefined {\n\tconst adapters = manifest.platform?.adapters;\n\tif (adapters === undefined || adapters.length === 0) return undefined;\n\tconst installed = host.adapters ?? [];\n\tconst candidates = adapters\n\t\t.filter((adapter) => adapterMatches(adapter, host))\n\t\t.filter((adapter) => installed.some((hostAdapter) => hostAdapterMatches(adapter, hostAdapter, host)))\n\t\t.sort((left, right) => {\n\t\t\tconst idOrder = left.id.localeCompare(right.id);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(right.version, left.version) : idOrder;\n\t\t});\n\tconst selected = candidates[0];\n\treturn selected === undefined\n\t\t? {\n\t\t\t\tdiagnostic: diagnostic(\n\t\t\t\t\t\"adapter-unavailable\",\n\t\t\t\t\t`No installed adapter satisfies plugin ${manifest.id} on ${host.os}/${host.arch}`,\n\t\t\t\t),\n\t\t\t}\n\t\t: { selected: { id: selected.id, version: selected.version } };\n}\n\nfunction normalizeRefs(refs: readonly CapabilityRefV1[] | undefined): readonly CapabilityRefV1[] {\n\tconst normalized = [...(refs ?? [])].map((ref) => {\n\t\tassertNonEmpty(ref.id, \"capability id\");\n\t\tif (!Number.isSafeInteger(ref.version) || ref.version < 1) {\n\t\t\tthrow new Error(`capability ${ref.id} version must be a positive safe integer`);\n\t\t}\n\t\treturn { id: ref.id, version: ref.version };\n\t});\n\tnormalized.sort((left, right) =>\n\t\tleft.id === right.id ? left.version - right.version : left.id.localeCompare(right.id),\n\t);\n\treturn normalized;\n}\n\nfunction hasCapability(ref: CapabilityRefV1, available: readonly CapabilityRefV1[]): boolean {\n\treturn available.some((candidate) => candidate.id === ref.id && candidate.version === ref.version);\n}\n\nfunction resolvePlatform(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): {\n\treadonly status?: PluginResolutionStatusV1;\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n\treadonly selectedAdapter?: SelectedAdapterV1;\n} {\n\tconst platform = manifest.platform;\n\tif (platform === undefined) return { diagnostics: [] };\n\tif (!matchesList(host.os, platform.os)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Plugin ${manifest.id} does not support host OS ${host.os}`)],\n\t\t};\n\t}\n\tif (!matchesList(host.arch, platform.arch)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"unsupported-architecture\",\n\t\t\t\t\t`Plugin ${manifest.id} does not support host architecture ${host.arch}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst missingFeature = hasAllFeatures(host.hostFeatures, platform.hostFeatures);\n\tif (missingFeature !== undefined) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"missing-host-feature\", `Host feature is missing: ${missingFeature}`, {\n\t\t\t\t\tfeature: missingFeature,\n\t\t\t\t}),\n\t\t\t],\n\t\t};\n\t}\n\tfor (const constraint of platform.runtime ?? []) {\n\t\tconst actual = runtimeVersion(host, constraint.name);\n\t\tif (actual === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\"missing-runtime\", `Required runtime is missing: ${constraint.name}`, {\n\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t(constraint.minVersion !== undefined && comparePluginVersionsV1(actual, constraint.minVersion) < 0) ||\n\t\t\t(constraint.maxVersion !== undefined && comparePluginVersionsV1(actual, constraint.maxVersion) > 0)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\"runtime-version-incompatible\",\n\t\t\t\t\t\t`Runtime ${constraint.name}@${actual} is outside the supported range`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t\t\tactual,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\tconst selected = selectAdapter(manifest, host);\n\tif (selected?.diagnostic !== undefined)\n\t\treturn { status: \"dependency-unavailable\", diagnostics: [selected.diagnostic] };\n\treturn { diagnostics: [], selectedAdapter: selected?.selected };\n}\n\n/** Resolve one installed plugin against concrete host facts. */\nexport function resolvePluginCompatibilityV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly disabled?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version; when omitted, the manifest min/maxHostVersion range is not checked. */\n\treadonly hostVersion?: string;\n}): PluginResolutionV1 {\n\tconst { manifest, host } = input;\n\tassertNonEmpty(manifest.id, \"plugin id\");\n\tassertNonEmpty(manifest.pluginVersion, \"pluginVersion\");\n\tassertNonEmpty(manifest.apiVersion, \"apiVersion\");\n\tconst required = input.required ?? true;\n\tif (input.disabled === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"disabled\",\n\t\t\tdiagnostics: [diagnostic(\"plugin-disabled\", `Plugin ${manifest.id} is disabled`)],\n\t\t};\n\t}\n\tif (manifest.testOnly === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"test-only-plugin\", `Plugin ${manifest.id} is test-only and cannot be selected for production`),\n\t\t\t],\n\t\t};\n\t}\n\tif (![\"windows\", \"macos\", \"linux\"].includes(host.os)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Host OS is unknown: ${host.os}`)],\n\t\t};\n\t}\n\tif (![\"x64\", \"arm64\"].includes(host.arch)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-architecture\", `Host architecture is unknown: ${host.arch}`)],\n\t\t};\n\t}\n\tif (manifest.minHostVersion !== undefined || manifest.maxHostVersion !== undefined) {\n\t\tif (manifest.minHostVersion !== undefined) assertNonEmpty(manifest.minHostVersion, \"minHostVersion\");\n\t\tif (manifest.maxHostVersion !== undefined) assertNonEmpty(manifest.maxHostVersion, \"maxHostVersion\");\n\t\tif (input.hostVersion !== undefined) {\n\t\t\tconst belowFloor =\n\t\t\t\tmanifest.minHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.minHostVersion) < 0;\n\t\t\tconst aboveCeiling =\n\t\t\t\tmanifest.maxHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.maxHostVersion) > 0;\n\t\t\tif (belowFloor || aboveCeiling) {\n\t\t\t\t// The declared compatibility range, rendered human-readably\n\t\t\t\t// (e.g. \">= 1.0.0 and <= 2.0.0\"); a single bound keeps the\n\t\t\t\t// floor-only shape the diagnostics contract pins.\n\t\t\t\tconst requiredRange = [\n\t\t\t\t\tmanifest.minHostVersion !== undefined ? `>= ${manifest.minHostVersion}` : undefined,\n\t\t\t\t\tmanifest.maxHostVersion !== undefined ? `<= ${manifest.maxHostVersion}` : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((bound) => bound !== undefined)\n\t\t\t\t\t.join(\" and \");\n\t\t\t\tconst guidance = belowFloor\n\t\t\t\t\t? `Upgrade the host to at least ${manifest.minHostVersion} to load this plugin.`\n\t\t\t\t\t: `Install a plugin version whose declared host range includes ${input.hostVersion}.`;\n\t\t\t\treturn {\n\t\t\t\t\tpluginId: manifest.id,\n\t\t\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\t\t\trequired,\n\t\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\t\"host-version-incompatible\",\n\t\t\t\t\t\t\t`Plugin ${manifest.id} requires host version ${requiredRange}, but the host is ${input.hostVersion}. ${guidance}`,\n\t\t\t\t\t\t\t{ required: requiredRange, actual: input.hostVersion },\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (manifest.apiVersion !== host.apiVersion) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"version-incompatible\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"api-version-incompatible\",\n\t\t\t\t\t`Plugin requires API ${manifest.apiVersion}, host provides ${host.apiVersion}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst platform = resolvePlatform(manifest, host);\n\tif (platform.status !== undefined) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: platform.status,\n\t\t\tdiagnostics: platform.diagnostics,\n\t\t};\n\t}\n\tconst available = input.availableCapabilities ?? [];\n\tconst dependencyDiagnostics: PluginDiagnosticV1[] = [];\n\tfor (const requirement of manifest.requires ?? []) {\n\t\tif (hasCapability(requirement, available)) continue;\n\t\tdependencyDiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\trequirement.optional === true ? \"optional-capability-unavailable\" : \"missing-capability\",\n\t\t\t\t`Capability ${requirement.id}@${requirement.version} is unavailable`,\n\t\t\t\t{ capability: requirement.id, version: String(requirement.version) },\n\t\t\t),\n\t\t);\n\t}\n\tconst hasRequiredMissing = dependencyDiagnostics.some((item) => item.code === \"missing-capability\");\n\tif (hasRequiredMissing) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"dependency-unavailable\",\n\t\t\tdiagnostics: dependencyDiagnostics,\n\t\t};\n\t}\n\tconst capabilityRefs = normalizeRefs(manifest.capabilityRefs);\n\tconst resolved: ResolvedPluginV1 = {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tcapabilityRefs,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n\treturn {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\trequired,\n\t\tstatus: \"installed-ready\",\n\t\tdiagnostics: dependencyDiagnostics,\n\t\tresolved,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n}\n\nfunction compareResolvedPlugins(left: ResolvedPluginV1, right: ResolvedPluginV1): number {\n\treturn left.pluginId === right.pluginId\n\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t: left.pluginId.localeCompare(right.pluginId);\n}\n\nfunction compareRefs(left: CapabilityRefV1, right: CapabilityRefV1): number {\n\treturn left.id === right.id ? left.version - right.version : left.id.localeCompare(right.id);\n}\n\n/** Build an order-independent identity including adapter and capability refs. */\nexport function buildResolvedManifestV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly ResolvedPluginV1[];\n}): ResolvedManifestV1 {\n\tassertNonEmpty(input.profileId, \"profileId\");\n\tassertNonEmpty(input.profileVersion, \"profileVersion\");\n\tconst plugins = [...input.plugins]\n\t\t.map((plugin) => ({\n\t\t\tpluginId: plugin.pluginId,\n\t\t\tpluginVersion: plugin.pluginVersion,\n\t\t\tcapabilityRefs: normalizeRefs(plugin.capabilityRefs),\n\t\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: { ...plugin.selectedAdapter } }),\n\t\t}))\n\t\t.sort(compareResolvedPlugins);\n\tconst capabilityRefs = plugins\n\t\t.flatMap((plugin) => plugin.capabilityRefs)\n\t\t.sort(compareRefs)\n\t\t.filter(\n\t\t\t(ref, index, all) => index === 0 || all[index - 1]!.id !== ref.id || all[index - 1]!.version !== ref.version,\n\t\t);\n\tconst digestInput = { profileId: input.profileId, profileVersion: input.profileVersion, plugins, capabilityRefs };\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tplugins: Object.freeze(\n\t\t\tplugins.map((plugin) => Object.freeze({ ...plugin, capabilityRefs: Object.freeze(plugin.capabilityRefs) })),\n\t\t),\n\t\tcapabilityRefs: Object.freeze(capabilityRefs),\n\t\tmanifestDigest: stableJsonDigest(digestInput as unknown as Parameters<typeof stableJsonDigest>[0]),\n\t});\n}\n\n/** Resolve all plugins in a Profile; optional unavailable plugins do not block startup. */\nexport function resolvePluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly {\n\t\treadonly manifest: PluginManifestV1;\n\t\treadonly required?: boolean;\n\t\treadonly disabled?: boolean;\n\t}[];\n\treadonly host: HostFactsV1;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version, forwarded to each plugin's min/maxHostVersion range check. */\n\treadonly hostVersion?: string;\n}): ProfileResolutionV1 {\n\tconst plugins = input.plugins\n\t\t.map((candidate) =>\n\t\t\tresolvePluginCompatibilityV1({\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t\thost: input.host,\n\t\t\t\trequired: candidate.required,\n\t\t\t\tdisabled: candidate.disabled,\n\t\t\t\tavailableCapabilities: input.availableCapabilities,\n\t\t\t\thostVersion: input.hostVersion,\n\t\t\t}),\n\t\t)\n\t\t.sort((left, right) =>\n\t\t\tleft.pluginId === right.pluginId\n\t\t\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t\t\t: left.pluginId.localeCompare(right.pluginId),\n\t\t);\n\tconst diagnostics = plugins.flatMap((plugin) => plugin.diagnostics);\n\tconst blocked = plugins.some((plugin) => plugin.required && plugin.status !== \"installed-ready\");\n\tconst resolvedPlugins = plugins.flatMap((plugin) => (plugin.resolved === undefined ? [] : [plugin.resolved]));\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tstatus: blocked ? \"blocked\" : \"ready\",\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\tresolvedManifest: buildResolvedManifestV1({\n\t\t\tprofileId: input.profileId,\n\t\t\tprofileVersion: input.profileVersion,\n\t\t\tplugins: resolvedPlugins,\n\t\t}),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { comparePluginVersionsV1 } from \"./catalog.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostAdapterFactV1,\n\tHostFactsV1,\n\tPluginAdapterManifestV1,\n\tPluginDiagnosticV1,\n\tPluginManifestV1,\n\tPluginResolutionStatusV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n\tResolvedManifestV1,\n\tResolvedPluginV1,\n\tSelectedAdapterV1,\n} from \"./types.ts\";\n\nfunction assertNonEmpty(value: string, label: string): void {\n\tif (typeof value !== \"string\" || value.trim().length === 0)\n\t\tthrow new Error(t(\"{label} must be a non-empty string\", { label }));\n}\n\nfunction matchesList<T extends string>(value: string, allowed: readonly T[] | undefined): boolean {\n\treturn (\n\t\tallowed === undefined || (allowed.length > 0 && (allowed.includes(value as T) || allowed.includes(\"any\" as T)))\n\t);\n}\n\nfunction hasAllFeatures(hostFeatures: readonly string[], required: readonly string[] | undefined): string | undefined {\n\tif (required === undefined) return undefined;\n\tconst available = new Set(hostFeatures);\n\treturn required.find((feature) => !available.has(feature));\n}\n\nfunction runtimeVersion(host: HostFactsV1, name: string): string | undefined {\n\treturn host.runtime.find((runtime) => runtime.name === name)?.version;\n}\n\nfunction diagnostic(\n\tcode: PluginDiagnosticV1[\"code\"],\n\tmessage: string,\n\tdetails?: Readonly<Record<string, string>>,\n): PluginDiagnosticV1 {\n\treturn details === undefined ? { code, message } : { code, message, details };\n}\n\nfunction adapterMatches(adapter: PluginAdapterManifestV1, host: HostFactsV1): boolean {\n\treturn (\n\t\tmatchesList(host.os, adapter.os) &&\n\t\tmatchesList(host.arch, adapter.arch) &&\n\t\thasAllFeatures(host.hostFeatures, adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction hostAdapterMatches(\n\tadapter: PluginAdapterManifestV1,\n\thostAdapter: HostAdapterFactV1,\n\thost: HostFactsV1,\n): boolean {\n\treturn (\n\t\thostAdapter.id === adapter.id &&\n\t\thostAdapter.version === adapter.version &&\n\t\tadapterMatches(adapter, host) &&\n\t\t(hostAdapter.os === undefined || hostAdapter.os === host.os || hostAdapter.os === \"any\") &&\n\t\t(hostAdapter.arch === undefined || hostAdapter.arch === host.arch || hostAdapter.arch === \"any\") &&\n\t\thasAllFeatures(hostAdapter.hostFeatures ?? [], adapter.hostFeatures) === undefined\n\t);\n}\n\nfunction selectAdapter(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): { readonly selected?: SelectedAdapterV1; readonly diagnostic?: PluginDiagnosticV1 } | undefined {\n\tconst adapters = manifest.platform?.adapters;\n\tif (adapters === undefined || adapters.length === 0) return undefined;\n\tconst installed = host.adapters ?? [];\n\tconst candidates = adapters\n\t\t.filter((adapter) => adapterMatches(adapter, host))\n\t\t.filter((adapter) => installed.some((hostAdapter) => hostAdapterMatches(adapter, hostAdapter, host)))\n\t\t.sort((left, right) => {\n\t\t\tconst idOrder = left.id.localeCompare(right.id);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(right.version, left.version) : idOrder;\n\t\t});\n\tconst selected = candidates[0];\n\treturn selected === undefined\n\t\t? {\n\t\t\t\tdiagnostic: diagnostic(\n\t\t\t\t\t\"adapter-unavailable\",\n\t\t\t\t\t`No installed adapter satisfies plugin ${manifest.id} on ${host.os}/${host.arch}`,\n\t\t\t\t),\n\t\t\t}\n\t\t: { selected: { id: selected.id, version: selected.version } };\n}\n\nfunction normalizeRefs(refs: readonly CapabilityRefV1[] | undefined): readonly CapabilityRefV1[] {\n\tconst normalized = [...(refs ?? [])].map((ref) => {\n\t\tassertNonEmpty(ref.id, \"capability id\");\n\t\tif (!Number.isSafeInteger(ref.version) || ref.version < 1) {\n\t\t\tthrow new Error(t(\"capability {id} version must be a positive safe integer\", { id: ref.id }));\n\t\t}\n\t\treturn { id: ref.id, version: ref.version };\n\t});\n\tnormalized.sort((left, right) =>\n\t\tleft.id === right.id ? left.version - right.version : left.id.localeCompare(right.id),\n\t);\n\treturn normalized;\n}\n\nfunction hasCapability(ref: CapabilityRefV1, available: readonly CapabilityRefV1[]): boolean {\n\treturn available.some((candidate) => candidate.id === ref.id && candidate.version === ref.version);\n}\n\nfunction resolvePlatform(\n\tmanifest: PluginManifestV1,\n\thost: HostFactsV1,\n): {\n\treadonly status?: PluginResolutionStatusV1;\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n\treadonly selectedAdapter?: SelectedAdapterV1;\n} {\n\tconst platform = manifest.platform;\n\tif (platform === undefined) return { diagnostics: [] };\n\tif (!matchesList(host.os, platform.os)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Plugin ${manifest.id} does not support host OS ${host.os}`)],\n\t\t};\n\t}\n\tif (!matchesList(host.arch, platform.arch)) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"unsupported-architecture\",\n\t\t\t\t\t`Plugin ${manifest.id} does not support host architecture ${host.arch}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst missingFeature = hasAllFeatures(host.hostFeatures, platform.hostFeatures);\n\tif (missingFeature !== undefined) {\n\t\treturn {\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"missing-host-feature\", `Host feature is missing: ${missingFeature}`, {\n\t\t\t\t\tfeature: missingFeature,\n\t\t\t\t}),\n\t\t\t],\n\t\t};\n\t}\n\tfor (const constraint of platform.runtime ?? []) {\n\t\tconst actual = runtimeVersion(host, constraint.name);\n\t\tif (actual === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\"missing-runtime\", `Required runtime is missing: ${constraint.name}`, {\n\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t(constraint.minVersion !== undefined && comparePluginVersionsV1(actual, constraint.minVersion) < 0) ||\n\t\t\t(constraint.maxVersion !== undefined && comparePluginVersionsV1(actual, constraint.maxVersion) > 0)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\"runtime-version-incompatible\",\n\t\t\t\t\t\t`Runtime ${constraint.name}@${actual} is outside the supported range`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: constraint.name,\n\t\t\t\t\t\t\tactual,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\tconst selected = selectAdapter(manifest, host);\n\tif (selected?.diagnostic !== undefined)\n\t\treturn { status: \"dependency-unavailable\", diagnostics: [selected.diagnostic] };\n\treturn { diagnostics: [], selectedAdapter: selected?.selected };\n}\n\n/** Resolve one installed plugin against concrete host facts. */\nexport function resolvePluginCompatibilityV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly disabled?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version; when omitted, the manifest min/maxHostVersion range is not checked. */\n\treadonly hostVersion?: string;\n}): PluginResolutionV1 {\n\tconst { manifest, host } = input;\n\tassertNonEmpty(manifest.id, \"plugin id\");\n\tassertNonEmpty(manifest.pluginVersion, \"pluginVersion\");\n\tassertNonEmpty(manifest.apiVersion, \"apiVersion\");\n\tconst required = input.required ?? true;\n\tif (input.disabled === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"disabled\",\n\t\t\tdiagnostics: [diagnostic(\"plugin-disabled\", `Plugin ${manifest.id} is disabled`)],\n\t\t};\n\t}\n\tif (manifest.testOnly === true) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\"test-only-plugin\", `Plugin ${manifest.id} is test-only and cannot be selected for production`),\n\t\t\t],\n\t\t};\n\t}\n\tif (![\"windows\", \"macos\", \"linux\"].includes(host.os)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-platform\", `Host OS is unknown: ${host.os}`)],\n\t\t};\n\t}\n\tif (![\"x64\", \"arm64\"].includes(host.arch)) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"installed-unavailable\",\n\t\t\tdiagnostics: [diagnostic(\"unsupported-architecture\", `Host architecture is unknown: ${host.arch}`)],\n\t\t};\n\t}\n\tif (manifest.minHostVersion !== undefined || manifest.maxHostVersion !== undefined) {\n\t\tif (manifest.minHostVersion !== undefined) assertNonEmpty(manifest.minHostVersion, \"minHostVersion\");\n\t\tif (manifest.maxHostVersion !== undefined) assertNonEmpty(manifest.maxHostVersion, \"maxHostVersion\");\n\t\tif (input.hostVersion !== undefined) {\n\t\t\tconst belowFloor =\n\t\t\t\tmanifest.minHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.minHostVersion) < 0;\n\t\t\tconst aboveCeiling =\n\t\t\t\tmanifest.maxHostVersion !== undefined &&\n\t\t\t\tcomparePluginVersionsV1(input.hostVersion, manifest.maxHostVersion) > 0;\n\t\t\tif (belowFloor || aboveCeiling) {\n\t\t\t\t// The declared compatibility range, rendered human-readably\n\t\t\t\t// (e.g. \">= 1.0.0 and <= 2.0.0\"); a single bound keeps the\n\t\t\t\t// floor-only shape the diagnostics contract pins.\n\t\t\t\tconst requiredRange = [\n\t\t\t\t\tmanifest.minHostVersion !== undefined ? `>= ${manifest.minHostVersion}` : undefined,\n\t\t\t\t\tmanifest.maxHostVersion !== undefined ? `<= ${manifest.maxHostVersion}` : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((bound) => bound !== undefined)\n\t\t\t\t\t.join(\" and \");\n\t\t\t\tconst guidance = belowFloor\n\t\t\t\t\t? `Upgrade the host to at least ${manifest.minHostVersion} to load this plugin.`\n\t\t\t\t\t: `Install a plugin version whose declared host range includes ${input.hostVersion}.`;\n\t\t\t\treturn {\n\t\t\t\t\tpluginId: manifest.id,\n\t\t\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\t\t\trequired,\n\t\t\t\t\tstatus: \"version-incompatible\",\n\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t\t\"host-version-incompatible\",\n\t\t\t\t\t\t\t`Plugin ${manifest.id} requires host version ${requiredRange}, but the host is ${input.hostVersion}. ${guidance}`,\n\t\t\t\t\t\t\t{ required: requiredRange, actual: input.hostVersion },\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (manifest.apiVersion !== host.apiVersion) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"version-incompatible\",\n\t\t\tdiagnostics: [\n\t\t\t\tdiagnostic(\n\t\t\t\t\t\"api-version-incompatible\",\n\t\t\t\t\t`Plugin requires API ${manifest.apiVersion}, host provides ${host.apiVersion}`,\n\t\t\t\t),\n\t\t\t],\n\t\t};\n\t}\n\tconst platform = resolvePlatform(manifest, host);\n\tif (platform.status !== undefined) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: platform.status,\n\t\t\tdiagnostics: platform.diagnostics,\n\t\t};\n\t}\n\tconst available = input.availableCapabilities ?? [];\n\tconst dependencyDiagnostics: PluginDiagnosticV1[] = [];\n\tfor (const requirement of manifest.requires ?? []) {\n\t\tif (hasCapability(requirement, available)) continue;\n\t\tdependencyDiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\trequirement.optional === true ? \"optional-capability-unavailable\" : \"missing-capability\",\n\t\t\t\t`Capability ${requirement.id}@${requirement.version} is unavailable`,\n\t\t\t\t{ capability: requirement.id, version: String(requirement.version) },\n\t\t\t),\n\t\t);\n\t}\n\tconst hasRequiredMissing = dependencyDiagnostics.some((item) => item.code === \"missing-capability\");\n\tif (hasRequiredMissing) {\n\t\treturn {\n\t\t\tpluginId: manifest.id,\n\t\t\tpluginVersion: manifest.pluginVersion,\n\t\t\trequired,\n\t\t\tstatus: \"dependency-unavailable\",\n\t\t\tdiagnostics: dependencyDiagnostics,\n\t\t};\n\t}\n\tconst capabilityRefs = normalizeRefs(manifest.capabilityRefs);\n\tconst resolved: ResolvedPluginV1 = {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tcapabilityRefs,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n\treturn {\n\t\tpluginId: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\trequired,\n\t\tstatus: \"installed-ready\",\n\t\tdiagnostics: dependencyDiagnostics,\n\t\tresolved,\n\t\t...(platform.selectedAdapter === undefined ? {} : { selectedAdapter: platform.selectedAdapter }),\n\t};\n}\n\nfunction compareResolvedPlugins(left: ResolvedPluginV1, right: ResolvedPluginV1): number {\n\treturn left.pluginId === right.pluginId\n\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t: left.pluginId.localeCompare(right.pluginId);\n}\n\nfunction compareRefs(left: CapabilityRefV1, right: CapabilityRefV1): number {\n\treturn left.id === right.id ? left.version - right.version : left.id.localeCompare(right.id);\n}\n\n/** Build an order-independent identity including adapter and capability refs. */\nexport function buildResolvedManifestV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly ResolvedPluginV1[];\n}): ResolvedManifestV1 {\n\tassertNonEmpty(input.profileId, \"profileId\");\n\tassertNonEmpty(input.profileVersion, \"profileVersion\");\n\tconst plugins = [...input.plugins]\n\t\t.map((plugin) => ({\n\t\t\tpluginId: plugin.pluginId,\n\t\t\tpluginVersion: plugin.pluginVersion,\n\t\t\tcapabilityRefs: normalizeRefs(plugin.capabilityRefs),\n\t\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: { ...plugin.selectedAdapter } }),\n\t\t}))\n\t\t.sort(compareResolvedPlugins);\n\tconst capabilityRefs = plugins\n\t\t.flatMap((plugin) => plugin.capabilityRefs)\n\t\t.sort(compareRefs)\n\t\t.filter(\n\t\t\t(ref, index, all) => index === 0 || all[index - 1]!.id !== ref.id || all[index - 1]!.version !== ref.version,\n\t\t);\n\tconst digestInput = { profileId: input.profileId, profileVersion: input.profileVersion, plugins, capabilityRefs };\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tplugins: Object.freeze(\n\t\t\tplugins.map((plugin) => Object.freeze({ ...plugin, capabilityRefs: Object.freeze(plugin.capabilityRefs) })),\n\t\t),\n\t\tcapabilityRefs: Object.freeze(capabilityRefs),\n\t\tmanifestDigest: stableJsonDigest(digestInput as unknown as Parameters<typeof stableJsonDigest>[0]),\n\t});\n}\n\n/** Resolve all plugins in a Profile; optional unavailable plugins do not block startup. */\nexport function resolvePluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly profileVersion: string;\n\treadonly plugins: readonly {\n\t\treadonly manifest: PluginManifestV1;\n\t\treadonly required?: boolean;\n\t\treadonly disabled?: boolean;\n\t}[];\n\treadonly host: HostFactsV1;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\t/** Host's own version, forwarded to each plugin's min/maxHostVersion range check. */\n\treadonly hostVersion?: string;\n}): ProfileResolutionV1 {\n\tconst plugins = input.plugins\n\t\t.map((candidate) =>\n\t\t\tresolvePluginCompatibilityV1({\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t\thost: input.host,\n\t\t\t\trequired: candidate.required,\n\t\t\t\tdisabled: candidate.disabled,\n\t\t\t\tavailableCapabilities: input.availableCapabilities,\n\t\t\t\thostVersion: input.hostVersion,\n\t\t\t}),\n\t\t)\n\t\t.sort((left, right) =>\n\t\t\tleft.pluginId === right.pluginId\n\t\t\t\t? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion)\n\t\t\t\t: left.pluginId.localeCompare(right.pluginId),\n\t\t);\n\tconst diagnostics = plugins.flatMap((plugin) => plugin.diagnostics);\n\tconst blocked = plugins.some((plugin) => plugin.required && plugin.status !== \"installed-ready\");\n\tconst resolvedPlugins = plugins.flatMap((plugin) => (plugin.resolved === undefined ? [] : [plugin.resolved]));\n\treturn Object.freeze({\n\t\tprofileId: input.profileId,\n\t\tprofileVersion: input.profileVersion,\n\t\tstatus: blocked ? \"blocked\" : \"ready\",\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\tresolvedManifest: buildResolvedManifestV1({\n\t\t\tprofileId: input.profileId,\n\t\t\tprofileVersion: input.profileVersion,\n\t\t\tplugins: resolvedPlugins,\n\t\t}),\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-store.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { createPluginSelectionV1, MAX_PLUGIN_SELECTION_IDS_V1, type PluginSelectionV1 } from \"./selection.ts\";\n\n/** Version of the host-independent user plugin selection snapshot. */\nexport const PLUGIN_SELECTION_STORE_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_PROFILES_V1 = 256;\nexport const MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1 = 4096;\n\nexport interface PluginSelectionStoreSnapshotV1 {\n\treadonly version: typeof PLUGIN_SELECTION_STORE_VERSION_V1;\n\treadonly selections: readonly PluginSelectionV1[];\n}\n\nexport type PluginSelectionStoreDiagnosticCodeV1 =\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_profile\"\n\t| \"too_many_profiles\"\n\t| \"cancelled\";\n\nexport interface PluginSelectionStoreDiagnosticV1 {\n\treadonly code: PluginSelectionStoreDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly profileId?: string;\n}\n\nexport type PluginSelectionStoreReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport type PluginSelectionStoreMutationResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1; readonly changed: boolean }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport interface PluginSelectionStoreFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginSelectionStoreOptionsV1 {\n\t/** Absolute path to the host-owned `.plugin-selection.json` file. */\n\treadonly filePath: string;\n\treadonly fileSystem?: PluginSelectionStoreFileSystemV1;\n}\n\nexport interface PluginSelectionStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginSelectionStoreReadResultV1>;\n\treadonly set: (input: {\n\t\treadonly selection: PluginSelectionV1;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n\treadonly clear: (input: {\n\t\treadonly profileId: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginSelectionStoreSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\tselections: Object.freeze([]),\n});\n\nfunction diagnostic(\n\tcode: PluginSelectionStoreDiagnosticCodeV1,\n\tmessage: string,\n\tprofileId?: string,\n): PluginSelectionStoreDiagnosticV1 {\n\treturn Object.freeze(profileId === undefined ? { code, message } : { code, message, profileId });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as { readonly code?: unknown }).code === \"ENOENT\"\n\t);\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin selection file path\");\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\treturn normalized;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateProfile(value: unknown): PluginSelectionV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"profileId\", \"selectedPluginIds\", \"disabledPluginIds\"]))\n\t\tthrow new Error(\"selection schema is invalid\");\n\tif (!Array.isArray(value.selectedPluginIds) || !Array.isArray(value.disabledPluginIds))\n\t\tthrow new Error(\"selection IDs must be arrays\");\n\tif (\n\t\tvalue.selectedPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1 ||\n\t\tvalue.disabledPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1\n\t)\n\t\tthrow new Error(\"too many plugin IDs\");\n\treturn createPluginSelectionV1({\n\t\tprofileId: value.profileId as string,\n\t\tselectedPluginIds: value.selectedPluginIds,\n\t\tdisabledPluginIds: value.disabledPluginIds,\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginSelectionStoreSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"selections\"]))\n\t\tthrow new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_SELECTION_STORE_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.selections)) throw new Error(\"selections must be an array\");\n\tif (value.selections.length > MAX_PLUGIN_SELECTION_PROFILES_V1) throw new Error(\"too many selection profiles\");\n\tconst selections = value.selections.map(validateProfile);\n\tconst profiles = new Set<string>();\n\tfor (const selection of selections) {\n\t\tif (profiles.has(selection.profileId)) throw new Error(`duplicate profile: ${selection.profileId}`);\n\t\tprofiles.add(selection.profileId);\n\t}\n\tselections.sort((left, right) => left.profileId.localeCompare(right.profileId));\n\treturn Object.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: Object.freeze(selections) });\n}\n\nfunction invalidFromError(error: unknown): PluginSelectionStoreDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin selection schema is invalid\";\n\tif (message === \"too many selection profiles\") return diagnostic(\"too_many_profiles\", message);\n\tconst duplicatePrefix = \"duplicate profile: \";\n\tif (message.startsWith(duplicatePrefix)) {\n\t\tconst profileId = message.slice(duplicatePrefix.length);\n\t\treturn diagnostic(\"duplicate_profile\", message, profileId);\n\t}\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginSelectionStoreFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin selection operation was cancelled\")]),\n\t});\n}\n\nfunction sortSelections(selections: readonly PluginSelectionV1[]): readonly PluginSelectionV1[] {\n\treturn Object.freeze([...selections].sort((left, right) => left.profileId.localeCompare(right.profileId)));\n}\n\nfunction persistedSelection(selection: PluginSelectionV1): Readonly<Record<string, unknown>> {\n\treturn Object.freeze({\n\t\tprofileId: selection.profileId,\n\t\tselectedPluginIds: selection.selectedPluginIds,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t});\n}\n\nexport function createPluginSelectionStoreV1(options: PluginSelectionStoreOptionsV1): PluginSelectionStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginSelectionStoreReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin selection JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot: validateSnapshot(parsed) });\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t}\n\t}\n\n\tasync function write(\n\t\tsnapshot: PluginSelectionStoreSnapshotV1,\n\t\tsignal?: AbortSignal,\n\t): Promise<PluginSelectionStoreMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst temporaryPath = join(dirname(filePath), `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(dirname(filePath));\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(\n\t\t\t\ttemporaryPath,\n\t\t\t\t`${JSON.stringify({\n\t\t\t\t\tversion: snapshot.version,\n\t\t\t\t\tselections: snapshot.selections.map(persistedSelection),\n\t\t\t\t})}\\n`,\n\t\t\t);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tset: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1(input.selection);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst existing = current.snapshot.selections.find((item) => item.profileId === selection.profileId);\n\t\t\t\tif (existing !== undefined && JSON.stringify(existing) === JSON.stringify(selection))\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\tif (current.snapshot.selections.length >= MAX_PLUGIN_SELECTION_PROFILES_V1 && existing === undefined)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_profiles\", \"too many selection profiles\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\t\t\t\t\tselections: sortSelections([\n\t\t\t\t\t\t...current.snapshot.selections.filter((item) => item.profileId !== selection.profileId),\n\t\t\t\t\t\tselection,\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tclear: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1({\n\t\t\t\t\t\tprofileId: input.profileId,\n\t\t\t\t\t\tselectedPluginIds: [],\n\t\t\t\t\t\tdisabledPluginIds: [],\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst selections = current.snapshot.selections.filter((item) => item.profileId !== selection.profileId);\n\t\t\t\tif (selections.length === current.snapshot.selections.length)\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\treturn await write(\n\t\t\t\t\tObject.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: sortSelections(selections) }),\n\t\t\t\t\tinput.signal,\n\t\t\t\t);\n\t\t\t}),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"selection-store.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { t } from \"../../core/i18n/index.ts\";\nimport { createPluginSelectionV1, MAX_PLUGIN_SELECTION_IDS_V1, type PluginSelectionV1 } from \"./selection.ts\";\n\n/** Version of the host-independent user plugin selection snapshot. */\nexport const PLUGIN_SELECTION_STORE_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_PROFILES_V1 = 256;\nexport const MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1 = 4096;\n\nexport interface PluginSelectionStoreSnapshotV1 {\n\treadonly version: typeof PLUGIN_SELECTION_STORE_VERSION_V1;\n\treadonly selections: readonly PluginSelectionV1[];\n}\n\nexport type PluginSelectionStoreDiagnosticCodeV1 =\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_profile\"\n\t| \"too_many_profiles\"\n\t| \"cancelled\";\n\nexport interface PluginSelectionStoreDiagnosticV1 {\n\treadonly code: PluginSelectionStoreDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly profileId?: string;\n}\n\nexport type PluginSelectionStoreReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport type PluginSelectionStoreMutationResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1; readonly changed: boolean }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport interface PluginSelectionStoreFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginSelectionStoreOptionsV1 {\n\t/** Absolute path to the host-owned `.plugin-selection.json` file. */\n\treadonly filePath: string;\n\treadonly fileSystem?: PluginSelectionStoreFileSystemV1;\n}\n\nexport interface PluginSelectionStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginSelectionStoreReadResultV1>;\n\treadonly set: (input: {\n\t\treadonly selection: PluginSelectionV1;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n\treadonly clear: (input: {\n\t\treadonly profileId: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginSelectionStoreSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\tselections: Object.freeze([]),\n});\n\nfunction diagnostic(\n\tcode: PluginSelectionStoreDiagnosticCodeV1,\n\tmessage: string,\n\tprofileId?: string,\n): PluginSelectionStoreDiagnosticV1 {\n\treturn Object.freeze(profileId === undefined ? { code, message } : { code, message, profileId });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as { readonly code?: unknown }).code === \"ENOENT\"\n\t);\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin selection file path\"));\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\treturn normalized;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateProfile(value: unknown): PluginSelectionV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"profileId\", \"selectedPluginIds\", \"disabledPluginIds\"]))\n\t\tthrow new Error(t(\"selection schema is invalid\"));\n\tif (!Array.isArray(value.selectedPluginIds) || !Array.isArray(value.disabledPluginIds))\n\t\tthrow new Error(t(\"selection IDs must be arrays\"));\n\tif (\n\t\tvalue.selectedPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1 ||\n\t\tvalue.disabledPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1\n\t)\n\t\tthrow new Error(t(\"too many plugin IDs\"));\n\treturn createPluginSelectionV1({\n\t\tprofileId: value.profileId as string,\n\t\tselectedPluginIds: value.selectedPluginIds,\n\t\tdisabledPluginIds: value.disabledPluginIds,\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginSelectionStoreSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"selections\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_SELECTION_STORE_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.selections)) throw new Error(t(\"selections must be an array\"));\n\tif (value.selections.length > MAX_PLUGIN_SELECTION_PROFILES_V1) throw new Error(\"too many selection profiles\");\n\tconst selections = value.selections.map(validateProfile);\n\tconst profiles = new Set<string>();\n\tfor (const selection of selections) {\n\t\tif (profiles.has(selection.profileId)) throw new Error(`duplicate profile: ${selection.profileId}`);\n\t\tprofiles.add(selection.profileId);\n\t}\n\tselections.sort((left, right) => left.profileId.localeCompare(right.profileId));\n\treturn Object.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: Object.freeze(selections) });\n}\n\nfunction invalidFromError(error: unknown): PluginSelectionStoreDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin selection schema is invalid\";\n\tif (message === \"too many selection profiles\") return diagnostic(\"too_many_profiles\", message);\n\tconst duplicatePrefix = \"duplicate profile: \";\n\tif (message.startsWith(duplicatePrefix)) {\n\t\tconst profileId = message.slice(duplicatePrefix.length);\n\t\treturn diagnostic(\"duplicate_profile\", message, profileId);\n\t}\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginSelectionStoreFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin selection operation was cancelled\")]),\n\t});\n}\n\nfunction sortSelections(selections: readonly PluginSelectionV1[]): readonly PluginSelectionV1[] {\n\treturn Object.freeze([...selections].sort((left, right) => left.profileId.localeCompare(right.profileId)));\n}\n\nfunction persistedSelection(selection: PluginSelectionV1): Readonly<Record<string, unknown>> {\n\treturn Object.freeze({\n\t\tprofileId: selection.profileId,\n\t\tselectedPluginIds: selection.selectedPluginIds,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t});\n}\n\nexport function createPluginSelectionStoreV1(options: PluginSelectionStoreOptionsV1): PluginSelectionStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginSelectionStoreReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin selection JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot: validateSnapshot(parsed) });\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t}\n\t}\n\n\tasync function write(\n\t\tsnapshot: PluginSelectionStoreSnapshotV1,\n\t\tsignal?: AbortSignal,\n\t): Promise<PluginSelectionStoreMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst temporaryPath = join(dirname(filePath), `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(dirname(filePath));\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(\n\t\t\t\ttemporaryPath,\n\t\t\t\t`${JSON.stringify({\n\t\t\t\t\tversion: snapshot.version,\n\t\t\t\t\tselections: snapshot.selections.map(persistedSelection),\n\t\t\t\t})}\\n`,\n\t\t\t);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tset: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1(input.selection);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst existing = current.snapshot.selections.find((item) => item.profileId === selection.profileId);\n\t\t\t\tif (existing !== undefined && JSON.stringify(existing) === JSON.stringify(selection))\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\tif (current.snapshot.selections.length >= MAX_PLUGIN_SELECTION_PROFILES_V1 && existing === undefined)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_profiles\", \"too many selection profiles\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\t\t\t\t\tselections: sortSelections([\n\t\t\t\t\t\t...current.snapshot.selections.filter((item) => item.profileId !== selection.profileId),\n\t\t\t\t\t\tselection,\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tclear: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1({\n\t\t\t\t\t\tprofileId: input.profileId,\n\t\t\t\t\t\tselectedPluginIds: [],\n\t\t\t\t\t\tdisabledPluginIds: [],\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst selections = current.snapshot.selections.filter((item) => item.profileId !== selection.profileId);\n\t\t\t\tif (selections.length === current.snapshot.selections.length)\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\treturn await write(\n\t\t\t\t\tObject.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: sortSelections(selections) }),\n\t\t\t\t\tinput.signal,\n\t\t\t\t);\n\t\t\t}),\n\t};\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { t } from "../../core/i18n/index.js";
|
|
4
5
|
import { createPluginSelectionV1, MAX_PLUGIN_SELECTION_IDS_V1 } from "./selection.js";
|
|
5
6
|
/** Version of the host-independent user plugin selection snapshot. */
|
|
6
7
|
export const PLUGIN_SELECTION_STORE_VERSION_V1 = 1;
|
|
@@ -24,14 +25,14 @@ function isMissingError(error) {
|
|
|
24
25
|
}
|
|
25
26
|
function validateFilePath(value) {
|
|
26
27
|
if (typeof value !== "string" || value.trim() === "" || value.length > MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)
|
|
27
|
-
throw new Error("invalid plugin selection file path");
|
|
28
|
+
throw new Error(t("invalid plugin selection file path"));
|
|
28
29
|
if (value.includes("\0") || /[\u0000-\u001f]/u.test(value))
|
|
29
|
-
throw new Error("invalid plugin selection file path");
|
|
30
|
+
throw new Error(t("invalid plugin selection file path"));
|
|
30
31
|
if (/^file:/iu.test(value) || (/^[a-z][a-z\d+.-]*:/iu.test(value) && !/^[a-z]:[\\/]/iu.test(value)))
|
|
31
|
-
throw new Error("invalid plugin selection file path");
|
|
32
|
+
throw new Error(t("invalid plugin selection file path"));
|
|
32
33
|
const normalized = isAbsolute(value) ? value : resolve(value);
|
|
33
34
|
if (basename(normalized).length === 0 || basename(normalized) === "." || basename(normalized) === "..")
|
|
34
|
-
throw new Error("invalid plugin selection file path");
|
|
35
|
+
throw new Error(t("invalid plugin selection file path"));
|
|
35
36
|
return normalized;
|
|
36
37
|
}
|
|
37
38
|
function isObject(value) {
|
|
@@ -43,12 +44,12 @@ function hasExactKeys(value, keys) {
|
|
|
43
44
|
}
|
|
44
45
|
function validateProfile(value) {
|
|
45
46
|
if (!isObject(value) || !hasExactKeys(value, ["profileId", "selectedPluginIds", "disabledPluginIds"]))
|
|
46
|
-
throw new Error("selection schema is invalid");
|
|
47
|
+
throw new Error(t("selection schema is invalid"));
|
|
47
48
|
if (!Array.isArray(value.selectedPluginIds) || !Array.isArray(value.disabledPluginIds))
|
|
48
|
-
throw new Error("selection IDs must be arrays");
|
|
49
|
+
throw new Error(t("selection IDs must be arrays"));
|
|
49
50
|
if (value.selectedPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1 ||
|
|
50
51
|
value.disabledPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1)
|
|
51
|
-
throw new Error("too many plugin IDs");
|
|
52
|
+
throw new Error(t("too many plugin IDs"));
|
|
52
53
|
return createPluginSelectionV1({
|
|
53
54
|
profileId: value.profileId,
|
|
54
55
|
selectedPluginIds: value.selectedPluginIds,
|
|
@@ -57,11 +58,11 @@ function validateProfile(value) {
|
|
|
57
58
|
}
|
|
58
59
|
function validateSnapshot(value) {
|
|
59
60
|
if (!isObject(value) || !hasExactKeys(value, ["version", "selections"]))
|
|
60
|
-
throw new Error("snapshot schema is invalid");
|
|
61
|
+
throw new Error(t("snapshot schema is invalid"));
|
|
61
62
|
if (value.version !== PLUGIN_SELECTION_STORE_VERSION_V1)
|
|
62
|
-
throw new Error("snapshot version is unsupported");
|
|
63
|
+
throw new Error(t("snapshot version is unsupported"));
|
|
63
64
|
if (!Array.isArray(value.selections))
|
|
64
|
-
throw new Error("selections must be an array");
|
|
65
|
+
throw new Error(t("selections must be an array"));
|
|
65
66
|
if (value.selections.length > MAX_PLUGIN_SELECTION_PROFILES_V1)
|
|
66
67
|
throw new Error("too many selection profiles");
|
|
67
68
|
const selections = value.selections.map(validateProfile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-store.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { createPluginSelectionV1, MAX_PLUGIN_SELECTION_IDS_V1, type PluginSelectionV1 } from \"./selection.ts\";\n\n/** Version of the host-independent user plugin selection snapshot. */\nexport const PLUGIN_SELECTION_STORE_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_PROFILES_V1 = 256;\nexport const MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1 = 4096;\n\nexport interface PluginSelectionStoreSnapshotV1 {\n\treadonly version: typeof PLUGIN_SELECTION_STORE_VERSION_V1;\n\treadonly selections: readonly PluginSelectionV1[];\n}\n\nexport type PluginSelectionStoreDiagnosticCodeV1 =\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_profile\"\n\t| \"too_many_profiles\"\n\t| \"cancelled\";\n\nexport interface PluginSelectionStoreDiagnosticV1 {\n\treadonly code: PluginSelectionStoreDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly profileId?: string;\n}\n\nexport type PluginSelectionStoreReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport type PluginSelectionStoreMutationResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1; readonly changed: boolean }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport interface PluginSelectionStoreFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginSelectionStoreOptionsV1 {\n\t/** Absolute path to the host-owned `.plugin-selection.json` file. */\n\treadonly filePath: string;\n\treadonly fileSystem?: PluginSelectionStoreFileSystemV1;\n}\n\nexport interface PluginSelectionStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginSelectionStoreReadResultV1>;\n\treadonly set: (input: {\n\t\treadonly selection: PluginSelectionV1;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n\treadonly clear: (input: {\n\t\treadonly profileId: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginSelectionStoreSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\tselections: Object.freeze([]),\n});\n\nfunction diagnostic(\n\tcode: PluginSelectionStoreDiagnosticCodeV1,\n\tmessage: string,\n\tprofileId?: string,\n): PluginSelectionStoreDiagnosticV1 {\n\treturn Object.freeze(profileId === undefined ? { code, message } : { code, message, profileId });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as { readonly code?: unknown }).code === \"ENOENT\"\n\t);\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin selection file path\");\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(\"invalid plugin selection file path\");\n\treturn normalized;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateProfile(value: unknown): PluginSelectionV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"profileId\", \"selectedPluginIds\", \"disabledPluginIds\"]))\n\t\tthrow new Error(\"selection schema is invalid\");\n\tif (!Array.isArray(value.selectedPluginIds) || !Array.isArray(value.disabledPluginIds))\n\t\tthrow new Error(\"selection IDs must be arrays\");\n\tif (\n\t\tvalue.selectedPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1 ||\n\t\tvalue.disabledPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1\n\t)\n\t\tthrow new Error(\"too many plugin IDs\");\n\treturn createPluginSelectionV1({\n\t\tprofileId: value.profileId as string,\n\t\tselectedPluginIds: value.selectedPluginIds,\n\t\tdisabledPluginIds: value.disabledPluginIds,\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginSelectionStoreSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"selections\"]))\n\t\tthrow new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_SELECTION_STORE_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.selections)) throw new Error(\"selections must be an array\");\n\tif (value.selections.length > MAX_PLUGIN_SELECTION_PROFILES_V1) throw new Error(\"too many selection profiles\");\n\tconst selections = value.selections.map(validateProfile);\n\tconst profiles = new Set<string>();\n\tfor (const selection of selections) {\n\t\tif (profiles.has(selection.profileId)) throw new Error(`duplicate profile: ${selection.profileId}`);\n\t\tprofiles.add(selection.profileId);\n\t}\n\tselections.sort((left, right) => left.profileId.localeCompare(right.profileId));\n\treturn Object.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: Object.freeze(selections) });\n}\n\nfunction invalidFromError(error: unknown): PluginSelectionStoreDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin selection schema is invalid\";\n\tif (message === \"too many selection profiles\") return diagnostic(\"too_many_profiles\", message);\n\tconst duplicatePrefix = \"duplicate profile: \";\n\tif (message.startsWith(duplicatePrefix)) {\n\t\tconst profileId = message.slice(duplicatePrefix.length);\n\t\treturn diagnostic(\"duplicate_profile\", message, profileId);\n\t}\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginSelectionStoreFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin selection operation was cancelled\")]),\n\t});\n}\n\nfunction sortSelections(selections: readonly PluginSelectionV1[]): readonly PluginSelectionV1[] {\n\treturn Object.freeze([...selections].sort((left, right) => left.profileId.localeCompare(right.profileId)));\n}\n\nfunction persistedSelection(selection: PluginSelectionV1): Readonly<Record<string, unknown>> {\n\treturn Object.freeze({\n\t\tprofileId: selection.profileId,\n\t\tselectedPluginIds: selection.selectedPluginIds,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t});\n}\n\nexport function createPluginSelectionStoreV1(options: PluginSelectionStoreOptionsV1): PluginSelectionStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginSelectionStoreReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin selection JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot: validateSnapshot(parsed) });\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t}\n\t}\n\n\tasync function write(\n\t\tsnapshot: PluginSelectionStoreSnapshotV1,\n\t\tsignal?: AbortSignal,\n\t): Promise<PluginSelectionStoreMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst temporaryPath = join(dirname(filePath), `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(dirname(filePath));\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(\n\t\t\t\ttemporaryPath,\n\t\t\t\t`${JSON.stringify({\n\t\t\t\t\tversion: snapshot.version,\n\t\t\t\t\tselections: snapshot.selections.map(persistedSelection),\n\t\t\t\t})}\\n`,\n\t\t\t);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tset: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1(input.selection);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst existing = current.snapshot.selections.find((item) => item.profileId === selection.profileId);\n\t\t\t\tif (existing !== undefined && JSON.stringify(existing) === JSON.stringify(selection))\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\tif (current.snapshot.selections.length >= MAX_PLUGIN_SELECTION_PROFILES_V1 && existing === undefined)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_profiles\", \"too many selection profiles\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\t\t\t\t\tselections: sortSelections([\n\t\t\t\t\t\t...current.snapshot.selections.filter((item) => item.profileId !== selection.profileId),\n\t\t\t\t\t\tselection,\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tclear: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1({\n\t\t\t\t\t\tprofileId: input.profileId,\n\t\t\t\t\t\tselectedPluginIds: [],\n\t\t\t\t\t\tdisabledPluginIds: [],\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst selections = current.snapshot.selections.filter((item) => item.profileId !== selection.profileId);\n\t\t\t\tif (selections.length === current.snapshot.selections.length)\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\treturn await write(\n\t\t\t\t\tObject.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: sortSelections(selections) }),\n\t\t\t\t\tinput.signal,\n\t\t\t\t);\n\t\t\t}),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"selection-store.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,0BAA0B,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAA0B,MAAM,gBAAgB,CAAC;AAE9G,sEAAsE;AACtE,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAU,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AACpD,MAAM,CAAC,MAAM,wCAAwC,GAAG,IAAI,CAAC;AAyD7D,MAAM,cAAc,GAAmC,MAAM,CAAC,MAAM,CAAC;IACpE,OAAO,EAAE,iCAAiC;IAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,SAAS,UAAU,CAClB,IAA0C,EAC1C,OAAe,EACf,SAAkB,EACiB;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;AAAA,CACjG;AAED,SAAS,YAAY,CAAC,KAAc,EAAW;IAC9C,OAAO,KAAK,YAAY,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;AAAA,CACpG;AAED,SAAS,cAAc,CAAC,KAAc,EAAW;IAChD,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACd,KAAqC,CAAC,IAAI,KAAK,QAAQ,CACxD,CAAC;AAAA,CACF;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAU;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,wCAAwC;QAC9G,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;IACrH,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI;QACrG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAC1D,OAAO,UAAU,CAAC;AAAA,CAClB;AAED,SAAS,QAAQ,CAAC,KAAc,EAAoC;IACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,YAAY,CAAC,KAA8B,EAAE,IAAuB,EAAW;IACvF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAAA,CAC3G;AAED,SAAS,eAAe,CAAC,KAAc,EAAqB;IAC3D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;QACpG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC;IACpD,IACC,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,2BAA2B;QAC5D,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,2BAA2B;QAE5D,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC3C,OAAO,uBAAuB,CAAC;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAmB;QACpC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;KAC1C,CAAC,CAAC;AAAA,CACH;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAkC;IACzE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,OAAO,KAAK,iCAAiC;QAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAC/G,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACxF,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,gCAAgC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC/G,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;QACpG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AAAA,CAC5G;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAoC;IAC3E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oCAAoC,CAAC;IAC9F,IAAI,OAAO,KAAK,6BAA6B;QAAE,OAAO,UAAU,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IAC/F,MAAM,eAAe,GAAG,qBAAqB,CAAC;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACxD,OAAO,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,UAAU,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAAA,CAC7C;AAED,SAAS,iBAAiB,GAAqC;IAC9D,OAAO;QACN,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtD,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;YACtB,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAAA,CACvC;QACD,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YAChC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAAA,CACpC;QACD,MAAM;QACN,MAAM;KACN,CAAC;AAAA,CACF;AAED,SAAS,eAAe,GAGtB;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACpB,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,0CAA0C,CAAC,CAAC,CAAC;KACjG,CAAC,CAAC;AAAA,CACH;AAED,SAAS,cAAc,CAAC,UAAwC,EAAgC;IAC/F,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,CAC3G;AAED,SAAS,kBAAkB,CAAC,SAA4B,EAAqC;IAC5F,OAAO,MAAM,CAAC,MAAM,CAAC;QACpB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;QAC9C,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;KAC9C,CAAC,CAAC;AAAA,CACH;AAED,MAAM,UAAU,4BAA4B,CAAC,OAAsC,EAA0B;IAC5G,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,EAAE,CAAC;IAE7D,KAAK,UAAU,IAAI,CAAC,MAAoB,EAA6C;QACpF,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,eAAe,EAAE,CAAC;QAC9C,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,cAAc,CAAC,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;YACjG,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,MAAM,EAAE,OAAO;gBAAE,OAAO,eAAe,EAAE,CAAC;YACrE,MAAM,KAAK,CAAC;QACb,CAAC;QACD,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,eAAe,EAAE,CAAC;QAC9C,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,MAAM,CAAC,MAAM,CAAC;gBACpB,MAAM,EAAE,SAAS;gBACjB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,kCAAkC,CAAC,CAAC,CAAC;aAC5F,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpG,CAAC;IAAA,CACD;IAED,KAAK,UAAU,KAAK,CACnB,QAAwC,EACxC,MAAoB,EAC4B;QAChD,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,eAAe,EAAE,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5F,IAAI,CAAC;YACJ,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC1C,IAAI,MAAM,EAAE,OAAO;gBAAE,OAAO,eAAe,EAAE,CAAC;YAC9C,MAAM,UAAU,CAAC,SAAS,CACzB,aAAa,EACb,GAAG,IAAI,CAAC,SAAS,CAAC;gBACjB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC;aACvD,CAAC,IAAI,CACN,CAAC;YACF,IAAI,MAAM,EAAE,OAAO;gBAAE,OAAO,eAAe,EAAE,CAAC;YAC9C,MAAM,UAAU,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACjD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC;gBACJ,MAAM,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACR,4DAA4D;YAC7D,CAAC;QACF,CAAC;IAAA,CACD;IAED,IAAI,YAAY,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACpD,SAAS,eAAe,CAAI,SAA2B,EAAc;QACpE,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACvD,YAAY,GAAG,MAAM,CAAC,IAAI,CACzB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,OAAO;QACN,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC;QACnD,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CACd,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAI,SAA4B,CAAC;YACjC,IAAI,CAAC;gBACJ,SAAS,GAAG,uBAAuB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACtD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpG,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC;YAC5E,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO;gBAAE,OAAO,eAAe,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC;YACpG,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;gBACnF,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACpF,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,IAAI,gCAAgC,IAAI,QAAQ,KAAK,SAAS;gBACnG,OAAO,MAAM,CAAC,MAAM,CAAC;oBACpB,MAAM,EAAE,SAAS;oBACjB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,mBAAmB,EAAE,6BAA6B,CAAC,CAAC,CAAC;iBAC5F,CAAC,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC9B,OAAO,EAAE,iCAAiC;gBAC1C,UAAU,EAAE,cAAc,CAAC;oBAC1B,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC;oBACvF,SAAS;iBACT,CAAC;aACF,CAAC,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAA,CAC3C,CAAC;QACH,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAI,SAA4B,CAAC;YACjC,IAAI,CAAC;gBACJ,SAAS,GAAG,uBAAuB,CAAC;oBACnC,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,iBAAiB,EAAE,EAAE;oBACrB,iBAAiB,EAAE,EAAE;iBACrB,CAAC,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpG,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC;YAC5E,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO;gBAAE,OAAO,eAAe,EAAE,CAAC;YACpD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC;YACxG,IAAI,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM;gBAC3D,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACpF,OAAO,MAAM,KAAK,CACjB,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,EACrG,KAAK,CAAC,MAAM,CACZ,CAAC;QAAA,CACF,CAAC;KACH,CAAC;AAAA,CACF","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { t } from \"../../core/i18n/index.ts\";\nimport { createPluginSelectionV1, MAX_PLUGIN_SELECTION_IDS_V1, type PluginSelectionV1 } from \"./selection.ts\";\n\n/** Version of the host-independent user plugin selection snapshot. */\nexport const PLUGIN_SELECTION_STORE_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_PROFILES_V1 = 256;\nexport const MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1 = 4096;\n\nexport interface PluginSelectionStoreSnapshotV1 {\n\treadonly version: typeof PLUGIN_SELECTION_STORE_VERSION_V1;\n\treadonly selections: readonly PluginSelectionV1[];\n}\n\nexport type PluginSelectionStoreDiagnosticCodeV1 =\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_profile\"\n\t| \"too_many_profiles\"\n\t| \"cancelled\";\n\nexport interface PluginSelectionStoreDiagnosticV1 {\n\treadonly code: PluginSelectionStoreDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly profileId?: string;\n}\n\nexport type PluginSelectionStoreReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginSelectionStoreSnapshotV1 }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport type PluginSelectionStoreMutationResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginSelectionStoreSnapshotV1; readonly changed: boolean }\n\t| { readonly status: \"invalid\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] }\n\t| { readonly status: \"cancelled\"; readonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[] };\n\nexport interface PluginSelectionStoreFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginSelectionStoreOptionsV1 {\n\t/** Absolute path to the host-owned `.plugin-selection.json` file. */\n\treadonly filePath: string;\n\treadonly fileSystem?: PluginSelectionStoreFileSystemV1;\n}\n\nexport interface PluginSelectionStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginSelectionStoreReadResultV1>;\n\treadonly set: (input: {\n\t\treadonly selection: PluginSelectionV1;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n\treadonly clear: (input: {\n\t\treadonly profileId: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginSelectionStoreMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginSelectionStoreSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\tselections: Object.freeze([]),\n});\n\nfunction diagnostic(\n\tcode: PluginSelectionStoreDiagnosticCodeV1,\n\tmessage: string,\n\tprofileId?: string,\n): PluginSelectionStoreDiagnosticV1 {\n\treturn Object.freeze(profileId === undefined ? { code, message } : { code, message, profileId });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as { readonly code?: unknown }).code === \"ENOENT\"\n\t);\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin selection file path\"));\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(t(\"invalid plugin selection file path\"));\n\treturn normalized;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateProfile(value: unknown): PluginSelectionV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"profileId\", \"selectedPluginIds\", \"disabledPluginIds\"]))\n\t\tthrow new Error(t(\"selection schema is invalid\"));\n\tif (!Array.isArray(value.selectedPluginIds) || !Array.isArray(value.disabledPluginIds))\n\t\tthrow new Error(t(\"selection IDs must be arrays\"));\n\tif (\n\t\tvalue.selectedPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1 ||\n\t\tvalue.disabledPluginIds.length > MAX_PLUGIN_SELECTION_IDS_V1\n\t)\n\t\tthrow new Error(t(\"too many plugin IDs\"));\n\treturn createPluginSelectionV1({\n\t\tprofileId: value.profileId as string,\n\t\tselectedPluginIds: value.selectedPluginIds,\n\t\tdisabledPluginIds: value.disabledPluginIds,\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginSelectionStoreSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"selections\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_SELECTION_STORE_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.selections)) throw new Error(t(\"selections must be an array\"));\n\tif (value.selections.length > MAX_PLUGIN_SELECTION_PROFILES_V1) throw new Error(\"too many selection profiles\");\n\tconst selections = value.selections.map(validateProfile);\n\tconst profiles = new Set<string>();\n\tfor (const selection of selections) {\n\t\tif (profiles.has(selection.profileId)) throw new Error(`duplicate profile: ${selection.profileId}`);\n\t\tprofiles.add(selection.profileId);\n\t}\n\tselections.sort((left, right) => left.profileId.localeCompare(right.profileId));\n\treturn Object.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: Object.freeze(selections) });\n}\n\nfunction invalidFromError(error: unknown): PluginSelectionStoreDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin selection schema is invalid\";\n\tif (message === \"too many selection profiles\") return diagnostic(\"too_many_profiles\", message);\n\tconst duplicatePrefix = \"duplicate profile: \";\n\tif (message.startsWith(duplicatePrefix)) {\n\t\tconst profileId = message.slice(duplicatePrefix.length);\n\t\treturn diagnostic(\"duplicate_profile\", message, profileId);\n\t}\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginSelectionStoreFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginSelectionStoreDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin selection operation was cancelled\")]),\n\t});\n}\n\nfunction sortSelections(selections: readonly PluginSelectionV1[]): readonly PluginSelectionV1[] {\n\treturn Object.freeze([...selections].sort((left, right) => left.profileId.localeCompare(right.profileId)));\n}\n\nfunction persistedSelection(selection: PluginSelectionV1): Readonly<Record<string, unknown>> {\n\treturn Object.freeze({\n\t\tprofileId: selection.profileId,\n\t\tselectedPluginIds: selection.selectedPluginIds,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t});\n}\n\nexport function createPluginSelectionStoreV1(options: PluginSelectionStoreOptionsV1): PluginSelectionStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginSelectionStoreReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin selection JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot: validateSnapshot(parsed) });\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t}\n\t}\n\n\tasync function write(\n\t\tsnapshot: PluginSelectionStoreSnapshotV1,\n\t\tsignal?: AbortSignal,\n\t): Promise<PluginSelectionStoreMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst temporaryPath = join(dirname(filePath), `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(dirname(filePath));\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(\n\t\t\t\ttemporaryPath,\n\t\t\t\t`${JSON.stringify({\n\t\t\t\t\tversion: snapshot.version,\n\t\t\t\t\tselections: snapshot.selections.map(persistedSelection),\n\t\t\t\t})}\\n`,\n\t\t\t);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tset: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1(input.selection);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst existing = current.snapshot.selections.find((item) => item.profileId === selection.profileId);\n\t\t\t\tif (existing !== undefined && JSON.stringify(existing) === JSON.stringify(selection))\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\tif (current.snapshot.selections.length >= MAX_PLUGIN_SELECTION_PROFILES_V1 && existing === undefined)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_profiles\", \"too many selection profiles\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_SELECTION_STORE_VERSION_V1,\n\t\t\t\t\tselections: sortSelections([\n\t\t\t\t\t\t...current.snapshot.selections.filter((item) => item.profileId !== selection.profileId),\n\t\t\t\t\t\tselection,\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tclear: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet selection: PluginSelectionV1;\n\t\t\t\ttry {\n\t\t\t\t\tselection = createPluginSelectionV1({\n\t\t\t\t\t\tprofileId: input.profileId,\n\t\t\t\t\t\tselectedPluginIds: [],\n\t\t\t\t\t\tdisabledPluginIds: [],\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({ status: \"invalid\", diagnostics: Object.freeze([invalidFromError(error)]) });\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst selections = current.snapshot.selections.filter((item) => item.profileId !== selection.profileId);\n\t\t\t\tif (selections.length === current.snapshot.selections.length)\n\t\t\t\t\treturn Object.freeze({ status: \"ok\", snapshot: current.snapshot, changed: false });\n\t\t\t\treturn await write(\n\t\t\t\t\tObject.freeze({ version: PLUGIN_SELECTION_STORE_VERSION_V1, selections: sortSelections(selections) }),\n\t\t\t\t\tinput.signal,\n\t\t\t\t);\n\t\t\t}),\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,oBAAoB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC7G,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErG,6EAA6E;AAC7E,eAAO,MAAM,2BAA2B,GAAa,CAAC;AACtD,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,2BAA2B,CAAC;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,0BAA0B,GACnC,oBAAoB,GACpB,qBAAqB,GACrB,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,mBAAmB,GACnB,mBAAmB,CAAC;AAEvB,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,YAAY,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAK/E;CACD;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACpD;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AA6DD,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAUxF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAChD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,2BAA2B,CAkD9B;AAED,2FAA2F;AAC3F,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAG/E","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport { buildPluginCatalogV1, type PluginCatalogEntryV1, type PluginCatalogSnapshotV1 } from \"./catalog.ts\";\nimport type { CapabilityRefV1, HostFactsV1, PluginDiagnosticV1, PluginManifestV1 } from \"./types.ts\";\n\n/** Version of the user-owned, host-independent plugin selection snapshot. */\nexport const PLUGIN_SELECTION_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_ID_CHARS_V1 = 128;\nexport const MAX_PLUGIN_SELECTION_IDS_V1 = 128;\n\nexport interface PluginSelectionV1 {\n\treadonly version: typeof PLUGIN_SELECTION_VERSION_V1;\n\treadonly profileId: string;\n\treadonly selectedPluginIds: readonly string[];\n\treadonly disabledPluginIds: readonly string[];\n}\n\nexport type PluginSelectionErrorCodeV1 =\n\t| \"invalid_profile_id\"\n\t| \"profile_id_too_long\"\n\t| \"invalid_plugin_id\"\n\t| \"plugin_id_too_long\"\n\t| \"too_many_plugin_ids\"\n\t| \"duplicate_plugin_id\"\n\t| \"unknown_plugin_id\"\n\t| \"catalog_truncated\";\n\nexport class PluginSelectionErrorV1 extends Error {\n\treadonly code: PluginSelectionErrorCodeV1;\n\treadonly pluginId?: string;\n\n\tconstructor(code: PluginSelectionErrorCodeV1, message: string, pluginId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PluginSelectionErrorV1\";\n\t\tthis.code = code;\n\t\tthis.pluginId = pluginId;\n\t}\n}\n\n/**\n * A pure catalog projection for a user selection. It never downloads,\n * writes, installs, activates, or mutates a plugin. The host owns those\n * operations through the separate installer contract.\n */\nexport interface PluginSelectionResolutionV1 {\n\treadonly selection: PluginSelectionV1;\n\t/** The bounded catalog of every discovered manifest. */\n\treadonly catalog: PluginCatalogSnapshotV1;\n\t/** Entries requested by the selection, in catalog order. */\n\treadonly entries: readonly PluginCatalogEntryV1[];\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n}\n\nexport interface PluginSelectionInputV1 {\n\treadonly profileId: string;\n\t/** Omitted means all discovered plugin IDs; [] means no plugin. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n}\n\nfunction validateId(value: unknown, label: \"profileId\" | \"pluginId\"): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"invalid_profile_id\" : \"invalid_plugin_id\",\n\t\t\tt(\"{label} must be a non-empty string\", { label }),\n\t\t\ttypeof value === \"string\" ? value : undefined,\n\t\t);\n\t}\n\tif (value.length > MAX_PLUGIN_SELECTION_ID_CHARS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"profile_id_too_long\" : \"plugin_id_too_long\",\n\t\t\tt(\"{label} must be at most {max} characters\", { label, max: MAX_PLUGIN_SELECTION_ID_CHARS_V1 }),\n\t\t\tvalue,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction normalizeIds(\n\tids: readonly string[] | undefined,\n\tlabel: \"selectedPluginIds\" | \"disabledPluginIds\",\n): readonly string[] {\n\tif (ids === undefined) return [];\n\tif (!Array.isArray(ids) || ids.length > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\tt(\"{label} must contain at most {max} plugin IDs\", { label, max: MAX_PLUGIN_SELECTION_IDS_V1 }),\n\t\t);\n\t}\n\tconst seen = new Set<string>();\n\tconst normalized: string[] = [];\n\tfor (const candidate of ids) {\n\t\tconst id = validateId(candidate, \"pluginId\");\n\t\tif (seen.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"duplicate_plugin_id\",\n\t\t\t\tt(\"{label} contains duplicate plugin ID: {id}\", { label, id }),\n\t\t\t\tid,\n\t\t\t);\n\t\t}\n\t\tseen.add(id);\n\t\tnormalized.push(id);\n\t}\n\tnormalized.sort((left, right) => left.localeCompare(right));\n\treturn Object.freeze(normalized);\n}\n\nfunction assertKnownIds(ids: readonly string[], knownIds: ReadonlySet<string>): void {\n\tfor (const id of ids) {\n\t\tif (!knownIds.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"unknown_plugin_id\",\n\t\t\t\tt(\"Selection references unknown plugin ID: {id}\", { id }),\n\t\t\t\tid,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Validate and freeze a selection without resolving or touching a host. */\nexport function createPluginSelectionV1(input: PluginSelectionInputV1): PluginSelectionV1 {\n\tconst profileId = validateId(input.profileId, \"profileId\");\n\tconst selectedPluginIds = normalizeIds(input.selectedPluginIds, \"selectedPluginIds\");\n\tconst disabledPluginIds = normalizeIds(input.disabledPluginIds, \"disabledPluginIds\");\n\treturn Object.freeze({\n\t\tversion: PLUGIN_SELECTION_VERSION_V1,\n\t\tprofileId,\n\t\tselectedPluginIds,\n\t\tdisabledPluginIds,\n\t});\n}\n\n/**\n * Resolve a selection to bounded catalog entries and diagnostics. This is a\n * read-only planning operation; it does not imply that any plugin is enabled.\n */\nexport function resolvePluginSelectionV1(input: {\n\treadonly selection: PluginSelectionInputV1;\n\treadonly manifests: readonly PluginManifestV1[];\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly maxEntries?: number;\n}): PluginSelectionResolutionV1 {\n\tfor (const manifest of input.manifests) validateId(manifest.id, \"pluginId\");\n\tconst knownIds = new Set(input.manifests.map((manifest) => manifest.id));\n\tconst provisional = createPluginSelectionV1(input.selection);\n\tif (input.selection.selectedPluginIds === undefined && knownIds.size > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\tt(\"discovered plugin IDs exceed the selection limit of {limit}\", { limit: MAX_PLUGIN_SELECTION_IDS_V1 }),\n\t\t);\n\t}\n\tconst selectedPluginIds =\n\t\tinput.selection.selectedPluginIds === undefined\n\t\t\t? Object.freeze([...knownIds].sort((a, b) => a.localeCompare(b)))\n\t\t\t: provisional.selectedPluginIds;\n\tconst selection = Object.freeze({ ...provisional, selectedPluginIds });\n\tassertKnownIds(selection.selectedPluginIds, knownIds);\n\tassertKnownIds(selection.disabledPluginIds, knownIds);\n\tconst catalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests,\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: input.maxEntries,\n\t});\n\tconst selected = new Set(selection.selectedPluginIds);\n\t// Resolve selected manifests separately so a bounded/truncated all-manifest\n\t// catalog cannot silently hide an explicitly selected plugin.\n\tconst selectedCatalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests.filter((manifest) => selected.has(manifest.id)),\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: Math.max(input.maxEntries ?? MAX_PLUGIN_SELECTION_IDS_V1, selection.selectedPluginIds.length),\n\t});\n\tif (selectedCatalog.truncated) {\n\t\tconst selectedEntryIds = new Set(selectedCatalog.entries.map((entry) => entry.pluginId));\n\t\tconst omitted = selection.selectedPluginIds.find((id) => !selectedEntryIds.has(id));\n\t\tif (omitted !== undefined) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"catalog_truncated\",\n\t\t\t\tt(\"Catalog truncation omitted selected plugin ID: {id}\", { id: omitted }),\n\t\t\t\tomitted,\n\t\t\t);\n\t\t}\n\t}\n\tconst entries = Object.freeze(selectedCatalog.entries);\n\tconst diagnostics = Object.freeze(entries.flatMap((entry) => entry.resolution.diagnostics));\n\treturn Object.freeze({ selection, catalog, entries, diagnostics });\n}\n\n/** Serialize only the stable selection data; no manifest, host, or payload is included. */\nexport function serializePluginSelectionV1(selection: PluginSelectionV1): string {\n\tconst normalized = createPluginSelectionV1(selection);\n\treturn JSON.stringify(normalized);\n}\n"]}
|