@ai-agent-forge/agent-forge 0.86.7 → 0.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +10 -11
- package/dist/artifacts/artifact-store.d.ts.map +1 -1
- package/dist/artifacts/artifact-store.js +9 -5
- package/dist/artifacts/artifact-store.js.map +1 -1
- package/dist/bundle/.build-manifest.json +430 -413
- package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
- package/dist/bundle/chunks/chunk-HLJEVRWP.js +13 -0
- package/dist/bundle/chunks/chunk-YGHQME4V.js +1456 -0
- package/dist/bundle/chunks/image-resize-worker.js +12 -1
- package/dist/bundle/chunks/{virtual-modules-3IZ4MYSQ.js → virtual-modules-KZ5DRH7Q.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +2 -2
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +231 -185
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js +17 -4
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +15 -9
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +14 -7
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +6 -5
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +9 -8
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/plugin-manager-controller.d.ts.map +1 -1
- package/dist/cli/plugin-manager-controller.js +2 -1
- package/dist/cli/plugin-manager-controller.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +8 -5
- package/dist/cli/serve.js.map +1 -1
- package/dist/client/remote-session.d.ts.map +1 -1
- package/dist/client/remote-session.js +16 -9
- package/dist/client/remote-session.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-capability-contract.d.ts +0 -7
- package/dist/core/agent-capability-contract.d.ts.map +1 -1
- package/dist/core/agent-capability-contract.js +72 -68
- package/dist/core/agent-capability-contract.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +5 -4
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +6 -10
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +35 -133
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-context.d.ts.map +1 -1
- package/dist/core/agent-session-context.js +18 -13
- package/dist/core/agent-session-context.js.map +1 -1
- package/dist/core/agent-session-internal.d.ts +0 -6
- package/dist/core/agent-session-internal.d.ts.map +1 -1
- package/dist/core/agent-session-internal.js.map +1 -1
- package/dist/core/agent-session-model.d.ts.map +1 -1
- package/dist/core/agent-session-model.js +2 -1
- package/dist/core/agent-session-model.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +3 -3
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +7 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tools.d.ts.map +1 -1
- package/dist/core/agent-session-tools.js +3 -2
- package/dist/core/agent-session-tools.js.map +1 -1
- package/dist/core/agent-session.d.ts +40 -22
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +147 -67
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js +11 -5
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +9 -6
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +2 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/embedded-sdk.d.ts.map +1 -1
- package/dist/core/embedded-sdk.js +10 -6
- package/dist/core/embedded-sdk.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +9 -4
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/agent-composition.d.ts.map +1 -1
- package/dist/core/extensions/agent-composition.js +26 -19
- package/dist/core/extensions/agent-composition.js.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.js +3 -2
- package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.js +0 -34
- package/dist/core/extensions/bootstrap-compaction-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.js +20 -17
- package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js +2 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.js +4 -3
- package/dist/core/extensions/bootstrap-retry-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-skills.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-skills.js +7 -6
- package/dist/core/extensions/bootstrap-skills.js.map +1 -1
- package/dist/core/extensions/bootstrap-tools.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-tools.js +2 -1
- package/dist/core/extensions/bootstrap-tools.js.map +1 -1
- package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
- package/dist/core/extensions/capability-plugin.js +37 -13
- package/dist/core/extensions/capability-plugin.js.map +1 -1
- package/dist/core/extensions/capability-runtime-events.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-events.js +17 -13
- package/dist/core/extensions/capability-runtime-events.js.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.js +16 -15
- package/dist/core/extensions/capability-runtime-guards.js.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.js +52 -30
- package/dist/core/extensions/capability-runtime-manifest.js.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.js +66 -65
- package/dist/core/extensions/capability-runtime-validation.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +147 -127
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.d.ts.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.js +3 -2
- package/dist/core/extensions/compaction-memory-failure-mode.js.map +1 -1
- package/dist/core/extensions/context-strategy-binding.d.ts.map +1 -1
- package/dist/core/extensions/context-strategy-binding.js +7 -4
- package/dist/core/extensions/context-strategy-binding.js.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.js +290 -279
- package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.js +3 -2
- package/dist/core/extensions/lifecycle-delivery-queue.js.map +1 -1
- package/dist/core/extensions/provider-failover.d.ts +7 -3
- package/dist/core/extensions/provider-failover.d.ts.map +1 -1
- package/dist/core/extensions/provider-failover.js +9 -8
- package/dist/core/extensions/provider-failover.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +6 -6
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +2 -3
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/i18n/index.d.ts +14 -0
- package/dist/core/i18n/index.d.ts.map +1 -0
- package/dist/core/i18n/index.js +67 -0
- package/dist/core/i18n/index.js.map +1 -0
- package/dist/core/i18n/locales/en/example.d.ts +7 -0
- package/dist/core/i18n/locales/en/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/en/example.js +7 -0
- package/dist/core/i18n/locales/en/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.js +229 -0
- package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts +6 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.js +6 -0
- package/dist/core/i18n/locales/zh-cn/common.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js +173 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +582 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js +55 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +455 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js +191 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.js +10 -0
- package/dist/core/i18n/locales/zh-cn/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts +2 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.js +41 -0
- package/dist/core/i18n/locales/zh-cn/index.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +267 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js +67 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js +39 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js +15 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +102 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +286 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js +79 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js +72 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js.map +1 -0
- package/dist/core/keybindings.d.ts +15 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +18 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +5 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/model-config.d.ts +0 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +9 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +11 -7
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-install-host.d.ts.map +1 -1
- package/dist/core/package-install-host.js +4 -3
- package/dist/core/package-install-host.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +15 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-resource-collection.d.ts.map +1 -1
- package/dist/core/package-resource-collection.js +2 -1
- package/dist/core/package-resource-collection.js.map +1 -1
- package/dist/core/package-source.d.ts.map +1 -1
- package/dist/core/package-source.js +3 -2
- package/dist/core/package-source.js.map +1 -1
- package/dist/core/provider-composer.d.ts +2 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +29 -21
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +6 -2
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +15 -5
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/sdk.d.ts +27 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +80 -55
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +5 -2
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +2 -1
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +39 -29
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts.map +1 -1
- package/dist/core/session-storage.js +3 -3
- package/dist/core/session-storage.js.map +1 -1
- package/dist/core/settings-manager.d.ts +20 -20
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +47 -59
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +53 -32
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +25 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +9 -4
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +2 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +6 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/durable/durable-service.d.ts.map +1 -1
- package/dist/durable/durable-service.js +25 -18
- package/dist/durable/durable-service.js.map +1 -1
- package/dist/host/checkpoint-commit.d.ts.map +1 -1
- package/dist/host/checkpoint-commit.js +2 -1
- package/dist/host/checkpoint-commit.js.map +1 -1
- package/dist/host/manual-compaction.d.ts.map +1 -1
- package/dist/host/manual-compaction.js +2 -1
- package/dist/host/manual-compaction.js.map +1 -1
- package/dist/host/output-projection.d.ts +0 -13
- package/dist/host/output-projection.d.ts.map +1 -1
- package/dist/host/output-projection.js +16 -2
- package/dist/host/output-projection.js.map +1 -1
- package/dist/host/summary-retry.d.ts.map +1 -1
- package/dist/host/summary-retry.js +3 -2
- package/dist/host/summary-retry.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +97 -60
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/agents-view.js +18 -15
- package/dist/modes/interactive/components/agents-view.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -5
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +12 -7
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +2 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +6 -5
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +9 -5
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +18 -15
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +2 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.js +5 -4
- package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
- package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-input.js +2 -1
- package/dist/modes/interactive/components/dialog-input.js.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.js +4 -3
- package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +11 -10
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +0 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -10
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +3 -2
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +12 -11
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js +6 -2
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +28 -16
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +10 -9
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.js +22 -13
- package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js +27 -12
- package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.d.ts +60 -0
- package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/queue-manager-selector.js +166 -0
- package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +16 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +43 -31
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -6
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +115 -120
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js +5 -4
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +3 -2
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +4 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +14 -5
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +2 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +11 -4
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +8 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-list.js +7 -6
- package/dist/modes/interactive/components/tree-list.js.map +1 -1
- package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-render.js +28 -23
- package/dist/modes/interactive/components/tree-render.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +9 -7
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +5 -4
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/workflow-view.js +36 -21
- package/dist/modes/interactive/components/workflow-view.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth.js +71 -40
- package/dist/modes/interactive/interactive-auth.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts +1 -0
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +3 -0
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.js +5 -5
- package/dist/modes/interactive/interactive-dialog-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-format.js +34 -18
- package/dist/modes/interactive/interactive-format.js.map +1 -1
- package/dist/modes/interactive/interactive-helpers.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-helpers.js +7 -2
- package/dist/modes/interactive/interactive-helpers.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +350 -279
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.d.ts +9 -0
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +79 -25
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +5 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +26 -23
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +3 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +0 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -14
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +0 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -19
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +28 -13
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/plugins/ecosystem/catalog.d.ts.map +1 -1
- package/dist/plugins/ecosystem/catalog.js +3 -2
- package/dist/plugins/ecosystem/catalog.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +2 -1
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.d.ts.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.js +3 -2
- package/dist/plugins/ecosystem/default-plugin-market.js.map +1 -1
- package/dist/plugins/ecosystem/distribution.d.ts.map +1 -1
- package/dist/plugins/ecosystem/distribution.js +2 -1
- package/dist/plugins/ecosystem/distribution.js.map +1 -1
- package/dist/plugins/ecosystem/installer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/installer.js +3 -2
- package/dist/plugins/ecosystem/installer.js.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.js +20 -17
- package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.js +35 -34
- package/dist/plugins/ecosystem/node-distribution-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.js +35 -34
- package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +9 -8
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.js +4 -3
- package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +44 -5
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.js +10 -9
- package/dist/plugins/ecosystem/node-plugin-trust-root.js.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.js +31 -30
- package/dist/plugins/ecosystem/node-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.js +30 -29
- package/dist/plugins/ecosystem/node-release-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.js +11 -10
- package/dist/plugins/ecosystem/node-tar-writer.js.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.js +21 -20
- package/dist/plugins/ecosystem/node-url-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.js +3 -2
- package/dist/plugins/ecosystem/plugin-acquisition.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
- package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js +2 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js.map +1 -1
- package/dist/plugins/ecosystem/registry.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry.js +35 -32
- package/dist/plugins/ecosystem/registry.js.map +1 -1
- package/dist/plugins/ecosystem/resolver.d.ts.map +1 -1
- package/dist/plugins/ecosystem/resolver.js +3 -2
- package/dist/plugins/ecosystem/resolver.js.map +1 -1
- package/dist/plugins/ecosystem/selection-store.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection-store.js +11 -10
- package/dist/plugins/ecosystem/selection-store.js.map +1 -1
- package/dist/plugins/ecosystem/selection.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection.js +8 -7
- package/dist/plugins/ecosystem/selection.js.map +1 -1
- package/dist/plugins/ecosystem/state.d.ts.map +1 -1
- package/dist/plugins/ecosystem/state.js +24 -23
- package/dist/plugins/ecosystem/state.js.map +1 -1
- package/dist/plugins/ecosystem/updates.d.ts.map +1 -1
- package/dist/plugins/ecosystem/updates.js +5 -4
- package/dist/plugins/ecosystem/updates.js.map +1 -1
- package/dist/plugins/mcp-http.d.ts +0 -17
- package/dist/plugins/mcp-http.d.ts.map +1 -1
- package/dist/plugins/mcp-http.js +30 -7
- package/dist/plugins/mcp-http.js.map +1 -1
- package/dist/plugins/plugin-supervisor.d.ts.map +1 -1
- package/dist/plugins/plugin-supervisor.js +19 -1
- package/dist/plugins/plugin-supervisor.js.map +1 -1
- package/dist/profile/first-roles.d.ts.map +1 -1
- package/dist/profile/first-roles.js +10 -1
- package/dist/profile/first-roles.js.map +1 -1
- package/dist/profile/goal-plugin.d.ts.map +1 -1
- package/dist/profile/goal-plugin.js +24 -5
- package/dist/profile/goal-plugin.js.map +1 -1
- package/dist/profile/identity.d.ts.map +1 -1
- package/dist/profile/identity.js +7 -6
- package/dist/profile/identity.js.map +1 -1
- package/dist/profile/lock.d.ts.map +1 -1
- package/dist/profile/lock.js +15 -1
- package/dist/profile/lock.js.map +1 -1
- package/dist/profile/plan-plugin.d.ts.map +1 -1
- package/dist/profile/plan-plugin.js +26 -13
- package/dist/profile/plan-plugin.js.map +1 -1
- package/dist/profile/plugin-profiles.d.ts.map +1 -1
- package/dist/profile/plugin-profiles.js +2 -1
- package/dist/profile/plugin-profiles.js.map +1 -1
- package/dist/profile/policy-manifest.d.ts.map +1 -1
- package/dist/profile/policy-manifest.js +5 -4
- package/dist/profile/policy-manifest.js.map +1 -1
- package/dist/profile/profile-registry.d.ts +0 -12
- package/dist/profile/profile-registry.d.ts.map +1 -1
- package/dist/profile/profile-registry.js +14 -1
- package/dist/profile/profile-registry.js.map +1 -1
- package/dist/profile/role-catalog.d.ts +0 -1
- package/dist/profile/role-catalog.d.ts.map +1 -1
- package/dist/profile/role-catalog.js +17 -15
- package/dist/profile/role-catalog.js.map +1 -1
- package/dist/profile/role-orchestrator.d.ts.map +1 -1
- package/dist/profile/role-orchestrator.js +8 -7
- package/dist/profile/role-orchestrator.js.map +1 -1
- package/dist/profile/role-runner.d.ts.map +1 -1
- package/dist/profile/role-runner.js +3 -2
- package/dist/profile/role-runner.js.map +1 -1
- package/dist/profile/root-facade.d.ts.map +1 -1
- package/dist/profile/root-facade.js +2 -1
- package/dist/profile/root-facade.js.map +1 -1
- package/dist/profile/skill-discovery-wiring.d.ts.map +1 -1
- package/dist/profile/skill-discovery-wiring.js +7 -2
- package/dist/profile/skill-discovery-wiring.js.map +1 -1
- package/dist/profile/state-store.d.ts.map +1 -1
- package/dist/profile/state-store.js +13 -9
- package/dist/profile/state-store.js.map +1 -1
- package/dist/profile/todo-plugin.d.ts.map +1 -1
- package/dist/profile/todo-plugin.js +9 -4
- package/dist/profile/todo-plugin.js.map +1 -1
- package/dist/profiles/builtin-suites.d.ts +13 -6
- package/dist/profiles/builtin-suites.d.ts.map +1 -1
- package/dist/profiles/builtin-suites.js +15 -6
- package/dist/profiles/builtin-suites.js.map +1 -1
- package/dist/profiles/suite-loader.d.ts +25 -1
- package/dist/profiles/suite-loader.d.ts.map +1 -1
- package/dist/profiles/suite-loader.js +34 -9
- package/dist/profiles/suite-loader.js.map +1 -1
- package/dist/remote/server-entry.d.ts.map +1 -1
- package/dist/remote/server-entry.js +3 -2
- package/dist/remote/server-entry.js.map +1 -1
- package/dist/remote/session-source.d.ts.map +1 -1
- package/dist/remote/session-source.js +8 -4
- package/dist/remote/session-source.js.map +1 -1
- package/dist/share/session-share.d.ts.map +1 -1
- package/dist/share/session-share.js +14 -2
- package/dist/share/session-share.js.map +1 -1
- package/dist/testing/plugin-testkit.d.ts.map +1 -1
- package/dist/testing/plugin-testkit.js +4 -3
- package/dist/testing/plugin-testkit.js.map +1 -1
- package/dist/testing/runtime-delivery-queue.d.ts.map +1 -1
- package/dist/testing/runtime-delivery-queue.js +2 -1
- package/dist/testing/runtime-delivery-queue.js.map +1 -1
- package/dist/testing/session-plugin-testkit.d.ts.map +1 -1
- package/dist/testing/session-plugin-testkit.js +10 -7
- package/dist/testing/session-plugin-testkit.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +2 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +7 -6
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/photon.d.ts +2 -2
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +2 -2
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +9 -8
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +23 -13
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +5 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +1 -3
- package/docs/docs.json +4 -0
- package/docs/index.md +1 -0
- package/docs/keybindings.md +3 -0
- package/docs/mcp.md +103 -0
- package/docs/models.md +14 -22
- package/docs/providers.md +0 -1
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +1 -26
- package/docs/sdk.md +4 -6
- package/docs/settings.md +10 -12
- package/docs/skills.md +1 -9
- package/docs/terminal-setup.md +2 -3
- package/docs/usage.md +7 -6
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/examples/sdk/10-settings.ts +2 -4
- package/examples/sdk/12-full-control.ts +1 -2
- package/package.json +1 -3
- package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
- package/dist/core/extensions/microcompact.d.ts +0 -80
- package/dist/core/extensions/microcompact.d.ts.map +0 -1
- package/dist/core/extensions/microcompact.js +0 -134
- package/dist/core/extensions/microcompact.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/oauth-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiKeyAuth, AuthCheck, OAuthAuth } from \"@agent-forge/ai\";\nimport { Container, type Focusable, fuzzyFilter, getKeybindings, Input, Spacer, TruncatedText } from \"@agent-forge/tui\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nexport type AuthSelectorProvider = {\n\tid: string;\n\tname: string;\n\tauthType: \"oauth\" | \"api_key\";\n\tmethod?: ApiKeyAuth | OAuthAuth;\n\tstatus?: AuthCheck;\n};\n\nexport function formatAuthSelectorProviderType(authType: AuthSelectorProvider[\"authType\"]): string {\n\treturn authType === \"oauth\" ? \"subscription\" : \"API key\";\n}\n\n/**\n * Component that renders an auth provider selector\n */\nexport class OAuthSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to search input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tprivate listContainer: Container;\n\tprivate allProviders: AuthSelectorProvider[];\n\tprivate filteredProviders: AuthSelectorProvider[];\n\tprivate selectedIndex: number = 0;\n\tprivate mode: \"login\" | \"logout\";\n\tprivate onSelectCallback: (providerId: string, authType: AuthSelectorProvider[\"authType\"]) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate showAuthTypeLabels: boolean;\n\n\tconstructor(\n\t\tmode: \"login\" | \"logout\",\n\t\tproviders: AuthSelectorProvider[],\n\t\tonSelect: (providerId: string, authType: AuthSelectorProvider[\"authType\"]) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.mode = mode;\n\t\tthis.allProviders = providers;\n\t\tthis.filteredProviders = providers;\n\t\tthis.showAuthTypeLabels = new Set(providers.map((provider) => provider.authType)).size > 1;\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tconst title = mode === \"login\" ? \"Select provider to configure:\" : \"Select provider to logout:\";\n\t\tthis.addChild(new TruncatedText(theme.fg(\"accent\", theme.bold(title)), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.searchInput = new Input();\n\t\tif (initialSearchInput) {\n\t\t\tthis.searchInput.setValue(initialSearchInput);\n\t\t}\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\tconst selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\t// v8 ignore next -- the search input never receives the confirm key; the list intercepts it\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id, selectedProvider.authType);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create list container\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Initial render\n\t\tthis.filterProviders(initialSearchInput ?? \"\");\n\t}\n\n\tprivate filterProviders(query: string): void {\n\t\tthis.filteredProviders = query\n\t\t\t? fuzzyFilter(\n\t\t\t\t\tthis.allProviders,\n\t\t\t\t\tquery,\n\t\t\t\t\t(provider) => `${provider.name} ${provider.id} ${provider.authType} ${provider.method?.name ?? \"\"}`,\n\t\t\t\t)\n\t\t\t: this.allProviders;\n\t\tthis.selectedIndex = Math.max(0, Math.min(this.selectedIndex, Math.max(0, this.filteredProviders.length - 1)));\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 8;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredProviders.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredProviders.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst provider = this.filteredProviders[i];\n\t\t\t// v8 ignore next -- the visible slice is always within the filtered provider bounds\n\t\t\tif (!provider) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tconst statusIndicator = this.formatStatusIndicator(provider);\n\t\t\tconst authTypeLabel = this.showAuthTypeLabels\n\t\t\t\t? theme.fg(\"muted\", ` [${formatAuthSelectorProviderType(provider.authType)}]`)\n\t\t\t\t: \"\";\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst text = theme.fg(\"accent\", provider.name);\n\t\t\t\tline = prefix + text + authTypeLabel + statusIndicator;\n\t\t\t} else {\n\t\t\t\tconst text = ` ${theme.fg(\"text\", provider.name)}`;\n\t\t\t\tline = text + authTypeLabel + statusIndicator;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new TruncatedText(line, 1, 0));\n\t\t}\n\n\t\tif (startIndex > 0 || endIndex < this.filteredProviders.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredProviders.length})`);\n\t\t\tthis.listContainer.addChild(new TruncatedText(scrollInfo, 1, 0));\n\t\t}\n\n\t\t// Show \"no providers\" if empty\n\t\tif (this.filteredProviders.length === 0) {\n\t\t\tconst message =\n\t\t\t\tthis.allProviders.length === 0\n\t\t\t\t\t? this.mode === \"login\"\n\t\t\t\t\t\t? \"No providers available\"\n\t\t\t\t\t\t: \"No providers logged in. Use /login first.\"\n\t\t\t\t\t: \"No matching providers\";\n\t\t\tthis.listContainer.addChild(new TruncatedText(theme.fg(\"muted\", ` ${message}`), 1, 0));\n\t\t}\n\t}\n\n\tprivate formatStatusIndicator(provider: AuthSelectorProvider): string {\n\t\tif (!provider.status) return theme.fg(\"muted\", \" • unconfigured\");\n\t\tif (provider.status.type !== provider.authType) {\n\t\t\tconst label = provider.status.type === \"oauth\" ? \"subscription configured\" : \"API key configured\";\n\t\t\treturn theme.fg(\"muted\", \" • \") + theme.fg(\"warning\", label);\n\t\t}\n\t\tif (\n\t\t\t!provider.status.source ||\n\t\t\tprovider.status.source === \"OAuth\" ||\n\t\t\tprovider.status.source === \"stored credential\"\n\t\t) {\n\t\t\treturn theme.fg(\"success\", \" ✓ configured\");\n\t\t}\n\t\tconst source = /^[A-Z][A-Z0-9_]*(?:, [A-Z][A-Z0-9_]*)*$/.test(provider.status.source)\n\t\t\t? `env: ${provider.status.source}`\n\t\t\t: provider.status.source;\n\t\treturn theme.fg(\"success\", ` ✓ ${source}`);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Up arrow\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Down arrow\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.min(this.filteredProviders.length - 1, this.selectedIndex + 1);\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id, selectedProvider.authType);\n\t\t\t}\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterProviders(this.searchInput.getValue());\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oauth-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/oauth-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiKeyAuth, AuthCheck, OAuthAuth } from \"@agent-forge/ai\";\nimport { Container, type Focusable, fuzzyFilter, getKeybindings, Input, Spacer, TruncatedText } from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nexport type AuthSelectorProvider = {\n\tid: string;\n\tname: string;\n\tauthType: \"oauth\" | \"api_key\";\n\tmethod?: ApiKeyAuth | OAuthAuth;\n\tstatus?: AuthCheck;\n};\n\nexport function formatAuthSelectorProviderType(authType: AuthSelectorProvider[\"authType\"]): string {\n\treturn authType === \"oauth\" ? t(\"subscription\") : t(\"API key\");\n}\n\n/**\n * Component that renders an auth provider selector\n */\nexport class OAuthSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to search input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tprivate listContainer: Container;\n\tprivate allProviders: AuthSelectorProvider[];\n\tprivate filteredProviders: AuthSelectorProvider[];\n\tprivate selectedIndex: number = 0;\n\tprivate mode: \"login\" | \"logout\";\n\tprivate onSelectCallback: (providerId: string, authType: AuthSelectorProvider[\"authType\"]) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate showAuthTypeLabels: boolean;\n\n\tconstructor(\n\t\tmode: \"login\" | \"logout\",\n\t\tproviders: AuthSelectorProvider[],\n\t\tonSelect: (providerId: string, authType: AuthSelectorProvider[\"authType\"]) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.mode = mode;\n\t\tthis.allProviders = providers;\n\t\tthis.filteredProviders = providers;\n\t\tthis.showAuthTypeLabels = new Set(providers.map((provider) => provider.authType)).size > 1;\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tconst title = mode === \"login\" ? t(\"Select provider to configure:\") : t(\"Select provider to logout:\");\n\t\tthis.addChild(new TruncatedText(theme.fg(\"accent\", theme.bold(title)), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.searchInput = new Input();\n\t\tif (initialSearchInput) {\n\t\t\tthis.searchInput.setValue(initialSearchInput);\n\t\t}\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\tconst selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\t// v8 ignore next -- the search input never receives the confirm key; the list intercepts it\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id, selectedProvider.authType);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create list container\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Initial render\n\t\tthis.filterProviders(initialSearchInput ?? \"\");\n\t}\n\n\tprivate filterProviders(query: string): void {\n\t\tthis.filteredProviders = query\n\t\t\t? fuzzyFilter(\n\t\t\t\t\tthis.allProviders,\n\t\t\t\t\tquery,\n\t\t\t\t\t(provider) => `${provider.name} ${provider.id} ${provider.authType} ${provider.method?.name ?? \"\"}`,\n\t\t\t\t)\n\t\t\t: this.allProviders;\n\t\tthis.selectedIndex = Math.max(0, Math.min(this.selectedIndex, Math.max(0, this.filteredProviders.length - 1)));\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 8;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredProviders.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredProviders.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst provider = this.filteredProviders[i];\n\t\t\t// v8 ignore next -- the visible slice is always within the filtered provider bounds\n\t\t\tif (!provider) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tconst statusIndicator = this.formatStatusIndicator(provider);\n\t\t\tconst authTypeLabel = this.showAuthTypeLabels\n\t\t\t\t? theme.fg(\"muted\", ` [${formatAuthSelectorProviderType(provider.authType)}]`)\n\t\t\t\t: \"\";\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst text = theme.fg(\"accent\", provider.name);\n\t\t\t\tline = prefix + text + authTypeLabel + statusIndicator;\n\t\t\t} else {\n\t\t\t\tconst text = ` ${theme.fg(\"text\", provider.name)}`;\n\t\t\t\tline = text + authTypeLabel + statusIndicator;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new TruncatedText(line, 1, 0));\n\t\t}\n\n\t\tif (startIndex > 0 || endIndex < this.filteredProviders.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredProviders.length})`);\n\t\t\tthis.listContainer.addChild(new TruncatedText(scrollInfo, 1, 0));\n\t\t}\n\n\t\t// Show \"no providers\" if empty\n\t\tif (this.filteredProviders.length === 0) {\n\t\t\tconst message =\n\t\t\t\tthis.allProviders.length === 0\n\t\t\t\t\t? this.mode === \"login\"\n\t\t\t\t\t\t? t(\"No providers available\")\n\t\t\t\t\t\t: t(\"No providers logged in. Use /login first.\")\n\t\t\t\t\t: t(\"No matching providers\");\n\t\t\tthis.listContainer.addChild(new TruncatedText(theme.fg(\"muted\", ` ${message}`), 1, 0));\n\t\t}\n\t}\n\n\tprivate formatStatusIndicator(provider: AuthSelectorProvider): string {\n\t\tif (!provider.status) return theme.fg(\"muted\", ` • ${t(\"unconfigured\")}`);\n\t\tif (provider.status.type !== provider.authType) {\n\t\t\tconst label = provider.status.type === \"oauth\" ? t(\"subscription configured\") : t(\"API key configured\");\n\t\t\treturn theme.fg(\"muted\", \" • \") + theme.fg(\"warning\", label);\n\t\t}\n\t\tif (\n\t\t\t!provider.status.source ||\n\t\t\tprovider.status.source === \"OAuth\" ||\n\t\t\tprovider.status.source === \"stored credential\"\n\t\t) {\n\t\t\treturn theme.fg(\"success\", ` ✓ ${t(\"configured\")}`);\n\t\t}\n\t\tconst source = /^[A-Z][A-Z0-9_]*(?:, [A-Z][A-Z0-9_]*)*$/.test(provider.status.source)\n\t\t\t? t(\"env: {source}\", { source: provider.status.source })\n\t\t\t: provider.status.source;\n\t\treturn theme.fg(\"success\", ` ✓ ${source}`);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Up arrow\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Down arrow\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.min(this.filteredProviders.length - 1, this.selectedIndex + 1);\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id, selectedProvider.authType);\n\t\t\t}\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterProviders(this.searchInput.getValue());\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-manager-entry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-manager-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAmC,MAAM,kBAAkB,CAAC;AACnG,OAAO,KAAK,EACX,kCAAkC,EAClC,yBAAyB,EAGzB,uBAAuB,EACvB,MAAM,2CAA2C,CAAC;AAOnD,KAAK,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC7D,KAAK,yBAAyB,GAAG,OAAO,GAAG,OAAO,CAAC;AAWnD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,+BAA+B;IAC/C,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,kCAAkC,CAAC;CAC7D;AAED,MAAM,MAAM,8BAA8B,GAAG,+BAA+B,CAAC;AAwD7E;;;GAGG;AACH,qBAAa,2BAA4B,YAAW,SAAS,EAAE,SAAS;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAa;IAC5C,OAAO,CAAC,OAAO,CAA0D;IACzE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,YAAY,CAAoF;IACxG,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAIX;IACH,OAAO,CAAC,QAAQ,CAAS;IAEzB,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,YAAY,OAAO,EAAE,2BAA2B,EAK/C;IAED,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,OAAO;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAgE9B;YAEa,OAAO;YAgCP,OAAO;IA4Bf,iBAAiB,IAAI,OAAO,CAAC,8BAA8B,CAAC,CAEjE;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiD9B;IAED,UAAU,IAAI,IAAI,CAAG;IAErB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,iBAAiB,IAAI,qBAAqB,GAAG,SAAS,CAErD;IAED,SAAS,IAAI,+BAA+B,CAE3C;CACD","sourcesContent":["/**\n * Host-owned plugin installation/update entry for the config screen.\n *\n * This component deliberately projects the manager snapshot to a small UI\n * view. Registry sources, paths, signatures, package bytes, credentials and\n * host response text never participate in rendering or action selection.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginManagerControllerErrorCodeV1,\n\tPluginManagerControllerV1,\n\tPluginManagerEntryStatusV1,\n\tPluginManagerMutationResultV1,\n\tPluginManagerSnapshotV1,\n} from \"../../../cli/plugin-manager-controller.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PLUGIN_ENTRIES_V1 = 128;\nconst MAX_DISPLAY_CHARS_V1 = 256;\nconst MAX_DIAGNOSTIC_CODES_V1 = 8;\n\ntype PluginManagerActionV1 = \"install\" | \"update\" | \"remove\";\ntype PluginManagerViewStatusV1 = \"ready\" | \"error\";\n\ninterface PluginManagerViewEntryV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly status: PluginManagerEntryStatusV1;\n\treadonly installedVersion?: string;\n\treadonly lifecycle?: \"installed\" | \"active\" | \"retained\";\n\treadonly diagnosticCodes: readonly string[];\n}\n\nexport interface PluginManagerEntryOptionsV1 {\n\treadonly controller: PluginManagerControllerV1;\n\treadonly snapshot?: PluginManagerSnapshotV1;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nexport interface PluginManagerEntryOpenContextV1 {\n\treadonly status: PluginManagerViewStatusV1;\n\treadonly entryCount: number;\n\treadonly truncated: boolean;\n\treadonly diagnosticCode?: PluginManagerControllerErrorCodeV1;\n}\n\nexport type PluginManagerEntryOpenResultV1 = PluginManagerEntryOpenContextV1;\n\nfunction safeDisplay(value: string): string {\n\t// Registry/state validators bound these values, but the UI remains\n\t// defensive because the component is also usable with injected test hosts.\n\treturn value\n\t\t.replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/gu, \"\")\n\t\t.replace(/[\\u0000-\\u001f\\u007f]/gu, \"�\")\n\t\t.slice(0, MAX_DISPLAY_CHARS_V1);\n}\n\nfunction projectSnapshot(snapshot: PluginManagerSnapshotV1): {\n\treadonly entries: readonly PluginManagerViewEntryV1[];\n\treadonly truncated: boolean;\n} {\n\tconst entries = snapshot.entries.slice(0, MAX_PLUGIN_ENTRIES_V1).map((entry) => {\n\t\t// Explicitly select only fields intended for this UI. In particular,\n\t\t// registrySource and signed are not read here.\n\t\treturn Object.freeze({\n\t\t\tpluginId: entry.pluginId,\n\t\t\tpluginVersion: entry.pluginVersion,\n\t\t\tstatus: entry.status,\n\t\t\t...(entry.installedVersion === undefined ? {} : { installedVersion: entry.installedVersion }),\n\t\t\t...(entry.lifecycle === undefined ? {} : { lifecycle: entry.lifecycle }),\n\t\t\tdiagnosticCodes: Object.freeze(\n\t\t\t\tentry.diagnosticCodes.slice(0, MAX_DIAGNOSTIC_CODES_V1).map((code) => safeDisplay(code)),\n\t\t\t),\n\t\t});\n\t});\n\treturn Object.freeze({\n\t\tentries: Object.freeze(entries),\n\t\ttruncated: snapshot.truncated || snapshot.entries.length > MAX_PLUGIN_ENTRIES_V1,\n\t});\n}\n\nfunction actionsFor(entry: PluginManagerViewEntryV1): readonly PluginManagerActionV1[] {\n\tswitch (entry.status) {\n\t\tcase \"available\":\n\t\t\treturn [\"install\"];\n\t\tcase \"update-available\":\n\t\t\treturn [\"update\", \"remove\"];\n\t\tcase \"installed\":\n\t\t\treturn [\"remove\"];\n\t\tcase \"unavailable\":\n\t\t\treturn [];\n\t}\n}\n\nfunction actionTargetVersion(entry: PluginManagerViewEntryV1, action: PluginManagerActionV1): string | undefined {\n\treturn action === \"remove\" ? (entry.installedVersion ?? entry.pluginVersion) : entry.pluginVersion;\n}\n\nfunction errorCode(result: PluginManagerMutationResultV1): PluginManagerControllerErrorCodeV1 {\n\treturn result.code ?? \"manager-operation-failed\";\n}\n\n/**\n * Focusable manager surface. The outer config selector owns navigation to this\n * entry; this surface owns confirmation and only emits stable host codes.\n */\nexport class PluginManagerEntryComponent implements Component, Focusable {\n\tprivate readonly controller: PluginManagerControllerV1;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate entries: readonly PluginManagerViewEntryV1[] = Object.freeze([]);\n\tprivate truncated = false;\n\tprivate selectedIndex = 0;\n\tprivate selectedActionIndex = 0;\n\tprivate confirmation: { readonly pluginId: string; readonly action: PluginManagerActionV1 } | undefined;\n\tprivate busy = false;\n\tprivate status: PluginManagerEntryOpenContextV1 = Object.freeze({\n\t\tstatus: \"error\",\n\t\tentryCount: 0,\n\t\ttruncated: false,\n\t});\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginManagerEntryOptionsV1) {\n\t\tthis.controller = options.controller;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tif (options.snapshot !== undefined) this.setSnapshot(options.snapshot);\n\t}\n\n\tprivate setSnapshot(snapshot: PluginManagerSnapshotV1): void {\n\t\tconst projected = projectSnapshot(snapshot);\n\t\tthis.entries = projected.entries;\n\t\tthis.truncated = projected.truncated;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.entries.length - 1));\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.status = Object.freeze({\n\t\t\tstatus: \"ready\",\n\t\t\tentryCount: this.entries.length,\n\t\t\ttruncated: this.truncated,\n\t\t});\n\t}\n\n\tprivate currentEntry(): PluginManagerViewEntryV1 | undefined {\n\t\treturn this.entries[this.selectedIndex];\n\t}\n\n\tprivate currentActions(): readonly PluginManagerActionV1[] {\n\t\tconst entry = this.currentEntry();\n\t\treturn entry === undefined ? [] : actionsFor(entry);\n\t}\n\n\tprivate currentAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentActions()[this.selectedActionIndex];\n\t}\n\n\tprivate request(): void {\n\t\tthis.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this._focused) {\n\t\t\tconst state = this.status.status === \"ready\" ? `catalog ${this.status.entryCount}` : \"catalog unavailable\";\n\t\t\tconst bounded = this.truncated ? \", bounded\" : \"\";\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", ` Plugin manager · ${state}${bounded} · Enter open`), width, \"...\"),\n\t\t\t];\n\t\t}\n\n\t\tconst lines: string[] = [truncateToWidth(theme.bold(\" Plugin manager\"), width, \"...\")];\n\t\tif (this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"accent\", \" Working…\"), width, \"...\"));\n\t\t} else if (this.confirmation !== undefined) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tconst targetVersion = actionTargetVersion(entry, action) ?? entry.pluginVersion;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t` Confirm ${action} ${safeDisplay(entry.pluginId)}@${safeDisplay(targetVersion)}? Enter confirm · Esc cancel`,\n\t\t\t\t\t\t),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (this.status.status === \"error\" && this.status.diagnosticCode !== undefined) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"error\", ` Error: ${this.status.diagnosticCode}`), width, \"...\"));\n\t\t}\n\n\t\tif (this.entries.length === 0) {\n\t\t\tlines.push(theme.fg(\"dim\", \" No plugins available\"));\n\t\t} else {\n\t\t\tfor (const [index, entry] of this.entries.entries()) {\n\t\t\t\tconst selected = index === this.selectedIndex;\n\t\t\t\tconst cursor = selected ? \">\" : \" \";\n\t\t\t\tconst status = entry.status;\n\t\t\t\tconst installed =\n\t\t\t\t\tentry.installedVersion === undefined ? \"\" : ` installed ${safeDisplay(entry.installedVersion)}`;\n\t\t\t\tconst diagnostics = entry.diagnosticCodes.length === 0 ? \"\" : ` [${entry.diagnosticCodes.join(\", \")}]`;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${cursor} ${safeDisplay(entry.pluginId)}@${safeDisplay(entry.pluginVersion)} · ${status}${installed}${diagnostics}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst actions = this.currentActions();\n\t\tif (actions.length > 0 && !this.busy) {\n\t\t\tconst action = this.currentAction();\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", ` Action: ${action} · Tab switch action · Enter confirm`), width, \"...\"),\n\t\t\t);\n\t\t} else if (this.entries.length > 0 && !this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", \" Selected plugin is unavailable\"), width, \"...\"));\n\t\t}\n\t\tif (this.truncated) lines.push(theme.fg(\"dim\", \" (list bounded)\"));\n\t\tlines.push(truncateToWidth(theme.fg(\"dim\", \" ↑↓ navigate · Esc close\"), width, \"...\"));\n\t\treturn lines;\n\t}\n\n\tprivate async refresh(): Promise<PluginManagerEntryOpenContextV1> {\n\t\ttry {\n\t\t\tconst result = await this.controller.getSnapshot();\n\t\t\tif (result.status === \"ok\") {\n\t\t\t\tthis.setSnapshot(result.snapshot);\n\t\t\t\tthis.request();\n\t\t\t\treturn this.status;\n\t\t\t}\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: result.code,\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t} catch {\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: \"manager-operation-failed\",\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t}\n\t}\n\n\tprivate async perform(action: PluginManagerActionV1): Promise<void> {\n\t\tconst entry = this.currentEntry();\n\t\tif (entry === undefined) return;\n\t\tthis.busy = true;\n\t\tthis.confirmation = undefined;\n\t\tthis.request();\n\t\tlet result: PluginManagerMutationResultV1;\n\t\ttry {\n\t\t\tconst input = {\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tpluginVersion: actionTargetVersion(entry, action),\n\t\t\t\tconfirmed: true as const,\n\t\t\t};\n\t\t\tresult = await this.controller[action](input);\n\t\t} catch {\n\t\t\tresult = { status: \"failed\", code: \"manager-operation-failed\" };\n\t\t}\n\t\tif (result.snapshot !== undefined) this.setSnapshot(result.snapshot);\n\t\tconst mutationCode = result.status === \"succeeded\" ? undefined : errorCode(result);\n\t\tconst refreshed = result.snapshot === undefined ? await this.refresh() : this.status;\n\t\tif (mutationCode !== undefined) {\n\t\t\tthis.status = Object.freeze({ ...refreshed, status: \"error\", diagnosticCode: mutationCode });\n\t\t}\n\t\tthis.busy = false;\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.request();\n\t}\n\n\tasync openPluginManager(): Promise<PluginManagerEntryOpenResultV1> {\n\t\treturn await this.refresh();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused) return;\n\t\tconst kb = getKeybindings();\n\t\tif (this.busy) return;\n\t\tif (this.confirmation !== undefined) {\n\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.confirmation = undefined;\n\t\t\t\tthis.request();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tconst action = this.currentAction();\n\t\t\t\tif (action !== undefined) void this.perform(action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(Math.max(0, this.entries.length - 1), this.selectedIndex + 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.input.tab\")) {\n\t\t\tconst actions = this.currentActions();\n\t\t\tif (actions.length > 0) this.selectedActionIndex = (this.selectedActionIndex + 1) % actions.length;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tthis.confirmation = { pluginId: entry.pluginId, action };\n\t\t\t\tthis.request();\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectedPluginId(): string | undefined {\n\t\treturn this.currentEntry()?.pluginId;\n\t}\n\n\tgetSelectedAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentAction();\n\t}\n\n\tgetStatus(): PluginManagerEntryOpenContextV1 {\n\t\treturn this.status;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin-manager-entry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-manager-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAmC,MAAM,kBAAkB,CAAC;AACnG,OAAO,KAAK,EACX,kCAAkC,EAClC,yBAAyB,EAGzB,uBAAuB,EACvB,MAAM,2CAA2C,CAAC;AAQnD,KAAK,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC7D,KAAK,yBAAyB,GAAG,OAAO,GAAG,OAAO,CAAC;AAWnD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,+BAA+B;IAC/C,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,kCAAkC,CAAC;CAC7D;AAED,MAAM,MAAM,8BAA8B,GAAG,+BAA+B,CAAC;AAwD7E;;;GAGG;AACH,qBAAa,2BAA4B,YAAW,SAAS,EAAE,SAAS;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAa;IAC5C,OAAO,CAAC,OAAO,CAA0D;IACzE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,YAAY,CAAoF;IACxG,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAIX;IACH,OAAO,CAAC,QAAQ,CAAS;IAEzB,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,YAAY,OAAO,EAAE,2BAA2B,EAK/C;IAED,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,OAAO;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0F9B;YAEa,OAAO;YAgCP,OAAO;IA4Bf,iBAAiB,IAAI,OAAO,CAAC,8BAA8B,CAAC,CAEjE;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiD9B;IAED,UAAU,IAAI,IAAI,CAAG;IAErB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,iBAAiB,IAAI,qBAAqB,GAAG,SAAS,CAErD;IAED,SAAS,IAAI,+BAA+B,CAE3C;CACD","sourcesContent":["/**\n * Host-owned plugin installation/update entry for the config screen.\n *\n * This component deliberately projects the manager snapshot to a small UI\n * view. Registry sources, paths, signatures, package bytes, credentials and\n * host response text never participate in rendering or action selection.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginManagerControllerErrorCodeV1,\n\tPluginManagerControllerV1,\n\tPluginManagerEntryStatusV1,\n\tPluginManagerMutationResultV1,\n\tPluginManagerSnapshotV1,\n} from \"../../../cli/plugin-manager-controller.ts\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PLUGIN_ENTRIES_V1 = 128;\nconst MAX_DISPLAY_CHARS_V1 = 256;\nconst MAX_DIAGNOSTIC_CODES_V1 = 8;\n\ntype PluginManagerActionV1 = \"install\" | \"update\" | \"remove\";\ntype PluginManagerViewStatusV1 = \"ready\" | \"error\";\n\ninterface PluginManagerViewEntryV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly status: PluginManagerEntryStatusV1;\n\treadonly installedVersion?: string;\n\treadonly lifecycle?: \"installed\" | \"active\" | \"retained\";\n\treadonly diagnosticCodes: readonly string[];\n}\n\nexport interface PluginManagerEntryOptionsV1 {\n\treadonly controller: PluginManagerControllerV1;\n\treadonly snapshot?: PluginManagerSnapshotV1;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nexport interface PluginManagerEntryOpenContextV1 {\n\treadonly status: PluginManagerViewStatusV1;\n\treadonly entryCount: number;\n\treadonly truncated: boolean;\n\treadonly diagnosticCode?: PluginManagerControllerErrorCodeV1;\n}\n\nexport type PluginManagerEntryOpenResultV1 = PluginManagerEntryOpenContextV1;\n\nfunction safeDisplay(value: string): string {\n\t// Registry/state validators bound these values, but the UI remains\n\t// defensive because the component is also usable with injected test hosts.\n\treturn value\n\t\t.replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/gu, \"\")\n\t\t.replace(/[\\u0000-\\u001f\\u007f]/gu, \"�\")\n\t\t.slice(0, MAX_DISPLAY_CHARS_V1);\n}\n\nfunction projectSnapshot(snapshot: PluginManagerSnapshotV1): {\n\treadonly entries: readonly PluginManagerViewEntryV1[];\n\treadonly truncated: boolean;\n} {\n\tconst entries = snapshot.entries.slice(0, MAX_PLUGIN_ENTRIES_V1).map((entry) => {\n\t\t// Explicitly select only fields intended for this UI. In particular,\n\t\t// registrySource and signed are not read here.\n\t\treturn Object.freeze({\n\t\t\tpluginId: entry.pluginId,\n\t\t\tpluginVersion: entry.pluginVersion,\n\t\t\tstatus: entry.status,\n\t\t\t...(entry.installedVersion === undefined ? {} : { installedVersion: entry.installedVersion }),\n\t\t\t...(entry.lifecycle === undefined ? {} : { lifecycle: entry.lifecycle }),\n\t\t\tdiagnosticCodes: Object.freeze(\n\t\t\t\tentry.diagnosticCodes.slice(0, MAX_DIAGNOSTIC_CODES_V1).map((code) => safeDisplay(code)),\n\t\t\t),\n\t\t});\n\t});\n\treturn Object.freeze({\n\t\tentries: Object.freeze(entries),\n\t\ttruncated: snapshot.truncated || snapshot.entries.length > MAX_PLUGIN_ENTRIES_V1,\n\t});\n}\n\nfunction actionsFor(entry: PluginManagerViewEntryV1): readonly PluginManagerActionV1[] {\n\tswitch (entry.status) {\n\t\tcase \"available\":\n\t\t\treturn [\"install\"];\n\t\tcase \"update-available\":\n\t\t\treturn [\"update\", \"remove\"];\n\t\tcase \"installed\":\n\t\t\treturn [\"remove\"];\n\t\tcase \"unavailable\":\n\t\t\treturn [];\n\t}\n}\n\nfunction actionTargetVersion(entry: PluginManagerViewEntryV1, action: PluginManagerActionV1): string | undefined {\n\treturn action === \"remove\" ? (entry.installedVersion ?? entry.pluginVersion) : entry.pluginVersion;\n}\n\nfunction errorCode(result: PluginManagerMutationResultV1): PluginManagerControllerErrorCodeV1 {\n\treturn result.code ?? \"manager-operation-failed\";\n}\n\n/**\n * Focusable manager surface. The outer config selector owns navigation to this\n * entry; this surface owns confirmation and only emits stable host codes.\n */\nexport class PluginManagerEntryComponent implements Component, Focusable {\n\tprivate readonly controller: PluginManagerControllerV1;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate entries: readonly PluginManagerViewEntryV1[] = Object.freeze([]);\n\tprivate truncated = false;\n\tprivate selectedIndex = 0;\n\tprivate selectedActionIndex = 0;\n\tprivate confirmation: { readonly pluginId: string; readonly action: PluginManagerActionV1 } | undefined;\n\tprivate busy = false;\n\tprivate status: PluginManagerEntryOpenContextV1 = Object.freeze({\n\t\tstatus: \"error\",\n\t\tentryCount: 0,\n\t\ttruncated: false,\n\t});\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginManagerEntryOptionsV1) {\n\t\tthis.controller = options.controller;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tif (options.snapshot !== undefined) this.setSnapshot(options.snapshot);\n\t}\n\n\tprivate setSnapshot(snapshot: PluginManagerSnapshotV1): void {\n\t\tconst projected = projectSnapshot(snapshot);\n\t\tthis.entries = projected.entries;\n\t\tthis.truncated = projected.truncated;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.entries.length - 1));\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.status = Object.freeze({\n\t\t\tstatus: \"ready\",\n\t\t\tentryCount: this.entries.length,\n\t\t\ttruncated: this.truncated,\n\t\t});\n\t}\n\n\tprivate currentEntry(): PluginManagerViewEntryV1 | undefined {\n\t\treturn this.entries[this.selectedIndex];\n\t}\n\n\tprivate currentActions(): readonly PluginManagerActionV1[] {\n\t\tconst entry = this.currentEntry();\n\t\treturn entry === undefined ? [] : actionsFor(entry);\n\t}\n\n\tprivate currentAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentActions()[this.selectedActionIndex];\n\t}\n\n\tprivate request(): void {\n\t\tthis.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this._focused) {\n\t\t\tconst state =\n\t\t\t\tthis.status.status === \"ready\"\n\t\t\t\t\t? t(\"catalog {count}\", { count: this.status.entryCount })\n\t\t\t\t\t: t(\"catalog unavailable\");\n\t\t\tconst bounded = this.truncated ? t(\", bounded\") : \"\";\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"muted\", ` ${t(\"Plugin manager · {state}{bounded} · Enter open\", { state, bounded })}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tconst lines: string[] = [truncateToWidth(theme.bold(` ${t(\"Plugin manager\")}`), width, \"...\")];\n\t\tif (this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"accent\", ` ${t(\"Working…\")}`), width, \"...\"));\n\t\t} else if (this.confirmation !== undefined) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tconst targetVersion = actionTargetVersion(entry, action) ?? entry.pluginVersion;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t` ${t(\"Confirm {action} {plugin}@{version}? Enter confirm · Esc cancel\", {\n\t\t\t\t\t\t\t\taction,\n\t\t\t\t\t\t\t\tplugin: safeDisplay(entry.pluginId),\n\t\t\t\t\t\t\t\tversion: safeDisplay(targetVersion),\n\t\t\t\t\t\t\t})}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (this.status.status === \"error\" && this.status.diagnosticCode !== undefined) {\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"error\", ` ${t(\"Error: {code}\", { code: this.status.diagnosticCode })}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (this.entries.length === 0) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${t(\"No plugins available\")}`));\n\t\t} else {\n\t\t\tfor (const [index, entry] of this.entries.entries()) {\n\t\t\t\tconst selected = index === this.selectedIndex;\n\t\t\t\tconst cursor = selected ? \">\" : \" \";\n\t\t\t\tconst status = entry.status;\n\t\t\t\tconst installed =\n\t\t\t\t\tentry.installedVersion === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: ` ${t(\"installed {version}\", { version: safeDisplay(entry.installedVersion) })}`;\n\t\t\t\tconst diagnostics = entry.diagnosticCodes.length === 0 ? \"\" : ` [${entry.diagnosticCodes.join(\", \")}]`;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${cursor} ${safeDisplay(entry.pluginId)}@${safeDisplay(entry.pluginVersion)} · ${status}${installed}${diagnostics}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst actions = this.currentActions();\n\t\tif (actions.length > 0 && !this.busy) {\n\t\t\tconst action = this.currentAction();\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t` ${t(\"Action: {action} · Tab switch action · Enter confirm\", { action: action ?? \"install\" })}`,\n\t\t\t\t\t),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (this.entries.length > 0 && !this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${t(\"Selected plugin is unavailable\")}`), width, \"...\"));\n\t\t}\n\t\tif (this.truncated) lines.push(theme.fg(\"dim\", ` ${t(\"(list bounded)\")}`));\n\t\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${t(\"↑↓ navigate · Esc close\")}`), width, \"...\"));\n\t\treturn lines;\n\t}\n\n\tprivate async refresh(): Promise<PluginManagerEntryOpenContextV1> {\n\t\ttry {\n\t\t\tconst result = await this.controller.getSnapshot();\n\t\t\tif (result.status === \"ok\") {\n\t\t\t\tthis.setSnapshot(result.snapshot);\n\t\t\t\tthis.request();\n\t\t\t\treturn this.status;\n\t\t\t}\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: result.code,\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t} catch {\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: \"manager-operation-failed\",\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t}\n\t}\n\n\tprivate async perform(action: PluginManagerActionV1): Promise<void> {\n\t\tconst entry = this.currentEntry();\n\t\tif (entry === undefined) return;\n\t\tthis.busy = true;\n\t\tthis.confirmation = undefined;\n\t\tthis.request();\n\t\tlet result: PluginManagerMutationResultV1;\n\t\ttry {\n\t\t\tconst input = {\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tpluginVersion: actionTargetVersion(entry, action),\n\t\t\t\tconfirmed: true as const,\n\t\t\t};\n\t\t\tresult = await this.controller[action](input);\n\t\t} catch {\n\t\t\tresult = { status: \"failed\", code: \"manager-operation-failed\" };\n\t\t}\n\t\tif (result.snapshot !== undefined) this.setSnapshot(result.snapshot);\n\t\tconst mutationCode = result.status === \"succeeded\" ? undefined : errorCode(result);\n\t\tconst refreshed = result.snapshot === undefined ? await this.refresh() : this.status;\n\t\tif (mutationCode !== undefined) {\n\t\t\tthis.status = Object.freeze({ ...refreshed, status: \"error\", diagnosticCode: mutationCode });\n\t\t}\n\t\tthis.busy = false;\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.request();\n\t}\n\n\tasync openPluginManager(): Promise<PluginManagerEntryOpenResultV1> {\n\t\treturn await this.refresh();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused) return;\n\t\tconst kb = getKeybindings();\n\t\tif (this.busy) return;\n\t\tif (this.confirmation !== undefined) {\n\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.confirmation = undefined;\n\t\t\t\tthis.request();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tconst action = this.currentAction();\n\t\t\t\tif (action !== undefined) void this.perform(action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(Math.max(0, this.entries.length - 1), this.selectedIndex + 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.input.tab\")) {\n\t\t\tconst actions = this.currentActions();\n\t\t\tif (actions.length > 0) this.selectedActionIndex = (this.selectedActionIndex + 1) % actions.length;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tthis.confirmation = { pluginId: entry.pluginId, action };\n\t\t\t\tthis.request();\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectedPluginId(): string | undefined {\n\t\treturn this.currentEntry()?.pluginId;\n\t}\n\n\tgetSelectedAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentAction();\n\t}\n\n\tgetStatus(): PluginManagerEntryOpenContextV1 {\n\t\treturn this.status;\n\t}\n}\n"]}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* host response text never participate in rendering or action selection.
|
|
7
7
|
*/
|
|
8
8
|
import { getKeybindings, truncateToWidth } from "@agent-forge/tui";
|
|
9
|
+
import { t } from "../../../core/i18n/index.js";
|
|
9
10
|
import { theme } from "../theme/theme.js";
|
|
10
11
|
const MAX_PLUGIN_ENTRIES_V1 = 128;
|
|
11
12
|
const MAX_DISPLAY_CHARS_V1 = 256;
|
|
@@ -114,36 +115,44 @@ export class PluginManagerEntryComponent {
|
|
|
114
115
|
}
|
|
115
116
|
render(width) {
|
|
116
117
|
if (!this._focused) {
|
|
117
|
-
const state = this.status.status === "ready"
|
|
118
|
-
|
|
118
|
+
const state = this.status.status === "ready"
|
|
119
|
+
? t("catalog {count}", { count: this.status.entryCount })
|
|
120
|
+
: t("catalog unavailable");
|
|
121
|
+
const bounded = this.truncated ? t(", bounded") : "";
|
|
119
122
|
return [
|
|
120
|
-
truncateToWidth(theme.fg("muted", ` Plugin manager ·
|
|
123
|
+
truncateToWidth(theme.fg("muted", ` ${t("Plugin manager · {state}{bounded} · Enter open", { state, bounded })}`), width, "..."),
|
|
121
124
|
];
|
|
122
125
|
}
|
|
123
|
-
const lines = [truncateToWidth(theme.bold("
|
|
126
|
+
const lines = [truncateToWidth(theme.bold(` ${t("Plugin manager")}`), width, "...")];
|
|
124
127
|
if (this.busy) {
|
|
125
|
-
lines.push(truncateToWidth(theme.fg("accent", "
|
|
128
|
+
lines.push(truncateToWidth(theme.fg("accent", ` ${t("Working…")}`), width, "..."));
|
|
126
129
|
}
|
|
127
130
|
else if (this.confirmation !== undefined) {
|
|
128
131
|
const entry = this.currentEntry();
|
|
129
132
|
const action = this.currentAction();
|
|
130
133
|
if (entry !== undefined && action !== undefined) {
|
|
131
134
|
const targetVersion = actionTargetVersion(entry, action) ?? entry.pluginVersion;
|
|
132
|
-
lines.push(truncateToWidth(theme.fg("error", ` Confirm
|
|
135
|
+
lines.push(truncateToWidth(theme.fg("error", ` ${t("Confirm {action} {plugin}@{version}? Enter confirm · Esc cancel", {
|
|
136
|
+
action,
|
|
137
|
+
plugin: safeDisplay(entry.pluginId),
|
|
138
|
+
version: safeDisplay(targetVersion),
|
|
139
|
+
})}`), width, "..."));
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
else if (this.status.status === "error" && this.status.diagnosticCode !== undefined) {
|
|
136
|
-
lines.push(truncateToWidth(theme.fg("error", ` Error:
|
|
143
|
+
lines.push(truncateToWidth(theme.fg("error", ` ${t("Error: {code}", { code: this.status.diagnosticCode })}`), width, "..."));
|
|
137
144
|
}
|
|
138
145
|
if (this.entries.length === 0) {
|
|
139
|
-
lines.push(theme.fg("dim", "
|
|
146
|
+
lines.push(theme.fg("dim", ` ${t("No plugins available")}`));
|
|
140
147
|
}
|
|
141
148
|
else {
|
|
142
149
|
for (const [index, entry] of this.entries.entries()) {
|
|
143
150
|
const selected = index === this.selectedIndex;
|
|
144
151
|
const cursor = selected ? ">" : " ";
|
|
145
152
|
const status = entry.status;
|
|
146
|
-
const installed = entry.installedVersion === undefined
|
|
153
|
+
const installed = entry.installedVersion === undefined
|
|
154
|
+
? ""
|
|
155
|
+
: ` ${t("installed {version}", { version: safeDisplay(entry.installedVersion) })}`;
|
|
147
156
|
const diagnostics = entry.diagnosticCodes.length === 0 ? "" : ` [${entry.diagnosticCodes.join(", ")}]`;
|
|
148
157
|
lines.push(truncateToWidth(`${cursor} ${safeDisplay(entry.pluginId)}@${safeDisplay(entry.pluginVersion)} · ${status}${installed}${diagnostics}`, width, "..."));
|
|
149
158
|
}
|
|
@@ -151,14 +160,14 @@ export class PluginManagerEntryComponent {
|
|
|
151
160
|
const actions = this.currentActions();
|
|
152
161
|
if (actions.length > 0 && !this.busy) {
|
|
153
162
|
const action = this.currentAction();
|
|
154
|
-
lines.push(truncateToWidth(theme.fg("muted", ` Action:
|
|
163
|
+
lines.push(truncateToWidth(theme.fg("muted", ` ${t("Action: {action} · Tab switch action · Enter confirm", { action: action ?? "install" })}`), width, "..."));
|
|
155
164
|
}
|
|
156
165
|
else if (this.entries.length > 0 && !this.busy) {
|
|
157
|
-
lines.push(truncateToWidth(theme.fg("dim", "
|
|
166
|
+
lines.push(truncateToWidth(theme.fg("dim", ` ${t("Selected plugin is unavailable")}`), width, "..."));
|
|
158
167
|
}
|
|
159
168
|
if (this.truncated)
|
|
160
|
-
lines.push(theme.fg("dim",
|
|
161
|
-
lines.push(truncateToWidth(theme.fg("dim", "
|
|
169
|
+
lines.push(theme.fg("dim", ` ${t("(list bounded)")}`));
|
|
170
|
+
lines.push(truncateToWidth(theme.fg("dim", ` ${t("↑↓ navigate · Esc close")}`), width, "..."));
|
|
162
171
|
return lines;
|
|
163
172
|
}
|
|
164
173
|
async refresh() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-manager-entry.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-manager-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAkC,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQnG,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAgClC,SAAS,WAAW,CAAC,KAAa,EAAU;IAC3C,mEAAmE;IACnE,2EAA2E;IAC3E,OAAO,KAAK;SACV,OAAO,CAAC,6BAA6B,EAAE,EAAE,CAAC;SAC1C,OAAO,CAAC,yBAAyB,EAAE,KAAG,CAAC;SACvC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAAA,CACjC;AAED,SAAS,eAAe,CAAC,QAAiC,EAGxD;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAC/E,qEAAqE;QACrE,+CAA+C;QAC/C,OAAO,MAAM,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAC7F,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;YACxE,eAAe,EAAE,MAAM,CAAC,MAAM,CAC7B,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CACxF;SACD,CAAC,CAAC;IAAA,CACH,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,qBAAqB;KAChF,CAAC,CAAC;AAAA,CACH;AAED,SAAS,UAAU,CAAC,KAA+B,EAAoC;IACtF,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,WAAW;YACf,OAAO,CAAC,SAAS,CAAC,CAAC;QACpB,KAAK,kBAAkB;YACtB,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7B,KAAK,WAAW;YACf,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnB,KAAK,aAAa;YACjB,OAAO,EAAE,CAAC;IACZ,CAAC;AAAA,CACD;AAED,SAAS,mBAAmB,CAAC,KAA+B,EAAE,MAA6B,EAAsB;IAChH,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;AAAA,CACnG;AAED,SAAS,SAAS,CAAC,MAAqC,EAAsC;IAC7F,OAAO,MAAM,CAAC,IAAI,IAAI,0BAA0B,CAAC;AAAA,CACjD;AAED;;;GAGG;AACH,MAAM,OAAO,2BAA2B;IACtB,UAAU,CAA4B;IACtC,OAAO,CAAc;IACrB,aAAa,CAAc;IACpC,OAAO,GAAwC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjE,SAAS,GAAG,KAAK,CAAC;IAClB,aAAa,GAAG,CAAC,CAAC;IAClB,mBAAmB,GAAG,CAAC,CAAC;IACxB,YAAY,CAAoF;IAChG,IAAI,GAAG,KAAK,CAAC;IACb,MAAM,GAAoC,MAAM,CAAC,MAAM,CAAC;QAC/D,MAAM,EAAE,OAAO;QACf,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,KAAK;KAChB,CAAC,CAAC;IACK,QAAQ,GAAG,KAAK,CAAC;IAEzB,IAAI,OAAO,GAAY;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC;IAAA,CACrB;IAED,IAAI,OAAO,CAAC,KAAc,EAAE;QAC3B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IAAA,CACtB;IAED,YAAY,OAAoC,EAAE;QACjD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAA,CACvE;IAEO,WAAW,CAAC,QAAiC,EAAQ;QAC5D,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7G,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3B,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC,CAAC;IAAA,CACH;IAEO,YAAY,GAAyC;QAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAAA,CACxC;IAEO,cAAc,GAAqC;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAAA,CACpD;IAEO,aAAa,GAAsC;QAC1D,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAAA,CACvD;IAEO,OAAO,GAAS;QACvB,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;IAAA,CACvB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;YAC3G,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO;gBACN,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAsB,KAAK,GAAG,OAAO,gBAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC;aACtG,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAa,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACxF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAY,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7E,CAAC;aAAM,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjD,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC;gBAChF,KAAK,CAAC,IAAI,CACT,eAAe,CACd,KAAK,CAAC,EAAE,CACP,OAAO,EACP,aAAa,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,+BAA8B,CAC9G,EACD,KAAK,EACL,KAAK,CACL,CACD,CAAC;YACH,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACvF,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACxG,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBACrD,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC;gBAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBACpC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC5B,MAAM,SAAS,GACd,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACjG,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACvG,KAAK,CAAC,IAAI,CACT,eAAe,CACd,GAAG,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,OAAM,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,EACpH,KAAK,EACL,KAAK,CACL,CACD,CAAC;YACH,CAAC;QACF,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CACT,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,MAAM,wCAAsC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAC3G,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,kCAAkC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAChG,CAAC;QACD,IAAI,IAAI,CAAC,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,gCAA2B,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACxF,OAAO,KAAK,CAAC;IAAA,CACb;IAEO,KAAK,CAAC,OAAO,GAA6C;QACjE,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;YACnD,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,MAAM,CAAC;YACpB,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC3B,MAAM,EAAE,OAAO;gBACf,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,KAAK;gBAChB,cAAc,EAAE,MAAM,CAAC,IAAI;aAC3B,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,MAAM,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC3B,MAAM,EAAE,OAAO;gBACf,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,KAAK;gBAChB,cAAc,EAAE,0BAA0B;aAC1C,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,MAAM,CAAC;QACpB,CAAC;IAAA,CACD;IAEO,KAAK,CAAC,OAAO,CAAC,MAA6B,EAAiB;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,MAAqC,CAAC;QAC1C,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG;gBACb,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,aAAa,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC;gBACjD,SAAS,EAAE,IAAa;aACxB,CAAC;YACF,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;QACjE,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnF,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACrF,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7G,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACf;IAED,KAAK,CAAC,iBAAiB,GAA4C;QAClE,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CAC5B;IAED,WAAW,CAAC,IAAY,EAAQ;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC3B,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QACtB,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;gBAC3C,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO;YACR,CAAC;YACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC;gBAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;gBACpC,IAAI,MAAM,KAAK,SAAS;oBAAE,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACpD,OAAO;YACR,CAAC;YACD,OAAO;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;YAC5F,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,mBAAmB,GAAG,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;YACnG,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjD,IAAI,CAAC,YAAY,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;QACF,CAAC;IAAA,CACD;IAED,UAAU,GAAS,EAAC,CAAC;IAErB,mBAAmB,GAAuB;QACzC,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC;IAAA,CACrC;IAED,iBAAiB,GAAsC;QACtD,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CAC5B;IAED,SAAS,GAAoC;QAC5C,OAAO,IAAI,CAAC,MAAM,CAAC;IAAA,CACnB;CACD","sourcesContent":["/**\n * Host-owned plugin installation/update entry for the config screen.\n *\n * This component deliberately projects the manager snapshot to a small UI\n * view. Registry sources, paths, signatures, package bytes, credentials and\n * host response text never participate in rendering or action selection.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginManagerControllerErrorCodeV1,\n\tPluginManagerControllerV1,\n\tPluginManagerEntryStatusV1,\n\tPluginManagerMutationResultV1,\n\tPluginManagerSnapshotV1,\n} from \"../../../cli/plugin-manager-controller.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PLUGIN_ENTRIES_V1 = 128;\nconst MAX_DISPLAY_CHARS_V1 = 256;\nconst MAX_DIAGNOSTIC_CODES_V1 = 8;\n\ntype PluginManagerActionV1 = \"install\" | \"update\" | \"remove\";\ntype PluginManagerViewStatusV1 = \"ready\" | \"error\";\n\ninterface PluginManagerViewEntryV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly status: PluginManagerEntryStatusV1;\n\treadonly installedVersion?: string;\n\treadonly lifecycle?: \"installed\" | \"active\" | \"retained\";\n\treadonly diagnosticCodes: readonly string[];\n}\n\nexport interface PluginManagerEntryOptionsV1 {\n\treadonly controller: PluginManagerControllerV1;\n\treadonly snapshot?: PluginManagerSnapshotV1;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nexport interface PluginManagerEntryOpenContextV1 {\n\treadonly status: PluginManagerViewStatusV1;\n\treadonly entryCount: number;\n\treadonly truncated: boolean;\n\treadonly diagnosticCode?: PluginManagerControllerErrorCodeV1;\n}\n\nexport type PluginManagerEntryOpenResultV1 = PluginManagerEntryOpenContextV1;\n\nfunction safeDisplay(value: string): string {\n\t// Registry/state validators bound these values, but the UI remains\n\t// defensive because the component is also usable with injected test hosts.\n\treturn value\n\t\t.replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/gu, \"\")\n\t\t.replace(/[\\u0000-\\u001f\\u007f]/gu, \"�\")\n\t\t.slice(0, MAX_DISPLAY_CHARS_V1);\n}\n\nfunction projectSnapshot(snapshot: PluginManagerSnapshotV1): {\n\treadonly entries: readonly PluginManagerViewEntryV1[];\n\treadonly truncated: boolean;\n} {\n\tconst entries = snapshot.entries.slice(0, MAX_PLUGIN_ENTRIES_V1).map((entry) => {\n\t\t// Explicitly select only fields intended for this UI. In particular,\n\t\t// registrySource and signed are not read here.\n\t\treturn Object.freeze({\n\t\t\tpluginId: entry.pluginId,\n\t\t\tpluginVersion: entry.pluginVersion,\n\t\t\tstatus: entry.status,\n\t\t\t...(entry.installedVersion === undefined ? {} : { installedVersion: entry.installedVersion }),\n\t\t\t...(entry.lifecycle === undefined ? {} : { lifecycle: entry.lifecycle }),\n\t\t\tdiagnosticCodes: Object.freeze(\n\t\t\t\tentry.diagnosticCodes.slice(0, MAX_DIAGNOSTIC_CODES_V1).map((code) => safeDisplay(code)),\n\t\t\t),\n\t\t});\n\t});\n\treturn Object.freeze({\n\t\tentries: Object.freeze(entries),\n\t\ttruncated: snapshot.truncated || snapshot.entries.length > MAX_PLUGIN_ENTRIES_V1,\n\t});\n}\n\nfunction actionsFor(entry: PluginManagerViewEntryV1): readonly PluginManagerActionV1[] {\n\tswitch (entry.status) {\n\t\tcase \"available\":\n\t\t\treturn [\"install\"];\n\t\tcase \"update-available\":\n\t\t\treturn [\"update\", \"remove\"];\n\t\tcase \"installed\":\n\t\t\treturn [\"remove\"];\n\t\tcase \"unavailable\":\n\t\t\treturn [];\n\t}\n}\n\nfunction actionTargetVersion(entry: PluginManagerViewEntryV1, action: PluginManagerActionV1): string | undefined {\n\treturn action === \"remove\" ? (entry.installedVersion ?? entry.pluginVersion) : entry.pluginVersion;\n}\n\nfunction errorCode(result: PluginManagerMutationResultV1): PluginManagerControllerErrorCodeV1 {\n\treturn result.code ?? \"manager-operation-failed\";\n}\n\n/**\n * Focusable manager surface. The outer config selector owns navigation to this\n * entry; this surface owns confirmation and only emits stable host codes.\n */\nexport class PluginManagerEntryComponent implements Component, Focusable {\n\tprivate readonly controller: PluginManagerControllerV1;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate entries: readonly PluginManagerViewEntryV1[] = Object.freeze([]);\n\tprivate truncated = false;\n\tprivate selectedIndex = 0;\n\tprivate selectedActionIndex = 0;\n\tprivate confirmation: { readonly pluginId: string; readonly action: PluginManagerActionV1 } | undefined;\n\tprivate busy = false;\n\tprivate status: PluginManagerEntryOpenContextV1 = Object.freeze({\n\t\tstatus: \"error\",\n\t\tentryCount: 0,\n\t\ttruncated: false,\n\t});\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginManagerEntryOptionsV1) {\n\t\tthis.controller = options.controller;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tif (options.snapshot !== undefined) this.setSnapshot(options.snapshot);\n\t}\n\n\tprivate setSnapshot(snapshot: PluginManagerSnapshotV1): void {\n\t\tconst projected = projectSnapshot(snapshot);\n\t\tthis.entries = projected.entries;\n\t\tthis.truncated = projected.truncated;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.entries.length - 1));\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.status = Object.freeze({\n\t\t\tstatus: \"ready\",\n\t\t\tentryCount: this.entries.length,\n\t\t\ttruncated: this.truncated,\n\t\t});\n\t}\n\n\tprivate currentEntry(): PluginManagerViewEntryV1 | undefined {\n\t\treturn this.entries[this.selectedIndex];\n\t}\n\n\tprivate currentActions(): readonly PluginManagerActionV1[] {\n\t\tconst entry = this.currentEntry();\n\t\treturn entry === undefined ? [] : actionsFor(entry);\n\t}\n\n\tprivate currentAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentActions()[this.selectedActionIndex];\n\t}\n\n\tprivate request(): void {\n\t\tthis.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this._focused) {\n\t\t\tconst state = this.status.status === \"ready\" ? `catalog ${this.status.entryCount}` : \"catalog unavailable\";\n\t\t\tconst bounded = this.truncated ? \", bounded\" : \"\";\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", ` Plugin manager · ${state}${bounded} · Enter open`), width, \"...\"),\n\t\t\t];\n\t\t}\n\n\t\tconst lines: string[] = [truncateToWidth(theme.bold(\" Plugin manager\"), width, \"...\")];\n\t\tif (this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"accent\", \" Working…\"), width, \"...\"));\n\t\t} else if (this.confirmation !== undefined) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tconst targetVersion = actionTargetVersion(entry, action) ?? entry.pluginVersion;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t` Confirm ${action} ${safeDisplay(entry.pluginId)}@${safeDisplay(targetVersion)}? Enter confirm · Esc cancel`,\n\t\t\t\t\t\t),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (this.status.status === \"error\" && this.status.diagnosticCode !== undefined) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"error\", ` Error: ${this.status.diagnosticCode}`), width, \"...\"));\n\t\t}\n\n\t\tif (this.entries.length === 0) {\n\t\t\tlines.push(theme.fg(\"dim\", \" No plugins available\"));\n\t\t} else {\n\t\t\tfor (const [index, entry] of this.entries.entries()) {\n\t\t\t\tconst selected = index === this.selectedIndex;\n\t\t\t\tconst cursor = selected ? \">\" : \" \";\n\t\t\t\tconst status = entry.status;\n\t\t\t\tconst installed =\n\t\t\t\t\tentry.installedVersion === undefined ? \"\" : ` installed ${safeDisplay(entry.installedVersion)}`;\n\t\t\t\tconst diagnostics = entry.diagnosticCodes.length === 0 ? \"\" : ` [${entry.diagnosticCodes.join(\", \")}]`;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${cursor} ${safeDisplay(entry.pluginId)}@${safeDisplay(entry.pluginVersion)} · ${status}${installed}${diagnostics}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst actions = this.currentActions();\n\t\tif (actions.length > 0 && !this.busy) {\n\t\t\tconst action = this.currentAction();\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", ` Action: ${action} · Tab switch action · Enter confirm`), width, \"...\"),\n\t\t\t);\n\t\t} else if (this.entries.length > 0 && !this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", \" Selected plugin is unavailable\"), width, \"...\"));\n\t\t}\n\t\tif (this.truncated) lines.push(theme.fg(\"dim\", \" (list bounded)\"));\n\t\tlines.push(truncateToWidth(theme.fg(\"dim\", \" ↑↓ navigate · Esc close\"), width, \"...\"));\n\t\treturn lines;\n\t}\n\n\tprivate async refresh(): Promise<PluginManagerEntryOpenContextV1> {\n\t\ttry {\n\t\t\tconst result = await this.controller.getSnapshot();\n\t\t\tif (result.status === \"ok\") {\n\t\t\t\tthis.setSnapshot(result.snapshot);\n\t\t\t\tthis.request();\n\t\t\t\treturn this.status;\n\t\t\t}\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: result.code,\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t} catch {\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: \"manager-operation-failed\",\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t}\n\t}\n\n\tprivate async perform(action: PluginManagerActionV1): Promise<void> {\n\t\tconst entry = this.currentEntry();\n\t\tif (entry === undefined) return;\n\t\tthis.busy = true;\n\t\tthis.confirmation = undefined;\n\t\tthis.request();\n\t\tlet result: PluginManagerMutationResultV1;\n\t\ttry {\n\t\t\tconst input = {\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tpluginVersion: actionTargetVersion(entry, action),\n\t\t\t\tconfirmed: true as const,\n\t\t\t};\n\t\t\tresult = await this.controller[action](input);\n\t\t} catch {\n\t\t\tresult = { status: \"failed\", code: \"manager-operation-failed\" };\n\t\t}\n\t\tif (result.snapshot !== undefined) this.setSnapshot(result.snapshot);\n\t\tconst mutationCode = result.status === \"succeeded\" ? undefined : errorCode(result);\n\t\tconst refreshed = result.snapshot === undefined ? await this.refresh() : this.status;\n\t\tif (mutationCode !== undefined) {\n\t\t\tthis.status = Object.freeze({ ...refreshed, status: \"error\", diagnosticCode: mutationCode });\n\t\t}\n\t\tthis.busy = false;\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.request();\n\t}\n\n\tasync openPluginManager(): Promise<PluginManagerEntryOpenResultV1> {\n\t\treturn await this.refresh();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused) return;\n\t\tconst kb = getKeybindings();\n\t\tif (this.busy) return;\n\t\tif (this.confirmation !== undefined) {\n\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.confirmation = undefined;\n\t\t\t\tthis.request();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tconst action = this.currentAction();\n\t\t\t\tif (action !== undefined) void this.perform(action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(Math.max(0, this.entries.length - 1), this.selectedIndex + 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.input.tab\")) {\n\t\t\tconst actions = this.currentActions();\n\t\t\tif (actions.length > 0) this.selectedActionIndex = (this.selectedActionIndex + 1) % actions.length;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tthis.confirmation = { pluginId: entry.pluginId, action };\n\t\t\t\tthis.request();\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectedPluginId(): string | undefined {\n\t\treturn this.currentEntry()?.pluginId;\n\t}\n\n\tgetSelectedAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentAction();\n\t}\n\n\tgetStatus(): PluginManagerEntryOpenContextV1 {\n\t\treturn this.status;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin-manager-entry.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-manager-entry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-owned plugin installation/update entry for the config screen.\n *\n * This component deliberately projects the manager snapshot to a small UI\n * view. Registry sources, paths, signatures, package bytes, credentials and\n * host response text never participate in rendering or action selection.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginManagerControllerErrorCodeV1,\n\tPluginManagerControllerV1,\n\tPluginManagerEntryStatusV1,\n\tPluginManagerMutationResultV1,\n\tPluginManagerSnapshotV1,\n} from \"../../../cli/plugin-manager-controller.ts\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PLUGIN_ENTRIES_V1 = 128;\nconst MAX_DISPLAY_CHARS_V1 = 256;\nconst MAX_DIAGNOSTIC_CODES_V1 = 8;\n\ntype PluginManagerActionV1 = \"install\" | \"update\" | \"remove\";\ntype PluginManagerViewStatusV1 = \"ready\" | \"error\";\n\ninterface PluginManagerViewEntryV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly status: PluginManagerEntryStatusV1;\n\treadonly installedVersion?: string;\n\treadonly lifecycle?: \"installed\" | \"active\" | \"retained\";\n\treadonly diagnosticCodes: readonly string[];\n}\n\nexport interface PluginManagerEntryOptionsV1 {\n\treadonly controller: PluginManagerControllerV1;\n\treadonly snapshot?: PluginManagerSnapshotV1;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nexport interface PluginManagerEntryOpenContextV1 {\n\treadonly status: PluginManagerViewStatusV1;\n\treadonly entryCount: number;\n\treadonly truncated: boolean;\n\treadonly diagnosticCode?: PluginManagerControllerErrorCodeV1;\n}\n\nexport type PluginManagerEntryOpenResultV1 = PluginManagerEntryOpenContextV1;\n\nfunction safeDisplay(value: string): string {\n\t// Registry/state validators bound these values, but the UI remains\n\t// defensive because the component is also usable with injected test hosts.\n\treturn value\n\t\t.replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/gu, \"\")\n\t\t.replace(/[\\u0000-\\u001f\\u007f]/gu, \"�\")\n\t\t.slice(0, MAX_DISPLAY_CHARS_V1);\n}\n\nfunction projectSnapshot(snapshot: PluginManagerSnapshotV1): {\n\treadonly entries: readonly PluginManagerViewEntryV1[];\n\treadonly truncated: boolean;\n} {\n\tconst entries = snapshot.entries.slice(0, MAX_PLUGIN_ENTRIES_V1).map((entry) => {\n\t\t// Explicitly select only fields intended for this UI. In particular,\n\t\t// registrySource and signed are not read here.\n\t\treturn Object.freeze({\n\t\t\tpluginId: entry.pluginId,\n\t\t\tpluginVersion: entry.pluginVersion,\n\t\t\tstatus: entry.status,\n\t\t\t...(entry.installedVersion === undefined ? {} : { installedVersion: entry.installedVersion }),\n\t\t\t...(entry.lifecycle === undefined ? {} : { lifecycle: entry.lifecycle }),\n\t\t\tdiagnosticCodes: Object.freeze(\n\t\t\t\tentry.diagnosticCodes.slice(0, MAX_DIAGNOSTIC_CODES_V1).map((code) => safeDisplay(code)),\n\t\t\t),\n\t\t});\n\t});\n\treturn Object.freeze({\n\t\tentries: Object.freeze(entries),\n\t\ttruncated: snapshot.truncated || snapshot.entries.length > MAX_PLUGIN_ENTRIES_V1,\n\t});\n}\n\nfunction actionsFor(entry: PluginManagerViewEntryV1): readonly PluginManagerActionV1[] {\n\tswitch (entry.status) {\n\t\tcase \"available\":\n\t\t\treturn [\"install\"];\n\t\tcase \"update-available\":\n\t\t\treturn [\"update\", \"remove\"];\n\t\tcase \"installed\":\n\t\t\treturn [\"remove\"];\n\t\tcase \"unavailable\":\n\t\t\treturn [];\n\t}\n}\n\nfunction actionTargetVersion(entry: PluginManagerViewEntryV1, action: PluginManagerActionV1): string | undefined {\n\treturn action === \"remove\" ? (entry.installedVersion ?? entry.pluginVersion) : entry.pluginVersion;\n}\n\nfunction errorCode(result: PluginManagerMutationResultV1): PluginManagerControllerErrorCodeV1 {\n\treturn result.code ?? \"manager-operation-failed\";\n}\n\n/**\n * Focusable manager surface. The outer config selector owns navigation to this\n * entry; this surface owns confirmation and only emits stable host codes.\n */\nexport class PluginManagerEntryComponent implements Component, Focusable {\n\tprivate readonly controller: PluginManagerControllerV1;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate entries: readonly PluginManagerViewEntryV1[] = Object.freeze([]);\n\tprivate truncated = false;\n\tprivate selectedIndex = 0;\n\tprivate selectedActionIndex = 0;\n\tprivate confirmation: { readonly pluginId: string; readonly action: PluginManagerActionV1 } | undefined;\n\tprivate busy = false;\n\tprivate status: PluginManagerEntryOpenContextV1 = Object.freeze({\n\t\tstatus: \"error\",\n\t\tentryCount: 0,\n\t\ttruncated: false,\n\t});\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginManagerEntryOptionsV1) {\n\t\tthis.controller = options.controller;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tif (options.snapshot !== undefined) this.setSnapshot(options.snapshot);\n\t}\n\n\tprivate setSnapshot(snapshot: PluginManagerSnapshotV1): void {\n\t\tconst projected = projectSnapshot(snapshot);\n\t\tthis.entries = projected.entries;\n\t\tthis.truncated = projected.truncated;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.entries.length - 1));\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.status = Object.freeze({\n\t\t\tstatus: \"ready\",\n\t\t\tentryCount: this.entries.length,\n\t\t\ttruncated: this.truncated,\n\t\t});\n\t}\n\n\tprivate currentEntry(): PluginManagerViewEntryV1 | undefined {\n\t\treturn this.entries[this.selectedIndex];\n\t}\n\n\tprivate currentActions(): readonly PluginManagerActionV1[] {\n\t\tconst entry = this.currentEntry();\n\t\treturn entry === undefined ? [] : actionsFor(entry);\n\t}\n\n\tprivate currentAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentActions()[this.selectedActionIndex];\n\t}\n\n\tprivate request(): void {\n\t\tthis.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this._focused) {\n\t\t\tconst state =\n\t\t\t\tthis.status.status === \"ready\"\n\t\t\t\t\t? t(\"catalog {count}\", { count: this.status.entryCount })\n\t\t\t\t\t: t(\"catalog unavailable\");\n\t\t\tconst bounded = this.truncated ? t(\", bounded\") : \"\";\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"muted\", ` ${t(\"Plugin manager · {state}{bounded} · Enter open\", { state, bounded })}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tconst lines: string[] = [truncateToWidth(theme.bold(` ${t(\"Plugin manager\")}`), width, \"...\")];\n\t\tif (this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"accent\", ` ${t(\"Working…\")}`), width, \"...\"));\n\t\t} else if (this.confirmation !== undefined) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tconst targetVersion = actionTargetVersion(entry, action) ?? entry.pluginVersion;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t` ${t(\"Confirm {action} {plugin}@{version}? Enter confirm · Esc cancel\", {\n\t\t\t\t\t\t\t\taction,\n\t\t\t\t\t\t\t\tplugin: safeDisplay(entry.pluginId),\n\t\t\t\t\t\t\t\tversion: safeDisplay(targetVersion),\n\t\t\t\t\t\t\t})}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (this.status.status === \"error\" && this.status.diagnosticCode !== undefined) {\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"error\", ` ${t(\"Error: {code}\", { code: this.status.diagnosticCode })}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (this.entries.length === 0) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${t(\"No plugins available\")}`));\n\t\t} else {\n\t\t\tfor (const [index, entry] of this.entries.entries()) {\n\t\t\t\tconst selected = index === this.selectedIndex;\n\t\t\t\tconst cursor = selected ? \">\" : \" \";\n\t\t\t\tconst status = entry.status;\n\t\t\t\tconst installed =\n\t\t\t\t\tentry.installedVersion === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: ` ${t(\"installed {version}\", { version: safeDisplay(entry.installedVersion) })}`;\n\t\t\t\tconst diagnostics = entry.diagnosticCodes.length === 0 ? \"\" : ` [${entry.diagnosticCodes.join(\", \")}]`;\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${cursor} ${safeDisplay(entry.pluginId)}@${safeDisplay(entry.pluginVersion)} · ${status}${installed}${diagnostics}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"...\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst actions = this.currentActions();\n\t\tif (actions.length > 0 && !this.busy) {\n\t\t\tconst action = this.currentAction();\n\t\t\tlines.push(\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t` ${t(\"Action: {action} · Tab switch action · Enter confirm\", { action: action ?? \"install\" })}`,\n\t\t\t\t\t),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (this.entries.length > 0 && !this.busy) {\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${t(\"Selected plugin is unavailable\")}`), width, \"...\"));\n\t\t}\n\t\tif (this.truncated) lines.push(theme.fg(\"dim\", ` ${t(\"(list bounded)\")}`));\n\t\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${t(\"↑↓ navigate · Esc close\")}`), width, \"...\"));\n\t\treturn lines;\n\t}\n\n\tprivate async refresh(): Promise<PluginManagerEntryOpenContextV1> {\n\t\ttry {\n\t\t\tconst result = await this.controller.getSnapshot();\n\t\t\tif (result.status === \"ok\") {\n\t\t\t\tthis.setSnapshot(result.snapshot);\n\t\t\t\tthis.request();\n\t\t\t\treturn this.status;\n\t\t\t}\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: result.code,\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t} catch {\n\t\t\tthis.status = Object.freeze({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tentryCount: 0,\n\t\t\t\ttruncated: false,\n\t\t\t\tdiagnosticCode: \"manager-operation-failed\",\n\t\t\t});\n\t\t\tthis.entries = Object.freeze([]);\n\t\t\tthis.truncated = false;\n\t\t\tthis.request();\n\t\t\treturn this.status;\n\t\t}\n\t}\n\n\tprivate async perform(action: PluginManagerActionV1): Promise<void> {\n\t\tconst entry = this.currentEntry();\n\t\tif (entry === undefined) return;\n\t\tthis.busy = true;\n\t\tthis.confirmation = undefined;\n\t\tthis.request();\n\t\tlet result: PluginManagerMutationResultV1;\n\t\ttry {\n\t\t\tconst input = {\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tpluginVersion: actionTargetVersion(entry, action),\n\t\t\t\tconfirmed: true as const,\n\t\t\t};\n\t\t\tresult = await this.controller[action](input);\n\t\t} catch {\n\t\t\tresult = { status: \"failed\", code: \"manager-operation-failed\" };\n\t\t}\n\t\tif (result.snapshot !== undefined) this.setSnapshot(result.snapshot);\n\t\tconst mutationCode = result.status === \"succeeded\" ? undefined : errorCode(result);\n\t\tconst refreshed = result.snapshot === undefined ? await this.refresh() : this.status;\n\t\tif (mutationCode !== undefined) {\n\t\t\tthis.status = Object.freeze({ ...refreshed, status: \"error\", diagnosticCode: mutationCode });\n\t\t}\n\t\tthis.busy = false;\n\t\tthis.selectedActionIndex = Math.min(this.selectedActionIndex, Math.max(0, this.currentActions().length - 1));\n\t\tthis.request();\n\t}\n\n\tasync openPluginManager(): Promise<PluginManagerEntryOpenResultV1> {\n\t\treturn await this.refresh();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused) return;\n\t\tconst kb = getKeybindings();\n\t\tif (this.busy) return;\n\t\tif (this.confirmation !== undefined) {\n\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.confirmation = undefined;\n\t\t\t\tthis.request();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tconst action = this.currentAction();\n\t\t\t\tif (action !== undefined) void this.perform(action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(Math.max(0, this.entries.length - 1), this.selectedIndex + 1);\n\t\t\tthis.selectedActionIndex = 0;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.input.tab\")) {\n\t\t\tconst actions = this.currentActions();\n\t\t\tif (actions.length > 0) this.selectedActionIndex = (this.selectedActionIndex + 1) % actions.length;\n\t\t\tthis.request();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.currentEntry();\n\t\t\tconst action = this.currentAction();\n\t\t\tif (entry !== undefined && action !== undefined) {\n\t\t\t\tthis.confirmation = { pluginId: entry.pluginId, action };\n\t\t\t\tthis.request();\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectedPluginId(): string | undefined {\n\t\treturn this.currentEntry()?.pluginId;\n\t}\n\n\tgetSelectedAction(): PluginManagerActionV1 | undefined {\n\t\treturn this.currentAction();\n\t}\n\n\tgetStatus(): PluginManagerEntryOpenContextV1 {\n\t\treturn this.status;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-selection-entry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-selection-entry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-owned plugin selection entry for the config screen.\n *\n * This component deliberately renders only counts and bounded status. The\n * catalog, selection IDs, adapters, paths, credentials, and plugin payloads\n * stay behind the injected host contract.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginSelectionControllerResultV1,\n\tPluginSelectionControllerV1,\n\tPluginSelectionUiPluginV1,\n\tPluginSelectionUiProfileV1,\n\tPluginSelectionUiSnapshotV1,\n} from \"../../../cli/plugin-selection-controller.ts\";\nimport type { PluginCatalogSnapshotV1 } from \"../../../plugins/ecosystem/catalog.ts\";\nimport type { PluginSelectionV1 } from \"../../../plugins/ecosystem/selection.ts\";\nimport type {\n\tPluginSelectionStoreDiagnosticCodeV1,\n\tPluginSelectionStoreReadResultV1,\n\tPluginSelectionStoreV1,\n} from \"../../../plugins/ecosystem/selection-store.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PROFILE_ID_CHARS = 128;\nconst MAX_SELECTION_IDS = 128;\nconst MAX_CATALOG_ENTRIES = 256;\nconst MAX_DIAGNOSTIC_CODES = 16;\n\nexport interface PluginSelectionSummaryV1 {\n\treadonly present: boolean;\n\treadonly selectedCount: number;\n\treadonly disabledCount: number;\n\treadonly truncated: boolean;\n}\n\nexport interface PluginCatalogSummaryV1 {\n\treadonly present: boolean;\n\treadonly entryCount: number;\n\treadonly readyCount: number;\n\treadonly unavailableCount: number;\n\treadonly truncated: boolean;\n}\n\nexport type PluginSelectionEntryStatusV1 = \"ready\" | \"missing\" | \"unsupported\" | \"invalid\" | \"cancelled\";\n\nexport interface PluginSelectionOpenContextV1 {\n\treadonly profileId: string;\n\treadonly status: PluginSelectionEntryStatusV1;\n\treadonly selection: PluginSelectionSummaryV1;\n\treadonly catalog: PluginCatalogSummaryV1;\n\treadonly diagnosticCodes: readonly PluginSelectionStoreDiagnosticCodeV1[];\n}\n\nexport type PluginSelectionEntryOpenResultV1 = PluginSelectionOpenContextV1;\n\nexport interface PluginSelectionEntryOptionsV1 {\n\treadonly profileId: string;\n\treadonly store?: PluginSelectionStoreV1;\n\treadonly selection?: PluginSelectionV1;\n\treadonly catalog?: PluginCatalogSnapshotV1;\n\treadonly controller?: PluginSelectionControllerV1;\n\treadonly snapshot?: PluginSelectionUiSnapshotV1;\n\t/** Host callback that opens the independent plugin selection surface. */\n\treadonly onOpen?: (context: PluginSelectionOpenContextV1) => void | Promise<void>;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nfunction boundedCount(value: readonly unknown[] | undefined, maximum: number): { count: number; truncated: boolean } {\n\tif (value === undefined) return { count: 0, truncated: false };\n\treturn { count: Math.min(value.length, maximum), truncated: value.length > maximum };\n}\n\nexport function summarizePluginSelectionV1(selection: PluginSelectionV1 | undefined): PluginSelectionSummaryV1 {\n\tif (selection === undefined) {\n\t\treturn Object.freeze({ present: false, selectedCount: 0, disabledCount: 0, truncated: false });\n\t}\n\tconst selected = boundedCount(selection.selectedPluginIds, MAX_SELECTION_IDS);\n\tconst disabled = boundedCount(selection.disabledPluginIds, MAX_SELECTION_IDS);\n\treturn Object.freeze({\n\t\tpresent: true,\n\t\tselectedCount: selected.count,\n\t\tdisabledCount: disabled.count,\n\t\ttruncated: selected.truncated || disabled.truncated,\n\t});\n}\n\nexport function summarizePluginCatalogV1(catalog: PluginCatalogSnapshotV1 | undefined): PluginCatalogSummaryV1 {\n\tif (catalog === undefined) {\n\t\treturn Object.freeze({ present: false, entryCount: 0, readyCount: 0, unavailableCount: 0, truncated: false });\n\t}\n\tconst entries = catalog.entries.slice(0, MAX_CATALOG_ENTRIES);\n\tconst readyCount = entries.filter((entry) => entry.resolution.status === \"installed-ready\").length;\n\treturn Object.freeze({\n\t\tpresent: true,\n\t\tentryCount: entries.length,\n\t\treadyCount,\n\t\tunavailableCount: entries.length - readyCount,\n\t\ttruncated: catalog.truncated || catalog.entries.length > MAX_CATALOG_ENTRIES,\n\t});\n}\n\nfunction validateProfileId(profileId: string): string {\n\tif (\n\t\ttypeof profileId !== \"string\" ||\n\t\tprofileId.trim().length === 0 ||\n\t\tprofileId.length > MAX_PROFILE_ID_CHARS ||\n\t\t/[\\u0000-\\u001f]/u.test(profileId)\n\t) {\n\t\tthrow new Error(\"invalid plugin selection profile ID\");\n\t}\n\treturn profileId;\n}\n\nfunction emptySelectionSummary(): PluginSelectionSummaryV1 {\n\treturn Object.freeze({ present: false, selectedCount: 0, disabledCount: 0, truncated: false });\n}\n\nfunction diagnosticCodes(result: PluginSelectionStoreReadResultV1): readonly PluginSelectionStoreDiagnosticCodeV1[] {\n\tif (result.status === \"ok\" || result.status === \"missing\") return Object.freeze([]);\n\treturn Object.freeze(result.diagnostics.slice(0, MAX_DIAGNOSTIC_CODES).map((item) => item.code));\n}\n\nfunction selectionForProfile(\n\tresult: Extract<PluginSelectionStoreReadResultV1, { readonly status: \"ok\" | \"missing\" }>,\n\tprofileId: string,\n): PluginSelectionV1 | undefined {\n\treturn result.snapshot.selections.find((selection) => selection.profileId === profileId);\n}\n\n/**\n * A non-focusable entry. The surrounding config selector can expose\n * `openPluginSelection()` to its host without assigning plugin actions to the\n * legacy resource list or inventing a new global key binding.\n */\nexport class PluginSelectionEntryComponent implements Component, Focusable {\n\tprivate readonly profileId: string;\n\tprivate readonly store?: PluginSelectionStoreV1;\n\tprivate readonly controller?: PluginSelectionControllerV1;\n\tprivate readonly onOpen?: (context: PluginSelectionOpenContextV1) => void | Promise<void>;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate selection: PluginSelectionSummaryV1;\n\tprivate readonly catalog: PluginCatalogSummaryV1;\n\tprivate uiProfile?: PluginSelectionUiProfileV1;\n\tprivate uiPluginIndex = 0;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginSelectionEntryOptionsV1) {\n\t\tthis.profileId = validateProfileId(options.profileId);\n\t\tif (options.selection !== undefined && options.selection.profileId !== this.profileId) {\n\t\t\tthrow new Error(\"plugin selection profile does not match the entry profile\");\n\t\t}\n\t\tthis.store = options.store;\n\t\tthis.controller = options.controller;\n\t\tthis.onOpen = options.onOpen;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tthis.selection = summarizePluginSelectionV1(options.selection);\n\t\tthis.catalog = summarizePluginCatalogV1(options.catalog);\n\t\tthis.uiProfile = options.snapshot?.profiles.find((profile) => profile.profileId === this.profileId);\n\t}\n\n\tprivate hasHostEntry(): boolean {\n\t\treturn this.store !== undefined || this.controller !== undefined || this.onOpen !== undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this.hasHostEntry()) {\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"dim\", \" Plugins: unsupported (host selection entry not injected)\"),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tif (this._focused && this.uiProfile !== undefined) {\n\t\t\tconst lines = [truncateToWidth(theme.bold(` Plugins · ${this.uiProfile.profileId}`), width, \"...\")];\n\t\t\tfor (const [index, plugin] of this.uiProfile.plugins.entries()) {\n\t\t\t\tconst cursor = index === this.uiPluginIndex ? \">\" : \" \";\n\t\t\t\tconst state = plugin.state === \"selected\" ? \"on\" : plugin.state === \"disabled\" ? \"off\" : \"available\";\n\t\t\t\tconst availability = plugin.availability === \"ready\" ? \"ready\" : \"unavailable\";\n\t\t\t\tlines.push(truncateToWidth(` ${cursor} [${state}] ${plugin.pluginId} (${availability})`, width, \"...\"));\n\t\t\t}\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", \" Enter/Space toggle · Esc close\"), width, \"...\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst selectionText = this.selection.present\n\t\t\t? `selected ${this.selection.selectedCount}, disabled ${this.selection.disabledCount}${\n\t\t\t\t\tthis.selection.truncated ? \", bounded\" : \"\"\n\t\t\t\t}`\n\t\t\t: this.store === undefined\n\t\t\t\t? \"selection pending\"\n\t\t\t\t: \"selection not loaded\";\n\t\tconst catalogText = this.catalog.present\n\t\t\t? `catalog ${this.catalog.entryCount} (${this.catalog.readyCount} ready, ${this.catalog.unavailableCount} unavailable${\n\t\t\t\t\tthis.catalog.truncated ? \", bounded\" : \"\"\n\t\t\t\t})`\n\t\t\t: \"catalog unavailable\";\n\t\tconst suffix = this.onOpen === undefined ? \"host store\" : \"open via host callback\";\n\t\treturn [\n\t\t\ttruncateToWidth(\n\t\t\t\ttheme.fg(\"muted\", ` Plugins: profile ${this.profileId} · ${selectionText} · ${catalogText} · ${suffix}`),\n\t\t\t\twidth,\n\t\t\t\t\"...\",\n\t\t\t),\n\t\t];\n\t}\n\n\tprivate setUiSnapshot(result: PluginSelectionControllerResultV1): void {\n\t\tif (result.status !== \"ok\") return;\n\t\tthis.uiProfile = result.snapshot.profiles.find((profile) => profile.profileId === this.profileId);\n\t\tif (this.uiProfile !== undefined) {\n\t\t\tthis.uiPluginIndex = Math.min(this.uiPluginIndex, Math.max(0, this.uiProfile.plugins.length - 1));\n\t\t}\n\t}\n\n\tprivate currentUiPlugin(): PluginSelectionUiPluginV1 | undefined {\n\t\treturn this.uiProfile?.plugins[this.uiPluginIndex];\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused || this.uiProfile === undefined) return;\n\t\tconst keybindings = getKeybindings();\n\t\tif (keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.uiPluginIndex = Math.max(0, this.uiPluginIndex - 1);\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.uiPluginIndex = Math.min(this.uiProfile.plugins.length - 1, this.uiPluginIndex + 1);\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (!keybindings.matches(data, \"tui.select.confirm\") && data !== \" \") return;\n\t\tconst plugin = this.currentUiPlugin();\n\t\tif (\n\t\t\tplugin === undefined ||\n\t\t\tthis.controller === undefined ||\n\t\t\t(plugin.state === \"disabled\" && plugin.availability !== \"ready\")\n\t\t)\n\t\t\treturn;\n\t\tvoid this.controller\n\t\t\t.toggle({ profileId: this.profileId, pluginId: plugin.pluginId })\n\t\t\t.then((result) => {\n\t\t\t\tthis.setUiSnapshot(result);\n\t\t\t\tthis.requestRender?.();\n\t\t\t})\n\t\t\t.catch(() => this.requestRender?.());\n\t}\n\n\t/** Read the bounded selection DTO and invoke the host-owned entry callback. */\n\tasync openPluginSelection(): Promise<PluginSelectionEntryOpenResultV1> {\n\t\tlet controllerResult: PluginSelectionControllerResultV1 | undefined;\n\t\tif (this.controller !== undefined) {\n\t\t\tcontrollerResult = await this.controller.getSnapshot();\n\t\t\tthis.setUiSnapshot(controllerResult);\n\t\t}\n\t\tlet status: PluginSelectionEntryStatusV1 = this.hasHostEntry() ? \"ready\" : \"unsupported\";\n\t\tlet selection = this.selection;\n\t\tlet codes: readonly PluginSelectionStoreDiagnosticCodeV1[] = Object.freeze([]);\n\t\tif (controllerResult?.status === \"error\") {\n\t\t\tstatus = controllerResult.code === \"store-cancelled\" ? \"cancelled\" : \"invalid\";\n\t\t}\n\n\t\tif (this.store !== undefined) {\n\t\t\tconst result = await this.store.read();\n\t\t\tcodes = diagnosticCodes(result);\n\t\t\tif (result.status === \"ok\" || result.status === \"missing\") {\n\t\t\t\tconst storedSelection = selectionForProfile(result, this.profileId);\n\t\t\t\tselection = summarizePluginSelectionV1(storedSelection);\n\t\t\t\tstatus = result.status === \"ok\" ? \"ready\" : \"missing\";\n\t\t\t} else {\n\t\t\t\tselection = emptySelectionSummary();\n\t\t\t\tstatus = result.status;\n\t\t\t}\n\t\t\tthis.selection = selection;\n\t\t}\n\n\t\tconst context: PluginSelectionOpenContextV1 = Object.freeze({\n\t\t\tprofileId: this.profileId,\n\t\t\tstatus,\n\t\t\tselection,\n\t\t\tcatalog: this.catalog,\n\t\t\tdiagnosticCodes: codes,\n\t\t});\n\t\tif (this.onOpen !== undefined) await this.onOpen(context);\n\t\treturn context;\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectionSummary(): PluginSelectionSummaryV1 {\n\t\treturn this.selection;\n\t}\n\n\tgetCatalogSummary(): PluginCatalogSummaryV1 {\n\t\treturn this.catalog;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin-selection-entry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/plugin-selection-entry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-owned plugin selection entry for the config screen.\n *\n * This component deliberately renders only counts and bounded status. The\n * catalog, selection IDs, adapters, paths, credentials, and plugin payloads\n * stay behind the injected host contract.\n */\n\nimport { type Component, type Focusable, getKeybindings, truncateToWidth } from \"@agent-forge/tui\";\nimport type {\n\tPluginSelectionControllerResultV1,\n\tPluginSelectionControllerV1,\n\tPluginSelectionUiPluginV1,\n\tPluginSelectionUiProfileV1,\n\tPluginSelectionUiSnapshotV1,\n} from \"../../../cli/plugin-selection-controller.ts\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport type { PluginCatalogSnapshotV1 } from \"../../../plugins/ecosystem/catalog.ts\";\nimport type { PluginSelectionV1 } from \"../../../plugins/ecosystem/selection.ts\";\nimport type {\n\tPluginSelectionStoreDiagnosticCodeV1,\n\tPluginSelectionStoreReadResultV1,\n\tPluginSelectionStoreV1,\n} from \"../../../plugins/ecosystem/selection-store.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nconst MAX_PROFILE_ID_CHARS = 128;\nconst MAX_SELECTION_IDS = 128;\nconst MAX_CATALOG_ENTRIES = 256;\nconst MAX_DIAGNOSTIC_CODES = 16;\n\nexport interface PluginSelectionSummaryV1 {\n\treadonly present: boolean;\n\treadonly selectedCount: number;\n\treadonly disabledCount: number;\n\treadonly truncated: boolean;\n}\n\nexport interface PluginCatalogSummaryV1 {\n\treadonly present: boolean;\n\treadonly entryCount: number;\n\treadonly readyCount: number;\n\treadonly unavailableCount: number;\n\treadonly truncated: boolean;\n}\n\nexport type PluginSelectionEntryStatusV1 = \"ready\" | \"missing\" | \"unsupported\" | \"invalid\" | \"cancelled\";\n\nexport interface PluginSelectionOpenContextV1 {\n\treadonly profileId: string;\n\treadonly status: PluginSelectionEntryStatusV1;\n\treadonly selection: PluginSelectionSummaryV1;\n\treadonly catalog: PluginCatalogSummaryV1;\n\treadonly diagnosticCodes: readonly PluginSelectionStoreDiagnosticCodeV1[];\n}\n\nexport type PluginSelectionEntryOpenResultV1 = PluginSelectionOpenContextV1;\n\nexport interface PluginSelectionEntryOptionsV1 {\n\treadonly profileId: string;\n\treadonly store?: PluginSelectionStoreV1;\n\treadonly selection?: PluginSelectionV1;\n\treadonly catalog?: PluginCatalogSnapshotV1;\n\treadonly controller?: PluginSelectionControllerV1;\n\treadonly snapshot?: PluginSelectionUiSnapshotV1;\n\t/** Host callback that opens the independent plugin selection surface. */\n\treadonly onOpen?: (context: PluginSelectionOpenContextV1) => void | Promise<void>;\n\t/** Called when the entry is closed after keyboard focus was transferred to it. */\n\treadonly onClose?: () => void;\n\t/** Request a render after an asynchronous host operation completes. */\n\treadonly requestRender?: () => void;\n}\n\nfunction boundedCount(value: readonly unknown[] | undefined, maximum: number): { count: number; truncated: boolean } {\n\tif (value === undefined) return { count: 0, truncated: false };\n\treturn { count: Math.min(value.length, maximum), truncated: value.length > maximum };\n}\n\nexport function summarizePluginSelectionV1(selection: PluginSelectionV1 | undefined): PluginSelectionSummaryV1 {\n\tif (selection === undefined) {\n\t\treturn Object.freeze({ present: false, selectedCount: 0, disabledCount: 0, truncated: false });\n\t}\n\tconst selected = boundedCount(selection.selectedPluginIds, MAX_SELECTION_IDS);\n\tconst disabled = boundedCount(selection.disabledPluginIds, MAX_SELECTION_IDS);\n\treturn Object.freeze({\n\t\tpresent: true,\n\t\tselectedCount: selected.count,\n\t\tdisabledCount: disabled.count,\n\t\ttruncated: selected.truncated || disabled.truncated,\n\t});\n}\n\nexport function summarizePluginCatalogV1(catalog: PluginCatalogSnapshotV1 | undefined): PluginCatalogSummaryV1 {\n\tif (catalog === undefined) {\n\t\treturn Object.freeze({ present: false, entryCount: 0, readyCount: 0, unavailableCount: 0, truncated: false });\n\t}\n\tconst entries = catalog.entries.slice(0, MAX_CATALOG_ENTRIES);\n\tconst readyCount = entries.filter((entry) => entry.resolution.status === \"installed-ready\").length;\n\treturn Object.freeze({\n\t\tpresent: true,\n\t\tentryCount: entries.length,\n\t\treadyCount,\n\t\tunavailableCount: entries.length - readyCount,\n\t\ttruncated: catalog.truncated || catalog.entries.length > MAX_CATALOG_ENTRIES,\n\t});\n}\n\nfunction validateProfileId(profileId: string): string {\n\tif (\n\t\ttypeof profileId !== \"string\" ||\n\t\tprofileId.trim().length === 0 ||\n\t\tprofileId.length > MAX_PROFILE_ID_CHARS ||\n\t\t/[\\u0000-\\u001f]/u.test(profileId)\n\t) {\n\t\tthrow new Error(t(\"invalid plugin selection profile ID\"));\n\t}\n\treturn profileId;\n}\n\nfunction emptySelectionSummary(): PluginSelectionSummaryV1 {\n\treturn Object.freeze({ present: false, selectedCount: 0, disabledCount: 0, truncated: false });\n}\n\nfunction diagnosticCodes(result: PluginSelectionStoreReadResultV1): readonly PluginSelectionStoreDiagnosticCodeV1[] {\n\tif (result.status === \"ok\" || result.status === \"missing\") return Object.freeze([]);\n\treturn Object.freeze(result.diagnostics.slice(0, MAX_DIAGNOSTIC_CODES).map((item) => item.code));\n}\n\nfunction selectionForProfile(\n\tresult: Extract<PluginSelectionStoreReadResultV1, { readonly status: \"ok\" | \"missing\" }>,\n\tprofileId: string,\n): PluginSelectionV1 | undefined {\n\treturn result.snapshot.selections.find((selection) => selection.profileId === profileId);\n}\n\n/**\n * A non-focusable entry. The surrounding config selector can expose\n * `openPluginSelection()` to its host without assigning plugin actions to the\n * legacy resource list or inventing a new global key binding.\n */\nexport class PluginSelectionEntryComponent implements Component, Focusable {\n\tprivate readonly profileId: string;\n\tprivate readonly store?: PluginSelectionStoreV1;\n\tprivate readonly controller?: PluginSelectionControllerV1;\n\tprivate readonly onOpen?: (context: PluginSelectionOpenContextV1) => void | Promise<void>;\n\tprivate readonly onClose?: () => void;\n\tprivate readonly requestRender?: () => void;\n\tprivate selection: PluginSelectionSummaryV1;\n\tprivate readonly catalog: PluginCatalogSummaryV1;\n\tprivate uiProfile?: PluginSelectionUiProfileV1;\n\tprivate uiPluginIndex = 0;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: PluginSelectionEntryOptionsV1) {\n\t\tthis.profileId = validateProfileId(options.profileId);\n\t\tif (options.selection !== undefined && options.selection.profileId !== this.profileId) {\n\t\t\tthrow new Error(t(\"plugin selection profile does not match the entry profile\"));\n\t\t}\n\t\tthis.store = options.store;\n\t\tthis.controller = options.controller;\n\t\tthis.onOpen = options.onOpen;\n\t\tthis.onClose = options.onClose;\n\t\tthis.requestRender = options.requestRender;\n\t\tthis.selection = summarizePluginSelectionV1(options.selection);\n\t\tthis.catalog = summarizePluginCatalogV1(options.catalog);\n\t\tthis.uiProfile = options.snapshot?.profiles.find((profile) => profile.profileId === this.profileId);\n\t}\n\n\tprivate hasHostEntry(): boolean {\n\t\treturn this.store !== undefined || this.controller !== undefined || this.onOpen !== undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this.hasHostEntry()) {\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.fg(\"dim\", ` ${t(\"Plugins: unsupported (host selection entry not injected)\")}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tif (this._focused && this.uiProfile !== undefined) {\n\t\t\tconst lines = [\n\t\t\t\ttruncateToWidth(\n\t\t\t\t\ttheme.bold(` ${t(\"Plugins · {profile}\", { profile: this.uiProfile.profileId })}`),\n\t\t\t\t\twidth,\n\t\t\t\t\t\"...\",\n\t\t\t\t),\n\t\t\t];\n\t\t\tfor (const [index, plugin] of this.uiProfile.plugins.entries()) {\n\t\t\t\tconst cursor = index === this.uiPluginIndex ? \">\" : \" \";\n\t\t\t\tconst state = plugin.state === \"selected\" ? \"on\" : plugin.state === \"disabled\" ? \"off\" : \"available\";\n\t\t\t\tconst availability = plugin.availability === \"ready\" ? \"ready\" : \"unavailable\";\n\t\t\t\tlines.push(truncateToWidth(` ${cursor} [${state}] ${plugin.pluginId} (${availability})`, width, \"...\"));\n\t\t\t}\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${t(\"Enter/Space toggle · Esc close\")}`), width, \"...\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst selectionText = this.selection.present\n\t\t\t? t(\"selected {selected}, disabled {disabled}\", {\n\t\t\t\t\tselected: this.selection.selectedCount,\n\t\t\t\t\tdisabled: this.selection.disabledCount,\n\t\t\t\t}) + (this.selection.truncated ? t(\", bounded\") : \"\")\n\t\t\t: this.store === undefined\n\t\t\t\t? t(\"selection pending\")\n\t\t\t\t: t(\"selection not loaded\");\n\t\tconst catalogText = this.catalog.present\n\t\t\t? t(\"catalog {count} ({ready} ready, {unavailable} unavailable)\", {\n\t\t\t\t\tcount: this.catalog.entryCount,\n\t\t\t\t\tready: this.catalog.readyCount,\n\t\t\t\t\tunavailable: this.catalog.unavailableCount,\n\t\t\t\t}) + (this.catalog.truncated ? t(\", bounded\") : \"\")\n\t\t\t: t(\"catalog unavailable\");\n\t\tconst suffix = this.onOpen === undefined ? t(\"host store\") : t(\"open via host callback\");\n\t\treturn [\n\t\t\ttruncateToWidth(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\t` ${t(\"Plugins: profile {profile} · {selection} · {catalog} · {suffix}\", {\n\t\t\t\t\t\tprofile: this.profileId,\n\t\t\t\t\t\tselection: selectionText,\n\t\t\t\t\t\tcatalog: catalogText,\n\t\t\t\t\t\tsuffix,\n\t\t\t\t\t})}`,\n\t\t\t\t),\n\t\t\t\twidth,\n\t\t\t\t\"...\",\n\t\t\t),\n\t\t];\n\t}\n\n\tprivate setUiSnapshot(result: PluginSelectionControllerResultV1): void {\n\t\tif (result.status !== \"ok\") return;\n\t\tthis.uiProfile = result.snapshot.profiles.find((profile) => profile.profileId === this.profileId);\n\t\tif (this.uiProfile !== undefined) {\n\t\t\tthis.uiPluginIndex = Math.min(this.uiPluginIndex, Math.max(0, this.uiProfile.plugins.length - 1));\n\t\t}\n\t}\n\n\tprivate currentUiPlugin(): PluginSelectionUiPluginV1 | undefined {\n\t\treturn this.uiProfile?.plugins[this.uiPluginIndex];\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this._focused || this.uiProfile === undefined) return;\n\t\tconst keybindings = getKeybindings();\n\t\tif (keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.uiPluginIndex = Math.max(0, this.uiPluginIndex - 1);\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.uiPluginIndex = Math.min(this.uiProfile.plugins.length - 1, this.uiPluginIndex + 1);\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis._focused = false;\n\t\t\tthis.onClose?.();\n\t\t\tthis.requestRender?.();\n\t\t\treturn;\n\t\t}\n\t\tif (!keybindings.matches(data, \"tui.select.confirm\") && data !== \" \") return;\n\t\tconst plugin = this.currentUiPlugin();\n\t\tif (\n\t\t\tplugin === undefined ||\n\t\t\tthis.controller === undefined ||\n\t\t\t(plugin.state === \"disabled\" && plugin.availability !== \"ready\")\n\t\t)\n\t\t\treturn;\n\t\tvoid this.controller\n\t\t\t.toggle({ profileId: this.profileId, pluginId: plugin.pluginId })\n\t\t\t.then((result) => {\n\t\t\t\tthis.setUiSnapshot(result);\n\t\t\t\tthis.requestRender?.();\n\t\t\t})\n\t\t\t.catch(() => this.requestRender?.());\n\t}\n\n\t/** Read the bounded selection DTO and invoke the host-owned entry callback. */\n\tasync openPluginSelection(): Promise<PluginSelectionEntryOpenResultV1> {\n\t\tlet controllerResult: PluginSelectionControllerResultV1 | undefined;\n\t\tif (this.controller !== undefined) {\n\t\t\tcontrollerResult = await this.controller.getSnapshot();\n\t\t\tthis.setUiSnapshot(controllerResult);\n\t\t}\n\t\tlet status: PluginSelectionEntryStatusV1 = this.hasHostEntry() ? \"ready\" : \"unsupported\";\n\t\tlet selection = this.selection;\n\t\tlet codes: readonly PluginSelectionStoreDiagnosticCodeV1[] = Object.freeze([]);\n\t\tif (controllerResult?.status === \"error\") {\n\t\t\tstatus = controllerResult.code === \"store-cancelled\" ? \"cancelled\" : \"invalid\";\n\t\t}\n\n\t\tif (this.store !== undefined) {\n\t\t\tconst result = await this.store.read();\n\t\t\tcodes = diagnosticCodes(result);\n\t\t\tif (result.status === \"ok\" || result.status === \"missing\") {\n\t\t\t\tconst storedSelection = selectionForProfile(result, this.profileId);\n\t\t\t\tselection = summarizePluginSelectionV1(storedSelection);\n\t\t\t\tstatus = result.status === \"ok\" ? \"ready\" : \"missing\";\n\t\t\t} else {\n\t\t\t\tselection = emptySelectionSummary();\n\t\t\t\tstatus = result.status;\n\t\t\t}\n\t\t\tthis.selection = selection;\n\t\t}\n\n\t\tconst context: PluginSelectionOpenContextV1 = Object.freeze({\n\t\t\tprofileId: this.profileId,\n\t\t\tstatus,\n\t\t\tselection,\n\t\t\tcatalog: this.catalog,\n\t\t\tdiagnosticCodes: codes,\n\t\t});\n\t\tif (this.onOpen !== undefined) await this.onOpen(context);\n\t\treturn context;\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSelectionSummary(): PluginSelectionSummaryV1 {\n\t\treturn this.selection;\n\t}\n\n\tgetCatalogSummary(): PluginCatalogSummaryV1 {\n\t\treturn this.catalog;\n\t}\n}\n"]}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* stay behind the injected host contract.
|
|
7
7
|
*/
|
|
8
8
|
import { getKeybindings, truncateToWidth } from "@agent-forge/tui";
|
|
9
|
+
import { t } from "../../../core/i18n/index.js";
|
|
9
10
|
import { theme } from "../theme/theme.js";
|
|
10
11
|
const MAX_PROFILE_ID_CHARS = 128;
|
|
11
12
|
const MAX_SELECTION_IDS = 128;
|
|
@@ -48,7 +49,7 @@ function validateProfileId(profileId) {
|
|
|
48
49
|
profileId.trim().length === 0 ||
|
|
49
50
|
profileId.length > MAX_PROFILE_ID_CHARS ||
|
|
50
51
|
/[\u0000-\u001f]/u.test(profileId)) {
|
|
51
|
-
throw new Error("invalid plugin selection profile ID");
|
|
52
|
+
throw new Error(t("invalid plugin selection profile ID"));
|
|
52
53
|
}
|
|
53
54
|
return profileId;
|
|
54
55
|
}
|
|
@@ -89,7 +90,7 @@ export class PluginSelectionEntryComponent {
|
|
|
89
90
|
constructor(options) {
|
|
90
91
|
this.profileId = validateProfileId(options.profileId);
|
|
91
92
|
if (options.selection !== undefined && options.selection.profileId !== this.profileId) {
|
|
92
|
-
throw new Error("plugin selection profile does not match the entry profile");
|
|
93
|
+
throw new Error(t("plugin selection profile does not match the entry profile"));
|
|
93
94
|
}
|
|
94
95
|
this.store = options.store;
|
|
95
96
|
this.controller = options.controller;
|
|
@@ -106,31 +107,45 @@ export class PluginSelectionEntryComponent {
|
|
|
106
107
|
render(width) {
|
|
107
108
|
if (!this.hasHostEntry()) {
|
|
108
109
|
return [
|
|
109
|
-
truncateToWidth(theme.fg("dim", "
|
|
110
|
+
truncateToWidth(theme.fg("dim", ` ${t("Plugins: unsupported (host selection entry not injected)")}`), width, "..."),
|
|
110
111
|
];
|
|
111
112
|
}
|
|
112
113
|
if (this._focused && this.uiProfile !== undefined) {
|
|
113
|
-
const lines = [
|
|
114
|
+
const lines = [
|
|
115
|
+
truncateToWidth(theme.bold(` ${t("Plugins · {profile}", { profile: this.uiProfile.profileId })}`), width, "..."),
|
|
116
|
+
];
|
|
114
117
|
for (const [index, plugin] of this.uiProfile.plugins.entries()) {
|
|
115
118
|
const cursor = index === this.uiPluginIndex ? ">" : " ";
|
|
116
119
|
const state = plugin.state === "selected" ? "on" : plugin.state === "disabled" ? "off" : "available";
|
|
117
120
|
const availability = plugin.availability === "ready" ? "ready" : "unavailable";
|
|
118
121
|
lines.push(truncateToWidth(` ${cursor} [${state}] ${plugin.pluginId} (${availability})`, width, "..."));
|
|
119
122
|
}
|
|
120
|
-
lines.push(truncateToWidth(theme.fg("dim", "
|
|
123
|
+
lines.push(truncateToWidth(theme.fg("dim", ` ${t("Enter/Space toggle · Esc close")}`), width, "..."));
|
|
121
124
|
return lines;
|
|
122
125
|
}
|
|
123
126
|
const selectionText = this.selection.present
|
|
124
|
-
?
|
|
127
|
+
? t("selected {selected}, disabled {disabled}", {
|
|
128
|
+
selected: this.selection.selectedCount,
|
|
129
|
+
disabled: this.selection.disabledCount,
|
|
130
|
+
}) + (this.selection.truncated ? t(", bounded") : "")
|
|
125
131
|
: this.store === undefined
|
|
126
|
-
? "selection pending"
|
|
127
|
-
: "selection not loaded";
|
|
132
|
+
? t("selection pending")
|
|
133
|
+
: t("selection not loaded");
|
|
128
134
|
const catalogText = this.catalog.present
|
|
129
|
-
?
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
? t("catalog {count} ({ready} ready, {unavailable} unavailable)", {
|
|
136
|
+
count: this.catalog.entryCount,
|
|
137
|
+
ready: this.catalog.readyCount,
|
|
138
|
+
unavailable: this.catalog.unavailableCount,
|
|
139
|
+
}) + (this.catalog.truncated ? t(", bounded") : "")
|
|
140
|
+
: t("catalog unavailable");
|
|
141
|
+
const suffix = this.onOpen === undefined ? t("host store") : t("open via host callback");
|
|
132
142
|
return [
|
|
133
|
-
truncateToWidth(theme.fg("muted", ` Plugins: profile
|
|
143
|
+
truncateToWidth(theme.fg("muted", ` ${t("Plugins: profile {profile} · {selection} · {catalog} · {suffix}", {
|
|
144
|
+
profile: this.profileId,
|
|
145
|
+
selection: selectionText,
|
|
146
|
+
catalog: catalogText,
|
|
147
|
+
suffix,
|
|
148
|
+
})}`), width, "..."),
|
|
134
149
|
];
|
|
135
150
|
}
|
|
136
151
|
setUiSnapshot(result) {
|