@akon-labs/nexus-cli 0.1.9 → 0.1.11-rc.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/CHANGELOG.md +21 -0
- package/LICENSE +1 -0
- package/README.md +3 -2
- package/dist/app-bridge.bundle.js +67 -0
- package/dist/cli/require-login.d.ts.map +1 -1
- package/dist/cli/require-login.js +2 -2
- package/dist/cli/require-login.js.map +1 -1
- package/dist/cli.js +20866 -1882
- package/dist/core/agent-session.d.ts +3 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +5 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auto-model.d.ts +1 -1
- package/dist/core/auto-model.d.ts.map +1 -1
- package/dist/core/auto-model.js +1 -1
- package/dist/core/auto-model.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +6 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +7 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +14 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +18 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +3 -3
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +15 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +50 -0
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -3
- 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 +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +5 -5
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/websearch.d.ts.map +1 -1
- package/dist/core/tools/websearch.js +3 -3
- package/dist/core/tools/websearch.js.map +1 -1
- package/dist/extensions/gitnexus/config.d.ts +15 -1
- package/dist/extensions/gitnexus/config.d.ts.map +1 -1
- package/dist/extensions/gitnexus/config.js +86 -2
- package/dist/extensions/gitnexus/config.js.map +1 -1
- package/dist/extensions/gitnexus/gateway.d.ts +6 -6
- package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
- package/dist/extensions/gitnexus/gateway.js +4 -4
- package/dist/extensions/gitnexus/gateway.js.map +1 -1
- package/dist/extensions/gitnexus/index.d.ts.map +1 -1
- package/dist/extensions/gitnexus/index.js +6 -4
- package/dist/extensions/gitnexus/index.js.map +1 -1
- package/dist/extensions/gitnexus/observatory.d.ts.map +1 -1
- package/dist/extensions/gitnexus/observatory.js +2 -2
- package/dist/extensions/gitnexus/observatory.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +3 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/mcp/abort.d.ts +3 -0
- package/dist/extensions/mcp/abort.d.ts.map +1 -0
- package/dist/extensions/mcp/abort.js +41 -0
- package/dist/extensions/mcp/abort.js.map +1 -0
- package/dist/extensions/mcp/agent-dir.d.ts +6 -0
- package/dist/extensions/mcp/agent-dir.d.ts.map +1 -0
- package/dist/extensions/mcp/agent-dir.js +18 -0
- package/dist/extensions/mcp/agent-dir.js.map +1 -0
- package/dist/extensions/mcp/agent-plugin-loader.d.ts +9 -0
- package/dist/extensions/mcp/agent-plugin-loader.d.ts.map +1 -0
- package/dist/extensions/mcp/agent-plugin-loader.js +384 -0
- package/dist/extensions/mcp/agent-plugin-loader.js.map +1 -0
- package/dist/extensions/mcp/app-bridge.bundle.js +67 -0
- package/dist/extensions/mcp/commands.d.ts +47 -0
- package/dist/extensions/mcp/commands.d.ts.map +1 -0
- package/dist/extensions/mcp/commands.js +821 -0
- package/dist/extensions/mcp/commands.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +123 -38
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +1035 -70
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/extensions/mcp/consent-manager.d.ts +14 -0
- package/dist/extensions/mcp/consent-manager.d.ts.map +1 -0
- package/dist/extensions/mcp/consent-manager.js +60 -0
- package/dist/extensions/mcp/consent-manager.js.map +1 -0
- package/dist/extensions/mcp/direct-tools.d.ts +11 -0
- package/dist/extensions/mcp/direct-tools.d.ts.map +1 -0
- package/dist/extensions/mcp/direct-tools.js +562 -0
- package/dist/extensions/mcp/direct-tools.js.map +1 -0
- package/dist/extensions/mcp/elicitation-handler.d.ts +18 -0
- package/dist/extensions/mcp/elicitation-handler.d.ts.map +1 -0
- package/dist/extensions/mcp/elicitation-handler.js +320 -0
- package/dist/extensions/mcp/elicitation-handler.js.map +1 -0
- package/dist/extensions/mcp/error-signal.d.ts +16 -0
- package/dist/extensions/mcp/error-signal.d.ts.map +1 -0
- package/dist/extensions/mcp/error-signal.js +22 -0
- package/dist/extensions/mcp/error-signal.js.map +1 -0
- package/dist/extensions/mcp/errors.d.ts +104 -0
- package/dist/extensions/mcp/errors.d.ts.map +1 -0
- package/dist/extensions/mcp/errors.js +171 -0
- package/dist/extensions/mcp/errors.js.map +1 -0
- package/dist/extensions/mcp/glimpse-ui.d.ts +10 -0
- package/dist/extensions/mcp/glimpse-ui.d.ts.map +1 -0
- package/dist/extensions/mcp/glimpse-ui.js +67 -0
- package/dist/extensions/mcp/glimpse-ui.js.map +1 -0
- package/dist/extensions/mcp/host-html-template.d.ts +17 -0
- package/dist/extensions/mcp/host-html-template.d.ts.map +1 -0
- package/dist/extensions/mcp/host-html-template.js +442 -0
- package/dist/extensions/mcp/host-html-template.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +20 -15
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +1113 -82
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/init.d.ts +28 -0
- package/dist/extensions/mcp/init.d.ts.map +1 -0
- package/dist/extensions/mcp/init.js +631 -0
- package/dist/extensions/mcp/init.js.map +1 -0
- package/dist/extensions/mcp/json-schema-validator.d.ts +3 -0
- package/dist/extensions/mcp/json-schema-validator.d.ts.map +1 -0
- package/dist/extensions/mcp/json-schema-validator.js +53 -0
- package/dist/extensions/mcp/json-schema-validator.js.map +1 -0
- package/dist/extensions/mcp/lifecycle.d.ts +56 -0
- package/dist/extensions/mcp/lifecycle.d.ts.map +1 -0
- package/dist/extensions/mcp/lifecycle.js +395 -0
- package/dist/extensions/mcp/lifecycle.js.map +1 -0
- package/dist/extensions/mcp/logger.d.ts +52 -0
- package/dist/extensions/mcp/logger.d.ts.map +1 -0
- package/dist/extensions/mcp/logger.js +134 -0
- package/dist/extensions/mcp/logger.js.map +1 -0
- package/dist/extensions/mcp/mcp-auth-flow.d.ts +117 -0
- package/dist/extensions/mcp/mcp-auth-flow.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-auth-flow.js +869 -0
- package/dist/extensions/mcp/mcp-auth-flow.js.map +1 -0
- package/dist/extensions/mcp/mcp-auth.d.ts +162 -0
- package/dist/extensions/mcp/mcp-auth.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-auth.js +897 -0
- package/dist/extensions/mcp/mcp-auth.js.map +1 -0
- package/dist/extensions/mcp/mcp-bearer-store.d.ts +25 -0
- package/dist/extensions/mcp/mcp-bearer-store.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-bearer-store.js +350 -0
- package/dist/extensions/mcp/mcp-bearer-store.js.map +1 -0
- package/dist/extensions/mcp/mcp-callback-server.d.ts +54 -0
- package/dist/extensions/mcp/mcp-callback-server.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-callback-server.js +454 -0
- package/dist/extensions/mcp/mcp-callback-server.js.map +1 -0
- package/dist/extensions/mcp/mcp-code.d.ts +48 -0
- package/dist/extensions/mcp/mcp-code.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-code.js +358 -0
- package/dist/extensions/mcp/mcp-code.js.map +1 -0
- package/dist/extensions/mcp/mcp-keyring-helper.cjs +89 -0
- package/dist/extensions/mcp/mcp-oauth-provider.d.ts +135 -0
- package/dist/extensions/mcp/mcp-oauth-provider.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-oauth-provider.js +491 -0
- package/dist/extensions/mcp/mcp-oauth-provider.js.map +1 -0
- package/dist/extensions/mcp/mcp-output-guard.d.ts +59 -0
- package/dist/extensions/mcp/mcp-output-guard.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-output-guard.js +343 -0
- package/dist/extensions/mcp/mcp-output-guard.js.map +1 -0
- package/dist/extensions/mcp/mcp-panel.d.ts +71 -0
- package/dist/extensions/mcp/mcp-panel.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-panel.js +973 -0
- package/dist/extensions/mcp/mcp-panel.js.map +1 -0
- package/dist/extensions/mcp/mcp-probe.d.ts +7 -0
- package/dist/extensions/mcp/mcp-probe.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-probe.js +155 -0
- package/dist/extensions/mcp/mcp-probe.js.map +1 -0
- package/dist/extensions/mcp/mcp-script-worker.mjs +130 -0
- package/dist/extensions/mcp/mcp-setup-panel.d.ts +146 -0
- package/dist/extensions/mcp/mcp-setup-panel.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-setup-panel.js +1104 -0
- package/dist/extensions/mcp/mcp-setup-panel.js.map +1 -0
- package/dist/extensions/mcp/mcp-status.d.ts +12 -0
- package/dist/extensions/mcp/mcp-status.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-status.js +98 -0
- package/dist/extensions/mcp/mcp-status.js.map +1 -0
- package/dist/extensions/mcp/mcp-trace.d.ts +95 -0
- package/dist/extensions/mcp/mcp-trace.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-trace.js +252 -0
- package/dist/extensions/mcp/mcp-trace.js.map +1 -0
- package/dist/extensions/mcp/metadata-cache.d.ts +20 -0
- package/dist/extensions/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/extensions/mcp/metadata-cache.js +318 -0
- package/dist/extensions/mcp/metadata-cache.js.map +1 -0
- package/dist/extensions/mcp/npx-resolver.d.ts +7 -0
- package/dist/extensions/mcp/npx-resolver.d.ts.map +1 -0
- package/dist/extensions/mcp/npx-resolver.js +505 -0
- package/dist/extensions/mcp/npx-resolver.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +21 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +15 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/onboarding-state.d.ts +13 -0
- package/dist/extensions/mcp/onboarding-state.d.ts.map +1 -0
- package/dist/extensions/mcp/onboarding-state.js +65 -0
- package/dist/extensions/mcp/onboarding-state.js.map +1 -0
- package/dist/extensions/mcp/package-mcp-loader.d.ts +3 -0
- package/dist/extensions/mcp/package-mcp-loader.d.ts.map +1 -0
- package/dist/extensions/mcp/package-mcp-loader.js +170 -0
- package/dist/extensions/mcp/package-mcp-loader.js.map +1 -0
- package/dist/extensions/mcp/panel-keys.d.ts +21 -0
- package/dist/extensions/mcp/panel-keys.d.ts.map +1 -0
- package/dist/extensions/mcp/panel-keys.js +29 -0
- package/dist/extensions/mcp/panel-keys.js.map +1 -0
- package/dist/extensions/mcp/prompts.d.ts +63 -0
- package/dist/extensions/mcp/prompts.d.ts.map +1 -0
- package/dist/extensions/mcp/prompts.js +297 -0
- package/dist/extensions/mcp/prompts.js.map +1 -0
- package/dist/extensions/mcp/proxy-modes.d.ts +15 -0
- package/dist/extensions/mcp/proxy-modes.d.ts.map +1 -0
- package/dist/extensions/mcp/proxy-modes.js +1421 -0
- package/dist/extensions/mcp/proxy-modes.js.map +1 -0
- package/dist/extensions/mcp/request-headers-command.d.ts +11 -0
- package/dist/extensions/mcp/request-headers-command.d.ts.map +1 -0
- package/dist/extensions/mcp/request-headers-command.js +334 -0
- package/dist/extensions/mcp/request-headers-command.js.map +1 -0
- package/dist/extensions/mcp/resource-tools.d.ts +2 -0
- package/dist/extensions/mcp/resource-tools.d.ts.map +1 -0
- package/dist/extensions/mcp/resource-tools.js +15 -0
- package/dist/extensions/mcp/resource-tools.js.map +1 -0
- package/dist/extensions/mcp/runtime-owner.d.ts +14 -0
- package/dist/extensions/mcp/runtime-owner.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime-owner.js +84 -0
- package/dist/extensions/mcp/runtime-owner.js.map +1 -0
- package/dist/extensions/mcp/sampling-handler.d.ts +18 -0
- package/dist/extensions/mcp/sampling-handler.d.ts.map +1 -0
- package/dist/extensions/mcp/sampling-handler.js +229 -0
- package/dist/extensions/mcp/sampling-handler.js.map +1 -0
- package/dist/extensions/mcp/search-ranking.d.ts +25 -0
- package/dist/extensions/mcp/search-ranking.d.ts.map +1 -0
- package/dist/extensions/mcp/search-ranking.js +234 -0
- package/dist/extensions/mcp/search-ranking.js.map +1 -0
- package/dist/extensions/mcp/server-manager.d.ts +116 -0
- package/dist/extensions/mcp/server-manager.d.ts.map +1 -0
- package/dist/extensions/mcp/server-manager.js +1052 -0
- package/dist/extensions/mcp/server-manager.js.map +1 -0
- package/dist/extensions/mcp/session-recovery.d.ts +27 -0
- package/dist/extensions/mcp/session-recovery.d.ts.map +1 -0
- package/dist/extensions/mcp/session-recovery.js +140 -0
- package/dist/extensions/mcp/session-recovery.js.map +1 -0
- package/dist/extensions/mcp/skills/mcp-scripting/SKILL.md +38 -0
- package/dist/extensions/mcp/state.d.ts +62 -0
- package/dist/extensions/mcp/state.d.ts.map +1 -0
- package/dist/extensions/mcp/state.js +2 -0
- package/dist/extensions/mcp/state.js.map +1 -0
- package/dist/extensions/mcp/tool-approval.d.ts +11 -0
- package/dist/extensions/mcp/tool-approval.d.ts.map +1 -0
- package/dist/extensions/mcp/tool-approval.js +156 -0
- package/dist/extensions/mcp/tool-approval.js.map +1 -0
- package/dist/extensions/mcp/tool-metadata.d.ts +11 -0
- package/dist/extensions/mcp/tool-metadata.d.ts.map +1 -0
- package/dist/extensions/mcp/tool-metadata.js +264 -0
- package/dist/extensions/mcp/tool-metadata.js.map +1 -0
- package/dist/extensions/mcp/tool-registrar.d.ts +21 -0
- package/dist/extensions/mcp/tool-registrar.d.ts.map +1 -0
- package/dist/extensions/mcp/tool-registrar.js +229 -0
- package/dist/extensions/mcp/tool-registrar.js.map +1 -0
- package/dist/extensions/mcp/tool-result-renderer.d.ts +83 -0
- package/dist/extensions/mcp/tool-result-renderer.d.ts.map +1 -0
- package/dist/extensions/mcp/tool-result-renderer.js +345 -0
- package/dist/extensions/mcp/tool-result-renderer.js.map +1 -0
- package/dist/extensions/mcp/ts-shape.d.ts +3 -0
- package/dist/extensions/mcp/ts-shape.d.ts.map +1 -0
- package/dist/extensions/mcp/ts-shape.js +160 -0
- package/dist/extensions/mcp/ts-shape.js.map +1 -0
- package/dist/extensions/mcp/types.d.ts +521 -0
- package/dist/extensions/mcp/types.d.ts.map +1 -0
- package/dist/extensions/mcp/types.js +294 -0
- package/dist/extensions/mcp/types.js.map +1 -0
- package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts +7 -0
- package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-app-bridge-helpers.js +37 -0
- package/dist/extensions/mcp/ui-app-bridge-helpers.js.map +1 -0
- package/dist/extensions/mcp/ui-resource-handler.d.ts +18 -0
- package/dist/extensions/mcp/ui-resource-handler.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-resource-handler.js +210 -0
- package/dist/extensions/mcp/ui-resource-handler.js.map +1 -0
- package/dist/extensions/mcp/ui-server.d.ts +52 -0
- package/dist/extensions/mcp/ui-server.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-server.js +740 -0
- package/dist/extensions/mcp/ui-server.js.map +1 -0
- package/dist/extensions/mcp/ui-session.d.ts +40 -0
- package/dist/extensions/mcp/ui-session.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-session.js +477 -0
- package/dist/extensions/mcp/ui-session.js.map +1 -0
- package/dist/extensions/mcp/ui-stream-types.d.ts +105 -0
- package/dist/extensions/mcp/ui-stream-types.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-stream-types.js +61 -0
- package/dist/extensions/mcp/ui-stream-types.js.map +1 -0
- package/dist/extensions/mcp/ui-tool-visibility.d.ts +5 -0
- package/dist/extensions/mcp/ui-tool-visibility.d.ts.map +1 -0
- package/dist/extensions/mcp/ui-tool-visibility.js +27 -0
- package/dist/extensions/mcp/ui-tool-visibility.js.map +1 -0
- package/dist/extensions/mcp/unix-socket-transport.d.ts +15 -0
- package/dist/extensions/mcp/unix-socket-transport.d.ts.map +1 -0
- package/dist/extensions/mcp/unix-socket-transport.js +85 -0
- package/dist/extensions/mcp/unix-socket-transport.js.map +1 -0
- package/dist/extensions/mcp/utils.d.ts +32 -0
- package/dist/extensions/mcp/utils.d.ts.map +1 -0
- package/dist/extensions/mcp/utils.js +336 -0
- package/dist/extensions/mcp/utils.js.map +1 -0
- package/dist/extensions/subagent/index.d.ts +62 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +195 -9
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent-render.d.ts +3 -0
- package/dist/extensions/subagent-render.d.ts.map +1 -0
- package/dist/extensions/subagent-render.js +39 -0
- package/dist/extensions/subagent-render.js.map +1 -0
- package/dist/extensions/web-access.d.ts.map +1 -1
- package/dist/extensions/web-access.js +1 -1
- package/dist/extensions/web-access.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20992 -2003
- package/dist/index.js.map +1 -1
- package/dist/mcp-keyring-helper.cjs +89 -0
- package/dist/mcp-script-worker.mjs +130 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/response-separator.d.ts +1 -1
- package/dist/modes/interactive/components/response-separator.d.ts.map +1 -1
- package/dist/modes/interactive/components/response-separator.js +1 -1
- package/dist/modes/interactive/components/response-separator.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +3 -2
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +12 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +14 -8
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/rpc-entry.js +20866 -1882
- package/dist/skills/mcp-scripting/SKILL.md +38 -0
- package/dist/utils/hidden-spawn.d.ts +29 -0
- package/dist/utils/hidden-spawn.d.ts.map +1 -0
- package/dist/utils/hidden-spawn.js +101 -0
- package/dist/utils/hidden-spawn.js.map +1 -0
- package/dist/vendor/ai.js +110 -35
- package/docs/mcp.md +178 -0
- package/docs/pi-subagents.md +75 -0
- package/docs/quickstart.md +1 -1
- package/docs/usage.md +2 -1
- package/examples/extensions/pi-subagents-worker-policy.ts +86 -0
- package/native/win32/build.mjs +95 -0
- package/native/win32/prebuilds/win32-x64/hidden-spawn.exe +0 -0
- package/native/win32/src/hidden-spawn.c +157 -0
- package/npm-shrinkwrap.json +728 -6
- package/package.json +21 -6
- package/dist/extensions/mcp/client.d.ts +0 -86
- package/dist/extensions/mcp/client.d.ts.map +0 -1
- package/dist/extensions/mcp/client.js +0 -275
- package/dist/extensions/mcp/client.js.map +0 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import net from "node:net";
|
|
4
|
+
import { UrlElicitationRequiredError } from "@modelcontextprotocol/client";
|
|
5
|
+
import { throwIfAborted } from "./abort.js";
|
|
6
|
+
import { isGlimpseAvailable, openGlimpseWindow } from "./glimpse-ui.js";
|
|
7
|
+
import { logger } from "./logger.js";
|
|
8
|
+
import { combineAbortSignals, isAbortError } from "./runtime-owner.js";
|
|
9
|
+
import { createUiModelContextUpdate, extractUiPromptText, UI_STREAM_HOST_CONTEXT_KEY, UI_STREAM_REQUEST_META_KEY, UI_STREAM_STRUCTURED_CONTENT_KEY, } from "./types.js";
|
|
10
|
+
import { startUiServer } from "./ui-server.js";
|
|
11
|
+
let activeGlimpseWindow = null;
|
|
12
|
+
export function summarizeUiSessionResult(uiSession) {
|
|
13
|
+
if (!uiSession) {
|
|
14
|
+
return {
|
|
15
|
+
message: "Interactive UI was unavailable; returning the tool result inline.",
|
|
16
|
+
uiOpen: false,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (!uiSession.windowOpen) {
|
|
20
|
+
const action = uiSession.reused ? "Updated the suppressed MCP UI session." : "MCP UI window was suppressed.";
|
|
21
|
+
return {
|
|
22
|
+
message: `${action} Open manually: ${uiSession.url}`,
|
|
23
|
+
uiOpen: false,
|
|
24
|
+
uiViewer: uiSession.viewer,
|
|
25
|
+
uiUrl: uiSession.url,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
message: uiSession.reused
|
|
30
|
+
? "Updated the open UI."
|
|
31
|
+
: "Interactive UI is open. I'll respond to your prompts and intents as you interact with it.",
|
|
32
|
+
uiOpen: true,
|
|
33
|
+
uiViewer: uiSession.viewer,
|
|
34
|
+
uiUrl: uiSession.url,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const MAX_COMPLETED_SESSIONS = 10;
|
|
38
|
+
function withStreamEnvelope(result, streamId, sequence) {
|
|
39
|
+
if (!streamId) {
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
const structuredContent = result.structuredContent &&
|
|
43
|
+
typeof result.structuredContent === "object" &&
|
|
44
|
+
!Array.isArray(result.structuredContent)
|
|
45
|
+
? { ...result.structuredContent }
|
|
46
|
+
: {};
|
|
47
|
+
const rawEnvelope = structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY];
|
|
48
|
+
const envelope = rawEnvelope && typeof rawEnvelope === "object" && !Array.isArray(rawEnvelope)
|
|
49
|
+
? { ...rawEnvelope }
|
|
50
|
+
: {
|
|
51
|
+
frameType: "final",
|
|
52
|
+
phase: "settled",
|
|
53
|
+
status: result.isError ? "error" : "ok",
|
|
54
|
+
};
|
|
55
|
+
structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY] = {
|
|
56
|
+
...envelope,
|
|
57
|
+
streamId,
|
|
58
|
+
sequence,
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
...result,
|
|
62
|
+
structuredContent,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async function openInBrowser(state, url, signal) {
|
|
66
|
+
throwIfAborted(signal);
|
|
67
|
+
try {
|
|
68
|
+
await state.openBrowser(url);
|
|
69
|
+
throwIfAborted(signal);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (isAbortError(error, signal))
|
|
74
|
+
throw error;
|
|
75
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
76
|
+
if (state.owner?.isActive() === false)
|
|
77
|
+
return null;
|
|
78
|
+
state.ui?.notify(`MCP UI browser open failed: ${message}`, "warning");
|
|
79
|
+
return message;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function isRemoteSession() {
|
|
83
|
+
return Boolean(process.env.SSH_CONNECTION || process.env.SSH_TTY);
|
|
84
|
+
}
|
|
85
|
+
function hasActiveRemoteLogin() {
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
execFile("who", { encoding: "utf8", timeout: 2000 }, (error, out) => {
|
|
88
|
+
if (error) {
|
|
89
|
+
resolve(false);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
resolve(/\(.+\)\s*$/m.test(out));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function probeMoshiGateway() {
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
const socket = net.connect({ host: "127.0.0.1", port: 24543 });
|
|
99
|
+
const done = (ok) => {
|
|
100
|
+
socket.destroy();
|
|
101
|
+
resolve(ok);
|
|
102
|
+
};
|
|
103
|
+
socket.setTimeout(300);
|
|
104
|
+
socket.once("connect", () => done(true));
|
|
105
|
+
socket.once("timeout", () => done(false));
|
|
106
|
+
socket.once("error", () => done(false));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function remoteAccessHint(opts) {
|
|
110
|
+
const lines = [
|
|
111
|
+
opts.openError !== null
|
|
112
|
+
? "Couldn't open MCP UI here. Open it from your own device:"
|
|
113
|
+
: opts.openedOnHost
|
|
114
|
+
? "MCP UI opened on this host. If you're controlling this session remotely, open it from your own device:"
|
|
115
|
+
: "This looks like a remote session - if no MCP UI appeared, open it from your own device:",
|
|
116
|
+
` ${opts.url}`,
|
|
117
|
+
];
|
|
118
|
+
if (opts.openError !== null) {
|
|
119
|
+
lines.push(`Browser launch failed: ${opts.openError}`);
|
|
120
|
+
}
|
|
121
|
+
if (opts.moshi) {
|
|
122
|
+
lines.push("Moshi: tap the preview button in the terminal title bar and pick this MCP UI server.");
|
|
123
|
+
}
|
|
124
|
+
lines.push(`SSH: run \`ssh -L ${opts.port}:127.0.0.1:${opts.port} <this-host>\` on your local machine, then open the URL above.`, "mosh can't forward ports - run that ssh command in a separate terminal.");
|
|
125
|
+
return lines.join("\n");
|
|
126
|
+
}
|
|
127
|
+
export async function maybeStartUiSession(state, request) {
|
|
128
|
+
const log = logger.child({
|
|
129
|
+
component: "UiSession",
|
|
130
|
+
server: request.serverName,
|
|
131
|
+
tool: request.toolName,
|
|
132
|
+
});
|
|
133
|
+
const runtimeSignal = combineAbortSignals(state.owner?.signal, request.signal) ?? new AbortController().signal;
|
|
134
|
+
try {
|
|
135
|
+
throwIfAborted(runtimeSignal);
|
|
136
|
+
if (state.uiServer &&
|
|
137
|
+
state.uiServer.serverName === request.serverName &&
|
|
138
|
+
state.uiServer.toolName === request.toolName) {
|
|
139
|
+
const existingHandle = state.uiServer;
|
|
140
|
+
const streamMode = request.streamMode;
|
|
141
|
+
const streamId = streamMode ? randomUUID() : undefined;
|
|
142
|
+
const streamToken = streamMode ? randomUUID() : undefined;
|
|
143
|
+
let active = true;
|
|
144
|
+
let nextStreamSequence = 0;
|
|
145
|
+
const cleanupStreamListener = () => {
|
|
146
|
+
if (streamToken) {
|
|
147
|
+
state.manager.removeUiStreamListener(streamToken);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
existingHandle.sendToolInput(request.toolArgs);
|
|
151
|
+
if (streamToken) {
|
|
152
|
+
state.manager.registerUiStreamListener(streamToken, (serverName, notification) => {
|
|
153
|
+
if (!active || state.uiServer !== existingHandle)
|
|
154
|
+
return;
|
|
155
|
+
if (serverName !== request.serverName)
|
|
156
|
+
return;
|
|
157
|
+
nextStreamSequence += 1;
|
|
158
|
+
existingHandle.sendResultPatch(withStreamEnvelope(notification.result, streamId, nextStreamSequence));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
serverName: request.serverName,
|
|
163
|
+
toolName: request.toolName,
|
|
164
|
+
reused: true,
|
|
165
|
+
...(streamId !== undefined ? { streamId } : {}),
|
|
166
|
+
...(streamToken !== undefined ? { streamToken } : {}),
|
|
167
|
+
...(streamMode !== undefined ? { streamMode } : {}),
|
|
168
|
+
...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),
|
|
169
|
+
url: existingHandle.url,
|
|
170
|
+
viewer: existingHandle.viewer ?? "browser",
|
|
171
|
+
windowOpen: existingHandle.windowOpen ?? true,
|
|
172
|
+
isActive: () => active && state.uiServer === existingHandle,
|
|
173
|
+
sendToolResult: (result) => {
|
|
174
|
+
if (!active || state.uiServer !== existingHandle)
|
|
175
|
+
return;
|
|
176
|
+
nextStreamSequence += 1;
|
|
177
|
+
existingHandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));
|
|
178
|
+
},
|
|
179
|
+
sendResultPatch: (result) => {
|
|
180
|
+
if (!active || state.uiServer !== existingHandle)
|
|
181
|
+
return;
|
|
182
|
+
nextStreamSequence += 1;
|
|
183
|
+
existingHandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));
|
|
184
|
+
},
|
|
185
|
+
sendToolCancelled: (reason) => {
|
|
186
|
+
if (!active || state.uiServer !== existingHandle)
|
|
187
|
+
return;
|
|
188
|
+
nextStreamSequence += 1;
|
|
189
|
+
existingHandle.sendToolResult(withStreamEnvelope({
|
|
190
|
+
isError: true,
|
|
191
|
+
content: [{ type: "text", text: reason }],
|
|
192
|
+
}, streamId, nextStreamSequence));
|
|
193
|
+
},
|
|
194
|
+
close: () => {
|
|
195
|
+
active = false;
|
|
196
|
+
cleanupStreamListener();
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const resource = await state.uiResourceHandler.readUiResource(request.serverName, request.uiResourceUri, {
|
|
201
|
+
config: state.config,
|
|
202
|
+
signal: runtimeSignal,
|
|
203
|
+
onNeedsAuth: request.onNeedsAuth,
|
|
204
|
+
});
|
|
205
|
+
throwIfAborted(runtimeSignal);
|
|
206
|
+
if (state.uiServer) {
|
|
207
|
+
state.uiServer.close("replaced");
|
|
208
|
+
state.uiServer = null;
|
|
209
|
+
}
|
|
210
|
+
if (activeGlimpseWindow) {
|
|
211
|
+
activeGlimpseWindow.close();
|
|
212
|
+
activeGlimpseWindow = null;
|
|
213
|
+
}
|
|
214
|
+
const streamMode = request.streamMode;
|
|
215
|
+
const streamId = streamMode ? randomUUID() : undefined;
|
|
216
|
+
const streamToken = streamMode ? randomUUID() : undefined;
|
|
217
|
+
const hostContext = streamMode && streamId
|
|
218
|
+
? {
|
|
219
|
+
[UI_STREAM_HOST_CONTEXT_KEY]: {
|
|
220
|
+
mode: streamMode,
|
|
221
|
+
streamId,
|
|
222
|
+
intermediateResultPatches: streamMode === "stream-first",
|
|
223
|
+
partialInput: false,
|
|
224
|
+
},
|
|
225
|
+
}
|
|
226
|
+
: undefined;
|
|
227
|
+
let active = true;
|
|
228
|
+
let nextStreamSequence = 0;
|
|
229
|
+
let handle;
|
|
230
|
+
const cleanupStreamListener = () => {
|
|
231
|
+
if (streamToken) {
|
|
232
|
+
state.manager.removeUiStreamListener(streamToken);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
handle = await startUiServer({
|
|
236
|
+
serverName: request.serverName,
|
|
237
|
+
toolName: request.toolName,
|
|
238
|
+
toolArgs: streamMode === "stream-first" ? {} : request.toolArgs,
|
|
239
|
+
resource,
|
|
240
|
+
manager: state.manager,
|
|
241
|
+
config: state.config,
|
|
242
|
+
state,
|
|
243
|
+
...(request.onNeedsAuth ? { onNeedsAuth: request.onNeedsAuth } : {}),
|
|
244
|
+
consentManager: state.consentManager,
|
|
245
|
+
...(hostContext !== undefined ? { hostContext } : {}),
|
|
246
|
+
onMessage: (params) => {
|
|
247
|
+
const prompt = extractUiPromptText(params);
|
|
248
|
+
if (prompt) {
|
|
249
|
+
if (state.sendMessage) {
|
|
250
|
+
state.sendMessage({
|
|
251
|
+
customType: "mcp-ui-prompt",
|
|
252
|
+
content: [
|
|
253
|
+
{ type: "text", text: `User sent prompt from ${request.serverName} UI: "${prompt}"` },
|
|
254
|
+
],
|
|
255
|
+
display: `💬 UI Prompt: ${prompt}`,
|
|
256
|
+
details: { server: request.serverName, tool: request.toolName, prompt },
|
|
257
|
+
}, { triggerTurn: true });
|
|
258
|
+
log.debug("Triggered agent turn for UI prompt", { prompt: prompt.slice(0, 50) });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (params.type === "intent" || params.intent) {
|
|
262
|
+
const intent = params.intent ?? "";
|
|
263
|
+
const intentParams = params.params;
|
|
264
|
+
if (intent && state.sendMessage) {
|
|
265
|
+
const paramsStr = intentParams ? ` ${JSON.stringify(intentParams)}` : "";
|
|
266
|
+
state.sendMessage({
|
|
267
|
+
customType: "mcp-ui-intent",
|
|
268
|
+
content: [
|
|
269
|
+
{
|
|
270
|
+
type: "text",
|
|
271
|
+
text: `User triggered intent from ${request.serverName} UI: ${intent}${paramsStr}`,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
display: `🎯 UI Intent: ${intent}`,
|
|
275
|
+
details: { server: request.serverName, tool: request.toolName, intent, params: intentParams },
|
|
276
|
+
}, { triggerTurn: true });
|
|
277
|
+
log.debug("Triggered agent turn for UI intent", { intent });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (params.type === "notify" || params.message) {
|
|
281
|
+
const text = params.message ?? "";
|
|
282
|
+
if (text && state.ui) {
|
|
283
|
+
state.ui.notify(`[${request.serverName}] ${text}`, "info");
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
onContextUpdate: (params) => {
|
|
288
|
+
const update = createUiModelContextUpdate(params);
|
|
289
|
+
log.debug("Model context update from UI", {
|
|
290
|
+
hasContent: !!params.content,
|
|
291
|
+
hasStructured: !!params.structuredContent,
|
|
292
|
+
hasUpdate: !!update,
|
|
293
|
+
});
|
|
294
|
+
if (update && state.sendMessage) {
|
|
295
|
+
state.sendMessage({
|
|
296
|
+
customType: "mcp-ui-context",
|
|
297
|
+
content: [
|
|
298
|
+
{
|
|
299
|
+
type: "text",
|
|
300
|
+
text: `User submitted model context from ${request.serverName} UI:\n${update.summary}`,
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
display: "UI Context submitted",
|
|
304
|
+
details: { server: request.serverName, tool: request.toolName, context: update },
|
|
305
|
+
}, { triggerTurn: true });
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
onComplete: (reason) => {
|
|
309
|
+
active = false;
|
|
310
|
+
cleanupStreamListener();
|
|
311
|
+
if (state.uiServer === handle) {
|
|
312
|
+
const messages = handle.getSessionMessages();
|
|
313
|
+
const stream = handle.getStreamSummary();
|
|
314
|
+
const hasContent = messages.prompts.length > 0 ||
|
|
315
|
+
messages.intents.length > 0 ||
|
|
316
|
+
messages.notifications.length > 0 ||
|
|
317
|
+
messages.contexts.length > 0 ||
|
|
318
|
+
!!stream;
|
|
319
|
+
if (hasContent) {
|
|
320
|
+
state.completedUiSessions.push({
|
|
321
|
+
serverName: handle.serverName,
|
|
322
|
+
toolName: handle.toolName,
|
|
323
|
+
completedAt: new Date(),
|
|
324
|
+
reason,
|
|
325
|
+
messages,
|
|
326
|
+
...(stream !== undefined ? { stream } : {}),
|
|
327
|
+
});
|
|
328
|
+
while (state.completedUiSessions.length > MAX_COMPLETED_SESSIONS) {
|
|
329
|
+
state.completedUiSessions.shift();
|
|
330
|
+
}
|
|
331
|
+
log.debug("Session completed", {
|
|
332
|
+
reason,
|
|
333
|
+
prompts: messages.prompts.length,
|
|
334
|
+
intents: messages.intents.length,
|
|
335
|
+
notifications: messages.notifications.length,
|
|
336
|
+
contexts: messages.contexts.length,
|
|
337
|
+
streamFrames: stream?.frames ?? 0,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
state.uiServer = null;
|
|
341
|
+
if (activeGlimpseWindow) {
|
|
342
|
+
activeGlimpseWindow.close();
|
|
343
|
+
activeGlimpseWindow = null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
if (state.owner?.isActive() === false || runtimeSignal.aborted) {
|
|
349
|
+
handle.close("runtime_owner_stopped");
|
|
350
|
+
throwIfAborted(runtimeSignal);
|
|
351
|
+
throw new Error("MCP UI session became stale before registration");
|
|
352
|
+
}
|
|
353
|
+
if (streamToken) {
|
|
354
|
+
state.manager.registerUiStreamListener(streamToken, (serverName, notification) => {
|
|
355
|
+
if (!active || state.uiServer !== handle)
|
|
356
|
+
return;
|
|
357
|
+
if (serverName !== request.serverName)
|
|
358
|
+
return;
|
|
359
|
+
nextStreamSequence += 1;
|
|
360
|
+
handle.sendResultPatch(withStreamEnvelope(notification.result, streamId, nextStreamSequence));
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
state.uiServer = handle;
|
|
364
|
+
const viewerPref = process.env.MCP_UI_VIEWER?.toLowerCase();
|
|
365
|
+
const uiSuppressed = viewerPref === "none" || viewerPref === "off" || viewerPref === "disabled";
|
|
366
|
+
let viewer = "browser";
|
|
367
|
+
let windowOpen = true;
|
|
368
|
+
const remoteByEnv = isRemoteSession();
|
|
369
|
+
if (uiSuppressed) {
|
|
370
|
+
viewer = "suppressed";
|
|
371
|
+
windowOpen = false;
|
|
372
|
+
state.ui?.notify(`MCP UI window suppressed (MCP_UI_VIEWER=${viewerPref}). Open manually: ${handle.url}`, "info");
|
|
373
|
+
log.info(`Suppressing MCP UI window (MCP_UI_VIEWER=${viewerPref})`, { url: handle.url });
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
const remoteLikely = remoteByEnv || (await hasActiveRemoteLogin());
|
|
377
|
+
const emitRemoteHint = async (openError, openedOnHost = false) => {
|
|
378
|
+
state.ui?.notify(remoteAccessHint({
|
|
379
|
+
url: handle.url,
|
|
380
|
+
port: handle.port,
|
|
381
|
+
moshi: await probeMoshiGateway(),
|
|
382
|
+
openError,
|
|
383
|
+
openedOnHost,
|
|
384
|
+
}), openError === null ? "info" : "warning");
|
|
385
|
+
};
|
|
386
|
+
const glimpseDetected = !remoteByEnv && isGlimpseAvailable();
|
|
387
|
+
const useGlimpse = !remoteByEnv && (viewerPref === "glimpse" || (viewerPref !== "browser" && glimpseDetected));
|
|
388
|
+
if (useGlimpse) {
|
|
389
|
+
try {
|
|
390
|
+
const glimpseHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src="${handle.url}"></iframe></body></html>`;
|
|
391
|
+
const glimpseWindow = await openGlimpseWindow(glimpseHtml, {
|
|
392
|
+
title: `MCP · ${request.serverName} · ${request.toolName}`,
|
|
393
|
+
width: 1000,
|
|
394
|
+
height: 800,
|
|
395
|
+
onClosed: () => {
|
|
396
|
+
if (active)
|
|
397
|
+
handle.close("glimpse-closed");
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
if (state.owner?.isActive() === false || runtimeSignal.aborted) {
|
|
401
|
+
glimpseWindow.close();
|
|
402
|
+
throwIfAborted(runtimeSignal);
|
|
403
|
+
throw new Error("MCP Glimpse window became stale before registration");
|
|
404
|
+
}
|
|
405
|
+
activeGlimpseWindow = glimpseWindow;
|
|
406
|
+
viewer = "glimpse";
|
|
407
|
+
if (remoteLikely) {
|
|
408
|
+
await emitRemoteHint(null, true);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
log.debug("Glimpse unavailable, using browser", {
|
|
413
|
+
error: error instanceof Error ? error.message : String(error),
|
|
414
|
+
});
|
|
415
|
+
const openError = await openInBrowser(state, handle.url, runtimeSignal);
|
|
416
|
+
if (openError !== null || remoteLikely) {
|
|
417
|
+
await emitRemoteHint(openError);
|
|
418
|
+
}
|
|
419
|
+
viewer = "browser";
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
const openError = await openInBrowser(state, handle.url, runtimeSignal);
|
|
424
|
+
if (openError !== null || remoteLikely) {
|
|
425
|
+
await emitRemoteHint(openError);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
throwIfAborted(runtimeSignal);
|
|
430
|
+
handle.viewer = viewer;
|
|
431
|
+
handle.windowOpen = windowOpen;
|
|
432
|
+
return {
|
|
433
|
+
serverName: request.serverName,
|
|
434
|
+
toolName: request.toolName,
|
|
435
|
+
reused: false,
|
|
436
|
+
...(streamId !== undefined ? { streamId } : {}),
|
|
437
|
+
...(streamToken !== undefined ? { streamToken } : {}),
|
|
438
|
+
...(streamMode !== undefined ? { streamMode } : {}),
|
|
439
|
+
...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),
|
|
440
|
+
url: handle.url,
|
|
441
|
+
viewer,
|
|
442
|
+
windowOpen,
|
|
443
|
+
isActive: () => active && state.uiServer === handle,
|
|
444
|
+
sendToolResult: (result) => {
|
|
445
|
+
if (!active || state.uiServer !== handle)
|
|
446
|
+
return;
|
|
447
|
+
nextStreamSequence += 1;
|
|
448
|
+
handle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));
|
|
449
|
+
},
|
|
450
|
+
sendResultPatch: (result) => {
|
|
451
|
+
if (!active || state.uiServer !== handle)
|
|
452
|
+
return;
|
|
453
|
+
nextStreamSequence += 1;
|
|
454
|
+
handle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));
|
|
455
|
+
},
|
|
456
|
+
sendToolCancelled: (reason) => {
|
|
457
|
+
if (!active || state.uiServer !== handle)
|
|
458
|
+
return;
|
|
459
|
+
handle.sendToolCancelled(reason);
|
|
460
|
+
},
|
|
461
|
+
close: (reason) => {
|
|
462
|
+
active = false;
|
|
463
|
+
cleanupStreamListener();
|
|
464
|
+
handle.close(reason);
|
|
465
|
+
},
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
if (error instanceof UrlElicitationRequiredError || isAbortError(error, runtimeSignal))
|
|
470
|
+
throw error;
|
|
471
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
472
|
+
log.error("Failed to start UI session", error instanceof Error ? error : undefined);
|
|
473
|
+
state.ui?.notify(`MCP UI unavailable for ${request.toolName} (${request.serverName}): ${message}`, "warning");
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
//# sourceMappingURL=ui-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-session.js","sourceRoot":"","sources":["../../../src/extensions/mcp/ui-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport net from \"node:net\";\nimport { type CallToolResult, UrlElicitationRequiredError } from \"@modelcontextprotocol/client\";\nimport { throwIfAborted } from \"./abort.ts\";\nimport { isGlimpseAvailable, openGlimpseWindow } from \"./glimpse-ui.ts\";\nimport { logger } from \"./logger.ts\";\nimport { combineAbortSignals, isAbortError } from \"./runtime-owner.ts\";\nimport type { SessionRecoveryDeps } from \"./session-recovery.ts\";\nimport type { McpExtensionState } from \"./state.ts\";\nimport {\n\tcreateUiModelContextUpdate,\n\textractUiPromptText,\n\tUI_STREAM_HOST_CONTEXT_KEY,\n\tUI_STREAM_REQUEST_META_KEY,\n\tUI_STREAM_STRUCTURED_CONTENT_KEY,\n\ttype UiHostContext,\n\ttype UiMessageParams,\n\ttype UiModelContextParams,\n\ttype UiStreamMode,\n} from \"./types.ts\";\nimport { startUiServer, type UiServerHandle } from \"./ui-server.ts\";\n\nlet activeGlimpseWindow: { close(): void } | null = null;\n\nexport interface UiSessionRequest {\n\tserverName: string;\n\ttoolName: string;\n\ttoolArgs: Record<string, unknown>;\n\tuiResourceUri: string;\n\tstreamMode?: UiStreamMode;\n\tsignal?: AbortSignal;\n\tonNeedsAuth?: SessionRecoveryDeps[\"onNeedsAuth\"];\n}\n\nexport type UiSessionViewer = \"browser\" | \"glimpse\" | \"suppressed\";\n\nexport interface UiSessionRuntime {\n\tserverName: string;\n\ttoolName: string;\n\treused: boolean;\n\tstreamId?: string;\n\tstreamToken?: string;\n\tstreamMode?: UiStreamMode;\n\trequestMeta?: Record<string, unknown>;\n\turl: string;\n\tviewer: UiSessionViewer;\n\twindowOpen: boolean;\n\tisActive: () => boolean;\n\tsendToolResult: (result: CallToolResult) => void;\n\tsendResultPatch: (result: CallToolResult) => void;\n\tsendToolCancelled: (reason: string) => void;\n\tclose: (reason?: string) => void;\n}\n\nexport interface UiSessionResultSummary {\n\tmessage: string;\n\tuiOpen: boolean;\n\tuiViewer?: UiSessionViewer;\n\tuiUrl?: string;\n}\n\nexport function summarizeUiSessionResult(uiSession: UiSessionRuntime | null): UiSessionResultSummary {\n\tif (!uiSession) {\n\t\treturn {\n\t\t\tmessage: \"Interactive UI was unavailable; returning the tool result inline.\",\n\t\t\tuiOpen: false,\n\t\t};\n\t}\n\n\tif (!uiSession.windowOpen) {\n\t\tconst action = uiSession.reused ? \"Updated the suppressed MCP UI session.\" : \"MCP UI window was suppressed.\";\n\t\treturn {\n\t\t\tmessage: `${action} Open manually: ${uiSession.url}`,\n\t\t\tuiOpen: false,\n\t\t\tuiViewer: uiSession.viewer,\n\t\t\tuiUrl: uiSession.url,\n\t\t};\n\t}\n\n\treturn {\n\t\tmessage: uiSession.reused\n\t\t\t? \"Updated the open UI.\"\n\t\t\t: \"Interactive UI is open. I'll respond to your prompts and intents as you interact with it.\",\n\t\tuiOpen: true,\n\t\tuiViewer: uiSession.viewer,\n\t\tuiUrl: uiSession.url,\n\t};\n}\n\nconst MAX_COMPLETED_SESSIONS = 10;\n\nfunction withStreamEnvelope(result: CallToolResult, streamId: string | undefined, sequence: number): CallToolResult {\n\tif (!streamId) {\n\t\treturn result;\n\t}\n\n\tconst structuredContent: Record<string, unknown> =\n\t\tresult.structuredContent &&\n\t\ttypeof result.structuredContent === \"object\" &&\n\t\t!Array.isArray(result.structuredContent)\n\t\t\t? { ...(result.structuredContent as Record<string, unknown>) }\n\t\t\t: {};\n\n\tconst rawEnvelope = structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY];\n\tconst envelope =\n\t\trawEnvelope && typeof rawEnvelope === \"object\" && !Array.isArray(rawEnvelope)\n\t\t\t? { ...(rawEnvelope as Record<string, unknown>) }\n\t\t\t: {\n\t\t\t\t\tframeType: \"final\",\n\t\t\t\t\tphase: \"settled\",\n\t\t\t\t\tstatus: result.isError ? \"error\" : \"ok\",\n\t\t\t\t};\n\n\tstructuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY] = {\n\t\t...envelope,\n\t\tstreamId,\n\t\tsequence,\n\t};\n\n\treturn {\n\t\t...result,\n\t\tstructuredContent,\n\t};\n}\n\nasync function openInBrowser(state: McpExtensionState, url: string, signal: AbortSignal): Promise<string | null> {\n\tthrowIfAborted(signal);\n\ttry {\n\t\tawait state.openBrowser(url);\n\t\tthrowIfAborted(signal);\n\t\treturn null;\n\t} catch (error) {\n\t\tif (isAbortError(error, signal)) throw error;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (state.owner?.isActive() === false) return null;\n\t\tstate.ui?.notify(`MCP UI browser open failed: ${message}`, \"warning\");\n\t\treturn message;\n\t}\n}\n\nfunction isRemoteSession(): boolean {\n\treturn Boolean(process.env.SSH_CONNECTION || process.env.SSH_TTY);\n}\n\nfunction hasActiveRemoteLogin(): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\texecFile(\"who\", { encoding: \"utf8\", timeout: 2000 }, (error, out) => {\n\t\t\tif (error) {\n\t\t\t\tresolve(false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(/\\(.+\\)\\s*$/m.test(out));\n\t\t});\n\t});\n}\n\nfunction probeMoshiGateway(): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.connect({ host: \"127.0.0.1\", port: 24543 });\n\t\tconst done = (ok: boolean) => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(ok);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nfunction remoteAccessHint(opts: {\n\turl: string;\n\tport: number;\n\tmoshi: boolean;\n\topenError: string | null;\n\topenedOnHost?: boolean;\n}): string {\n\tconst lines = [\n\t\topts.openError !== null\n\t\t\t? \"Couldn't open MCP UI here. Open it from your own device:\"\n\t\t\t: opts.openedOnHost\n\t\t\t\t? \"MCP UI opened on this host. If you're controlling this session remotely, open it from your own device:\"\n\t\t\t\t: \"This looks like a remote session - if no MCP UI appeared, open it from your own device:\",\n\t\t` ${opts.url}`,\n\t];\n\tif (opts.openError !== null) {\n\t\tlines.push(`Browser launch failed: ${opts.openError}`);\n\t}\n\tif (opts.moshi) {\n\t\tlines.push(\"Moshi: tap the preview button in the terminal title bar and pick this MCP UI server.\");\n\t}\n\tlines.push(\n\t\t`SSH: run \\`ssh -L ${opts.port}:127.0.0.1:${opts.port} <this-host>\\` on your local machine, then open the URL above.`,\n\t\t\"mosh can't forward ports - run that ssh command in a separate terminal.\",\n\t);\n\treturn lines.join(\"\\n\");\n}\n\nexport async function maybeStartUiSession(\n\tstate: McpExtensionState,\n\trequest: UiSessionRequest,\n): Promise<UiSessionRuntime | null> {\n\tconst log = logger.child({\n\t\tcomponent: \"UiSession\",\n\t\tserver: request.serverName,\n\t\ttool: request.toolName,\n\t});\n\tconst runtimeSignal = combineAbortSignals(state.owner?.signal, request.signal) ?? new AbortController().signal;\n\n\ttry {\n\t\tthrowIfAborted(runtimeSignal);\n\t\tif (\n\t\t\tstate.uiServer &&\n\t\t\tstate.uiServer.serverName === request.serverName &&\n\t\t\tstate.uiServer.toolName === request.toolName\n\t\t) {\n\t\t\tconst existingHandle = state.uiServer;\n\t\t\tconst streamMode = request.streamMode;\n\t\t\tconst streamId = streamMode ? randomUUID() : undefined;\n\t\t\tconst streamToken = streamMode ? randomUUID() : undefined;\n\t\t\tlet active = true;\n\t\t\tlet nextStreamSequence = 0;\n\n\t\t\tconst cleanupStreamListener = () => {\n\t\t\t\tif (streamToken) {\n\t\t\t\t\tstate.manager.removeUiStreamListener(streamToken);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\texistingHandle.sendToolInput(request.toolArgs);\n\n\t\t\tif (streamToken) {\n\t\t\t\tstate.manager.registerUiStreamListener(streamToken, (serverName, notification) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tif (serverName !== request.serverName) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendResultPatch(\n\t\t\t\t\t\twithStreamEnvelope(notification.result as CallToolResult, streamId, nextStreamSequence),\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tserverName: request.serverName,\n\t\t\t\ttoolName: request.toolName,\n\t\t\t\treused: true,\n\t\t\t\t...(streamId !== undefined ? { streamId } : {}),\n\t\t\t\t...(streamToken !== undefined ? { streamToken } : {}),\n\t\t\t\t...(streamMode !== undefined ? { streamMode } : {}),\n\t\t\t\t...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),\n\t\t\t\turl: existingHandle.url,\n\t\t\t\tviewer: existingHandle.viewer ?? \"browser\",\n\t\t\t\twindowOpen: existingHandle.windowOpen ?? true,\n\t\t\t\tisActive: () => active && state.uiServer === existingHandle,\n\t\t\t\tsendToolResult: (result: CallToolResult) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t\t},\n\t\t\t\tsendResultPatch: (result: CallToolResult) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t\t},\n\t\t\t\tsendToolCancelled: (reason: string) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendToolResult(\n\t\t\t\t\t\twithStreamEnvelope(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: reason }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tnextStreamSequence,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tclose: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tcleanupStreamListener();\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst resource = await state.uiResourceHandler.readUiResource(request.serverName, request.uiResourceUri, {\n\t\t\tconfig: state.config,\n\t\t\tsignal: runtimeSignal,\n\t\t\tonNeedsAuth: request.onNeedsAuth,\n\t\t});\n\t\tthrowIfAborted(runtimeSignal);\n\n\t\tif (state.uiServer) {\n\t\t\tstate.uiServer.close(\"replaced\");\n\t\t\tstate.uiServer = null;\n\t\t}\n\t\tif (activeGlimpseWindow) {\n\t\t\tactiveGlimpseWindow.close();\n\t\t\tactiveGlimpseWindow = null;\n\t\t}\n\n\t\tconst streamMode = request.streamMode;\n\t\tconst streamId = streamMode ? randomUUID() : undefined;\n\t\tconst streamToken = streamMode ? randomUUID() : undefined;\n\t\tconst hostContext: UiHostContext | undefined =\n\t\t\tstreamMode && streamId\n\t\t\t\t? {\n\t\t\t\t\t\t[UI_STREAM_HOST_CONTEXT_KEY]: {\n\t\t\t\t\t\t\tmode: streamMode,\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tintermediateResultPatches: streamMode === \"stream-first\",\n\t\t\t\t\t\t\tpartialInput: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\tlet active = true;\n\t\tlet nextStreamSequence = 0;\n\t\tlet handle: UiServerHandle;\n\n\t\tconst cleanupStreamListener = () => {\n\t\t\tif (streamToken) {\n\t\t\t\tstate.manager.removeUiStreamListener(streamToken);\n\t\t\t}\n\t\t};\n\n\t\thandle = await startUiServer({\n\t\t\tserverName: request.serverName,\n\t\t\ttoolName: request.toolName,\n\t\t\ttoolArgs: streamMode === \"stream-first\" ? {} : request.toolArgs,\n\t\t\tresource,\n\t\t\tmanager: state.manager,\n\t\t\tconfig: state.config,\n\t\t\tstate,\n\t\t\t...(request.onNeedsAuth ? { onNeedsAuth: request.onNeedsAuth } : {}),\n\t\t\tconsentManager: state.consentManager,\n\t\t\t...(hostContext !== undefined ? { hostContext } : {}),\n\n\t\t\tonMessage: (params: UiMessageParams) => {\n\t\t\t\tconst prompt = extractUiPromptText(params);\n\t\t\t\tif (prompt) {\n\t\t\t\t\tif (state.sendMessage) {\n\t\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcustomType: \"mcp-ui-prompt\",\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{ type: \"text\", text: `User sent prompt from ${request.serverName} UI: \"${prompt}\"` },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdisplay: `💬 UI Prompt: ${prompt}`,\n\t\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, prompt },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlog.debug(\"Triggered agent turn for UI prompt\", { prompt: prompt.slice(0, 50) });\n\t\t\t\t\t}\n\t\t\t\t} else if (params.type === \"intent\" || params.intent) {\n\t\t\t\t\tconst intent = params.intent ?? \"\";\n\t\t\t\t\tconst intentParams = params.params;\n\t\t\t\t\tif (intent && state.sendMessage) {\n\t\t\t\t\t\tconst paramsStr = intentParams ? ` ${JSON.stringify(intentParams)}` : \"\";\n\t\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcustomType: \"mcp-ui-intent\",\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\ttext: `User triggered intent from ${request.serverName} UI: ${intent}${paramsStr}`,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdisplay: `🎯 UI Intent: ${intent}`,\n\t\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, intent, params: intentParams },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlog.debug(\"Triggered agent turn for UI intent\", { intent });\n\t\t\t\t\t}\n\t\t\t\t} else if (params.type === \"notify\" || params.message) {\n\t\t\t\t\tconst text = params.message ?? \"\";\n\t\t\t\t\tif (text && state.ui) {\n\t\t\t\t\t\tstate.ui.notify(`[${request.serverName}] ${text}`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonContextUpdate: (params: UiModelContextParams) => {\n\t\t\t\tconst update = createUiModelContextUpdate(params);\n\t\t\t\tlog.debug(\"Model context update from UI\", {\n\t\t\t\t\thasContent: !!params.content,\n\t\t\t\t\thasStructured: !!params.structuredContent,\n\t\t\t\t\thasUpdate: !!update,\n\t\t\t\t});\n\t\t\t\tif (update && state.sendMessage) {\n\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomType: \"mcp-ui-context\",\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\ttext: `User submitted model context from ${request.serverName} UI:\\n${update.summary}`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdisplay: \"UI Context submitted\",\n\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, context: update },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonComplete: (reason: string) => {\n\t\t\t\tactive = false;\n\t\t\t\tcleanupStreamListener();\n\n\t\t\t\tif (state.uiServer === handle) {\n\t\t\t\t\tconst messages = handle.getSessionMessages();\n\t\t\t\t\tconst stream = handle.getStreamSummary();\n\t\t\t\t\tconst hasContent =\n\t\t\t\t\t\tmessages.prompts.length > 0 ||\n\t\t\t\t\t\tmessages.intents.length > 0 ||\n\t\t\t\t\t\tmessages.notifications.length > 0 ||\n\t\t\t\t\t\tmessages.contexts.length > 0 ||\n\t\t\t\t\t\t!!stream;\n\n\t\t\t\t\tif (hasContent) {\n\t\t\t\t\t\tstate.completedUiSessions.push({\n\t\t\t\t\t\t\tserverName: handle.serverName,\n\t\t\t\t\t\t\ttoolName: handle.toolName,\n\t\t\t\t\t\t\tcompletedAt: new Date(),\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tmessages,\n\t\t\t\t\t\t\t...(stream !== undefined ? { stream } : {}),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\twhile (state.completedUiSessions.length > MAX_COMPLETED_SESSIONS) {\n\t\t\t\t\t\t\tstate.completedUiSessions.shift();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlog.debug(\"Session completed\", {\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tprompts: messages.prompts.length,\n\t\t\t\t\t\t\tintents: messages.intents.length,\n\t\t\t\t\t\t\tnotifications: messages.notifications.length,\n\t\t\t\t\t\t\tcontexts: messages.contexts.length,\n\t\t\t\t\t\t\tstreamFrames: stream?.frames ?? 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.uiServer = null;\n\t\t\t\t\tif (activeGlimpseWindow) {\n\t\t\t\t\t\tactiveGlimpseWindow.close();\n\t\t\t\t\t\tactiveGlimpseWindow = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (state.owner?.isActive() === false || runtimeSignal.aborted) {\n\t\t\thandle.close(\"runtime_owner_stopped\");\n\t\t\tthrowIfAborted(runtimeSignal);\n\t\t\tthrow new Error(\"MCP UI session became stale before registration\");\n\t\t}\n\n\t\tif (streamToken) {\n\t\t\tstate.manager.registerUiStreamListener(streamToken, (serverName, notification) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tif (serverName !== request.serverName) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendResultPatch(\n\t\t\t\t\twithStreamEnvelope(notification.result as CallToolResult, streamId, nextStreamSequence),\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tstate.uiServer = handle;\n\n\t\tconst viewerPref = process.env.MCP_UI_VIEWER?.toLowerCase();\n\t\tconst uiSuppressed = viewerPref === \"none\" || viewerPref === \"off\" || viewerPref === \"disabled\";\n\n\t\tlet viewer: UiSessionViewer = \"browser\";\n\t\tlet windowOpen = true;\n\t\tconst remoteByEnv = isRemoteSession();\n\n\t\tif (uiSuppressed) {\n\t\t\tviewer = \"suppressed\";\n\t\t\twindowOpen = false;\n\t\t\tstate.ui?.notify(\n\t\t\t\t`MCP UI window suppressed (MCP_UI_VIEWER=${viewerPref}). Open manually: ${handle.url}`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t\tlog.info(`Suppressing MCP UI window (MCP_UI_VIEWER=${viewerPref})`, { url: handle.url });\n\t\t} else {\n\t\t\tconst remoteLikely = remoteByEnv || (await hasActiveRemoteLogin());\n\t\t\tconst emitRemoteHint = async (openError: string | null, openedOnHost = false) => {\n\t\t\t\tstate.ui?.notify(\n\t\t\t\t\tremoteAccessHint({\n\t\t\t\t\t\turl: handle.url,\n\t\t\t\t\t\tport: handle.port,\n\t\t\t\t\t\tmoshi: await probeMoshiGateway(),\n\t\t\t\t\t\topenError,\n\t\t\t\t\t\topenedOnHost,\n\t\t\t\t\t}),\n\t\t\t\t\topenError === null ? \"info\" : \"warning\",\n\t\t\t\t);\n\t\t\t};\n\t\t\tconst glimpseDetected = !remoteByEnv && isGlimpseAvailable();\n\t\t\tconst useGlimpse = !remoteByEnv && (viewerPref === \"glimpse\" || (viewerPref !== \"browser\" && glimpseDetected));\n\n\t\t\tif (useGlimpse) {\n\t\t\t\ttry {\n\t\t\t\t\tconst glimpseHtml = `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src=\"${handle.url}\"></iframe></body></html>`;\n\t\t\t\t\tconst glimpseWindow = await openGlimpseWindow(glimpseHtml, {\n\t\t\t\t\t\ttitle: `MCP · ${request.serverName} · ${request.toolName}`,\n\t\t\t\t\t\twidth: 1000,\n\t\t\t\t\t\theight: 800,\n\t\t\t\t\t\tonClosed: () => {\n\t\t\t\t\t\t\tif (active) handle.close(\"glimpse-closed\");\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (state.owner?.isActive() === false || runtimeSignal.aborted) {\n\t\t\t\t\t\tglimpseWindow.close();\n\t\t\t\t\t\tthrowIfAborted(runtimeSignal);\n\t\t\t\t\t\tthrow new Error(\"MCP Glimpse window became stale before registration\");\n\t\t\t\t\t}\n\t\t\t\t\tactiveGlimpseWindow = glimpseWindow;\n\t\t\t\t\tviewer = \"glimpse\";\n\t\t\t\t\tif (remoteLikely) {\n\t\t\t\t\t\tawait emitRemoteHint(null, true);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlog.debug(\"Glimpse unavailable, using browser\", {\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t\tconst openError = await openInBrowser(state, handle.url, runtimeSignal);\n\t\t\t\t\tif (openError !== null || remoteLikely) {\n\t\t\t\t\t\tawait emitRemoteHint(openError);\n\t\t\t\t\t}\n\t\t\t\t\tviewer = \"browser\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst openError = await openInBrowser(state, handle.url, runtimeSignal);\n\t\t\t\tif (openError !== null || remoteLikely) {\n\t\t\t\t\tawait emitRemoteHint(openError);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrowIfAborted(runtimeSignal);\n\t\thandle.viewer = viewer;\n\t\thandle.windowOpen = windowOpen;\n\n\t\treturn {\n\t\t\tserverName: request.serverName,\n\t\t\ttoolName: request.toolName,\n\t\t\treused: false,\n\t\t\t...(streamId !== undefined ? { streamId } : {}),\n\t\t\t...(streamToken !== undefined ? { streamToken } : {}),\n\t\t\t...(streamMode !== undefined ? { streamMode } : {}),\n\t\t\t...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),\n\t\t\turl: handle.url,\n\t\t\tviewer,\n\t\t\twindowOpen,\n\t\t\tisActive: () => active && state.uiServer === handle,\n\t\t\tsendToolResult: (result: CallToolResult) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t},\n\t\t\tsendResultPatch: (result: CallToolResult) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t},\n\t\t\tsendToolCancelled: (reason: string) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\thandle.sendToolCancelled(reason);\n\t\t\t},\n\t\t\tclose: (reason?: string) => {\n\t\t\t\tactive = false;\n\t\t\t\tcleanupStreamListener();\n\t\t\t\thandle.close(reason);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof UrlElicitationRequiredError || isAbortError(error, runtimeSignal)) throw error;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlog.error(\"Failed to start UI session\", error instanceof Error ? error : undefined);\n\t\tstate.ui?.notify(`MCP UI unavailable for ${request.toolName} (${request.serverName}): ${message}`, \"warning\");\n\t\treturn null;\n\t}\n}\n"]}
|