dsh-agent-plugins-market 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -154
- package/README.zh.md +74 -164
- package/assets/dsh-agent-plugins.png +0 -0
- package/client/client.js +5371 -1085
- package/client/client.js.map +1 -1
- package/lib/index.js +2 -257
- package/lib/{application → packages/market-bundle/src/application}/catalog.js +207 -41
- package/lib/{application → packages/market-bundle/src/application}/details.js +73 -29
- package/lib/packages/market-bundle/src/application/extension-inventory.js +408 -0
- package/lib/packages/market-bundle/src/application/extension-project.js +64 -0
- package/lib/packages/market-bundle/src/application/resource-inventory.js +96 -0
- package/lib/packages/market-bundle/src/application/server-config.js +9 -0
- package/lib/packages/market-bundle/src/application/suite-queries.js +86 -0
- package/lib/packages/market-bundle/src/index.js +372 -0
- package/lib/{runtime/host → packages/market-bundle/src/platform}/feedback-tool.js +2 -2
- package/lib/{runtime/host → packages/market-bundle/src/platform}/settings-namespace.js +55 -7
- package/lib/packages/market-bundle/src/platform/settings-schema.js +25 -0
- package/lib/packages/market-bundle/src/routes-extension-presets.js +161 -0
- package/lib/packages/market-bundle/src/routes-resources.js +127 -0
- package/lib/{routes.js → packages/market-bundle/src/routes.js} +225 -21
- package/lib/packages/market-bundle/src/runtime-adapters.js +57 -0
- package/lib/packages/market-bundle/src/session-extension.js +337 -0
- package/lib/{application → packages/market-catalog/src/application}/catalog-context.js +7 -4
- package/lib/{application → packages/market-catalog/src/application}/install-store.js +3 -3
- package/lib/{application → packages/market-catalog/src/application}/snapshot-cache.js +100 -11
- package/lib/{application → packages/market-catalog/src/application}/source-store.js +24 -11
- package/lib/{application → packages/market-catalog/src/application}/state/state-store.js +1 -1
- package/lib/{application → packages/market-catalog/src/application}/state/storage-migration.js +1 -1
- package/lib/packages/market-catalog/src/index.js +19 -0
- package/lib/{catalog → packages/market-catalog/src/scanning}/archive.js +1 -1
- package/lib/{catalog → packages/market-catalog/src/scanning}/codex-mcp.js +1 -1
- package/lib/{catalog → packages/market-catalog/src/scanning}/component-files.js +2 -2
- package/lib/{catalog → packages/market-catalog/src/scanning}/manifests.js +2 -2
- package/lib/{catalog → packages/market-catalog/src/scanning}/native-project.js +1 -1
- package/lib/{catalog → packages/market-catalog/src/scanning}/paths.js +1 -1
- package/lib/{catalog → packages/market-catalog/src/scanning}/plugin-variables.js +21 -1
- package/lib/{catalog → packages/market-catalog/src/scanning}/scan-resolvers.js +35 -2
- package/lib/{catalog → packages/market-catalog/src/scanning}/skills-parse.js +40 -10
- package/lib/{catalog → packages/market-catalog/src/scanning}/validate.js +15 -2
- package/lib/packages/market-contracts/src/contracts/extension-presets.js +125 -0
- package/lib/{contracts → packages/market-contracts/src/contracts}/market.js +33 -5
- package/lib/packages/market-contracts/src/contracts/mcp-overrides.js +2 -0
- package/lib/packages/market-contracts/src/contracts/resource-window.js +29 -0
- package/lib/packages/market-contracts/src/contracts/settings.js +130 -0
- package/lib/packages/market-contracts/src/contracts/surface-toggles.js +29 -0
- package/lib/packages/market-contracts/src/contracts/translation.js +28 -0
- package/lib/packages/market-contracts/src/index.js +4 -0
- package/lib/{model → packages/market-contracts/src/model}/layouts.js +11 -0
- package/lib/{application → packages/market-contracts/src/ports}/ports.js +3 -0
- package/lib/{application/mcp/mcp-redaction.js → packages/market-contracts/src/redaction.js} +17 -1
- package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-direct-config.js +2 -2
- package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-server-state.js +1 -1
- package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-status.js +20 -3
- package/lib/{application → packages/market-lsp/src/application}/lsp/profile-seam.js +1 -1
- package/lib/packages/market-lsp/src/application/lsp/validation.js +46 -0
- package/lib/{application → packages/market-lsp/src/application}/lsp-service.js +61 -3
- package/lib/packages/market-lsp/src/index.js +8 -0
- package/lib/{runtime → packages/market-lsp/src/runtime}/lsp/lsp-mounts.js +79 -40
- package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-backend.js +0 -16
- package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-config.js +104 -21
- package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-direct-config.js +12 -4
- package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-overrides.js +4 -4
- package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-status.js +49 -10
- package/lib/packages/market-mcp/src/application/mcp/validation.js +63 -0
- package/lib/{application → packages/market-mcp/src/application}/mcp-service.js +111 -91
- package/lib/packages/market-mcp/src/index.js +10 -0
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/bridge.js +12 -9
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/connection.js +1 -1
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/oauth.js +1 -1
- package/lib/packages/market-mcp/src/runtime/mcp/bridge/tool-ownership.js +26 -0
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/tools.js +1 -1
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-auth-record.js +35 -4
- package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-mounts.js +35 -4
- package/lib/packages/market-runtime/src/adapter-contracts.js +1 -0
- package/lib/packages/market-runtime/src/application/command-resources.js +74 -0
- package/lib/packages/market-runtime/src/application/extension-authorization.js +27 -0
- package/lib/packages/market-runtime/src/application/extension-hook-selection.js +56 -0
- package/lib/packages/market-runtime/src/application/extension-suite-declarations.js +57 -0
- package/lib/packages/market-runtime/src/application/extension-suite-selection.js +84 -0
- package/lib/packages/market-runtime/src/application/fs-probe.js +43 -0
- package/lib/packages/market-runtime/src/application/panel-resources.js +370 -0
- package/lib/{application → packages/market-runtime/src/application}/panels/user-hooks.js +2 -2
- package/lib/{application → packages/market-runtime/src/application}/panels/user-store.js +53 -13
- package/lib/{application → packages/market-runtime/src/application}/project-agent-roles.js +20 -11
- package/lib/packages/market-runtime/src/application/state/extension-presets.js +144 -0
- package/lib/packages/market-runtime/src/application/state/resource-favorites.js +90 -0
- package/lib/packages/market-runtime/src/application/state/resource-filters.js +2 -0
- package/lib/packages/market-runtime/src/application/state/surface-toggles.js +10 -0
- package/lib/packages/market-runtime/src/application/state/workspace-policy.js +56 -0
- package/lib/packages/market-runtime/src/catalog-port.js +1 -0
- package/lib/packages/market-runtime/src/extension-service.js +1 -0
- package/lib/packages/market-runtime/src/index.js +31 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-router.js +74 -79
- package/lib/packages/market-runtime/src/runtime/agents/agent-teams-seat.js +58 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/agents/subagent-catalog.js +89 -21
- package/lib/packages/market-runtime/src/runtime/agents/team-coordination.js +51 -0
- package/lib/packages/market-runtime/src/runtime/agents/teammate-role-runtime.js +241 -0
- package/lib/packages/market-runtime/src/runtime/agents/teammate-role-tool.js +130 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/core/reconcile-scheduler.js +2 -2
- package/lib/packages/market-runtime/src/runtime/core/reconciler.js +457 -0
- package/lib/packages/market-runtime/src/runtime/host/command-name-allocator.js +168 -0
- package/lib/packages/market-runtime/src/runtime/host/extension-progress.js +120 -0
- package/lib/packages/market-runtime/src/runtime/host/extension-runtime.js +405 -0
- package/lib/packages/market-runtime/src/runtime/host/extension-session-state.js +839 -0
- package/lib/packages/market-runtime/src/runtime/host/extension-tool-gates.js +96 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/host/failure-detail.js +1 -1
- package/lib/{runtime → packages/market-runtime/src/runtime}/host/host-locale.js +2 -0
- package/lib/packages/market-runtime/src/runtime/host/menu-row-identities.js +38 -0
- package/lib/packages/market-runtime/src/runtime/host/resource-filter-service.js +81 -0
- package/lib/packages/market-runtime/src/runtime/host/scoped-contributors.js +304 -0
- package/lib/packages/market-runtime/src/runtime/host/surface-toggle-service.js +15 -0
- package/lib/packages/market-runtime/src/runtime/panels/user-commands.js +211 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/panels/user-panels.js +34 -14
- package/lib/packages/market-runtime/src/runtime/surfaces/commands-mounts.js +256 -0
- package/lib/packages/market-runtime/src/runtime/surfaces/extension-hooks.js +294 -0
- package/lib/packages/market-runtime/src/runtime/surfaces/hook-dry-run.js +122 -0
- package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/hooks-mounts.js +1 -1
- package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/project-runtime.js +23 -13
- package/lib/packages/market-runtime/src/runtime/surfaces/skills-provider.js +241 -0
- package/lib/packages/market-translation/src/application/state/translation-cache.js +122 -0
- package/lib/packages/market-translation/src/application/translation/chain.js +99 -0
- package/lib/packages/market-translation/src/application/translation/document.js +384 -0
- package/lib/packages/market-translation/src/application/translation/localizer.js +642 -0
- package/lib/packages/market-translation/src/application/translation/service.js +113 -0
- package/lib/packages/market-translation/src/application/translation/unit.js +19 -0
- package/lib/packages/market-translation/src/index.js +4 -0
- package/lib/packages/market-translation/src/runtime/host/llm-translator.js +278 -0
- package/lib/packages/market-translation/src/runtime/host/machine-translator.js +152 -0
- package/lib/packages/market-translation/src/runtime/host/text-masking.js +96 -0
- package/lib/packages/market-translation/src/runtime/host/translation-providers.js +116 -0
- package/lib/types/index.d.ts +2 -130
- package/lib/types/{application → packages/market-bundle/src/application}/catalog.d.ts +117 -22
- package/lib/types/packages/market-bundle/src/application/details.d.ts +24 -0
- package/lib/types/packages/market-bundle/src/application/extension-inventory.d.ts +45 -0
- package/lib/types/packages/market-bundle/src/application/extension-project.d.ts +26 -0
- package/lib/types/packages/market-bundle/src/application/resource-inventory.d.ts +42 -0
- package/lib/types/packages/market-bundle/src/application/server-config.d.ts +9 -0
- package/lib/types/packages/market-bundle/src/application/suite-queries.d.ts +84 -0
- package/lib/types/packages/market-bundle/src/index.d.ts +125 -0
- package/lib/types/{runtime/host → packages/market-bundle/src/platform}/settings-namespace.d.ts +44 -9
- package/lib/types/{application/mcp/mcp-backend.d.ts → packages/market-bundle/src/platform/settings-schema.d.ts} +13 -28
- package/lib/types/packages/market-bundle/src/routes-extension-presets.d.ts +15 -0
- package/lib/types/packages/market-bundle/src/routes-resources.d.ts +17 -0
- package/lib/types/packages/market-bundle/src/routes.d.ts +32 -0
- package/lib/types/packages/market-bundle/src/runtime-adapters.d.ts +42 -0
- package/lib/types/packages/market-bundle/src/session-extension.d.ts +62 -0
- package/lib/types/{application → packages/market-catalog/src/application}/catalog-context.d.ts +11 -3
- package/lib/types/{application → packages/market-catalog/src/application}/install-store.d.ts +1 -1
- package/lib/types/{application → packages/market-catalog/src/application}/regions.d.ts +1 -1
- package/lib/types/{application → packages/market-catalog/src/application}/snapshot-cache.d.ts +44 -2
- package/lib/types/{application → packages/market-catalog/src/application}/source-store.d.ts +12 -3
- package/lib/types/{application → packages/market-catalog/src/application}/state/state-store.d.ts +1 -1
- package/lib/types/packages/market-catalog/src/index.d.ts +22 -0
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/archive.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/codex-mcp.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/component-files.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/lsp-spec.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/manifests.d.ts +3 -3
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/native-project.d.ts +2 -2
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/plugin-variables.d.ts +12 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/project-config.d.ts +2 -2
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/project-hooks.d.ts +2 -2
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/scan-pipeline.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/scan-resolvers.d.ts +3 -3
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/source-catalog.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/suite-components.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/suite-scanner.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/surfaces.d.ts +1 -1
- package/lib/types/{catalog → packages/market-catalog/src/scanning}/validate.d.ts +1 -1
- package/lib/types/packages/market-contracts/src/contracts/extension-presets.d.ts +237 -0
- package/lib/types/{contracts → packages/market-contracts/src/contracts}/market.d.ts +87 -16
- package/lib/types/packages/market-contracts/src/contracts/mcp-overrides.d.ts +39 -0
- package/lib/types/{contracts → packages/market-contracts/src/contracts}/mcp-status.d.ts +9 -0
- package/lib/types/packages/market-contracts/src/contracts/resource-window.d.ts +70 -0
- package/lib/types/packages/market-contracts/src/contracts/settings.d.ts +121 -0
- package/lib/types/packages/market-contracts/src/contracts/surface-toggles.d.ts +28 -0
- package/lib/types/packages/market-contracts/src/contracts/translation.d.ts +81 -0
- package/lib/types/{runtime → packages/market-contracts/src}/host/plugin-message-source.d.ts +1 -1
- package/lib/types/packages/market-contracts/src/index.d.ts +5 -0
- package/lib/types/{model → packages/market-contracts/src/model}/layouts.d.ts +7 -0
- package/lib/types/{model → packages/market-contracts/src/model}/types.d.ts +2 -2
- package/lib/types/packages/market-contracts/src/ports/ports.d.ts +183 -0
- package/lib/types/{application → packages/market-contracts/src/ports}/queries.d.ts +27 -6
- package/lib/types/{application/mcp/mcp-redaction.d.ts → packages/market-contracts/src/redaction.d.ts} +2 -0
- package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-direct-config.d.ts +1 -1
- package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-status.d.ts +21 -5
- package/lib/types/packages/market-lsp/src/application/lsp/validation.d.ts +8 -0
- package/lib/types/{application → packages/market-lsp/src/application}/lsp-service.d.ts +19 -6
- package/lib/types/packages/market-lsp/src/index.d.ts +8 -0
- package/lib/types/{runtime → packages/market-lsp/src/runtime}/lsp/lsp-mounts.d.ts +26 -6
- package/lib/types/packages/market-mcp/src/application/mcp/mcp-backend.d.ts +28 -0
- package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-bridge-config.d.ts +1 -1
- package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-config.d.ts +2 -2
- package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-direct-config.d.ts +6 -1
- package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-overrides.d.ts +4 -38
- package/lib/types/packages/market-mcp/src/application/mcp/mcp-status.d.ts +40 -0
- package/lib/types/{application/server-config.d.ts → packages/market-mcp/src/application/mcp/validation.d.ts} +2 -10
- package/lib/types/{application → packages/market-mcp/src/application}/mcp-service.d.ts +22 -16
- package/lib/types/packages/market-mcp/src/index.d.ts +12 -0
- package/lib/types/packages/market-mcp/src/runtime/mcp/bridge/tool-ownership.d.ts +14 -0
- package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-auth-record.d.ts +4 -0
- package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-mounts.d.ts +19 -3
- package/lib/types/packages/market-runtime/src/adapter-contracts.d.ts +89 -0
- package/lib/types/{application → packages/market-runtime/src/application}/agent-roles.d.ts +2 -0
- package/lib/types/packages/market-runtime/src/application/command-resources.d.ts +26 -0
- package/lib/types/packages/market-runtime/src/application/extension-authorization.d.ts +12 -0
- package/lib/types/packages/market-runtime/src/application/extension-hook-selection.d.ts +23 -0
- package/lib/types/packages/market-runtime/src/application/extension-suite-declarations.d.ts +10 -0
- package/lib/types/packages/market-runtime/src/application/extension-suite-selection.d.ts +30 -0
- package/lib/types/packages/market-runtime/src/application/fs-probe.d.ts +12 -0
- package/lib/types/packages/market-runtime/src/application/panel-resources.d.ts +100 -0
- package/lib/types/{application → packages/market-runtime/src/application}/panels/user-hooks.d.ts +1 -1
- package/lib/types/packages/market-runtime/src/application/project-agent-roles.d.ts +10 -0
- package/lib/types/packages/market-runtime/src/application/state/extension-presets.d.ts +24 -0
- package/lib/types/packages/market-runtime/src/application/state/resource-favorites.d.ts +9 -0
- package/lib/types/packages/market-runtime/src/application/state/resource-filters.d.ts +2 -0
- package/lib/types/packages/market-runtime/src/application/state/surface-toggles.d.ts +6 -0
- package/lib/types/packages/market-runtime/src/application/state/workspace-policy.d.ts +19 -0
- package/lib/types/packages/market-runtime/src/catalog-port.d.ts +30 -0
- package/lib/types/packages/market-runtime/src/extension-service.d.ts +14 -0
- package/lib/types/packages/market-runtime/src/index.d.ts +41 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-router.d.ts +66 -31
- package/lib/types/packages/market-runtime/src/runtime/agents/agent-teams-seat.d.ts +41 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/subagent-catalog.d.ts +34 -2
- package/lib/types/packages/market-runtime/src/runtime/agents/team-coordination.d.ts +8 -0
- package/lib/types/packages/market-runtime/src/runtime/agents/teammate-role-runtime.d.ts +74 -0
- package/lib/types/packages/market-runtime/src/runtime/agents/teammate-role-tool.d.ts +6 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/reconcile-scheduler.d.ts +5 -2
- package/lib/types/packages/market-runtime/src/runtime/core/reconciler.d.ts +141 -0
- package/lib/types/packages/market-runtime/src/runtime/host/command-name-allocator.d.ts +132 -0
- package/lib/types/packages/market-runtime/src/runtime/host/extension-progress.d.ts +91 -0
- package/lib/types/packages/market-runtime/src/runtime/host/extension-runtime.d.ts +77 -0
- package/lib/types/packages/market-runtime/src/runtime/host/extension-session-state.d.ts +242 -0
- package/lib/types/packages/market-runtime/src/runtime/host/extension-tool-gates.d.ts +38 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/host-locale.d.ts +1 -1
- package/lib/types/packages/market-runtime/src/runtime/host/menu-row-identities.d.ts +50 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/model-catalog.d.ts +1 -1
- package/lib/types/packages/market-runtime/src/runtime/host/resource-filter-service.d.ts +34 -0
- package/lib/types/packages/market-runtime/src/runtime/host/scoped-contributors.d.ts +58 -0
- package/lib/types/packages/market-runtime/src/runtime/host/surface-toggle-service.d.ts +10 -0
- package/lib/types/packages/market-runtime/src/runtime/panels/user-commands.d.ts +74 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/panels/user-panels.d.ts +7 -1
- package/lib/types/packages/market-runtime/src/runtime/surfaces/commands-mounts.d.ts +81 -0
- package/lib/types/packages/market-runtime/src/runtime/surfaces/extension-hooks.d.ts +59 -0
- package/lib/types/packages/market-runtime/src/runtime/surfaces/hook-dry-run.d.ts +91 -0
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/hooks-mounts.d.ts +1 -1
- package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/project-runtime.d.ts +8 -5
- package/lib/types/packages/market-runtime/src/runtime/surfaces/skills-provider.d.ts +71 -0
- package/lib/types/packages/market-translation/src/application/state/translation-cache.d.ts +56 -0
- package/lib/types/packages/market-translation/src/application/translation/chain.d.ts +47 -0
- package/lib/types/packages/market-translation/src/application/translation/document.d.ts +54 -0
- package/lib/types/packages/market-translation/src/application/translation/localizer.d.ts +325 -0
- package/lib/types/packages/market-translation/src/application/translation/service.d.ts +89 -0
- package/lib/types/packages/market-translation/src/application/translation/unit.d.ts +35 -0
- package/lib/types/packages/market-translation/src/index.d.ts +4 -0
- package/lib/types/packages/market-translation/src/runtime/host/llm-translator.d.ts +30 -0
- package/lib/types/packages/market-translation/src/runtime/host/machine-translator.d.ts +52 -0
- package/lib/types/packages/market-translation/src/runtime/host/text-masking.d.ts +42 -0
- package/lib/types/packages/market-translation/src/runtime/host/translation-providers.d.ts +42 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +47 -10
- package/schemas/README.md +4 -4
- package/schemas/agent-plugins/spec.md +2 -2
- package/schemas/com.deepseek.harness/spec.md +1 -1
- package/schemas/skill-collection/spec.md +10 -2
- package/lib/application/panel-resources.js +0 -161
- package/lib/application/server-config.js +0 -109
- package/lib/contracts/settings.js +0 -63
- package/lib/runtime/core/reconciler.js +0 -100
- package/lib/runtime/panels/user-commands.js +0 -105
- package/lib/runtime/surfaces/commands-mounts.js +0 -186
- package/lib/runtime/surfaces/skills-provider.js +0 -160
- package/lib/types/application/details.d.ts +0 -7
- package/lib/types/application/mcp/mcp-status.d.ts +0 -24
- package/lib/types/application/panel-resources.d.ts +0 -28
- package/lib/types/application/ports.d.ts +0 -86
- package/lib/types/application/project-agent-roles.d.ts +0 -3
- package/lib/types/contracts/settings.d.ts +0 -59
- package/lib/types/routes.d.ts +0 -16
- package/lib/types/runtime/core/reconciler.d.ts +0 -58
- package/lib/types/runtime/panels/user-commands.d.ts +0 -27
- package/lib/types/runtime/surfaces/commands-mounts.d.ts +0 -48
- package/lib/types/runtime/surfaces/skills-provider.d.ts +0 -23
- /package/lib/{application → packages/market-catalog/src/application}/deadline.js +0 -0
- /package/lib/{application → packages/market-catalog/src/application}/json-file.js +0 -0
- /package/lib/{application → packages/market-catalog/src/application}/regions.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/fs-probes.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/git.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/lsp-spec.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/project-config.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/project-hooks.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/scan-pipeline.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/source-catalog.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/suite-components.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/suite-scanner.js +0 -0
- /package/lib/{catalog → packages/market-catalog/src/scanning}/surfaces.js +0 -0
- /package/lib/{contracts → packages/market-contracts/src/contracts}/lsp-status.js +0 -0
- /package/lib/{contracts → packages/market-contracts/src/contracts}/lsp.js +0 -0
- /package/lib/{contracts → packages/market-contracts/src/contracts}/mcp-status.js +0 -0
- /package/lib/{contracts → packages/market-contracts/src/contracts}/mcp.js +0 -0
- /package/lib/{runtime → packages/market-contracts/src}/host/plugin-message-source.js +0 -0
- /package/lib/{model → packages/market-contracts/src/model}/command-names.js +0 -0
- /package/lib/{model → packages/market-contracts/src/model}/preset-source.js +0 -0
- /package/lib/{model → packages/market-contracts/src/model}/types.js +0 -0
- /package/lib/{application → packages/market-contracts/src/ports}/queries.js +0 -0
- /package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-bridge-config.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-contract.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-seams.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/plugin-identity.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/projection.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/transport.js +0 -0
- /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-credentials.js +0 -0
- /package/lib/{application → packages/market-runtime/src/application}/agent-roles.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-names.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/core/context.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/core/mount-lifecycle.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/core/source-auto-update.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/core/timer-seat.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/host/model-catalog.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/host/shell-path.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/host/tool-registry-observer.js +0 -0
- /package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/dynamic-context.js +0 -0
- /package/lib/types/{runtime/host → packages/market-bundle/src/platform}/feedback-tool.d.ts +0 -0
- /package/lib/types/{application → packages/market-catalog/src/application}/deadline.d.ts +0 -0
- /package/lib/types/{application → packages/market-catalog/src/application}/json-file.d.ts +0 -0
- /package/lib/types/{application → packages/market-catalog/src/application}/state/storage-migration.d.ts +0 -0
- /package/lib/types/{catalog → packages/market-catalog/src/scanning}/fs-probes.d.ts +0 -0
- /package/lib/types/{catalog → packages/market-catalog/src/scanning}/git.d.ts +0 -0
- /package/lib/types/{catalog → packages/market-catalog/src/scanning}/paths.d.ts +0 -0
- /package/lib/types/{catalog → packages/market-catalog/src/scanning}/skills-parse.d.ts +0 -0
- /package/lib/types/{contracts → packages/market-contracts/src/contracts}/lsp-status.d.ts +0 -0
- /package/lib/types/{contracts → packages/market-contracts/src/contracts}/lsp.d.ts +0 -0
- /package/lib/types/{contracts → packages/market-contracts/src/contracts}/mcp.d.ts +0 -0
- /package/lib/types/{model → packages/market-contracts/src/model}/command-names.d.ts +0 -0
- /package/lib/types/{model → packages/market-contracts/src/model}/preset-source.d.ts +0 -0
- /package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-server-state.d.ts +0 -0
- /package/lib/types/{application → packages/market-lsp/src/application}/lsp/profile-seam.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/bridge.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/connection.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-contract.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-seams.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/oauth.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/plugin-identity.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/projection.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/tools.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/transport.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-credentials.d.ts +0 -0
- /package/lib/types/{application → packages/market-runtime/src/application}/panels/user-store.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-names.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/context.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/mount-lifecycle.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/source-auto-update.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/timer-seat.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/failure-detail.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/shell-path.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/tool-registry-observer.d.ts +0 -0
- /package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/dynamic-context.d.ts +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** Suite detail and preview projections owned by the application layer. */
|
|
2
2
|
import { readFile, stat } from 'node:fs/promises';
|
|
3
3
|
import { parse as parseYaml } from 'yaml';
|
|
4
|
-
import { discoverLspEntries } from '
|
|
5
|
-
import { defaultMarkdownResources, resourceText } from '
|
|
6
|
-
import { credentialRefsInServer } from '
|
|
7
|
-
import { redactMcpConfig, redactMcpOverrides } from '
|
|
8
|
-
import { applyOverride } from '
|
|
9
|
-
import { effectiveSurfaces } from '
|
|
4
|
+
import { discoverLspEntries } from '../../../market-catalog/src/index.js';
|
|
5
|
+
import { defaultMarkdownResources, resourceText } from '../../../market-catalog/src/index.js';
|
|
6
|
+
import { credentialRefsInServer } from '../../../market-mcp/src/index.js';
|
|
7
|
+
import { redactMcpConfig, redactMcpOverrides } from '../../../market-contracts/src/redaction.js';
|
|
8
|
+
import { applyOverride } from '../../../market-mcp/src/index.js';
|
|
9
|
+
import { effectiveSurfaces } from '../../../market-contracts/src/model/types.js';
|
|
10
10
|
/** The checkout's last modification, or null when the path cannot be read. */
|
|
11
11
|
async function rootModifiedAt(root) {
|
|
12
12
|
try {
|
|
@@ -60,53 +60,97 @@ export async function buildSuiteDetail(suite, installed, diagnostics, mcpOverrid
|
|
|
60
60
|
: { count: 0, entries: [] }
|
|
61
61
|
: normalizedHookPreviews(suite.hooks)
|
|
62
62
|
: { count: 0, entries: [] },
|
|
63
|
-
commands: remoteUrl === undefined ? await
|
|
64
|
-
agents: remoteUrl === undefined ? await
|
|
63
|
+
commands: remoteUrl === undefined ? await documentMetas(suite.resources?.commands ?? (await defaultMarkdownResources(suite.root, 'commands'))) : [],
|
|
64
|
+
agents: remoteUrl === undefined ? await documentMetas(suite.resources?.agents ?? (await defaultMarkdownResources(suite.root, 'agents'))) : [],
|
|
65
65
|
lsp: remoteUrl === undefined ? await lspDetail(suite) : { servers: [], raw: [] },
|
|
66
66
|
errors: suite.errors,
|
|
67
67
|
mcpErrors: diagnostics.filter(diagnostic => diagnostic.suiteId === suite.id).map(diagnostic => `${diagnostic.serverKey}: ${diagnostic.reason}`)
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
/**
|
|
71
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Read one skill's authored text from a normalized suite.
|
|
72
|
+
*
|
|
73
|
+
* A skill's file is resolved by the scan; commands and agents resolve theirs
|
|
74
|
+
* through the suite's own resource list ({@link readSuiteDocument}). A skill a
|
|
75
|
+
* suite does not carry is a miss, not a lookup.
|
|
76
|
+
*/
|
|
77
|
+
async function readSkillText(suite, skillName) {
|
|
72
78
|
const skill = suite.skills.find(entry => entry.name === skillName);
|
|
73
79
|
if (skill === undefined)
|
|
74
80
|
throw new Error(`skill "${skillName}" not found in suite "${suite.id}"`);
|
|
75
|
-
let content;
|
|
76
81
|
try {
|
|
77
|
-
|
|
82
|
+
return await readFile(skill.file, 'utf8');
|
|
78
83
|
}
|
|
79
84
|
catch (error) {
|
|
80
85
|
throw new Error(`skill file unreadable: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
81
86
|
}
|
|
82
|
-
return { name: skill.name, description: skill.description, content, path: skill.file };
|
|
83
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Read one of a suite's document surfaces — a skill, a command, or an agent —
|
|
90
|
+
* by the identity the market detail page addresses it with.
|
|
91
|
+
*
|
|
92
|
+
* This is the only body the market ever serves. The detail payload carries a
|
|
93
|
+
* document's name and description so its row can render, and the text arrives
|
|
94
|
+
* here when a reader opens that row, whole and uncut.
|
|
95
|
+
*
|
|
96
|
+
* The suite's own scanned resource list is the only source of a path: the
|
|
97
|
+
* caller names a document, never a path, and a name the scan did not produce is
|
|
98
|
+
* a miss rather than a lookup. Commands and agents read the same resource the
|
|
99
|
+
* scan that built the detail payload found, so a document read here is the
|
|
100
|
+
* document that payload named — re-read rather than taken from the request.
|
|
101
|
+
* @param suite - the normalized suite the document belongs to.
|
|
102
|
+
* @param kind - which of the three document surfaces the name belongs to.
|
|
103
|
+
* @param name - the document's name inside that surface.
|
|
104
|
+
* @returns the document's text exactly as authored.
|
|
105
|
+
*/
|
|
106
|
+
export async function readSuiteDocument(suite, kind, name) {
|
|
107
|
+
if (kind === 'skills')
|
|
108
|
+
return readSkillText(suite, name);
|
|
109
|
+
const resources = suite.resources?.[kind] ?? (await defaultMarkdownResources(suite.root, kind));
|
|
110
|
+
const resource = resources.find(entry => entry.name === name);
|
|
111
|
+
if (resource === undefined)
|
|
112
|
+
throw new Error(`no ${kind} document named "${name}" in suite "${suite.id}"`);
|
|
113
|
+
return resourceText(resource);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A capped preview of a file whose bytes still travel inside the detail
|
|
117
|
+
* payload — the directory-style LSP definition files, and nothing else. The
|
|
118
|
+
* cap is written into the text it produces, so a reader who gets one never
|
|
119
|
+
* mistakes a cut document for a whole one.
|
|
120
|
+
*/
|
|
84
121
|
async function readPreview(path, capBytes = 64 * 1024) {
|
|
85
122
|
const text = await readFile(path, 'utf8');
|
|
86
123
|
return text.length > capBytes ? `${text.slice(0, capBytes)}\n… (truncated)` : text;
|
|
87
124
|
}
|
|
88
|
-
|
|
89
|
-
|
|
125
|
+
/**
|
|
126
|
+
* One document's identity as the suite detail payload carries it: the name its
|
|
127
|
+
* row shows and the description its frontmatter declares. The body is not part
|
|
128
|
+
* of the payload — it is read on demand, by the document route, when a reader
|
|
129
|
+
* opens the row.
|
|
130
|
+
*/
|
|
131
|
+
async function documentMetas(resources) {
|
|
132
|
+
const metas = [];
|
|
90
133
|
for (const resource of resources) {
|
|
91
134
|
try {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
let description;
|
|
95
|
-
if (frontmatter !== undefined) {
|
|
96
|
-
const yaml = parseYaml(frontmatter);
|
|
97
|
-
if (typeof yaml === 'object' && yaml !== null) {
|
|
98
|
-
const desc = yaml['description'];
|
|
99
|
-
if (typeof desc === 'string')
|
|
100
|
-
description = desc;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
previews.push({ name: resource.name, ...(description === undefined ? {} : { description }), content });
|
|
135
|
+
const description = frontmatterDescription(await resourceText(resource));
|
|
136
|
+
metas.push({ name: resource.name, ...(description === undefined ? {} : { description }) });
|
|
104
137
|
}
|
|
105
138
|
catch {
|
|
106
|
-
// Unreadable
|
|
139
|
+
// Unreadable document files are omitted from the detail response.
|
|
107
140
|
}
|
|
108
141
|
}
|
|
109
|
-
return
|
|
142
|
+
return metas;
|
|
143
|
+
}
|
|
144
|
+
/** The `description` a document's YAML frontmatter declares, when it declares one. */
|
|
145
|
+
function frontmatterDescription(text) {
|
|
146
|
+
const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text)?.[1];
|
|
147
|
+
if (frontmatter === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
const yaml = parseYaml(frontmatter);
|
|
150
|
+
if (typeof yaml !== 'object' || yaml === null)
|
|
151
|
+
return undefined;
|
|
152
|
+
const description = yaml['description'];
|
|
153
|
+
return typeof description === 'string' ? description : undefined;
|
|
110
154
|
}
|
|
111
155
|
function normalizedHookPreviews(hooks) {
|
|
112
156
|
const entries = Object.entries(hooks.events).flatMap(([event, groups]) => groups.flatMap(group => group.hooks.map(hook => ({ event, ...(group.matcher === undefined ? {} : { matcher: group.matcher }), command: hook.command }))));
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/** Extension inventory reuses catalog/panel status queries and preserves their full-detail identities. */
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { HOOK_EVENT_HOST_SUPPORT, hookResourceId } from '../../../market-contracts/src/contracts/extension-presets.js';
|
|
4
|
+
import { SUITE_SURFACE_KEYS } from '../../../market-contracts/src/model/types.js';
|
|
5
|
+
import { USER_MCP_SOURCE, USER_MCP_SUITE } from '../../../market-mcp/src/index.js';
|
|
6
|
+
import { qualifiedSuiteId } from '../../../market-catalog/src/index.js';
|
|
7
|
+
import { deriveServerName } from '../../../market-mcp/src/index.js';
|
|
8
|
+
import { USER_HOOKS_SOURCE, USER_HOOKS_SUITE, exposesIndividualHooks } from '../../../market-runtime/src/index.js';
|
|
9
|
+
import { DIRECT_LSP_SUITE_ID } from '../../../market-lsp/src/index.js';
|
|
10
|
+
/** User-owned configuration is not a market offering. Its direct MCP servers have no suite parent. */
|
|
11
|
+
const isOwnedSentinel = (sourceId, id) => (sourceId === USER_MCP_SOURCE && id === USER_MCP_SUITE) || (sourceId === USER_HOOKS_SOURCE && id === USER_HOOKS_SUITE);
|
|
12
|
+
/** Classification does not change the identifiers used by existing preset and session records. */
|
|
13
|
+
function localConfiguration(suite) {
|
|
14
|
+
if (suite.sourceId === USER_HOOKS_SOURCE && suite.id === USER_HOOKS_SUITE)
|
|
15
|
+
return { configuration: 'user-hooks', name: 'User Hooks' };
|
|
16
|
+
if (suite.dimension === 'project')
|
|
17
|
+
return { configuration: 'project', name: suite.sourceId === 'native' ? basename(suite.root) : suite.manifest.name };
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Suite panel ids are JSON tuples, not display names or flattened command identifiers. */
|
|
21
|
+
export function suiteResourceOwner(entry) {
|
|
22
|
+
if (entry.origin !== 'plugin' || entry.id === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
try {
|
|
25
|
+
const value = JSON.parse(entry.id);
|
|
26
|
+
if (Array.isArray(value) && value.length === 4 && typeof value[0] === 'string' && typeof value[1] === 'string') {
|
|
27
|
+
return 'market:' + value[0] + '/' + value[1];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* Invalid provenance remains unavailable instead of guessing its owner. */
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The composed global switch for one panel entry.
|
|
37
|
+
*
|
|
38
|
+
* Only a candidate's validated declaration can say whether an entry the panel
|
|
39
|
+
* reports as off is an ordinary disabled consumer (selectable per session) or an
|
|
40
|
+
* invalid one (not selectable at all). Without a candidate the panel's own verdict
|
|
41
|
+
* is the whole answer, which is the legacy behaviour.
|
|
42
|
+
*/
|
|
43
|
+
function candidateEntryVerdict(candidate, kind, name, panelDisabled) {
|
|
44
|
+
// An ordinary disabled consumer stays selectable per session; a surface that failed
|
|
45
|
+
// validation, or an entry the declaration does not actually carry, does not.
|
|
46
|
+
const selectable = candidate.validSurfaces[kind] === true && declaresResource(candidate, kind, name);
|
|
47
|
+
// The panel's own flag cannot stand in for the parent switch: it reports one entry's
|
|
48
|
+
// combined state, so a suite that is off globally must be composed in explicitly or
|
|
49
|
+
// its entries would read as globally enabled.
|
|
50
|
+
return { available: selectable, globalEnabled: selectable && globalSurfaceEnabled(candidate, kind) && !panelDisabled };
|
|
51
|
+
}
|
|
52
|
+
/** The composed global switch for one surface of one candidate suite. */
|
|
53
|
+
function globalSurfaceEnabled(candidate, kind) {
|
|
54
|
+
const { suite, validSurfaces } = candidate;
|
|
55
|
+
return suite.enabled && validSurfaces[kind] === true && suite.activeSurfaces?.[kind] === true;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A candidate is displayable while any surface or its system prompt validated; a
|
|
59
|
+
* candidate the parser rejected contributes nothing to select.
|
|
60
|
+
*/
|
|
61
|
+
function candidateAvailable(candidate) {
|
|
62
|
+
const { suite, validSurfaces } = candidate;
|
|
63
|
+
return SUITE_SURFACE_KEYS.some(key => validSurfaces[key] === true) || (suite.systemPrompt !== undefined && suite.systemPrompt !== '');
|
|
64
|
+
}
|
|
65
|
+
/** Whether the validated declaration really carries the entry the panel reported. */
|
|
66
|
+
function declaresResource(candidate, kind, name) {
|
|
67
|
+
return kind === 'skills' ? candidate.suite.skills.some(skill => skill.name === name) : (candidate.suite.resources?.[kind] ?? []).some(resource => resource.name === name);
|
|
68
|
+
}
|
|
69
|
+
export async function readExtensionInventory(ports, options = {}) {
|
|
70
|
+
// A caller outside the type system could still name candidates without the override
|
|
71
|
+
// data. Absence there would read as "enabled", so it is refused rather than guessed.
|
|
72
|
+
if (options.candidates !== undefined && (options.mcpOverrides === undefined || options.lspDisabledIds === undefined))
|
|
73
|
+
throw new Error('extension-inventory-override-data-required');
|
|
74
|
+
const [overview, mcp, lsp, skills, commands, agents] = await Promise.all([
|
|
75
|
+
ports.catalog.overview(),
|
|
76
|
+
ports.catalog.mcpStatus(),
|
|
77
|
+
ports.catalog.lspStatus(),
|
|
78
|
+
ports.panels.skills.list(true),
|
|
79
|
+
ports.panels.commands.list(true),
|
|
80
|
+
ports.panels.agents.list(true)
|
|
81
|
+
]);
|
|
82
|
+
const rows = [];
|
|
83
|
+
for (const suite of overview.suites) {
|
|
84
|
+
if (!suite.installed || suite.dimension !== 'user')
|
|
85
|
+
continue;
|
|
86
|
+
rows.push({
|
|
87
|
+
id: 'market:' + suite.sourceId + '/' + suite.suiteId,
|
|
88
|
+
face: 'market',
|
|
89
|
+
name: suite.name,
|
|
90
|
+
source: suite.sourceId,
|
|
91
|
+
description: suite.description,
|
|
92
|
+
...(suite.translatedDescription === undefined ? {} : { translatedDescription: suite.translatedDescription }),
|
|
93
|
+
...(suite.version === undefined ? {} : { version: suite.version }),
|
|
94
|
+
available: suite.enabled !== false,
|
|
95
|
+
counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
|
|
96
|
+
detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.suiteId }
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const candidates = options.candidates ?? [];
|
|
100
|
+
const candidateOwners = new Map(candidates.map(candidate => ['market:' + candidate.suite.sourceId + '/' + candidate.suite.id, candidate]));
|
|
101
|
+
const rowById = new Map(rows.map(row => [row.id, row]));
|
|
102
|
+
for (const candidate of candidates) {
|
|
103
|
+
const { suite } = candidate;
|
|
104
|
+
// Direct MCP entries have no parent, and the user hooks configuration has no
|
|
105
|
+
// card anywhere: neither publishes a market row. The hooks suite's rows stay
|
|
106
|
+
// on the Hooks face, where its grant is derived from the selected hooks
|
|
107
|
+
// themselves instead of from a parent id no preset carries.
|
|
108
|
+
if (isOwnedSentinel(suite.sourceId, suite.id))
|
|
109
|
+
continue;
|
|
110
|
+
const owner = 'market:' + suite.sourceId + '/' + suite.id;
|
|
111
|
+
const usable = candidateAvailable(candidate);
|
|
112
|
+
const globalEnabled = usable && suite.enabled && SUITE_SURFACE_KEYS.some(key => globalSurfaceEnabled(candidate, key));
|
|
113
|
+
// One suite is one row. The overview row stays the display authority — its name and
|
|
114
|
+
// description carry the panel's translation — while the validated declaration
|
|
115
|
+
// supplies availability and the switch.
|
|
116
|
+
const existing = rowById.get(owner);
|
|
117
|
+
if (existing !== undefined) {
|
|
118
|
+
existing.available = usable;
|
|
119
|
+
existing.globalEnabled = globalEnabled;
|
|
120
|
+
Object.assign(existing, localConfiguration(suite));
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// A project suite the overview never listed still needs its row.
|
|
124
|
+
const row = {
|
|
125
|
+
id: owner,
|
|
126
|
+
face: 'market',
|
|
127
|
+
name: suite.manifest.name,
|
|
128
|
+
...localConfiguration(suite),
|
|
129
|
+
source: suite.sourceId,
|
|
130
|
+
description: suite.manifest.description,
|
|
131
|
+
available: usable,
|
|
132
|
+
globalEnabled,
|
|
133
|
+
counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
|
|
134
|
+
detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.id, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
|
|
135
|
+
};
|
|
136
|
+
rows.push(row);
|
|
137
|
+
rowById.set(owner, row);
|
|
138
|
+
}
|
|
139
|
+
for (const suite of options.projectSuites ?? []) {
|
|
140
|
+
const owner = 'market:' + suite.sourceId + '/' + suite.id;
|
|
141
|
+
// Candidate validation already owns this resource; legacy discovery cannot append or override it.
|
|
142
|
+
if (rowById.has(owner))
|
|
143
|
+
continue;
|
|
144
|
+
// The user hooks configuration has no card on any face; its hook rows come
|
|
145
|
+
// from the hook loop below and its grant is derived from them.
|
|
146
|
+
if (isOwnedSentinel(suite.sourceId, suite.id))
|
|
147
|
+
continue;
|
|
148
|
+
const row = {
|
|
149
|
+
id: owner,
|
|
150
|
+
face: 'market',
|
|
151
|
+
name: suite.manifest.name,
|
|
152
|
+
...localConfiguration(suite),
|
|
153
|
+
source: suite.sourceId,
|
|
154
|
+
available: suite.enabled,
|
|
155
|
+
description: suite.manifest.description,
|
|
156
|
+
counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
|
|
157
|
+
detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.id, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
|
|
158
|
+
};
|
|
159
|
+
rows.push(row);
|
|
160
|
+
rowById.set(owner, row);
|
|
161
|
+
}
|
|
162
|
+
const projectOwners = new Set((options.projectSuites ?? []).map(suite => 'market:' + suite.sourceId + '/' + suite.id));
|
|
163
|
+
const address = (owner) => (owner !== undefined && projectOwners.has(owner) && options.sessionId !== undefined ? { sessionId: options.sessionId } : {});
|
|
164
|
+
const parents = new Map(rows.map(row => [row.id, row.available]));
|
|
165
|
+
// The user's own hook declarations are configuration rows, not suite children:
|
|
166
|
+
// one row per declared command hook, grouped by event, carrying the host's
|
|
167
|
+
// support verdict for that event. A supported event's rows select like any
|
|
168
|
+
// other resource; a partial or registered-only event's rows stay read-only
|
|
169
|
+
// with the reason, so the Hooks tab registers the declaration without
|
|
170
|
+
// pretending the host runs it.
|
|
171
|
+
for (const suite of options.hookSuites ?? options.projectSuites ?? []) {
|
|
172
|
+
if (suite.hooks === undefined)
|
|
173
|
+
continue;
|
|
174
|
+
const provenance = suite.sourceId === USER_HOOKS_SOURCE && suite.id === USER_HOOKS_SUITE ? 'user-hooks' : suite.manifest.name;
|
|
175
|
+
// The rule is the suite's, not the caller's: an installed suite publishes no
|
|
176
|
+
// per-hook switch, so every row of its declaration follows the parent
|
|
177
|
+
// grant, while project and @user-hooks declarations stay individually
|
|
178
|
+
// addressable. Both reads carry the same verdict.
|
|
179
|
+
const followsSuite = !exposesIndividualHooks(suite);
|
|
180
|
+
const supportedEvents = suite.hooks.events;
|
|
181
|
+
for (const [event, groups] of Object.entries(supportedEvents)) {
|
|
182
|
+
const support = HOOK_EVENT_HOST_SUPPORT[event] ?? 'registered-only';
|
|
183
|
+
const selectable = support === 'supported';
|
|
184
|
+
let index = 0;
|
|
185
|
+
for (const group of groups) {
|
|
186
|
+
for (const hook of group.hooks) {
|
|
187
|
+
// The position is the identity the row was published under, so it is
|
|
188
|
+
// read before the counter moves rather than inside the id expression.
|
|
189
|
+
const hookIndex = index;
|
|
190
|
+
index += 1;
|
|
191
|
+
rows.push({
|
|
192
|
+
id: hookResourceId(suite.sourceId, suite.id, event, hookIndex),
|
|
193
|
+
face: 'hooks',
|
|
194
|
+
name: hook.command,
|
|
195
|
+
source: group.matcher === undefined || group.matcher === '*' ? provenance : provenance + ' · ' + group.matcher,
|
|
196
|
+
description: event,
|
|
197
|
+
suiteResourceId: 'market:' + suite.sourceId + '/' + suite.id,
|
|
198
|
+
...(selectable
|
|
199
|
+
? { available: true, globalEnabled: true }
|
|
200
|
+
: { available: false, control: 'global-only', unavailableReason: support === 'supported-partial' ? 'hook-event-partial' : 'hook-event-unsupported' }),
|
|
201
|
+
...(followsSuite ? { followsSuite: true } : {}),
|
|
202
|
+
// The detail a row opens is the hook itself, not the suite behind it:
|
|
203
|
+
// every field the surface shows comes from this scanned declaration.
|
|
204
|
+
detail: {
|
|
205
|
+
kind: 'hook',
|
|
206
|
+
sourceId: suite.sourceId,
|
|
207
|
+
suiteId: suite.id,
|
|
208
|
+
event,
|
|
209
|
+
hookIndex,
|
|
210
|
+
command: hook.command,
|
|
211
|
+
...(group.matcher === undefined ? {} : { matcher: group.matcher }),
|
|
212
|
+
...(hook.timeout === undefined ? {} : { timeoutSec: hook.timeout }),
|
|
213
|
+
provenance,
|
|
214
|
+
support,
|
|
215
|
+
...(options.sessionId === undefined ? {} : { sessionId: options.sessionId })
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Declarations the catalog validator rejected (Notification, SessionEnd,
|
|
222
|
+
// PreCompact and anything else the host cannot run) exist only as
|
|
223
|
+
// diagnostics on the suite. Each names its event, so one read-only row per
|
|
224
|
+
// diagnostic registers the declaration in the Hooks tab instead of letting
|
|
225
|
+
// it disappear into the suite detail's error list.
|
|
226
|
+
for (const error of suite.errors) {
|
|
227
|
+
const event = /^\S+ unsupported hook event (\S+)$/.exec(error)?.[1];
|
|
228
|
+
if (event === undefined)
|
|
229
|
+
continue;
|
|
230
|
+
const support = HOOK_EVENT_HOST_SUPPORT[event] ?? 'registered-only';
|
|
231
|
+
rows.push({
|
|
232
|
+
id: 'hooks:' + suite.sourceId + '/' + suite.id + '/' + event + '/declared',
|
|
233
|
+
face: 'hooks',
|
|
234
|
+
name: event,
|
|
235
|
+
source: provenance,
|
|
236
|
+
description: event,
|
|
237
|
+
available: false,
|
|
238
|
+
control: 'global-only',
|
|
239
|
+
unavailableReason: support === 'supported-partial' ? 'hook-event-partial' : 'hook-event-unsupported',
|
|
240
|
+
...(followsSuite ? { followsSuite: true } : {}),
|
|
241
|
+
// A rejected declaration has no admitted hook, so the detail carries the
|
|
242
|
+
// event and the validator's own words instead of a command or position.
|
|
243
|
+
detail: {
|
|
244
|
+
kind: 'hook',
|
|
245
|
+
sourceId: suite.sourceId,
|
|
246
|
+
suiteId: suite.id,
|
|
247
|
+
event,
|
|
248
|
+
provenance,
|
|
249
|
+
support,
|
|
250
|
+
diagnostic: error,
|
|
251
|
+
...(options.sessionId === undefined ? {} : { sessionId: options.sessionId })
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
for (const [face, entries] of [
|
|
257
|
+
['skills', skills],
|
|
258
|
+
['commands', commands],
|
|
259
|
+
['agents', agents]
|
|
260
|
+
]) {
|
|
261
|
+
for (const entry of entries) {
|
|
262
|
+
const owner = suiteResourceOwner(entry);
|
|
263
|
+
const identity = entry.id ?? entry.name;
|
|
264
|
+
rows.push({
|
|
265
|
+
id: face + ':' + identity,
|
|
266
|
+
face,
|
|
267
|
+
name: entry.name,
|
|
268
|
+
// Both texts travel: the panel renders the translated one until the
|
|
269
|
+
// reader flips the shared view, which needs the authored text too.
|
|
270
|
+
description: entry.description,
|
|
271
|
+
...(entry.translatedDescription === undefined ? {} : { translatedDescription: entry.translatedDescription }),
|
|
272
|
+
source: entry.suiteName ?? 'user',
|
|
273
|
+
...(owner === undefined ? {} : { suiteResourceId: owner }),
|
|
274
|
+
...(face === 'skills' && entry.origin === 'user'
|
|
275
|
+
? { globalEnabled: !entry.disabled, available: entry.metadata['validationError'] === undefined }
|
|
276
|
+
: candidateOwners.has(owner ?? '')
|
|
277
|
+
? candidateEntryVerdict(candidateOwners.get(owner), face, entry.name, entry.disabled)
|
|
278
|
+
: // A native (user-origin) entry the user switched off is an ordinary disabled
|
|
279
|
+
// consumer: a preset may name it. A document that failed to parse is not
|
|
280
|
+
// selectable, whatever a preset says, and `metadata.validationError` is the
|
|
281
|
+
// panel's own evidence for that.
|
|
282
|
+
entry.origin === 'user'
|
|
283
|
+
? { available: entry.metadata['validationError'] === undefined, globalEnabled: !entry.disabled && entry.metadata['validationError'] === undefined }
|
|
284
|
+
: { available: !entry.disabled && owner !== undefined && parents.get(owner) === true }),
|
|
285
|
+
detail: { kind: 'panel', panel: face, entryId: identity, ...address(owner) }
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
for (const entry of mcp.entries) {
|
|
290
|
+
const owner = entry.suiteId === undefined || entry.suiteId === USER_MCP_SOURCE + '/' + USER_MCP_SUITE ? undefined : 'market:' + entry.suiteId;
|
|
291
|
+
const row = {
|
|
292
|
+
id: 'mcp:' + entry.id,
|
|
293
|
+
face: 'mcp',
|
|
294
|
+
name: entry.name,
|
|
295
|
+
source: entry.source ?? 'direct',
|
|
296
|
+
description: entry.transport,
|
|
297
|
+
...((entry.kind === 'direct' && entry.managed !== true) || options.mcpSessionControl === false
|
|
298
|
+
? { control: 'global-only', unavailableReason: entry.kind === 'direct' && entry.managed !== true ? 'direct-mcp-uncontrolled' : 'host-mcp-uncontrolled' }
|
|
299
|
+
: {}),
|
|
300
|
+
...(owner === undefined ? {} : { suiteResourceId: owner }),
|
|
301
|
+
available: entry.state !== 'disabled' && entry.state !== 'foreign' && entry.state !== 'orphaned' && (owner === undefined || parents.get(owner) === true),
|
|
302
|
+
detail: { kind: 'mcp', entryId: entry.id, ...address(owner) }
|
|
303
|
+
};
|
|
304
|
+
rows.push(row);
|
|
305
|
+
// Registered so a candidate corrects this row in place instead of adding another.
|
|
306
|
+
rowById.set(row.id, row);
|
|
307
|
+
}
|
|
308
|
+
for (const entry of lsp.entries) {
|
|
309
|
+
const owner = entry.kind === 'direct' ? undefined : 'market:' + entry.suiteId;
|
|
310
|
+
const row = {
|
|
311
|
+
id: 'lsp:' + entry.id,
|
|
312
|
+
face: 'lsp',
|
|
313
|
+
name: entry.serverKey,
|
|
314
|
+
source: entry.kind === 'direct' ? 'direct' : entry.suiteName,
|
|
315
|
+
description: entry.command,
|
|
316
|
+
...(owner === undefined ? {} : { suiteResourceId: owner }),
|
|
317
|
+
// Only candidate mode can say a disabled direct server is still nameable, because
|
|
318
|
+
// only then does the caller supply the disabled-id switch. Legacy mode has no such
|
|
319
|
+
// evidence, so it keeps the original rule exactly: a disabled row is unavailable.
|
|
320
|
+
available: entry.kind === 'direct'
|
|
321
|
+
? options.candidates === undefined
|
|
322
|
+
? entry.state !== 'disabled'
|
|
323
|
+
: entry.state !== 'failed' && entry.state !== 'conflict' && entry.state !== 'host-missing'
|
|
324
|
+
: entry.state !== 'disabled' && parents.get(owner) === true,
|
|
325
|
+
...(entry.kind !== 'direct'
|
|
326
|
+
? { globalEnabled: entry.state !== 'disabled' }
|
|
327
|
+
: options.candidates === undefined || options.lspDisabledIds === undefined
|
|
328
|
+
? {}
|
|
329
|
+
: { globalEnabled: !options.lspDisabledIds.has(entry.id) }),
|
|
330
|
+
detail: { kind: 'lsp', entryId: entry.id, ...address(owner) }
|
|
331
|
+
};
|
|
332
|
+
rows.push(row);
|
|
333
|
+
rowById.set(row.id, row);
|
|
334
|
+
}
|
|
335
|
+
// Rows for declarations the status layer omits, because it only reports installed
|
|
336
|
+
// and globally enabled suites. These are exactly the entries a preset still has to
|
|
337
|
+
// be able to name, and they are synthesized from the validated declaration rather
|
|
338
|
+
// than inferred from the absence of a status row.
|
|
339
|
+
for (const candidate of candidates) {
|
|
340
|
+
const { suite } = candidate;
|
|
341
|
+
const suiteKey = qualifiedSuiteId(suite.sourceId, suite.id);
|
|
342
|
+
// A user-owned sentinel's server is a direct resource: it has no suite parent to
|
|
343
|
+
// gate it, exactly as the status layer reports the same server.
|
|
344
|
+
const owner = isOwnedSentinel(suite.sourceId, suite.id) ? undefined : 'market:' + suite.sourceId + '/' + suite.id;
|
|
345
|
+
const ownerAvailable = owner === undefined || parents.get(owner) === true;
|
|
346
|
+
// Overrides are keyed by the source-qualified suite key the MCP layer itself uses,
|
|
347
|
+
// not by the resource id a preset names.
|
|
348
|
+
const overrides = options.mcpOverrides?.get(suiteKey);
|
|
349
|
+
for (const [serverKey, server] of Object.entries(suite.mcp?.servers ?? {})) {
|
|
350
|
+
const rowId = 'plugin:' + suiteKey + '/' + serverKey;
|
|
351
|
+
const override = overrides?.[serverKey];
|
|
352
|
+
const selectable = ownerAvailable && candidate.validSurfaces.mcp === true;
|
|
353
|
+
const globalEnabled = override?.enabled === false ? false : globalSurfaceEnabled(candidate, 'mcp');
|
|
354
|
+
// The status layer reports the row for an enabled suite and updates it in place;
|
|
355
|
+
// a row it omitted (a disabled suite) is synthesized from the declaration. Either
|
|
356
|
+
// way a status row that exists is corrected, never duplicated.
|
|
357
|
+
const existing = rowById.get('mcp:' + rowId);
|
|
358
|
+
if (existing !== undefined) {
|
|
359
|
+
existing.available = selectable;
|
|
360
|
+
existing.globalEnabled = globalEnabled;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const hostBackend = options.mcpSessionControl === false;
|
|
364
|
+
rows.push({
|
|
365
|
+
id: 'mcp:' + rowId,
|
|
366
|
+
face: 'mcp',
|
|
367
|
+
name: deriveServerName(suite, serverKey),
|
|
368
|
+
source: suite.manifest.name,
|
|
369
|
+
description: server.type,
|
|
370
|
+
...(hostBackend ? { control: 'global-only', unavailableReason: 'host-mcp-uncontrolled' } : {}),
|
|
371
|
+
suiteResourceId: owner,
|
|
372
|
+
available: selectable,
|
|
373
|
+
globalEnabled,
|
|
374
|
+
detail: { kind: 'mcp', entryId: rowId, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
for (const spec of Object.values(suite.lsp?.servers ?? {})) {
|
|
378
|
+
const rowId = suiteKey + '/' + spec.key;
|
|
379
|
+
if (suiteKey === DIRECT_LSP_SUITE_ID)
|
|
380
|
+
continue;
|
|
381
|
+
// A project suite's LSP declaration is never enableable, whatever the preset says.
|
|
382
|
+
const valid = candidate.validSurfaces.lsp === true;
|
|
383
|
+
const selectable = ownerAvailable && valid;
|
|
384
|
+
const globalEnabled = valid && suite.enabled && suite.activeSurfaces?.lsp === true && options.lspDisabledIds?.has(rowId) !== true;
|
|
385
|
+
const existing = rowById.get('lsp:' + rowId);
|
|
386
|
+
if (existing !== undefined) {
|
|
387
|
+
existing.available = selectable;
|
|
388
|
+
existing.globalEnabled = globalEnabled;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const row = {
|
|
392
|
+
id: 'lsp:' + rowId,
|
|
393
|
+
face: 'lsp',
|
|
394
|
+
name: spec.key,
|
|
395
|
+
source: suite.manifest.name,
|
|
396
|
+
description: spec.command,
|
|
397
|
+
suiteResourceId: owner,
|
|
398
|
+
available: selectable,
|
|
399
|
+
globalEnabled,
|
|
400
|
+
detail: { kind: 'lsp', entryId: rowId, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
|
|
401
|
+
};
|
|
402
|
+
rows.push(row);
|
|
403
|
+
rowById.set(row.id, row);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return rows;
|
|
407
|
+
}
|
|
408
|
+
export { extensionResourceEnabled } from '../../../market-runtime/src/index.js';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createPanelResources } from '../../../market-runtime/src/index.js';
|
|
2
|
+
import { buildMcpStatus } from '../../../market-mcp/src/index.js';
|
|
3
|
+
import { buildLspStatus } from '../../../market-lsp/src/index.js';
|
|
4
|
+
import { buildSuiteDetail } from './details.js';
|
|
5
|
+
import { USER_HOOKS_SOURCE, USER_HOOKS_SUITE, loadUserHooksSuite } from '../../../market-runtime/src/index.js';
|
|
6
|
+
export function createProjectExtensionResources(catalog, users, cwd) {
|
|
7
|
+
const panels = createPanelResources(catalog, users, cwd);
|
|
8
|
+
const suites = async () => (await catalog.readProjectCatalog(cwd)).suites;
|
|
9
|
+
return {
|
|
10
|
+
panels,
|
|
11
|
+
suites,
|
|
12
|
+
async suiteDetail(sourceId, suiteId) {
|
|
13
|
+
// The user-hooks synthetic suite is a configuration row, not an install:
|
|
14
|
+
// `enabledUserSuites` carries it only while it declares events, so the
|
|
15
|
+
// detail reads the always-built suite and shows its diagnostics when the
|
|
16
|
+
// configuration is empty or malformed instead of a 404.
|
|
17
|
+
if (sourceId === USER_HOOKS_SOURCE && suiteId === USER_HOOKS_SUITE) {
|
|
18
|
+
const hooks = await loadUserHooksSuite(catalog.agentsRoot);
|
|
19
|
+
// The suite declares hooks only; an explicit empty resource list keeps the
|
|
20
|
+
// detail from discovering the shared Agent layout root's commands and
|
|
21
|
+
// agents directories as if they were this configuration's surfaces.
|
|
22
|
+
return buildSuiteDetail({ ...hooks, resources: { commands: [], agents: [] } }, undefined, [], undefined);
|
|
23
|
+
}
|
|
24
|
+
const suite = (await suites()).find(row => row.sourceId === sourceId && row.id === suiteId) ??
|
|
25
|
+
(await catalog.enabledUserSuites()).find(row => row.sourceId === sourceId && row.id === suiteId && row.sourceId === '@user-hooks');
|
|
26
|
+
if (!suite)
|
|
27
|
+
throw new Error('project suite not found');
|
|
28
|
+
return buildSuiteDetail(suite, undefined, [], undefined);
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* One document of this workspace's suite, on any of the three surfaces.
|
|
32
|
+
*
|
|
33
|
+
* The lookup stays in Catalog — one reader for skills, commands and agents — and
|
|
34
|
+
* the project cwd only selects which snapshot answers. Re-scanning here would
|
|
35
|
+
* duplicate the catalog's own identity handling.
|
|
36
|
+
*/
|
|
37
|
+
async suiteDocument(sourceId, suiteId, kind, name) {
|
|
38
|
+
return catalog.suiteDocument(sourceId, suiteId, kind, name, cwd);
|
|
39
|
+
},
|
|
40
|
+
/** The same document's translation, answered from this workspace's snapshot. */
|
|
41
|
+
async suiteDocumentTranslation(sourceId, suiteId, kind, name, retry = false) {
|
|
42
|
+
return catalog.suiteDocumentTranslation(sourceId, suiteId, kind, name, retry, cwd);
|
|
43
|
+
},
|
|
44
|
+
async mcpStatus(diagnostics = [], observed = []) {
|
|
45
|
+
const declared = (await suites()).map(suite => ({ ...suite, installedAt: suite.installedAt ?? 'project' }));
|
|
46
|
+
return buildMcpStatus(declared, diagnostics, observed, await catalog.allMcpOverrides(declared));
|
|
47
|
+
},
|
|
48
|
+
async lspStatus() {
|
|
49
|
+
const declared = (await suites()).map(suite => ({ ...suite, installedAt: suite.installedAt ?? 'project' }));
|
|
50
|
+
return buildLspStatus(declared, {
|
|
51
|
+
hasLiveMounts: () => false,
|
|
52
|
+
// Same shape the mount registry records: one row per suite, keyed by suite id,
|
|
53
|
+
// with the suite's declared server keys joined as the registry joins them.
|
|
54
|
+
diagnosticsSnapshot: () => new Map(declared.flatMap(suite => {
|
|
55
|
+
const servers = suite.lsp?.servers;
|
|
56
|
+
if (servers === undefined)
|
|
57
|
+
return [];
|
|
58
|
+
const suiteId = suite.sourceId + '/' + suite.id;
|
|
59
|
+
return [[suiteId, { suiteId, serverKey: Object.keys(servers).join(','), code: 'mount-failed', reason: 'project-lsp-unsupported' }]];
|
|
60
|
+
}))
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|