@akon-labs/nexus-cli 0.1.9 → 0.1.10
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.js +20263 -2158
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -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/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/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/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 +4 -2
- package/dist/extensions/gitnexus/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 +27 -0
- package/dist/extensions/mcp/commands.d.ts.map +1 -0
- package/dist/extensions/mcp/commands.js +629 -0
- package/dist/extensions/mcp/commands.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +121 -38
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +1030 -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 +1064 -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 +85 -0
- package/dist/extensions/mcp/mcp-setup-panel.d.ts.map +1 -0
- package/dist/extensions/mcp/mcp-setup-panel.js +618 -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 +61 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +177 -4
- package/dist/extensions/subagent/index.js.map +1 -1
- 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 +20057 -1947
- 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/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/rpc-entry.js +20263 -2158
- package/dist/skills/mcp-scripting/SKILL.md +38 -0
- package/dist/vendor/ai.js +280 -205
- 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/npm-shrinkwrap.json +763 -6
- package/package.json +15 -4
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-callback-server.js","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-callback-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP OAuth Callback Server\n *\n * HTTP server that handles OAuth callbacks from the authorization server.\n * Uses Node.js http module for compatibility.\n */\n\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"http\";\nimport { getAppName } from \"./agent-dir.ts\";\nimport {\n\tDEFAULT_OAUTH_CALLBACK_PATH,\n\tgetConfiguredOAuthCallbackPort,\n\tgetOAuthCallbackPath,\n\tgetOAuthCallbackPort,\n\tsetOAuthCallbackPath,\n\tsetOAuthCallbackPort,\n} from \"./mcp-oauth-provider.ts\";\n\n// HTML templates for callback responses.\n//\n// These pages are served from localhost during OAuth and are the last thing a\n// user sees before returning to their terminal, so they are self-contained: no\n// webfonts, no external assets, nothing that needs the network. They also name\n// the host rather than hardcoding \"Nexus\", so a distribution that rebrands nexus\n// (arc, tau, …) does not send its users back to an app they are not running.\n\n/** Shared chrome: system fonts, a centred card, and light/dark support. */\nconst PAGE_STYLE = `\n :root { color-scheme: light dark; }\n * { box-sizing: border-box; }\n body {\n margin: 0;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n font: 15px/1.55 ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;\n background: #0f1117;\n color: #e6e8ee;\n }\n .card {\n width: 100%;\n max-width: 26rem;\n padding: 2.5rem 2rem;\n text-align: center;\n background: #161922;\n border: 1px solid #242938;\n border-radius: 14px;\n box-shadow: 0 1px 2px rgba(0,0,0,.3), 0 12px 32px rgba(0,0,0,.25);\n }\n .badge {\n width: 3rem; height: 3rem;\n margin: 0 auto 1.25rem;\n display: grid; place-items: center;\n border-radius: 50%;\n }\n .badge svg { width: 1.5rem; height: 1.5rem; display: block; }\n .ok { background: rgba(74,222,128,.12); color: #4ade80; }\n .bad { background: rgba(248,113,113,.12); color: #f87171; }\n h1 { margin: 0 0 .5rem; font-size: 1.15rem; font-weight: 600; letter-spacing: -0.01em; }\n p { margin: 0; color: #9aa1b1; }\n .app { color: #e6e8ee; font-weight: 500; }\n .hint { margin-top: 1.25rem; font-size: .8125rem; color: #6b7280; }\n code {\n display: block;\n margin-top: 1.25rem;\n padding: .75rem .875rem;\n text-align: left;\n font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;\n color: #fca5a5;\n background: rgba(248,113,113,.08);\n border: 1px solid rgba(248,113,113,.2);\n border-radius: 8px;\n overflow-wrap: anywhere;\n }\n @media (prefers-color-scheme: light) {\n body { background: #f6f7f9; color: #121620; }\n .card { background: #fff; border-color: #e4e7ee; }\n p { color: #5b6474; }\n .app { color: #121620; }\n .hint { color: #8b93a3; }\n }`;\n\nconst CHECK_ICON =\n\t'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\"/></svg>';\n\nconst CROSS_ICON =\n\t'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18M6 6l12 12\"/></svg>';\n\nfunction page(options: {\n\ttitle: string;\n\theading: string;\n\tbody: string;\n\ticon: string;\n\ttone: \"ok\" | \"bad\";\n\textra?: string;\n\tautoClose?: boolean;\n}): string {\n\treturn `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>${options.title}</title>\n <style>${PAGE_STYLE}\n </style>\n</head>\n<body>\n <main class=\"card\">\n <div class=\"badge ${options.tone}\">${options.icon}</div>\n <h1>${options.heading}</h1>\n <p>${options.body}</p>\n ${options.extra ?? \"\"}\n </main>\n${options.autoClose ? \" <script>setTimeout(() => window.close(), 2000);</script>\\n\" : \"\"}</body>\n</html>`;\n}\n\nfunction escapeHtml(value: string): string {\n\treturn value\n\t\t.replace(/&/g, \"&\")\n\t\t.replace(/</g, \"<\")\n\t\t.replace(/>/g, \">\")\n\t\t.replace(/\"/g, \""\")\n\t\t.replace(/'/g, \"'\");\n}\n\n/** Built per request so authorization pages always use the Nexus product name. */\nfunction htmlSuccess(): string {\n\tconst app = escapeHtml(getAppName());\n\treturn page({\n\t\ttitle: `${app} — Authorization Successful`,\n\t\theading: \"Authorization Successful\",\n\t\tbody: `You can close this window and return to <span class=\"app\">${app}</span>.`,\n\t\ticon: CHECK_ICON,\n\t\ttone: \"ok\",\n\t\tautoClose: true,\n\t});\n}\n\nfunction htmlError(error: string): string {\n\tconst app = escapeHtml(getAppName());\n\treturn page({\n\t\ttitle: `${app} — Authorization Failed`,\n\t\theading: \"Authorization Failed\",\n\t\tbody: `Something went wrong during authorization. You can close this window and try again from <span class=\"app\">${app}</span>.`,\n\t\ticon: CROSS_ICON,\n\t\ttone: \"bad\",\n\t\textra: `<code>${escapeHtml(error)}</code>`,\n\t});\n}\n\n/** Result of a successful OAuth callback */\nexport interface OAuthCallbackResult {\n\tcode: string;\n\t/** RFC 9207 `iss` authorization response parameter, when provided */\n\tiss?: string;\n}\n\n/** Pending authorization request */\ninterface PendingAuth {\n\tresolve: (result: OAuthCallbackResult) => void;\n\treject: (error: Error) => void;\n\ttimeout: ReturnType<typeof setTimeout>;\n}\n\ntype EarlyAuthResult = { status: \"resolved\"; result: OAuthCallbackResult } | { status: \"rejected\"; error: Error };\n\n/** Server singleton state */\nlet server: Server | undefined;\nlet bindingPromise: Promise<void> | undefined;\nlet stoppingPromise: Promise<void> | undefined;\nlet restartableStoppingPromise: Promise<void> | undefined;\nlet callbackGeneration = 0;\nconst pendingAuths = new Map<string, PendingAuth>();\nconst reservedAuthStates = new Set<string>();\nconst earlyAuthResults = new Map<string, EarlyAuthResult>();\n\n/** Timeout for callback completion (5 minutes) */\nconst CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;\n\ninterface EnsureCallbackServerOptions {\n\tstrictPort?: boolean;\n\tport?: number;\n\tcallbackHost?: string;\n\tcallbackPath?: string;\n\toauthState?: string;\n\treserveState?: boolean;\n}\n\nconst DEFAULT_OAUTH_CALLBACK_HOST = \"localhost\";\nlet callbackServerHost = DEFAULT_OAUTH_CALLBACK_HOST;\n\n/**\n * Handle incoming HTTP requests to the callback server.\n */\nfunction handleRequest(req: IncomingMessage, res: ServerResponse): void {\n\tconst url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n\n\t// Only handle the callback path\n\tif (url.pathname !== getOAuthCallbackPath()) {\n\t\tres.writeHead(404, { \"Content-Type\": \"text/plain\" });\n\t\tres.end(\"Not found\");\n\t\treturn;\n\t}\n\n\tconst code = url.searchParams.get(\"code\");\n\tconst iss = url.searchParams.get(\"iss\");\n\tconst state = url.searchParams.get(\"state\");\n\tconst error = url.searchParams.get(\"error\");\n\tconst errorDescription = url.searchParams.get(\"error_description\");\n\n\t// Enforce state parameter presence for CSRF protection\n\tif (!state) {\n\t\tconst errorMsg = \"Missing required state parameter - potential CSRF attack\";\n\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\tres.end(htmlError(errorMsg));\n\t\treturn;\n\t}\n\n\tconst pending = pendingAuths.get(state);\n\tconst isReserved = reservedAuthStates.has(state);\n\n\t// Handle OAuth errors only for a state that belongs to an active flow.\n\tif (error) {\n\t\tif (!pending && !isReserved) {\n\t\t\tconst errorMsg = \"Invalid or expired state parameter - potential CSRF attack\";\n\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\t\tres.end(htmlError(errorMsg));\n\t\t\treturn;\n\t\t}\n\n\t\tconst errorMsg = errorDescription || error;\n\t\t// Send HTTP response first before rejecting promise\n\t\tres.writeHead(200, { \"Content-Type\": \"text/html\" });\n\t\tres.end(htmlError(errorMsg));\n\t\tif (pending) {\n\t\t\treservedAuthStates.delete(state);\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpendingAuths.delete(state);\n\t\t\t// Reject after the response is sent so callers can attach their handler.\n\t\t\tsetTimeout(() => pending.reject(new Error(errorMsg)), 0);\n\t\t} else {\n\t\t\treservedAuthStates.delete(state);\n\t\t\tearlyAuthResults.set(state, { status: \"rejected\", error: new Error(errorMsg) });\n\t\t}\n\t\treturn;\n\t}\n\n\t// Validate state parameter\n\tif (!pending && !isReserved) {\n\t\tconst errorMsg = \"Invalid or expired state parameter - potential CSRF attack\";\n\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\tres.end(htmlError(errorMsg));\n\t\treturn;\n\t}\n\n\t// Require authorization code\n\tif (!code) {\n\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\tres.end(htmlError(\"No authorization code provided\"));\n\t\treturn;\n\t}\n\n\tif (!pending) {\n\t\treservedAuthStates.delete(state);\n\t\tearlyAuthResults.set(state, {\n\t\t\tstatus: \"resolved\",\n\t\t\tresult: { code, ...(iss !== null ? { iss } : {}) },\n\t\t});\n\t\tres.writeHead(200, { \"Content-Type\": \"text/html\" });\n\t\tres.end(htmlSuccess());\n\t\treturn;\n\t}\n\n\t// Clear timeout and resolve the pending promise\n\tclearTimeout(pending.timeout);\n\tpendingAuths.delete(state);\n\tpending.resolve({ code, ...(iss !== null ? { iss } : {}) });\n\n\tres.writeHead(200, { \"Content-Type\": \"text/html\" });\n\tres.end(htmlSuccess());\n}\n\n/**\n * Ensure the callback server is running.\n * If strictPort is true, requires binding on the configured callback port.\n * If strictPort is false, asks the OS for an available local port.\n */\nexport async function ensureCallbackServer(options: EnsureCallbackServerOptions = {}): Promise<void> {\n\tconst generation = callbackGeneration;\n\tif (stoppingPromise) {\n\t\tif (!restartableStoppingPromise) {\n\t\t\tthrow new Error(\"OAuth callback server stopped\");\n\t\t}\n\t\tawait restartableStoppingPromise;\n\t\tif (generation !== callbackGeneration) {\n\t\t\tthrow new Error(\"OAuth callback server stopped\");\n\t\t}\n\t}\n\twhile (bindingPromise) {\n\t\tawait bindingPromise;\n\t\tif (generation !== callbackGeneration) {\n\t\t\tthrow new Error(\"OAuth callback server stopped\");\n\t\t}\n\t}\n\tif (generation !== callbackGeneration) {\n\t\tthrow new Error(\"OAuth callback server stopped\");\n\t}\n\n\tconst operation = ensureCallbackServerLocked(options);\n\tbindingPromise = operation;\n\ttry {\n\t\tawait operation;\n\t} finally {\n\t\tif (bindingPromise === operation) {\n\t\t\tbindingPromise = undefined;\n\t\t}\n\t}\n}\n\nasync function ensureCallbackServerLocked(options: EnsureCallbackServerOptions = {}): Promise<void> {\n\tconst requiredPort = options.port ?? getConfiguredOAuthCallbackPort();\n\tconst strictPort = options.strictPort === true;\n\tconst requestedHost = options.callbackHost ?? DEFAULT_OAUTH_CALLBACK_HOST;\n\tconst rawRequestedPath = options.callbackPath ?? DEFAULT_OAUTH_CALLBACK_PATH;\n\tconst requestedPath = rawRequestedPath.startsWith(\"/\") ? rawRequestedPath : `/${rawRequestedPath}`;\n\tif (options.reserveState && !options.oauthState) {\n\t\tthrow new Error(\"OAuth callback reservation requires an oauthState\");\n\t}\n\tlet reservedState: string | undefined;\n\n\tconst previousServer = server;\n\tconst needsStrictRebind = Boolean(previousServer && strictPort && getOAuthCallbackPort() !== requiredPort);\n\tconst needsHostSwitch = Boolean(previousServer && callbackServerHost !== requestedHost);\n\tconst needsPathSwitch = Boolean(previousServer && getOAuthCallbackPath() !== requestedPath);\n\n\tif (previousServer) {\n\t\tif (!needsStrictRebind && !needsHostSwitch) {\n\t\t\tif (needsPathSwitch) {\n\t\t\t\tif (pendingAuths.size > 0 || reservedAuthStates.size > 0) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`OAuth callback server is using path ${getOAuthCallbackPath()}, but callback path ${requestedPath} is required and cannot be switched while authorizations are pending`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tsetOAuthCallbackPath(requestedPath);\n\t\t\t}\n\t\t\tif (options.reserveState && options.oauthState) {\n\t\t\t\tearlyAuthResults.delete(options.oauthState);\n\t\t\t\treservedAuthStates.add(options.oauthState);\n\t\t\t\treservedState = options.oauthState;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (pendingAuths.size > 0 || reservedAuthStates.size > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`OAuth callback server is running on ${callbackServerHost}:${getOAuthCallbackPort()}, but strict callback endpoint ${requestedHost}:${requiredPort} is required and cannot be switched while authorizations are pending`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst candidateServer = createServer(handleRequest);\n\tconst listenPort = strictPort ? requiredPort : 0;\n\n\ttry {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tcandidateServer.once(\"error\", (err) => {\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tcandidateServer.listen(listenPort, requestedHost, () => {\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\n\t\tif (strictPort) {\n\t\t\tsetOAuthCallbackPort(requiredPort);\n\t\t} else {\n\t\t\tconst address = candidateServer.address();\n\t\t\tif (!address || typeof address === \"string\" || typeof address.port !== \"number\") {\n\t\t\t\tthrow new Error(\"OAuth callback server did not report an assigned port\");\n\t\t\t}\n\t\t\tsetOAuthCallbackPort(address.port);\n\t\t}\n\n\t\tif (previousServer && (needsStrictRebind || needsHostSwitch)) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tpreviousServer.close(() => resolve());\n\t\t\t});\n\t\t}\n\n\t\tcallbackServerHost = requestedHost;\n\t\tsetOAuthCallbackPath(requestedPath);\n\t\tserver = candidateServer;\n\t\tif (options.reserveState && options.oauthState) {\n\t\t\tearlyAuthResults.delete(options.oauthState);\n\t\t\treservedAuthStates.add(options.oauthState);\n\t\t\treservedState = options.oauthState;\n\t\t}\n\t\tserver.unref();\n\t} catch (error) {\n\t\tif (reservedState) {\n\t\t\treservedAuthStates.delete(reservedState);\n\t\t}\n\t\tconst nodeError = error as NodeJS.ErrnoException;\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tcandidateServer.close(() => resolve());\n\t\t});\n\n\t\tif (strictPort && nodeError.code === \"EADDRINUSE\") {\n\t\t\tthrow new Error(\n\t\t\t\t`OAuth callback port ${requiredPort} is already in use. Pre-registered OAuth clients require an exact redirect URI; set MCP_OAUTH_CALLBACK_PORT to your registered port or free port ${requiredPort}`,\n\t\t\t\t{ cause: error },\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport function reserveCallbackServer(oauthState: string): void {\n\tearlyAuthResults.delete(oauthState);\n\treservedAuthStates.add(oauthState);\n}\n\nexport function releaseCallbackServer(oauthState: string): void {\n\treservedAuthStates.delete(oauthState);\n\tearlyAuthResults.delete(oauthState);\n}\n\n/**\n * Wait for a callback with the given OAuth state.\n * Returns a promise that resolves with the authorization code and, when the\n * authorization server sends one, the RFC 9207 `iss` parameter.\n */\nexport function waitForCallback(oauthState: string): Promise<OAuthCallbackResult> {\n\treservedAuthStates.delete(oauthState);\n\tconst earlyResult = earlyAuthResults.get(oauthState);\n\tif (earlyResult) {\n\t\tearlyAuthResults.delete(oauthState);\n\t\treturn earlyResult.status === \"resolved\"\n\t\t\t? Promise.resolve(earlyResult.result)\n\t\t\t: Promise.reject(earlyResult.error);\n\t}\n\treturn new Promise((resolve, reject) => {\n\t\tconst timeout = setTimeout(() => {\n\t\t\tif (pendingAuths.has(oauthState)) {\n\t\t\t\tpendingAuths.delete(oauthState);\n\t\t\t\treject(new Error(\"OAuth callback timeout - authorization took too long\"));\n\t\t\t}\n\t\t}, CALLBACK_TIMEOUT_MS);\n\n\t\tpendingAuths.set(oauthState, { resolve, reject, timeout });\n\t});\n}\n\n/**\n * Cancel a pending authorization by state.\n */\nexport function cancelPendingCallback(oauthState: string): void {\n\treservedAuthStates.delete(oauthState);\n\tearlyAuthResults.delete(oauthState);\n\tconst pending = pendingAuths.get(oauthState);\n\tif (pending) {\n\t\tclearTimeout(pending.timeout);\n\t\tpendingAuths.delete(oauthState);\n\t\tpending.reject(new Error(\"Authorization cancelled\"));\n\t}\n}\n\n/**\n * Stop the callback server and reject all pending authorizations.\n */\nexport function stopCallbackServer(): Promise<void> {\n\tif (stoppingPromise) {\n\t\trestartableStoppingPromise = undefined;\n\t\tcallbackGeneration += 1;\n\t\treturn stoppingPromise;\n\t}\n\n\tcallbackGeneration += 1;\n\tconst cleanup = (async () => {\n\t\twhile (bindingPromise) {\n\t\t\tawait bindingPromise.catch(() => {});\n\t\t}\n\n\t\tif (server) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver!.close(() => {\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t});\n\t\t\tserver = undefined;\n\t\t}\n\n\t\tsetOAuthCallbackPort(getConfiguredOAuthCallbackPort());\n\t\tcallbackServerHost = DEFAULT_OAUTH_CALLBACK_HOST;\n\t\tsetOAuthCallbackPath(DEFAULT_OAUTH_CALLBACK_PATH);\n\n\t\t// Reject all pending auths (defer to allow any pending operations to complete)\n\t\tconst pendingList = Array.from(pendingAuths.entries());\n\t\tpendingAuths.clear();\n\t\treservedAuthStates.clear();\n\t\tearlyAuthResults.clear();\n\t\tsetTimeout(() => {\n\t\t\tfor (const [, pending] of pendingList) {\n\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\tpending.reject(new Error(\"OAuth callback server stopped\"));\n\t\t\t}\n\t\t}, 0);\n\t})();\n\n\tconst operation = cleanup.finally(() => {\n\t\tif (stoppingPromise === operation) stoppingPromise = undefined;\n\t});\n\tstoppingPromise = operation;\n\treturn operation;\n}\n\n/** Stop the callback server only when no bind or authorization owns it. */\nexport function stopCallbackServerIfIdle(): Promise<void> {\n\tif (stoppingPromise) return stoppingPromise;\n\tif (bindingPromise || !server || pendingAuths.size > 0 || reservedAuthStates.size > 0) {\n\t\treturn Promise.resolve();\n\t}\n\tconst operation = stopCallbackServer().finally(() => {\n\t\tif (restartableStoppingPromise === operation) restartableStoppingPromise = undefined;\n\t});\n\trestartableStoppingPromise = operation;\n\treturn operation;\n}\n\n/**\n * Check if the callback server is running.\n */\nexport function isCallbackServerRunning(): boolean {\n\treturn server !== undefined;\n}\n\n/**\n * Get the number of pending authorizations.\n */\nexport function getPendingAuthCount(): number {\n\treturn pendingAuths.size;\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ToolInfo } from "../../core/extensions/types.ts";
|
|
2
|
+
import type { McpExtensionState } from "./state.ts";
|
|
3
|
+
import type { ContentBlock } from "./types.ts";
|
|
4
|
+
export declare const DEFAULT_MCP_SCRIPT_TIMEOUT_MS = 30000;
|
|
5
|
+
export declare function runMcpScript(state: McpExtensionState, code: string, timeoutMs?: number, getNexusTools?: () => ToolInfo[], signal?: AbortSignal): Promise<{
|
|
6
|
+
content: ContentBlock[];
|
|
7
|
+
details: {
|
|
8
|
+
mode: string;
|
|
9
|
+
error?: "aborted" | "script_error" | "timeout" | undefined;
|
|
10
|
+
message?: string | undefined;
|
|
11
|
+
timeoutMs: number;
|
|
12
|
+
calls?: ({
|
|
13
|
+
operation: "call";
|
|
14
|
+
path: string;
|
|
15
|
+
ok: true;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
} | {
|
|
18
|
+
operation: "call";
|
|
19
|
+
path: string;
|
|
20
|
+
ok: false;
|
|
21
|
+
error: string;
|
|
22
|
+
durationMs: number;
|
|
23
|
+
} | {
|
|
24
|
+
operation: "search";
|
|
25
|
+
query: string;
|
|
26
|
+
ok: true;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
} | {
|
|
29
|
+
operation: "search";
|
|
30
|
+
query: string;
|
|
31
|
+
ok: false;
|
|
32
|
+
error: string;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
} | {
|
|
35
|
+
operation: "describe";
|
|
36
|
+
path: string;
|
|
37
|
+
ok: true;
|
|
38
|
+
durationMs: number;
|
|
39
|
+
} | {
|
|
40
|
+
operation: "describe";
|
|
41
|
+
path: string;
|
|
42
|
+
ok: false;
|
|
43
|
+
error: string;
|
|
44
|
+
durationMs: number;
|
|
45
|
+
})[] | undefined;
|
|
46
|
+
};
|
|
47
|
+
}>;
|
|
48
|
+
//# sourceMappingURL=mcp-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-code.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-code.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAK/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAgGpD,wBAAsB,YAAY,CACjC,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE,MAAM,EACZ,SAAS,SAAgC,EACzC,aAAa,CAAC,EAAE,MAAM,QAAQ,EAAE,EAChC,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsRpB","sourcesContent":["import { formatWithOptions } from \"node:util\";\nimport { Worker } from \"node:worker_threads\";\nimport type { ToolInfo } from \"../../core/extensions/types.ts\";\nimport { guardedMcpDetails, guardMcpOutput, resolveMcpOutputGuardOptions } from \"./mcp-output-guard.ts\";\nimport { executeCall } from \"./proxy-modes.ts\";\nimport { combineAbortSignals } from \"./runtime-owner.ts\";\nimport { paginate, rankSuggestions, rankToolMatches } from \"./search-ranking.ts\";\nimport type { McpExtensionState } from \"./state.ts\";\nimport { findToolByName, formatSchema } from \"./tool-metadata.ts\";\nimport { renderTsShape } from \"./ts-shape.ts\";\nimport type { ContentBlock } from \"./types.ts\";\n\nexport const DEFAULT_MCP_SCRIPT_TIMEOUT_MS = 30_000;\n\nclass McpScriptTimeoutError extends Error {\n\tconstructor(timeoutMs: number) {\n\t\tsuper(`mcpScript timed out after ${timeoutMs}ms`);\n\t\tthis.name = \"McpScriptTimeoutError\";\n\t}\n}\n\ntype SearchInput = { query?: unknown; server?: unknown; limit?: unknown; offset?: unknown };\ntype DescribeInput = { path?: unknown };\ntype WorkerMessage =\n\t| { type: \"emit\"; block: unknown }\n\t| { type: \"call\"; id: number; path: string; args?: unknown }\n\t| { type: \"search\"; id: number; input?: unknown }\n\t| { type: \"describe\"; id: number; input?: unknown }\n\t| { type: \"done\"; returnBlock?: unknown }\n\t| { type: \"error\"; message: string };\n\ntype WorkerResultMessage = { type: \"result\"; id: number; envelope: unknown };\n\nfunction needsInspectableFormatting(value: unknown, stack = new WeakSet<object>()): boolean {\n\tif (value === undefined || typeof value === \"bigint\" || typeof value === \"function\" || typeof value === \"symbol\")\n\t\treturn true;\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (stack.has(value)) return true;\n\tif (value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet)\n\t\treturn true;\n\tstack.add(value);\n\ttry {\n\t\treturn Object.values(value).some((entry) => needsInspectableFormatting(entry, stack));\n\t} finally {\n\t\tstack.delete(value);\n\t}\n}\n\nfunction formatValue(value: unknown): string {\n\tif (typeof value === \"string\") return value;\n\ttry {\n\t\tif (!needsInspectableFormatting(value)) {\n\t\t\tconst json = JSON.stringify(value, null, 2);\n\t\t\tif (json !== undefined) return json;\n\t\t}\n\t\treturn formatWithOptions({ colors: false, depth: 6 }, value);\n\t} catch {\n\t\treturn \"[unserializable value]\";\n\t}\n}\n\nfunction toContentBlock(value: unknown): ContentBlock {\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst block = value as Record<string, unknown>;\n\t\tif (block.type === \"text\" && typeof block.text === \"string\") {\n\t\t\treturn { type: \"text\", text: block.text };\n\t\t}\n\t\tif (block.type === \"image\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\t\treturn { type: \"image\", data: block.data, mimeType: block.mimeType };\n\t\t}\n\t}\n\treturn { type: \"text\", text: formatValue(value) };\n}\n\nfunction textFromContent(content: ContentBlock[]): string {\n\treturn content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\nfunction abortReasonError(reason: unknown): Error {\n\treturn reason instanceof Error ? reason : new Error(String(reason ?? \"MCP request aborted\"));\n}\n\nfunction parseWorkerMessage(value: unknown): WorkerMessage | null {\n\tif (typeof value !== \"object\" || value === null) return null;\n\tconst message = value as Record<string, unknown>;\n\tif (message.type === \"emit\" && \"block\" in message) return { type: \"emit\", block: message.block };\n\tif (message.type === \"call\" && typeof message.id === \"number\" && typeof message.path === \"string\") {\n\t\treturn \"args\" in message\n\t\t\t? { type: \"call\", id: message.id, path: message.path, args: message.args }\n\t\t\t: { type: \"call\", id: message.id, path: message.path };\n\t}\n\tif ((message.type === \"search\" || message.type === \"describe\") && typeof message.id === \"number\") {\n\t\treturn \"input\" in message\n\t\t\t? { type: message.type, id: message.id, input: message.input }\n\t\t\t: { type: message.type, id: message.id };\n\t}\n\tif (message.type === \"done\") {\n\t\treturn \"returnBlock\" in message ? { type: \"done\", returnBlock: message.returnBlock } : { type: \"done\" };\n\t}\n\tif (message.type === \"error\" && typeof message.message === \"string\") {\n\t\treturn { type: \"error\", message: message.message };\n\t}\n\treturn null;\n}\n\nexport async function runMcpScript(\n\tstate: McpExtensionState,\n\tcode: string,\n\ttimeoutMs = DEFAULT_MCP_SCRIPT_TIMEOUT_MS,\n\tgetNexusTools?: () => ToolInfo[],\n\tsignal?: AbortSignal,\n) {\n\tconst resolvedTimeoutMs =\n\t\tNumber.isFinite(timeoutMs) && timeoutMs > 0 ? Math.floor(timeoutMs) : DEFAULT_MCP_SCRIPT_TIMEOUT_MS;\n\tconst output: ContentBlock[] = [];\n\tconst externalSignal = combineAbortSignals(state.owner?.signal, signal);\n\tconst timeoutController = new AbortController();\n\tconst callSignal = combineAbortSignals(externalSignal, timeoutController.signal);\n\n\ttype ScriptOperation =\n\t\t| { operation: \"call\"; path: string; ok: true; durationMs: number }\n\t\t| { operation: \"call\"; path: string; ok: false; error: string; durationMs: number }\n\t\t| { operation: \"search\"; query: string; ok: true; durationMs: number }\n\t\t| { operation: \"search\"; query: string; ok: false; error: string; durationMs: number }\n\t\t| { operation: \"describe\"; path: string; ok: true; durationMs: number }\n\t\t| { operation: \"describe\"; path: string; ok: false; error: string; durationMs: number };\n\ttype TrackedScriptOperation = ScriptOperation & { startedAt: number };\n\tconst calls: TrackedScriptOperation[] = [];\n\tconst snapshotCalls = (): ScriptOperation[] =>\n\t\tcalls.map(({ startedAt, ...operation }) => ({\n\t\t\t...operation,\n\t\t\tdurationMs:\n\t\t\t\t\"error\" in operation && operation.error === \"incomplete\"\n\t\t\t\t\t? Math.max(0, Date.now() - startedAt)\n\t\t\t\t\t: operation.durationMs,\n\t\t}));\n\tlet callsSnapshot: ScriptOperation[] | undefined;\n\tconst callTool = async (path: string, args?: Record<string, unknown>) => {\n\t\t// Record before dispatch so calls still in flight at timeout/abort appear in the trace.\n\t\tconst startedAt = Date.now();\n\t\tconst index =\n\t\t\tcalls.push({ operation: \"call\", path, ok: false, error: \"incomplete\", durationMs: 0, startedAt }) - 1;\n\t\tconst result = await executeCall(state, path, args, undefined, getNexusTools, callSignal, \"script\");\n\t\tconst details = result.details;\n\t\tif (details.error !== undefined) {\n\t\t\tconst errorCode = String(details.error);\n\t\t\tconst suggestions = Array.isArray(details.suggestions)\n\t\t\t\t? details.suggestions.filter((suggestion): suggestion is string => typeof suggestion === \"string\")\n\t\t\t\t: [];\n\t\t\tconst message =\n\t\t\t\terrorCode === \"tool_not_found\"\n\t\t\t\t\t? `Tool \"${path}\" not found. Use await tools.search({ query: \"...\" }) inside mcpScript.${suggestions.length > 0 ? ` Did you mean: ${suggestions.join(\", \")}` : \"\"}`\n\t\t\t\t\t: typeof details.message === \"string\"\n\t\t\t\t\t\t? details.message\n\t\t\t\t\t\t: textFromContent(result.content);\n\t\t\tcalls[index] = {\n\t\t\t\toperation: \"call\",\n\t\t\t\tpath,\n\t\t\t\tok: false,\n\t\t\t\terror: errorCode,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\tstartedAt,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tok: false as const,\n\t\t\t\terror: { code: errorCode, message },\n\t\t\t};\n\t\t}\n\t\tcalls[index] = { operation: \"call\", path, ok: true, durationMs: Date.now() - startedAt, startedAt };\n\t\treturn {\n\t\t\tok: true as const,\n\t\t\tdata: details.mcpResult !== undefined ? details.mcpResult : textFromContent(result.content),\n\t\t};\n\t};\n\n\tconst searchTools = (input?: SearchInput) => {\n\t\tconst startedAt = Date.now();\n\t\tconst query = typeof input?.query === \"string\" ? input.query : \"\";\n\t\tlet error: unknown;\n\t\ttry {\n\t\t\tif (query.trim() === \"\") {\n\t\t\t\treturn { items: [], total: 0, hasMore: false, nextOffset: null };\n\t\t\t}\n\t\t\tconst server = typeof input?.server === \"string\" ? input.server : undefined;\n\t\t\tconst limit = typeof input?.limit === \"number\" ? input.limit : 12;\n\t\t\tconst offset = typeof input?.offset === \"number\" ? input.offset : 0;\n\t\t\tconst page = paginate(rankToolMatches(state, query, server), offset, limit);\n\t\t\treturn {\n\t\t\t\t...page,\n\t\t\t\titems: page.items.map(({ server: matchServer, tool, score }) => ({\n\t\t\t\t\tpath: tool.name,\n\t\t\t\t\tname: tool.originalName,\n\t\t\t\t\tserver: matchServer,\n\t\t\t\t\t...(tool.description ? { description: tool.description } : {}),\n\t\t\t\t\tscore,\n\t\t\t\t})),\n\t\t\t};\n\t\t} catch (caught) {\n\t\t\terror = caught;\n\t\t\tthrow caught;\n\t\t} finally {\n\t\t\tcalls.push(\n\t\t\t\terror === undefined\n\t\t\t\t\t? { operation: \"search\", query, ok: true, durationMs: Date.now() - startedAt, startedAt }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\toperation: \"search\",\n\t\t\t\t\t\t\tquery,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t\t},\n\t\t\t);\n\t\t}\n\t};\n\n\tconst describeTool = (input?: DescribeInput) => {\n\t\tconst startedAt = Date.now();\n\t\tconst path = typeof input?.path === \"string\" ? input.path : \"\";\n\t\tlet error: unknown;\n\t\ttry {\n\t\t\tfor (const [server, metadata] of state.toolMetadata) {\n\t\t\t\tconst tool = findToolByName(metadata, path);\n\t\t\t\tif (!tool) continue;\n\t\t\t\tconst inputTypeScript = tool.inputSchema\n\t\t\t\t\t? (renderTsShape(tool.inputSchema) ?? formatSchema(tool.inputSchema))\n\t\t\t\t\t: null;\n\t\t\t\treturn {\n\t\t\t\t\tpath: tool.name,\n\t\t\t\t\tname: tool.originalName,\n\t\t\t\t\tserver,\n\t\t\t\t\t...(tool.description ? { description: tool.description } : {}),\n\t\t\t\t\t...(inputTypeScript ? { inputTypeScript } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst suggestions = path ? rankSuggestions(state, path, 5) : [];\n\t\t\terror = \"tool_not_found\";\n\t\t\treturn {\n\t\t\t\tpath,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"tool_not_found\",\n\t\t\t\t\tmessage: `Tool not found: ${path}`,\n\t\t\t\t\tsuggestions,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (caught) {\n\t\t\terror = caught;\n\t\t\tthrow caught;\n\t\t} finally {\n\t\t\tcalls.push(\n\t\t\t\terror === undefined\n\t\t\t\t\t? { operation: \"describe\", path, ok: true, durationMs: Date.now() - startedAt, startedAt }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\toperation: \"describe\",\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t\t},\n\t\t\t);\n\t\t}\n\t};\n\n\tlet worker: Worker | undefined;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet removeAbortListener = () => {};\n\tlet errorCode: \"timeout\" | \"aborted\" | \"script_error\" | undefined;\n\tlet errorMessage: string | undefined;\n\n\ttry {\n\t\tif (externalSignal?.aborted) {\n\t\t\tthrow abortReasonError(externalSignal.reason);\n\t\t}\n\n\t\tworker = new Worker(new URL(\"./mcp-script-worker.mjs\", import.meta.url), {\n\t\t\tworkerData: { code },\n\t\t\tenv: {},\n\t\t\t// The sandbox cannot open files, and the host always terminates this worker.\n\t\t\t// Disable Node's unmanaged FD bookkeeping, which emits false warnings when\n\t\t\t// short-lived workers are terminated on Node 24.\n\t\t\ttrackUnmanagedFds: false,\n\t\t});\n\t\tconst activeWorker = worker;\n\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\tlet completed = false;\n\t\t\tactiveWorker.on(\"message\", (value: unknown) => {\n\t\t\t\tconst message = parseWorkerMessage(value);\n\t\t\t\tif (!message || completed) return;\n\t\t\t\tif (message.type === \"emit\") {\n\t\t\t\t\toutput.push(toContentBlock(message.block));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"done\") {\n\t\t\t\t\tcompleted = true;\n\t\t\t\t\tif (\"returnBlock\" in message) output.push(toContentBlock(message.returnBlock));\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"error\") {\n\t\t\t\t\tcompleted = true;\n\t\t\t\t\treject(new Error(message.message));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvoid (async () => {\n\t\t\t\t\tlet envelope: unknown;\n\t\t\t\t\tif (message.type === \"call\") {\n\t\t\t\t\t\tenvelope = await callTool(message.path, message.args as Record<string, unknown> | undefined);\n\t\t\t\t\t} else if (message.type === \"search\") {\n\t\t\t\t\t\tenvelope = searchTools(message.input as SearchInput | undefined);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tenvelope = describeTool(message.input as DescribeInput | undefined);\n\t\t\t\t\t}\n\t\t\t\t\tconst response: WorkerResultMessage = { type: \"result\", id: message.id, envelope };\n\t\t\t\t\tactiveWorker.postMessage(response);\n\t\t\t\t})().catch(reject);\n\t\t\t});\n\t\t\tactiveWorker.once(\"error\", reject);\n\t\t\tactiveWorker.once(\"exit\", (code) => {\n\t\t\t\tif (!completed && code !== 0) reject(new Error(`mcpScript worker exited with code ${code}`));\n\t\t\t});\n\t\t});\n\t\tconst timeoutError = new McpScriptTimeoutError(resolvedTimeoutMs);\n\t\tconst timeout = new Promise<never>((_resolve, reject) => {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tcallsSnapshot = snapshotCalls();\n\t\t\t\ttimeoutController.abort(timeoutError);\n\t\t\t\tvoid activeWorker.terminate();\n\t\t\t\treject(timeoutError);\n\t\t\t}, resolvedTimeoutMs);\n\t\t});\n\t\tconst aborted = externalSignal\n\t\t\t? new Promise<never>((_resolve, reject) => {\n\t\t\t\t\tlet handled = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tif (handled) return;\n\t\t\t\t\t\thandled = true;\n\t\t\t\t\t\tcallsSnapshot = snapshotCalls();\n\t\t\t\t\t\tvoid activeWorker.terminate();\n\t\t\t\t\t\treject(abortReasonError(externalSignal.reason));\n\t\t\t\t\t};\n\t\t\t\t\texternalSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\tremoveAbortListener = () => externalSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tif (externalSignal.aborted) onAbort();\n\t\t\t\t})\n\t\t\t: new Promise<never>(() => {});\n\n\t\tawait Promise.race([execution, timeout, aborted]);\n\t} catch (error) {\n\t\tif (error instanceof McpScriptTimeoutError) {\n\t\t\terrorCode = \"timeout\";\n\t\t\terrorMessage = `mcpScript timed out after ${resolvedTimeoutMs}ms`;\n\t\t} else if (externalSignal?.aborted) {\n\t\t\terrorCode = \"aborted\";\n\t\t\terrorMessage = error instanceof Error ? error.message : String(error);\n\t\t} else {\n\t\t\terrorCode = \"script_error\";\n\t\t\terrorMessage = error instanceof Error ? error.message : String(error);\n\t\t}\n\t\toutput.push({ type: \"text\", text: errorMessage });\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tremoveAbortListener();\n\t\t// \"incomplete\" means the call had not settled when the script finished\n\t\t// (deadline, abort, or early return). Snapshot before aborting stragglers.\n\t\tcallsSnapshot ??= snapshotCalls();\n\t\t// A script may finish without awaiting every call; abort leftovers so\n\t\t// parent-side dispatches do not outlive the script.\n\t\ttimeoutController.abort(new Error(\"mcpScript finished\"));\n\t\tawait worker?.terminate();\n\t}\n\n\t// Snapshot before the asynchronous output guard; the terminated worker can no longer emit.\n\tconst guarded = await guardMcpOutput(\n\t\toutput.length > 0 ? [...output] : [{ type: \"text\", text: \"(no output)\" }],\n\t\tresolveMcpOutputGuardOptions(state.config.settings),\n\t);\n\treturn {\n\t\tcontent: guarded.content,\n\t\tdetails: {\n\t\t\tmode: \"script\",\n\t\t\t...(errorCode ? { error: errorCode, message: errorMessage } : {}),\n\t\t\ttimeoutMs: resolvedTimeoutMs,\n\t\t\t...(callsSnapshot.length > 0 ? { calls: callsSnapshot } : {}),\n\t\t\t...guardedMcpDetails(guarded),\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { formatWithOptions } from "node:util";
|
|
2
|
+
import { Worker } from "node:worker_threads";
|
|
3
|
+
import { guardedMcpDetails, guardMcpOutput, resolveMcpOutputGuardOptions } from "./mcp-output-guard.js";
|
|
4
|
+
import { executeCall } from "./proxy-modes.js";
|
|
5
|
+
import { combineAbortSignals } from "./runtime-owner.js";
|
|
6
|
+
import { paginate, rankSuggestions, rankToolMatches } from "./search-ranking.js";
|
|
7
|
+
import { findToolByName, formatSchema } from "./tool-metadata.js";
|
|
8
|
+
import { renderTsShape } from "./ts-shape.js";
|
|
9
|
+
export const DEFAULT_MCP_SCRIPT_TIMEOUT_MS = 30_000;
|
|
10
|
+
class McpScriptTimeoutError extends Error {
|
|
11
|
+
constructor(timeoutMs) {
|
|
12
|
+
super(`mcpScript timed out after ${timeoutMs}ms`);
|
|
13
|
+
this.name = "McpScriptTimeoutError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function needsInspectableFormatting(value, stack = new WeakSet()) {
|
|
17
|
+
if (value === undefined || typeof value === "bigint" || typeof value === "function" || typeof value === "symbol")
|
|
18
|
+
return true;
|
|
19
|
+
if (typeof value !== "object" || value === null)
|
|
20
|
+
return false;
|
|
21
|
+
if (stack.has(value))
|
|
22
|
+
return true;
|
|
23
|
+
if (value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet)
|
|
24
|
+
return true;
|
|
25
|
+
stack.add(value);
|
|
26
|
+
try {
|
|
27
|
+
return Object.values(value).some((entry) => needsInspectableFormatting(entry, stack));
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
stack.delete(value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function formatValue(value) {
|
|
34
|
+
if (typeof value === "string")
|
|
35
|
+
return value;
|
|
36
|
+
try {
|
|
37
|
+
if (!needsInspectableFormatting(value)) {
|
|
38
|
+
const json = JSON.stringify(value, null, 2);
|
|
39
|
+
if (json !== undefined)
|
|
40
|
+
return json;
|
|
41
|
+
}
|
|
42
|
+
return formatWithOptions({ colors: false, depth: 6 }, value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return "[unserializable value]";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function toContentBlock(value) {
|
|
49
|
+
if (typeof value === "object" && value !== null) {
|
|
50
|
+
const block = value;
|
|
51
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
52
|
+
return { type: "text", text: block.text };
|
|
53
|
+
}
|
|
54
|
+
if (block.type === "image" && typeof block.data === "string" && typeof block.mimeType === "string") {
|
|
55
|
+
return { type: "image", data: block.data, mimeType: block.mimeType };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { type: "text", text: formatValue(value) };
|
|
59
|
+
}
|
|
60
|
+
function textFromContent(content) {
|
|
61
|
+
return content
|
|
62
|
+
.filter((block) => block.type === "text")
|
|
63
|
+
.map((block) => block.text)
|
|
64
|
+
.join("\n");
|
|
65
|
+
}
|
|
66
|
+
function abortReasonError(reason) {
|
|
67
|
+
return reason instanceof Error ? reason : new Error(String(reason ?? "MCP request aborted"));
|
|
68
|
+
}
|
|
69
|
+
function parseWorkerMessage(value) {
|
|
70
|
+
if (typeof value !== "object" || value === null)
|
|
71
|
+
return null;
|
|
72
|
+
const message = value;
|
|
73
|
+
if (message.type === "emit" && "block" in message)
|
|
74
|
+
return { type: "emit", block: message.block };
|
|
75
|
+
if (message.type === "call" && typeof message.id === "number" && typeof message.path === "string") {
|
|
76
|
+
return "args" in message
|
|
77
|
+
? { type: "call", id: message.id, path: message.path, args: message.args }
|
|
78
|
+
: { type: "call", id: message.id, path: message.path };
|
|
79
|
+
}
|
|
80
|
+
if ((message.type === "search" || message.type === "describe") && typeof message.id === "number") {
|
|
81
|
+
return "input" in message
|
|
82
|
+
? { type: message.type, id: message.id, input: message.input }
|
|
83
|
+
: { type: message.type, id: message.id };
|
|
84
|
+
}
|
|
85
|
+
if (message.type === "done") {
|
|
86
|
+
return "returnBlock" in message ? { type: "done", returnBlock: message.returnBlock } : { type: "done" };
|
|
87
|
+
}
|
|
88
|
+
if (message.type === "error" && typeof message.message === "string") {
|
|
89
|
+
return { type: "error", message: message.message };
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
export async function runMcpScript(state, code, timeoutMs = DEFAULT_MCP_SCRIPT_TIMEOUT_MS, getNexusTools, signal) {
|
|
94
|
+
const resolvedTimeoutMs = Number.isFinite(timeoutMs) && timeoutMs > 0 ? Math.floor(timeoutMs) : DEFAULT_MCP_SCRIPT_TIMEOUT_MS;
|
|
95
|
+
const output = [];
|
|
96
|
+
const externalSignal = combineAbortSignals(state.owner?.signal, signal);
|
|
97
|
+
const timeoutController = new AbortController();
|
|
98
|
+
const callSignal = combineAbortSignals(externalSignal, timeoutController.signal);
|
|
99
|
+
const calls = [];
|
|
100
|
+
const snapshotCalls = () => calls.map(({ startedAt, ...operation }) => ({
|
|
101
|
+
...operation,
|
|
102
|
+
durationMs: "error" in operation && operation.error === "incomplete"
|
|
103
|
+
? Math.max(0, Date.now() - startedAt)
|
|
104
|
+
: operation.durationMs,
|
|
105
|
+
}));
|
|
106
|
+
let callsSnapshot;
|
|
107
|
+
const callTool = async (path, args) => {
|
|
108
|
+
// Record before dispatch so calls still in flight at timeout/abort appear in the trace.
|
|
109
|
+
const startedAt = Date.now();
|
|
110
|
+
const index = calls.push({ operation: "call", path, ok: false, error: "incomplete", durationMs: 0, startedAt }) - 1;
|
|
111
|
+
const result = await executeCall(state, path, args, undefined, getNexusTools, callSignal, "script");
|
|
112
|
+
const details = result.details;
|
|
113
|
+
if (details.error !== undefined) {
|
|
114
|
+
const errorCode = String(details.error);
|
|
115
|
+
const suggestions = Array.isArray(details.suggestions)
|
|
116
|
+
? details.suggestions.filter((suggestion) => typeof suggestion === "string")
|
|
117
|
+
: [];
|
|
118
|
+
const message = errorCode === "tool_not_found"
|
|
119
|
+
? `Tool "${path}" not found. Use await tools.search({ query: "..." }) inside mcpScript.${suggestions.length > 0 ? ` Did you mean: ${suggestions.join(", ")}` : ""}`
|
|
120
|
+
: typeof details.message === "string"
|
|
121
|
+
? details.message
|
|
122
|
+
: textFromContent(result.content);
|
|
123
|
+
calls[index] = {
|
|
124
|
+
operation: "call",
|
|
125
|
+
path,
|
|
126
|
+
ok: false,
|
|
127
|
+
error: errorCode,
|
|
128
|
+
durationMs: Date.now() - startedAt,
|
|
129
|
+
startedAt,
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
ok: false,
|
|
133
|
+
error: { code: errorCode, message },
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
calls[index] = { operation: "call", path, ok: true, durationMs: Date.now() - startedAt, startedAt };
|
|
137
|
+
return {
|
|
138
|
+
ok: true,
|
|
139
|
+
data: details.mcpResult !== undefined ? details.mcpResult : textFromContent(result.content),
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
const searchTools = (input) => {
|
|
143
|
+
const startedAt = Date.now();
|
|
144
|
+
const query = typeof input?.query === "string" ? input.query : "";
|
|
145
|
+
let error;
|
|
146
|
+
try {
|
|
147
|
+
if (query.trim() === "") {
|
|
148
|
+
return { items: [], total: 0, hasMore: false, nextOffset: null };
|
|
149
|
+
}
|
|
150
|
+
const server = typeof input?.server === "string" ? input.server : undefined;
|
|
151
|
+
const limit = typeof input?.limit === "number" ? input.limit : 12;
|
|
152
|
+
const offset = typeof input?.offset === "number" ? input.offset : 0;
|
|
153
|
+
const page = paginate(rankToolMatches(state, query, server), offset, limit);
|
|
154
|
+
return {
|
|
155
|
+
...page,
|
|
156
|
+
items: page.items.map(({ server: matchServer, tool, score }) => ({
|
|
157
|
+
path: tool.name,
|
|
158
|
+
name: tool.originalName,
|
|
159
|
+
server: matchServer,
|
|
160
|
+
...(tool.description ? { description: tool.description } : {}),
|
|
161
|
+
score,
|
|
162
|
+
})),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (caught) {
|
|
166
|
+
error = caught;
|
|
167
|
+
throw caught;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
calls.push(error === undefined
|
|
171
|
+
? { operation: "search", query, ok: true, durationMs: Date.now() - startedAt, startedAt }
|
|
172
|
+
: {
|
|
173
|
+
operation: "search",
|
|
174
|
+
query,
|
|
175
|
+
ok: false,
|
|
176
|
+
error: error instanceof Error ? error.message : String(error),
|
|
177
|
+
durationMs: Date.now() - startedAt,
|
|
178
|
+
startedAt,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const describeTool = (input) => {
|
|
183
|
+
const startedAt = Date.now();
|
|
184
|
+
const path = typeof input?.path === "string" ? input.path : "";
|
|
185
|
+
let error;
|
|
186
|
+
try {
|
|
187
|
+
for (const [server, metadata] of state.toolMetadata) {
|
|
188
|
+
const tool = findToolByName(metadata, path);
|
|
189
|
+
if (!tool)
|
|
190
|
+
continue;
|
|
191
|
+
const inputTypeScript = tool.inputSchema
|
|
192
|
+
? (renderTsShape(tool.inputSchema) ?? formatSchema(tool.inputSchema))
|
|
193
|
+
: null;
|
|
194
|
+
return {
|
|
195
|
+
path: tool.name,
|
|
196
|
+
name: tool.originalName,
|
|
197
|
+
server,
|
|
198
|
+
...(tool.description ? { description: tool.description } : {}),
|
|
199
|
+
...(inputTypeScript ? { inputTypeScript } : {}),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const suggestions = path ? rankSuggestions(state, path, 5) : [];
|
|
203
|
+
error = "tool_not_found";
|
|
204
|
+
return {
|
|
205
|
+
path,
|
|
206
|
+
error: {
|
|
207
|
+
code: "tool_not_found",
|
|
208
|
+
message: `Tool not found: ${path}`,
|
|
209
|
+
suggestions,
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (caught) {
|
|
214
|
+
error = caught;
|
|
215
|
+
throw caught;
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
calls.push(error === undefined
|
|
219
|
+
? { operation: "describe", path, ok: true, durationMs: Date.now() - startedAt, startedAt }
|
|
220
|
+
: {
|
|
221
|
+
operation: "describe",
|
|
222
|
+
path,
|
|
223
|
+
ok: false,
|
|
224
|
+
error: error instanceof Error ? error.message : String(error),
|
|
225
|
+
durationMs: Date.now() - startedAt,
|
|
226
|
+
startedAt,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
let worker;
|
|
231
|
+
let timer;
|
|
232
|
+
let removeAbortListener = () => { };
|
|
233
|
+
let errorCode;
|
|
234
|
+
let errorMessage;
|
|
235
|
+
try {
|
|
236
|
+
if (externalSignal?.aborted) {
|
|
237
|
+
throw abortReasonError(externalSignal.reason);
|
|
238
|
+
}
|
|
239
|
+
worker = new Worker(new URL("./mcp-script-worker.mjs", import.meta.url), {
|
|
240
|
+
workerData: { code },
|
|
241
|
+
env: {},
|
|
242
|
+
// The sandbox cannot open files, and the host always terminates this worker.
|
|
243
|
+
// Disable Node's unmanaged FD bookkeeping, which emits false warnings when
|
|
244
|
+
// short-lived workers are terminated on Node 24.
|
|
245
|
+
trackUnmanagedFds: false,
|
|
246
|
+
});
|
|
247
|
+
const activeWorker = worker;
|
|
248
|
+
const execution = new Promise((resolve, reject) => {
|
|
249
|
+
let completed = false;
|
|
250
|
+
activeWorker.on("message", (value) => {
|
|
251
|
+
const message = parseWorkerMessage(value);
|
|
252
|
+
if (!message || completed)
|
|
253
|
+
return;
|
|
254
|
+
if (message.type === "emit") {
|
|
255
|
+
output.push(toContentBlock(message.block));
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (message.type === "done") {
|
|
259
|
+
completed = true;
|
|
260
|
+
if ("returnBlock" in message)
|
|
261
|
+
output.push(toContentBlock(message.returnBlock));
|
|
262
|
+
resolve();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (message.type === "error") {
|
|
266
|
+
completed = true;
|
|
267
|
+
reject(new Error(message.message));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
void (async () => {
|
|
271
|
+
let envelope;
|
|
272
|
+
if (message.type === "call") {
|
|
273
|
+
envelope = await callTool(message.path, message.args);
|
|
274
|
+
}
|
|
275
|
+
else if (message.type === "search") {
|
|
276
|
+
envelope = searchTools(message.input);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
envelope = describeTool(message.input);
|
|
280
|
+
}
|
|
281
|
+
const response = { type: "result", id: message.id, envelope };
|
|
282
|
+
activeWorker.postMessage(response);
|
|
283
|
+
})().catch(reject);
|
|
284
|
+
});
|
|
285
|
+
activeWorker.once("error", reject);
|
|
286
|
+
activeWorker.once("exit", (code) => {
|
|
287
|
+
if (!completed && code !== 0)
|
|
288
|
+
reject(new Error(`mcpScript worker exited with code ${code}`));
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
const timeoutError = new McpScriptTimeoutError(resolvedTimeoutMs);
|
|
292
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
293
|
+
timer = setTimeout(() => {
|
|
294
|
+
callsSnapshot = snapshotCalls();
|
|
295
|
+
timeoutController.abort(timeoutError);
|
|
296
|
+
void activeWorker.terminate();
|
|
297
|
+
reject(timeoutError);
|
|
298
|
+
}, resolvedTimeoutMs);
|
|
299
|
+
});
|
|
300
|
+
const aborted = externalSignal
|
|
301
|
+
? new Promise((_resolve, reject) => {
|
|
302
|
+
let handled = false;
|
|
303
|
+
const onAbort = () => {
|
|
304
|
+
if (handled)
|
|
305
|
+
return;
|
|
306
|
+
handled = true;
|
|
307
|
+
callsSnapshot = snapshotCalls();
|
|
308
|
+
void activeWorker.terminate();
|
|
309
|
+
reject(abortReasonError(externalSignal.reason));
|
|
310
|
+
};
|
|
311
|
+
externalSignal.addEventListener("abort", onAbort, { once: true });
|
|
312
|
+
removeAbortListener = () => externalSignal.removeEventListener("abort", onAbort);
|
|
313
|
+
if (externalSignal.aborted)
|
|
314
|
+
onAbort();
|
|
315
|
+
})
|
|
316
|
+
: new Promise(() => { });
|
|
317
|
+
await Promise.race([execution, timeout, aborted]);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
if (error instanceof McpScriptTimeoutError) {
|
|
321
|
+
errorCode = "timeout";
|
|
322
|
+
errorMessage = `mcpScript timed out after ${resolvedTimeoutMs}ms`;
|
|
323
|
+
}
|
|
324
|
+
else if (externalSignal?.aborted) {
|
|
325
|
+
errorCode = "aborted";
|
|
326
|
+
errorMessage = error instanceof Error ? error.message : String(error);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
errorCode = "script_error";
|
|
330
|
+
errorMessage = error instanceof Error ? error.message : String(error);
|
|
331
|
+
}
|
|
332
|
+
output.push({ type: "text", text: errorMessage });
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
clearTimeout(timer);
|
|
336
|
+
removeAbortListener();
|
|
337
|
+
// "incomplete" means the call had not settled when the script finished
|
|
338
|
+
// (deadline, abort, or early return). Snapshot before aborting stragglers.
|
|
339
|
+
callsSnapshot ??= snapshotCalls();
|
|
340
|
+
// A script may finish without awaiting every call; abort leftovers so
|
|
341
|
+
// parent-side dispatches do not outlive the script.
|
|
342
|
+
timeoutController.abort(new Error("mcpScript finished"));
|
|
343
|
+
await worker?.terminate();
|
|
344
|
+
}
|
|
345
|
+
// Snapshot before the asynchronous output guard; the terminated worker can no longer emit.
|
|
346
|
+
const guarded = await guardMcpOutput(output.length > 0 ? [...output] : [{ type: "text", text: "(no output)" }], resolveMcpOutputGuardOptions(state.config.settings));
|
|
347
|
+
return {
|
|
348
|
+
content: guarded.content,
|
|
349
|
+
details: {
|
|
350
|
+
mode: "script",
|
|
351
|
+
...(errorCode ? { error: errorCode, message: errorMessage } : {}),
|
|
352
|
+
timeoutMs: resolvedTimeoutMs,
|
|
353
|
+
...(callsSnapshot.length > 0 ? { calls: callsSnapshot } : {}),
|
|
354
|
+
...guardedMcpDetails(guarded),
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=mcp-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-code.js","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatWithOptions } from \"node:util\";\nimport { Worker } from \"node:worker_threads\";\nimport type { ToolInfo } from \"../../core/extensions/types.ts\";\nimport { guardedMcpDetails, guardMcpOutput, resolveMcpOutputGuardOptions } from \"./mcp-output-guard.ts\";\nimport { executeCall } from \"./proxy-modes.ts\";\nimport { combineAbortSignals } from \"./runtime-owner.ts\";\nimport { paginate, rankSuggestions, rankToolMatches } from \"./search-ranking.ts\";\nimport type { McpExtensionState } from \"./state.ts\";\nimport { findToolByName, formatSchema } from \"./tool-metadata.ts\";\nimport { renderTsShape } from \"./ts-shape.ts\";\nimport type { ContentBlock } from \"./types.ts\";\n\nexport const DEFAULT_MCP_SCRIPT_TIMEOUT_MS = 30_000;\n\nclass McpScriptTimeoutError extends Error {\n\tconstructor(timeoutMs: number) {\n\t\tsuper(`mcpScript timed out after ${timeoutMs}ms`);\n\t\tthis.name = \"McpScriptTimeoutError\";\n\t}\n}\n\ntype SearchInput = { query?: unknown; server?: unknown; limit?: unknown; offset?: unknown };\ntype DescribeInput = { path?: unknown };\ntype WorkerMessage =\n\t| { type: \"emit\"; block: unknown }\n\t| { type: \"call\"; id: number; path: string; args?: unknown }\n\t| { type: \"search\"; id: number; input?: unknown }\n\t| { type: \"describe\"; id: number; input?: unknown }\n\t| { type: \"done\"; returnBlock?: unknown }\n\t| { type: \"error\"; message: string };\n\ntype WorkerResultMessage = { type: \"result\"; id: number; envelope: unknown };\n\nfunction needsInspectableFormatting(value: unknown, stack = new WeakSet<object>()): boolean {\n\tif (value === undefined || typeof value === \"bigint\" || typeof value === \"function\" || typeof value === \"symbol\")\n\t\treturn true;\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (stack.has(value)) return true;\n\tif (value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet)\n\t\treturn true;\n\tstack.add(value);\n\ttry {\n\t\treturn Object.values(value).some((entry) => needsInspectableFormatting(entry, stack));\n\t} finally {\n\t\tstack.delete(value);\n\t}\n}\n\nfunction formatValue(value: unknown): string {\n\tif (typeof value === \"string\") return value;\n\ttry {\n\t\tif (!needsInspectableFormatting(value)) {\n\t\t\tconst json = JSON.stringify(value, null, 2);\n\t\t\tif (json !== undefined) return json;\n\t\t}\n\t\treturn formatWithOptions({ colors: false, depth: 6 }, value);\n\t} catch {\n\t\treturn \"[unserializable value]\";\n\t}\n}\n\nfunction toContentBlock(value: unknown): ContentBlock {\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst block = value as Record<string, unknown>;\n\t\tif (block.type === \"text\" && typeof block.text === \"string\") {\n\t\t\treturn { type: \"text\", text: block.text };\n\t\t}\n\t\tif (block.type === \"image\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\t\treturn { type: \"image\", data: block.data, mimeType: block.mimeType };\n\t\t}\n\t}\n\treturn { type: \"text\", text: formatValue(value) };\n}\n\nfunction textFromContent(content: ContentBlock[]): string {\n\treturn content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\nfunction abortReasonError(reason: unknown): Error {\n\treturn reason instanceof Error ? reason : new Error(String(reason ?? \"MCP request aborted\"));\n}\n\nfunction parseWorkerMessage(value: unknown): WorkerMessage | null {\n\tif (typeof value !== \"object\" || value === null) return null;\n\tconst message = value as Record<string, unknown>;\n\tif (message.type === \"emit\" && \"block\" in message) return { type: \"emit\", block: message.block };\n\tif (message.type === \"call\" && typeof message.id === \"number\" && typeof message.path === \"string\") {\n\t\treturn \"args\" in message\n\t\t\t? { type: \"call\", id: message.id, path: message.path, args: message.args }\n\t\t\t: { type: \"call\", id: message.id, path: message.path };\n\t}\n\tif ((message.type === \"search\" || message.type === \"describe\") && typeof message.id === \"number\") {\n\t\treturn \"input\" in message\n\t\t\t? { type: message.type, id: message.id, input: message.input }\n\t\t\t: { type: message.type, id: message.id };\n\t}\n\tif (message.type === \"done\") {\n\t\treturn \"returnBlock\" in message ? { type: \"done\", returnBlock: message.returnBlock } : { type: \"done\" };\n\t}\n\tif (message.type === \"error\" && typeof message.message === \"string\") {\n\t\treturn { type: \"error\", message: message.message };\n\t}\n\treturn null;\n}\n\nexport async function runMcpScript(\n\tstate: McpExtensionState,\n\tcode: string,\n\ttimeoutMs = DEFAULT_MCP_SCRIPT_TIMEOUT_MS,\n\tgetNexusTools?: () => ToolInfo[],\n\tsignal?: AbortSignal,\n) {\n\tconst resolvedTimeoutMs =\n\t\tNumber.isFinite(timeoutMs) && timeoutMs > 0 ? Math.floor(timeoutMs) : DEFAULT_MCP_SCRIPT_TIMEOUT_MS;\n\tconst output: ContentBlock[] = [];\n\tconst externalSignal = combineAbortSignals(state.owner?.signal, signal);\n\tconst timeoutController = new AbortController();\n\tconst callSignal = combineAbortSignals(externalSignal, timeoutController.signal);\n\n\ttype ScriptOperation =\n\t\t| { operation: \"call\"; path: string; ok: true; durationMs: number }\n\t\t| { operation: \"call\"; path: string; ok: false; error: string; durationMs: number }\n\t\t| { operation: \"search\"; query: string; ok: true; durationMs: number }\n\t\t| { operation: \"search\"; query: string; ok: false; error: string; durationMs: number }\n\t\t| { operation: \"describe\"; path: string; ok: true; durationMs: number }\n\t\t| { operation: \"describe\"; path: string; ok: false; error: string; durationMs: number };\n\ttype TrackedScriptOperation = ScriptOperation & { startedAt: number };\n\tconst calls: TrackedScriptOperation[] = [];\n\tconst snapshotCalls = (): ScriptOperation[] =>\n\t\tcalls.map(({ startedAt, ...operation }) => ({\n\t\t\t...operation,\n\t\t\tdurationMs:\n\t\t\t\t\"error\" in operation && operation.error === \"incomplete\"\n\t\t\t\t\t? Math.max(0, Date.now() - startedAt)\n\t\t\t\t\t: operation.durationMs,\n\t\t}));\n\tlet callsSnapshot: ScriptOperation[] | undefined;\n\tconst callTool = async (path: string, args?: Record<string, unknown>) => {\n\t\t// Record before dispatch so calls still in flight at timeout/abort appear in the trace.\n\t\tconst startedAt = Date.now();\n\t\tconst index =\n\t\t\tcalls.push({ operation: \"call\", path, ok: false, error: \"incomplete\", durationMs: 0, startedAt }) - 1;\n\t\tconst result = await executeCall(state, path, args, undefined, getNexusTools, callSignal, \"script\");\n\t\tconst details = result.details;\n\t\tif (details.error !== undefined) {\n\t\t\tconst errorCode = String(details.error);\n\t\t\tconst suggestions = Array.isArray(details.suggestions)\n\t\t\t\t? details.suggestions.filter((suggestion): suggestion is string => typeof suggestion === \"string\")\n\t\t\t\t: [];\n\t\t\tconst message =\n\t\t\t\terrorCode === \"tool_not_found\"\n\t\t\t\t\t? `Tool \"${path}\" not found. Use await tools.search({ query: \"...\" }) inside mcpScript.${suggestions.length > 0 ? ` Did you mean: ${suggestions.join(\", \")}` : \"\"}`\n\t\t\t\t\t: typeof details.message === \"string\"\n\t\t\t\t\t\t? details.message\n\t\t\t\t\t\t: textFromContent(result.content);\n\t\t\tcalls[index] = {\n\t\t\t\toperation: \"call\",\n\t\t\t\tpath,\n\t\t\t\tok: false,\n\t\t\t\terror: errorCode,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\tstartedAt,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tok: false as const,\n\t\t\t\terror: { code: errorCode, message },\n\t\t\t};\n\t\t}\n\t\tcalls[index] = { operation: \"call\", path, ok: true, durationMs: Date.now() - startedAt, startedAt };\n\t\treturn {\n\t\t\tok: true as const,\n\t\t\tdata: details.mcpResult !== undefined ? details.mcpResult : textFromContent(result.content),\n\t\t};\n\t};\n\n\tconst searchTools = (input?: SearchInput) => {\n\t\tconst startedAt = Date.now();\n\t\tconst query = typeof input?.query === \"string\" ? input.query : \"\";\n\t\tlet error: unknown;\n\t\ttry {\n\t\t\tif (query.trim() === \"\") {\n\t\t\t\treturn { items: [], total: 0, hasMore: false, nextOffset: null };\n\t\t\t}\n\t\t\tconst server = typeof input?.server === \"string\" ? input.server : undefined;\n\t\t\tconst limit = typeof input?.limit === \"number\" ? input.limit : 12;\n\t\t\tconst offset = typeof input?.offset === \"number\" ? input.offset : 0;\n\t\t\tconst page = paginate(rankToolMatches(state, query, server), offset, limit);\n\t\t\treturn {\n\t\t\t\t...page,\n\t\t\t\titems: page.items.map(({ server: matchServer, tool, score }) => ({\n\t\t\t\t\tpath: tool.name,\n\t\t\t\t\tname: tool.originalName,\n\t\t\t\t\tserver: matchServer,\n\t\t\t\t\t...(tool.description ? { description: tool.description } : {}),\n\t\t\t\t\tscore,\n\t\t\t\t})),\n\t\t\t};\n\t\t} catch (caught) {\n\t\t\terror = caught;\n\t\t\tthrow caught;\n\t\t} finally {\n\t\t\tcalls.push(\n\t\t\t\terror === undefined\n\t\t\t\t\t? { operation: \"search\", query, ok: true, durationMs: Date.now() - startedAt, startedAt }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\toperation: \"search\",\n\t\t\t\t\t\t\tquery,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t\t},\n\t\t\t);\n\t\t}\n\t};\n\n\tconst describeTool = (input?: DescribeInput) => {\n\t\tconst startedAt = Date.now();\n\t\tconst path = typeof input?.path === \"string\" ? input.path : \"\";\n\t\tlet error: unknown;\n\t\ttry {\n\t\t\tfor (const [server, metadata] of state.toolMetadata) {\n\t\t\t\tconst tool = findToolByName(metadata, path);\n\t\t\t\tif (!tool) continue;\n\t\t\t\tconst inputTypeScript = tool.inputSchema\n\t\t\t\t\t? (renderTsShape(tool.inputSchema) ?? formatSchema(tool.inputSchema))\n\t\t\t\t\t: null;\n\t\t\t\treturn {\n\t\t\t\t\tpath: tool.name,\n\t\t\t\t\tname: tool.originalName,\n\t\t\t\t\tserver,\n\t\t\t\t\t...(tool.description ? { description: tool.description } : {}),\n\t\t\t\t\t...(inputTypeScript ? { inputTypeScript } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst suggestions = path ? rankSuggestions(state, path, 5) : [];\n\t\t\terror = \"tool_not_found\";\n\t\t\treturn {\n\t\t\t\tpath,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"tool_not_found\",\n\t\t\t\t\tmessage: `Tool not found: ${path}`,\n\t\t\t\t\tsuggestions,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (caught) {\n\t\t\terror = caught;\n\t\t\tthrow caught;\n\t\t} finally {\n\t\t\tcalls.push(\n\t\t\t\terror === undefined\n\t\t\t\t\t? { operation: \"describe\", path, ok: true, durationMs: Date.now() - startedAt, startedAt }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\toperation: \"describe\",\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t\t},\n\t\t\t);\n\t\t}\n\t};\n\n\tlet worker: Worker | undefined;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet removeAbortListener = () => {};\n\tlet errorCode: \"timeout\" | \"aborted\" | \"script_error\" | undefined;\n\tlet errorMessage: string | undefined;\n\n\ttry {\n\t\tif (externalSignal?.aborted) {\n\t\t\tthrow abortReasonError(externalSignal.reason);\n\t\t}\n\n\t\tworker = new Worker(new URL(\"./mcp-script-worker.mjs\", import.meta.url), {\n\t\t\tworkerData: { code },\n\t\t\tenv: {},\n\t\t\t// The sandbox cannot open files, and the host always terminates this worker.\n\t\t\t// Disable Node's unmanaged FD bookkeeping, which emits false warnings when\n\t\t\t// short-lived workers are terminated on Node 24.\n\t\t\ttrackUnmanagedFds: false,\n\t\t});\n\t\tconst activeWorker = worker;\n\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\tlet completed = false;\n\t\t\tactiveWorker.on(\"message\", (value: unknown) => {\n\t\t\t\tconst message = parseWorkerMessage(value);\n\t\t\t\tif (!message || completed) return;\n\t\t\t\tif (message.type === \"emit\") {\n\t\t\t\t\toutput.push(toContentBlock(message.block));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"done\") {\n\t\t\t\t\tcompleted = true;\n\t\t\t\t\tif (\"returnBlock\" in message) output.push(toContentBlock(message.returnBlock));\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"error\") {\n\t\t\t\t\tcompleted = true;\n\t\t\t\t\treject(new Error(message.message));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvoid (async () => {\n\t\t\t\t\tlet envelope: unknown;\n\t\t\t\t\tif (message.type === \"call\") {\n\t\t\t\t\t\tenvelope = await callTool(message.path, message.args as Record<string, unknown> | undefined);\n\t\t\t\t\t} else if (message.type === \"search\") {\n\t\t\t\t\t\tenvelope = searchTools(message.input as SearchInput | undefined);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tenvelope = describeTool(message.input as DescribeInput | undefined);\n\t\t\t\t\t}\n\t\t\t\t\tconst response: WorkerResultMessage = { type: \"result\", id: message.id, envelope };\n\t\t\t\t\tactiveWorker.postMessage(response);\n\t\t\t\t})().catch(reject);\n\t\t\t});\n\t\t\tactiveWorker.once(\"error\", reject);\n\t\t\tactiveWorker.once(\"exit\", (code) => {\n\t\t\t\tif (!completed && code !== 0) reject(new Error(`mcpScript worker exited with code ${code}`));\n\t\t\t});\n\t\t});\n\t\tconst timeoutError = new McpScriptTimeoutError(resolvedTimeoutMs);\n\t\tconst timeout = new Promise<never>((_resolve, reject) => {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tcallsSnapshot = snapshotCalls();\n\t\t\t\ttimeoutController.abort(timeoutError);\n\t\t\t\tvoid activeWorker.terminate();\n\t\t\t\treject(timeoutError);\n\t\t\t}, resolvedTimeoutMs);\n\t\t});\n\t\tconst aborted = externalSignal\n\t\t\t? new Promise<never>((_resolve, reject) => {\n\t\t\t\t\tlet handled = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tif (handled) return;\n\t\t\t\t\t\thandled = true;\n\t\t\t\t\t\tcallsSnapshot = snapshotCalls();\n\t\t\t\t\t\tvoid activeWorker.terminate();\n\t\t\t\t\t\treject(abortReasonError(externalSignal.reason));\n\t\t\t\t\t};\n\t\t\t\t\texternalSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\tremoveAbortListener = () => externalSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tif (externalSignal.aborted) onAbort();\n\t\t\t\t})\n\t\t\t: new Promise<never>(() => {});\n\n\t\tawait Promise.race([execution, timeout, aborted]);\n\t} catch (error) {\n\t\tif (error instanceof McpScriptTimeoutError) {\n\t\t\terrorCode = \"timeout\";\n\t\t\terrorMessage = `mcpScript timed out after ${resolvedTimeoutMs}ms`;\n\t\t} else if (externalSignal?.aborted) {\n\t\t\terrorCode = \"aborted\";\n\t\t\terrorMessage = error instanceof Error ? error.message : String(error);\n\t\t} else {\n\t\t\terrorCode = \"script_error\";\n\t\t\terrorMessage = error instanceof Error ? error.message : String(error);\n\t\t}\n\t\toutput.push({ type: \"text\", text: errorMessage });\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tremoveAbortListener();\n\t\t// \"incomplete\" means the call had not settled when the script finished\n\t\t// (deadline, abort, or early return). Snapshot before aborting stragglers.\n\t\tcallsSnapshot ??= snapshotCalls();\n\t\t// A script may finish without awaiting every call; abort leftovers so\n\t\t// parent-side dispatches do not outlive the script.\n\t\ttimeoutController.abort(new Error(\"mcpScript finished\"));\n\t\tawait worker?.terminate();\n\t}\n\n\t// Snapshot before the asynchronous output guard; the terminated worker can no longer emit.\n\tconst guarded = await guardMcpOutput(\n\t\toutput.length > 0 ? [...output] : [{ type: \"text\", text: \"(no output)\" }],\n\t\tresolveMcpOutputGuardOptions(state.config.settings),\n\t);\n\treturn {\n\t\tcontent: guarded.content,\n\t\tdetails: {\n\t\t\tmode: \"script\",\n\t\t\t...(errorCode ? { error: errorCode, message: errorMessage } : {}),\n\t\t\ttimeoutMs: resolvedTimeoutMs,\n\t\t\t...(callsSnapshot.length > 0 ? { calls: callsSnapshot } : {}),\n\t\t\t...guardedMcpDetails(guarded),\n\t\t},\n\t};\n}\n"]}
|