@ai-agent-forge/agent-forge 0.86.7 → 0.87.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 +18 -0
- package/README.md +8 -9
- 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 +410 -371
- package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
- package/dist/bundle/chunks/chunk-BFC2BDVJ.js +13 -0
- package/dist/bundle/chunks/chunk-MOHOLL3F.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 +3 -2
- 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 +2 -1
- 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.map +1 -1
- package/dist/core/agent-session-compaction.js +28 -22
- 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-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 -2
- 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 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +142 -34
- 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-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 +2 -1
- 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/facade/coding-agent-facade.d.ts +6 -0
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +2 -0
- 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 +227 -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 +265 -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 +288 -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-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 +8 -4
- 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.map +1 -1
- package/dist/core/provider-composer.js +22 -13
- 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 +19 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +74 -54
- 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 +11 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +27 -5
- 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 +94 -58
- 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.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -4
- 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 +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +113 -96
- 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 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +327 -243
- 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.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -2
- package/dist/modes/rpc/rpc-client.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.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +21 -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/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/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/keybindings.md +3 -0
- package/docs/quickstart.md +1 -1
- package/docs/settings.md +1 -0
- package/docs/terminal-setup.md +2 -3
- package/docs/usage.md +6 -5
- 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/package.json +1 -1
- package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.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 {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\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 PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\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\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin state 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 state 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 state file path\");\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin scope reference\");\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(`${label} is invalid`);\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(\"record source label is invalid\");\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\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 validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(\"record schema is invalid\");\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(\"record schema is invalid\");\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(\"state schema is invalid\");\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(\"state lifecycle is invalid\");\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"])) throw new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.records)) throw new Error(\"records must be an array\");\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\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 PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tif (installation.scope !== scope) throw new Error(\"installation scope does not match state scope\");\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\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 state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\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\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\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\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\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_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.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 {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\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 PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\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\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin state 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 state 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 state file path\"));\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin scope reference\"));\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(t(\"{label} is invalid\", { label }));\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(t(\"record source label is invalid\"));\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\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 validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(t(\"record schema is invalid\"));\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(t(\"record schema is invalid\"));\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(t(\"state schema is invalid\"));\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(t(\"state lifecycle is invalid\"));\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.records)) throw new Error(t(\"records must be an array\"));\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\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 PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tif (installation.scope !== scope) throw new Error(t(\"installation scope does not match state scope\"));\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\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 state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\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\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\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\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\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_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\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 { DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1, MAX_PLUGIN_SCOPE_REF_CHARS_V1, } from "./installer.js";
|
|
5
6
|
export const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1;
|
|
6
7
|
export const MAX_PLUGIN_STATE_RECORDS_V1 = 256;
|
|
@@ -26,14 +27,14 @@ function isMissingError(error) {
|
|
|
26
27
|
}
|
|
27
28
|
function validateFilePath(value) {
|
|
28
29
|
if (typeof value !== "string" || value.trim() === "" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)
|
|
29
|
-
throw new Error("invalid plugin state file path");
|
|
30
|
+
throw new Error(t("invalid plugin state file path"));
|
|
30
31
|
if (value.includes("\0") || /[\u0000-\u001f]/u.test(value))
|
|
31
|
-
throw new Error("invalid plugin state file path");
|
|
32
|
+
throw new Error(t("invalid plugin state file path"));
|
|
32
33
|
if (/^file:/iu.test(value) || (/^[a-z][a-z\d+.-]*:/iu.test(value) && !/^[a-z]:[\\/]/iu.test(value)))
|
|
33
|
-
throw new Error("invalid plugin state file path");
|
|
34
|
+
throw new Error(t("invalid plugin state file path"));
|
|
34
35
|
const normalized = isAbsolute(value) ? value : resolve(value);
|
|
35
36
|
if (basename(normalized).length === 0 || basename(normalized) === "." || basename(normalized) === "..")
|
|
36
|
-
throw new Error("invalid plugin state file path");
|
|
37
|
+
throw new Error(t("invalid plugin state file path"));
|
|
37
38
|
return normalized;
|
|
38
39
|
}
|
|
39
40
|
function validateOpaqueInstallationRef(value) {
|
|
@@ -47,18 +48,18 @@ function validateOpaqueInstallationRef(value) {
|
|
|
47
48
|
}
|
|
48
49
|
function validateScopeRef(scope, value) {
|
|
49
50
|
if (typeof value !== "string" || value.trim() === "" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)
|
|
50
|
-
throw new Error("invalid plugin scope reference");
|
|
51
|
+
throw new Error(t("invalid plugin scope reference"));
|
|
51
52
|
if (/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/u.test(value) || /\s/u.test(value))
|
|
52
|
-
throw new Error("invalid plugin scope reference");
|
|
53
|
+
throw new Error(t("invalid plugin scope reference"));
|
|
53
54
|
if (value.includes("\0") || /[\u0000-\u001f]/u.test(value))
|
|
54
|
-
throw new Error("invalid plugin scope reference");
|
|
55
|
+
throw new Error(t("invalid plugin scope reference"));
|
|
55
56
|
if (scope === "global" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)
|
|
56
|
-
throw new Error("invalid plugin scope reference");
|
|
57
|
+
throw new Error(t("invalid plugin scope reference"));
|
|
57
58
|
return value;
|
|
58
59
|
}
|
|
59
60
|
function validateString(value, label, max = MAX_PLUGIN_STATE_STRING_CHARS_V1) {
|
|
60
61
|
if (typeof value !== "string" || value.trim().length === 0 || value.length > max || /[\u0000-\u001f]/u.test(value))
|
|
61
|
-
throw new Error(
|
|
62
|
+
throw new Error(t("{label} is invalid", { label }));
|
|
62
63
|
return value;
|
|
63
64
|
}
|
|
64
65
|
/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */
|
|
@@ -67,7 +68,7 @@ function validateSourceLabel(value) {
|
|
|
67
68
|
value.length === 0 ||
|
|
68
69
|
value.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||
|
|
69
70
|
!/^[a-z][a-z0-9.:[\]_/@-]*$/u.test(value))
|
|
70
|
-
throw new Error("record source label is invalid");
|
|
71
|
+
throw new Error(t("record source label is invalid"));
|
|
71
72
|
return value;
|
|
72
73
|
}
|
|
73
74
|
function identityOf(record) {
|
|
@@ -84,26 +85,26 @@ function validateRecord(value) {
|
|
|
84
85
|
const requiredKeys = ["pluginId", "pluginVersion", "manifestDigest", "installationRef", "state"];
|
|
85
86
|
const allowedKeys = new Set([...requiredKeys, "source"]);
|
|
86
87
|
if (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))
|
|
87
|
-
throw new Error("record schema is invalid");
|
|
88
|
+
throw new Error(t("record schema is invalid"));
|
|
88
89
|
for (const key of requiredKeys)
|
|
89
90
|
if (!(key in value))
|
|
90
|
-
throw new Error("record schema is invalid");
|
|
91
|
+
throw new Error(t("record schema is invalid"));
|
|
91
92
|
const pluginId = validateString(value.pluginId, "pluginId", MAX_PLUGIN_STATE_ID_CHARS_V1);
|
|
92
93
|
const pluginVersion = validateString(value.pluginVersion, "pluginVersion", MAX_PLUGIN_STATE_ID_CHARS_V1);
|
|
93
94
|
const manifestDigest = validateString(value.manifestDigest, "manifestDigest");
|
|
94
95
|
const installationRef = validateOpaqueInstallationRef(value.installationRef);
|
|
95
96
|
const source = value.source === undefined ? undefined : validateSourceLabel(value.source);
|
|
96
97
|
if (!isObject(value.state) || !hasExactKeys(value.state, ["scope", "scopeRef", "enabled", "lifecycle"]))
|
|
97
|
-
throw new Error("state schema is invalid");
|
|
98
|
+
throw new Error(t("state schema is invalid"));
|
|
98
99
|
if (value.state.scope !== "global" && value.state.scope !== "project")
|
|
99
|
-
throw new Error("state scope is invalid");
|
|
100
|
+
throw new Error(t("state scope is invalid"));
|
|
100
101
|
const scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);
|
|
101
102
|
if (typeof value.state.enabled !== "boolean")
|
|
102
|
-
throw new Error("state enabled flag is invalid");
|
|
103
|
+
throw new Error(t("state enabled flag is invalid"));
|
|
103
104
|
if (value.state.lifecycle !== "installed" &&
|
|
104
105
|
value.state.lifecycle !== "active" &&
|
|
105
106
|
value.state.lifecycle !== "retained")
|
|
106
|
-
throw new Error("state lifecycle is invalid");
|
|
107
|
+
throw new Error(t("state lifecycle is invalid"));
|
|
107
108
|
return Object.freeze({
|
|
108
109
|
pluginId,
|
|
109
110
|
pluginVersion,
|
|
@@ -120,11 +121,11 @@ function validateRecord(value) {
|
|
|
120
121
|
}
|
|
121
122
|
function validateSnapshot(value) {
|
|
122
123
|
if (!isObject(value) || !hasExactKeys(value, ["version", "records"]))
|
|
123
|
-
throw new Error("snapshot schema is invalid");
|
|
124
|
+
throw new Error(t("snapshot schema is invalid"));
|
|
124
125
|
if (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1)
|
|
125
|
-
throw new Error("snapshot version is unsupported");
|
|
126
|
+
throw new Error(t("snapshot version is unsupported"));
|
|
126
127
|
if (!Array.isArray(value.records))
|
|
127
|
-
throw new Error("records must be an array");
|
|
128
|
+
throw new Error(t("records must be an array"));
|
|
128
129
|
if (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1)
|
|
129
130
|
throw new Error("too many plugin state records");
|
|
130
131
|
const records = value.records.map(validateRecord);
|
|
@@ -182,12 +183,12 @@ function makeRecord(installation, scope, enabled, source) {
|
|
|
182
183
|
const manifestDigest = validateString(installation.manifestDigest, "manifestDigest");
|
|
183
184
|
const installationRef = validateOpaqueInstallationRef(installation.installationRef);
|
|
184
185
|
if (scope !== "global" && scope !== "project")
|
|
185
|
-
throw new Error("state scope is invalid");
|
|
186
|
+
throw new Error(t("state scope is invalid"));
|
|
186
187
|
if (installation.scope !== scope)
|
|
187
|
-
throw new Error("installation scope does not match state scope");
|
|
188
|
+
throw new Error(t("installation scope does not match state scope"));
|
|
188
189
|
const scopeRef = validateScopeRef(scope, scope === "global" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef);
|
|
189
190
|
if (typeof enabled !== "boolean")
|
|
190
|
-
throw new Error("state enabled flag is invalid");
|
|
191
|
+
throw new Error(t("state enabled flag is invalid"));
|
|
191
192
|
const sourceLabel = source === undefined ? undefined : validateSourceLabel(source);
|
|
192
193
|
return Object.freeze({
|
|
193
194
|
pluginId,
|
|
@@ -312,7 +313,7 @@ export function createPluginStateStoreV1(options) {
|
|
|
312
313
|
pluginId = validateString(input.pluginId, "pluginId", MAX_PLUGIN_STATE_ID_CHARS_V1);
|
|
313
314
|
pluginVersion = validateString(input.pluginVersion, "pluginVersion", MAX_PLUGIN_STATE_ID_CHARS_V1);
|
|
314
315
|
if (input.scope !== "global" && input.scope !== "project")
|
|
315
|
-
throw new Error("state scope is invalid");
|
|
316
|
+
throw new Error(t("state scope is invalid"));
|
|
316
317
|
scope = input.scope;
|
|
317
318
|
scopeRef = validateScopeRef(scope, input.scopeRef);
|
|
318
319
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.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 {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\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 PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\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\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin state 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 state 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 state file path\");\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin scope reference\");\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(`${label} is invalid`);\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(\"record source label is invalid\");\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\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 validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(\"record schema is invalid\");\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(\"record schema is invalid\");\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(\"state schema is invalid\");\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(\"state lifecycle is invalid\");\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"])) throw new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.records)) throw new Error(\"records must be an array\");\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\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 PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tif (installation.scope !== scope) throw new Error(\"installation scope does not match state scope\");\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\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 state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\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\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\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\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\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_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.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 {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\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 PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\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\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin state 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 state 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 state file path\"));\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin scope reference\"));\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(t(\"{label} is invalid\", { label }));\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(t(\"record source label is invalid\"));\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\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 validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(t(\"record schema is invalid\"));\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(t(\"record schema is invalid\"));\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(t(\"state schema is invalid\"));\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(t(\"state lifecycle is invalid\"));\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.records)) throw new Error(t(\"records must be an array\"));\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\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 PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tif (installation.scope !== scope) throw new Error(t(\"installation scope does not match state scope\"));\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\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 state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\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\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\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\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\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_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\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([invalidFromError(error)]),\n\t\t\t\t\t});\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 identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,YAAY,CAAC;AAcpB,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEzE;AAoCD,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,CAUvB;AAED,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CAC3C,GAAG,oBAAoB,CAsEvB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAIzF;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;CACxC,GAAG,oBAAoB,CAMvB","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { resolvePluginCompatibilityV1 } from \"./resolver.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginSourceVerifierV1,\n\tPluginUpdateRecordV1,\n} from \"./types.ts\";\n\nfunction manifestPayload(manifest: PluginManifestV1): Record<string, unknown> {\n\treturn {\n\t\tid: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tapiVersion: manifest.apiVersion,\n\t\t...(manifest.capabilityRefs === undefined ? {} : { capabilityRefs: manifest.capabilityRefs }),\n\t\t...(manifest.requires === undefined ? {} : { requires: manifest.requires }),\n\t\t...(manifest.platform === undefined ? {} : { platform: manifest.platform }),\n\t\ttestOnly: manifest.testOnly ?? false,\n\t};\n}\n\nexport function pluginManifestDigestV1(manifest: PluginManifestV1): string {\n\treturn stableJsonDigest(manifestPayload(manifest) as Parameters<typeof stableJsonDigest>[0]);\n}\n\nfunction snapshotManifest(manifest: PluginManifestV1): PluginManifestV1 {\n\tconst capabilityRefs = manifest.capabilityRefs?.map((ref) => Object.freeze({ ...ref }));\n\tconst requires = manifest.requires?.map((requirement) => Object.freeze({ ...requirement }));\n\tconst platform = manifest.platform;\n\tconst runtime = platform?.runtime?.map((constraint) => Object.freeze({ ...constraint }));\n\tconst adapters = platform?.adapters?.map((adapter) =>\n\t\tObject.freeze({\n\t\t\t...adapter,\n\t\t\tos: Object.freeze([...adapter.os]),\n\t\t\t...(adapter.arch === undefined ? {} : { arch: Object.freeze([...adapter.arch]) }),\n\t\t\t...(adapter.hostFeatures === undefined ? {} : { hostFeatures: Object.freeze([...adapter.hostFeatures]) }),\n\t\t}),\n\t);\n\tconst platformSnapshot =\n\t\tplatform === undefined\n\t\t\t? undefined\n\t\t\t: Object.freeze({\n\t\t\t\t\t...platform,\n\t\t\t\t\tos: Object.freeze([...platform.os]),\n\t\t\t\t\t...(platform.arch === undefined ? {} : { arch: Object.freeze([...platform.arch]) }),\n\t\t\t\t\t...(runtime === undefined ? {} : { runtime: Object.freeze(runtime) }),\n\t\t\t\t\t...(platform.hostFeatures === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { hostFeatures: Object.freeze([...platform.hostFeatures]) }),\n\t\t\t\t\t...(adapters === undefined ? {} : { adapters: Object.freeze(adapters) }),\n\t\t\t\t});\n\treturn Object.freeze({\n\t\t...manifest,\n\t\t...(capabilityRefs === undefined ? {} : { capabilityRefs: Object.freeze(capabilityRefs) }),\n\t\t...(requires === undefined ? {} : { requires: Object.freeze(requires) }),\n\t\t...(platformSnapshot === undefined ? {} : { platform: platformSnapshot }),\n\t});\n}\n\n/** Create an immutable staged update; activation is a separate explicit transition. */\nexport function stagePluginUpdateV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly source: string;\n}): PluginUpdateRecordV1 {\n\tif (input.source.trim().length === 0) throw new Error(t(\"update source must be a non-empty string\"));\n\treturn Object.freeze({\n\t\tpluginId: input.manifest.id,\n\t\tpluginVersion: input.manifest.pluginVersion,\n\t\tsource: input.source,\n\t\tmanifest: snapshotManifest(input.manifest),\n\t\tmanifestDigest: pluginManifestDigestV1(input.manifest),\n\t\tstate: \"staged\",\n\t});\n}\n\nexport type UpdateVerificationV1 =\n\t| { readonly status: \"verified\"; readonly record: PluginUpdateRecordV1 }\n\t| { readonly status: \"rejected\"; readonly record: PluginUpdateRecordV1; readonly reason: string };\n\n/** Verify digest and host compatibility without applying any policy or side effect. */\nexport function verifyPluginUpdateV1(input: {\n\treadonly record: PluginUpdateRecordV1;\n\treadonly host: HostFactsV1;\n\treadonly expectedDigest?: string;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly verifier?: PluginSourceVerifierV1;\n}): UpdateVerificationV1 {\n\tconst actualDigest = pluginManifestDigestV1(input.record.manifest);\n\tif (input.record.state !== \"staged\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Update must be staged before verification: ${input.record.state}`,\n\t\t};\n\t}\n\tif (input.record.pluginId !== input.record.manifest.id) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin ID does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.pluginVersion !== input.record.manifest.pluginVersion) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin version does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.manifestDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Staged manifest digest drifted\" };\n\t}\n\tif (input.expectedDigest !== undefined && input.expectedDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Manifest digest does not match expectation\" };\n\t}\n\tconst resolution = resolvePluginCompatibilityV1({\n\t\tmanifest: input.record.manifest,\n\t\thost: input.host,\n\t\trequired: true,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\t// D-073: update verification enforces the declared host version range;\n\t\t// previously this path skipped the check entirely.\n\t\thostVersion: VERSION,\n\t});\n\tif (resolution.status !== \"installed-ready\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Plugin is not ready on host: ${resolution.status}`,\n\t\t};\n\t}\n\tif (input.verifier !== undefined) {\n\t\ttry {\n\t\t\tconst sourceVerification = input.verifier({\n\t\t\t\tpluginId: input.record.pluginId,\n\t\t\t\tpluginVersion: input.record.pluginVersion,\n\t\t\t\tsource: input.record.source,\n\t\t\t\tmanifestDigest: actualDigest,\n\t\t\t});\n\t\t\tif (sourceVerification.status !== \"accepted\") {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\trecord: input.record,\n\t\t\t\t\treason: \"Plugin source was rejected by the configured verifier\",\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstatus: \"rejected\",\n\t\t\t\trecord: input.record,\n\t\t\t\treason: \"Plugin source verifier failed\",\n\t\t\t};\n\t\t}\n\t}\n\tconst record = Object.freeze({ ...input.record, state: \"verified\" as const });\n\treturn { status: \"verified\", record };\n}\n\nexport function activatePluginUpdateV1(record: PluginUpdateRecordV1): PluginUpdateRecordV1 {\n\tif (record.state !== \"verified\")\n\t\tthrow new Error(t(\"Only a verified update can become active: {pluginId}\", { pluginId: record.pluginId }));\n\treturn Object.freeze({ ...record, state: \"active\" as const });\n}\n\n/** Preserve the old record and return it as active after a failed update. */\nexport function rollbackPluginUpdateV1(input: {\n\treadonly failed: PluginUpdateRecordV1;\n\treadonly previous: PluginUpdateRecordV1;\n}): PluginUpdateRecordV1 {\n\tif (input.previous.pluginId !== input.failed.pluginId) {\n\t\tthrow new Error(t(\"Cannot rollback updates for different plugins\"));\n\t}\n\tif (input.previous.state !== \"active\") throw new Error(t(\"Rollback target must be active\"));\n\treturn Object.freeze({ ...input.previous, state: \"active\" as const });\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VERSION } from "../../config.js";
|
|
2
|
+
import { t } from "../../core/i18n/index.js";
|
|
2
3
|
import { stableJsonDigest } from "../../profile/identity.js";
|
|
3
4
|
import { resolvePluginCompatibilityV1 } from "./resolver.js";
|
|
4
5
|
function manifestPayload(manifest) {
|
|
@@ -48,7 +49,7 @@ function snapshotManifest(manifest) {
|
|
|
48
49
|
/** Create an immutable staged update; activation is a separate explicit transition. */
|
|
49
50
|
export function stagePluginUpdateV1(input) {
|
|
50
51
|
if (input.source.trim().length === 0)
|
|
51
|
-
throw new Error("update source must be a non-empty string");
|
|
52
|
+
throw new Error(t("update source must be a non-empty string"));
|
|
52
53
|
return Object.freeze({
|
|
53
54
|
pluginId: input.manifest.id,
|
|
54
55
|
pluginVersion: input.manifest.pluginVersion,
|
|
@@ -133,16 +134,16 @@ export function verifyPluginUpdateV1(input) {
|
|
|
133
134
|
}
|
|
134
135
|
export function activatePluginUpdateV1(record) {
|
|
135
136
|
if (record.state !== "verified")
|
|
136
|
-
throw new Error(
|
|
137
|
+
throw new Error(t("Only a verified update can become active: {pluginId}", { pluginId: record.pluginId }));
|
|
137
138
|
return Object.freeze({ ...record, state: "active" });
|
|
138
139
|
}
|
|
139
140
|
/** Preserve the old record and return it as active after a failed update. */
|
|
140
141
|
export function rollbackPluginUpdateV1(input) {
|
|
141
142
|
if (input.previous.pluginId !== input.failed.pluginId) {
|
|
142
|
-
throw new Error("Cannot rollback updates for different plugins");
|
|
143
|
+
throw new Error(t("Cannot rollback updates for different plugins"));
|
|
143
144
|
}
|
|
144
145
|
if (input.previous.state !== "active")
|
|
145
|
-
throw new Error("Rollback target must be active");
|
|
146
|
+
throw new Error(t("Rollback target must be active"));
|
|
146
147
|
return Object.freeze({ ...input.previous, state: "active" });
|
|
147
148
|
}
|
|
148
149
|
//# sourceMappingURL=updates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updates.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { resolvePluginCompatibilityV1 } from \"./resolver.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginSourceVerifierV1,\n\tPluginUpdateRecordV1,\n} from \"./types.ts\";\n\nfunction manifestPayload(manifest: PluginManifestV1): Record<string, unknown> {\n\treturn {\n\t\tid: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tapiVersion: manifest.apiVersion,\n\t\t...(manifest.capabilityRefs === undefined ? {} : { capabilityRefs: manifest.capabilityRefs }),\n\t\t...(manifest.requires === undefined ? {} : { requires: manifest.requires }),\n\t\t...(manifest.platform === undefined ? {} : { platform: manifest.platform }),\n\t\ttestOnly: manifest.testOnly ?? false,\n\t};\n}\n\nexport function pluginManifestDigestV1(manifest: PluginManifestV1): string {\n\treturn stableJsonDigest(manifestPayload(manifest) as Parameters<typeof stableJsonDigest>[0]);\n}\n\nfunction snapshotManifest(manifest: PluginManifestV1): PluginManifestV1 {\n\tconst capabilityRefs = manifest.capabilityRefs?.map((ref) => Object.freeze({ ...ref }));\n\tconst requires = manifest.requires?.map((requirement) => Object.freeze({ ...requirement }));\n\tconst platform = manifest.platform;\n\tconst runtime = platform?.runtime?.map((constraint) => Object.freeze({ ...constraint }));\n\tconst adapters = platform?.adapters?.map((adapter) =>\n\t\tObject.freeze({\n\t\t\t...adapter,\n\t\t\tos: Object.freeze([...adapter.os]),\n\t\t\t...(adapter.arch === undefined ? {} : { arch: Object.freeze([...adapter.arch]) }),\n\t\t\t...(adapter.hostFeatures === undefined ? {} : { hostFeatures: Object.freeze([...adapter.hostFeatures]) }),\n\t\t}),\n\t);\n\tconst platformSnapshot =\n\t\tplatform === undefined\n\t\t\t? undefined\n\t\t\t: Object.freeze({\n\t\t\t\t\t...platform,\n\t\t\t\t\tos: Object.freeze([...platform.os]),\n\t\t\t\t\t...(platform.arch === undefined ? {} : { arch: Object.freeze([...platform.arch]) }),\n\t\t\t\t\t...(runtime === undefined ? {} : { runtime: Object.freeze(runtime) }),\n\t\t\t\t\t...(platform.hostFeatures === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { hostFeatures: Object.freeze([...platform.hostFeatures]) }),\n\t\t\t\t\t...(adapters === undefined ? {} : { adapters: Object.freeze(adapters) }),\n\t\t\t\t});\n\treturn Object.freeze({\n\t\t...manifest,\n\t\t...(capabilityRefs === undefined ? {} : { capabilityRefs: Object.freeze(capabilityRefs) }),\n\t\t...(requires === undefined ? {} : { requires: Object.freeze(requires) }),\n\t\t...(platformSnapshot === undefined ? {} : { platform: platformSnapshot }),\n\t});\n}\n\n/** Create an immutable staged update; activation is a separate explicit transition. */\nexport function stagePluginUpdateV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly source: string;\n}): PluginUpdateRecordV1 {\n\tif (input.source.trim().length === 0) throw new Error(\"update source must be a non-empty string\");\n\treturn Object.freeze({\n\t\tpluginId: input.manifest.id,\n\t\tpluginVersion: input.manifest.pluginVersion,\n\t\tsource: input.source,\n\t\tmanifest: snapshotManifest(input.manifest),\n\t\tmanifestDigest: pluginManifestDigestV1(input.manifest),\n\t\tstate: \"staged\",\n\t});\n}\n\nexport type UpdateVerificationV1 =\n\t| { readonly status: \"verified\"; readonly record: PluginUpdateRecordV1 }\n\t| { readonly status: \"rejected\"; readonly record: PluginUpdateRecordV1; readonly reason: string };\n\n/** Verify digest and host compatibility without applying any policy or side effect. */\nexport function verifyPluginUpdateV1(input: {\n\treadonly record: PluginUpdateRecordV1;\n\treadonly host: HostFactsV1;\n\treadonly expectedDigest?: string;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly verifier?: PluginSourceVerifierV1;\n}): UpdateVerificationV1 {\n\tconst actualDigest = pluginManifestDigestV1(input.record.manifest);\n\tif (input.record.state !== \"staged\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Update must be staged before verification: ${input.record.state}`,\n\t\t};\n\t}\n\tif (input.record.pluginId !== input.record.manifest.id) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin ID does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.pluginVersion !== input.record.manifest.pluginVersion) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin version does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.manifestDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Staged manifest digest drifted\" };\n\t}\n\tif (input.expectedDigest !== undefined && input.expectedDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Manifest digest does not match expectation\" };\n\t}\n\tconst resolution = resolvePluginCompatibilityV1({\n\t\tmanifest: input.record.manifest,\n\t\thost: input.host,\n\t\trequired: true,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\t// D-073: update verification enforces the declared host version range;\n\t\t// previously this path skipped the check entirely.\n\t\thostVersion: VERSION,\n\t});\n\tif (resolution.status !== \"installed-ready\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Plugin is not ready on host: ${resolution.status}`,\n\t\t};\n\t}\n\tif (input.verifier !== undefined) {\n\t\ttry {\n\t\t\tconst sourceVerification = input.verifier({\n\t\t\t\tpluginId: input.record.pluginId,\n\t\t\t\tpluginVersion: input.record.pluginVersion,\n\t\t\t\tsource: input.record.source,\n\t\t\t\tmanifestDigest: actualDigest,\n\t\t\t});\n\t\t\tif (sourceVerification.status !== \"accepted\") {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\trecord: input.record,\n\t\t\t\t\treason: \"Plugin source was rejected by the configured verifier\",\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstatus: \"rejected\",\n\t\t\t\trecord: input.record,\n\t\t\t\treason: \"Plugin source verifier failed\",\n\t\t\t};\n\t\t}\n\t}\n\tconst record = Object.freeze({ ...input.record, state: \"verified\" as const });\n\treturn { status: \"verified\", record };\n}\n\nexport function activatePluginUpdateV1(record: PluginUpdateRecordV1): PluginUpdateRecordV1 {\n\tif (record.state !== \"verified\") throw new Error(`Only a verified update can become active: ${record.pluginId}`);\n\treturn Object.freeze({ ...record, state: \"active\" as const });\n}\n\n/** Preserve the old record and return it as active after a failed update. */\nexport function rollbackPluginUpdateV1(input: {\n\treadonly failed: PluginUpdateRecordV1;\n\treadonly previous: PluginUpdateRecordV1;\n}): PluginUpdateRecordV1 {\n\tif (input.previous.pluginId !== input.failed.pluginId) {\n\t\tthrow new Error(\"Cannot rollback updates for different plugins\");\n\t}\n\tif (input.previous.state !== \"active\") throw new Error(\"Rollback target must be active\");\n\treturn Object.freeze({ ...input.previous, state: \"active\" as const });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"updates.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { resolvePluginCompatibilityV1 } from \"./resolver.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginSourceVerifierV1,\n\tPluginUpdateRecordV1,\n} from \"./types.ts\";\n\nfunction manifestPayload(manifest: PluginManifestV1): Record<string, unknown> {\n\treturn {\n\t\tid: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tapiVersion: manifest.apiVersion,\n\t\t...(manifest.capabilityRefs === undefined ? {} : { capabilityRefs: manifest.capabilityRefs }),\n\t\t...(manifest.requires === undefined ? {} : { requires: manifest.requires }),\n\t\t...(manifest.platform === undefined ? {} : { platform: manifest.platform }),\n\t\ttestOnly: manifest.testOnly ?? false,\n\t};\n}\n\nexport function pluginManifestDigestV1(manifest: PluginManifestV1): string {\n\treturn stableJsonDigest(manifestPayload(manifest) as Parameters<typeof stableJsonDigest>[0]);\n}\n\nfunction snapshotManifest(manifest: PluginManifestV1): PluginManifestV1 {\n\tconst capabilityRefs = manifest.capabilityRefs?.map((ref) => Object.freeze({ ...ref }));\n\tconst requires = manifest.requires?.map((requirement) => Object.freeze({ ...requirement }));\n\tconst platform = manifest.platform;\n\tconst runtime = platform?.runtime?.map((constraint) => Object.freeze({ ...constraint }));\n\tconst adapters = platform?.adapters?.map((adapter) =>\n\t\tObject.freeze({\n\t\t\t...adapter,\n\t\t\tos: Object.freeze([...adapter.os]),\n\t\t\t...(adapter.arch === undefined ? {} : { arch: Object.freeze([...adapter.arch]) }),\n\t\t\t...(adapter.hostFeatures === undefined ? {} : { hostFeatures: Object.freeze([...adapter.hostFeatures]) }),\n\t\t}),\n\t);\n\tconst platformSnapshot =\n\t\tplatform === undefined\n\t\t\t? undefined\n\t\t\t: Object.freeze({\n\t\t\t\t\t...platform,\n\t\t\t\t\tos: Object.freeze([...platform.os]),\n\t\t\t\t\t...(platform.arch === undefined ? {} : { arch: Object.freeze([...platform.arch]) }),\n\t\t\t\t\t...(runtime === undefined ? {} : { runtime: Object.freeze(runtime) }),\n\t\t\t\t\t...(platform.hostFeatures === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { hostFeatures: Object.freeze([...platform.hostFeatures]) }),\n\t\t\t\t\t...(adapters === undefined ? {} : { adapters: Object.freeze(adapters) }),\n\t\t\t\t});\n\treturn Object.freeze({\n\t\t...manifest,\n\t\t...(capabilityRefs === undefined ? {} : { capabilityRefs: Object.freeze(capabilityRefs) }),\n\t\t...(requires === undefined ? {} : { requires: Object.freeze(requires) }),\n\t\t...(platformSnapshot === undefined ? {} : { platform: platformSnapshot }),\n\t});\n}\n\n/** Create an immutable staged update; activation is a separate explicit transition. */\nexport function stagePluginUpdateV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly source: string;\n}): PluginUpdateRecordV1 {\n\tif (input.source.trim().length === 0) throw new Error(t(\"update source must be a non-empty string\"));\n\treturn Object.freeze({\n\t\tpluginId: input.manifest.id,\n\t\tpluginVersion: input.manifest.pluginVersion,\n\t\tsource: input.source,\n\t\tmanifest: snapshotManifest(input.manifest),\n\t\tmanifestDigest: pluginManifestDigestV1(input.manifest),\n\t\tstate: \"staged\",\n\t});\n}\n\nexport type UpdateVerificationV1 =\n\t| { readonly status: \"verified\"; readonly record: PluginUpdateRecordV1 }\n\t| { readonly status: \"rejected\"; readonly record: PluginUpdateRecordV1; readonly reason: string };\n\n/** Verify digest and host compatibility without applying any policy or side effect. */\nexport function verifyPluginUpdateV1(input: {\n\treadonly record: PluginUpdateRecordV1;\n\treadonly host: HostFactsV1;\n\treadonly expectedDigest?: string;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly verifier?: PluginSourceVerifierV1;\n}): UpdateVerificationV1 {\n\tconst actualDigest = pluginManifestDigestV1(input.record.manifest);\n\tif (input.record.state !== \"staged\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Update must be staged before verification: ${input.record.state}`,\n\t\t};\n\t}\n\tif (input.record.pluginId !== input.record.manifest.id) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin ID does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.pluginVersion !== input.record.manifest.pluginVersion) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin version does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.manifestDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Staged manifest digest drifted\" };\n\t}\n\tif (input.expectedDigest !== undefined && input.expectedDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Manifest digest does not match expectation\" };\n\t}\n\tconst resolution = resolvePluginCompatibilityV1({\n\t\tmanifest: input.record.manifest,\n\t\thost: input.host,\n\t\trequired: true,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\t// D-073: update verification enforces the declared host version range;\n\t\t// previously this path skipped the check entirely.\n\t\thostVersion: VERSION,\n\t});\n\tif (resolution.status !== \"installed-ready\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Plugin is not ready on host: ${resolution.status}`,\n\t\t};\n\t}\n\tif (input.verifier !== undefined) {\n\t\ttry {\n\t\t\tconst sourceVerification = input.verifier({\n\t\t\t\tpluginId: input.record.pluginId,\n\t\t\t\tpluginVersion: input.record.pluginVersion,\n\t\t\t\tsource: input.record.source,\n\t\t\t\tmanifestDigest: actualDigest,\n\t\t\t});\n\t\t\tif (sourceVerification.status !== \"accepted\") {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\trecord: input.record,\n\t\t\t\t\treason: \"Plugin source was rejected by the configured verifier\",\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstatus: \"rejected\",\n\t\t\t\trecord: input.record,\n\t\t\t\treason: \"Plugin source verifier failed\",\n\t\t\t};\n\t\t}\n\t}\n\tconst record = Object.freeze({ ...input.record, state: \"verified\" as const });\n\treturn { status: \"verified\", record };\n}\n\nexport function activatePluginUpdateV1(record: PluginUpdateRecordV1): PluginUpdateRecordV1 {\n\tif (record.state !== \"verified\")\n\t\tthrow new Error(t(\"Only a verified update can become active: {pluginId}\", { pluginId: record.pluginId }));\n\treturn Object.freeze({ ...record, state: \"active\" as const });\n}\n\n/** Preserve the old record and return it as active after a failed update. */\nexport function rollbackPluginUpdateV1(input: {\n\treadonly failed: PluginUpdateRecordV1;\n\treadonly previous: PluginUpdateRecordV1;\n}): PluginUpdateRecordV1 {\n\tif (input.previous.pluginId !== input.failed.pluginId) {\n\t\tthrow new Error(t(\"Cannot rollback updates for different plugins\"));\n\t}\n\tif (input.previous.state !== \"active\") throw new Error(t(\"Rollback target must be active\"));\n\treturn Object.freeze({ ...input.previous, state: \"active\" as const });\n}\n"]}
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP HTTP transport (4.3) — a streamable-HTTP MCP transport implementing the
|
|
3
|
-
* same transport interface as the stdio plugin, plus observable retry.
|
|
4
|
-
*
|
|
5
|
-
* Retries apply ONLY to requests the server could not have started (connect
|
|
6
|
-
* errors, 5xx, 429) — a completed response (any JSON-RPC reply) is never
|
|
7
|
-
* re-sent, keeping calls idempotent from the caller's perspective. Every
|
|
8
|
-
* transport error, retry attempt, and reconnect is reported through the
|
|
9
|
-
* `onEvent` callback so callers can observe what happened. CLI
|
|
10
|
-
* productization is out of scope.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Per-request options for MCP transports. Defined here rather than imported
|
|
14
|
-
* from the mcp-stdio example so production src never depends on examples/
|
|
15
|
-
* (统一修复轮 C reverse-dependency fix); structurally identical to the
|
|
16
|
-
* example's own declaration, which stays self-contained.
|
|
17
|
-
*/
|
|
18
1
|
export interface McpRequestOptions {
|
|
19
2
|
signal?: AbortSignal;
|
|
20
3
|
timeoutMs?: number;
|