@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,345 @@
|
|
|
1
|
+
import { Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
const plainTheme = { fg: (_name, text) => text };
|
|
3
|
+
const DEFAULT_MAX_CALL_INPUT_CHARS = 1500;
|
|
4
|
+
const DEFAULT_MAX_COMPACT_INPUT_CHARS = 240;
|
|
5
|
+
const DEFAULT_BOXED_COLLAPSED_LINES = 3;
|
|
6
|
+
const DEFAULT_COMPACT_COLLAPSED_LINES = 1;
|
|
7
|
+
const DEFAULT_MAX_COLLAPSED_CHARS = 8000;
|
|
8
|
+
const COLLAPSED_RENDER_CHAR_SLACK = 8;
|
|
9
|
+
class EmptyComponent {
|
|
10
|
+
render() {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
invalidate() { }
|
|
14
|
+
}
|
|
15
|
+
class CompactMcpToolResult {
|
|
16
|
+
rendered = null;
|
|
17
|
+
title;
|
|
18
|
+
inputPreview;
|
|
19
|
+
display;
|
|
20
|
+
theme;
|
|
21
|
+
constructor(title, inputPreview, display, theme) {
|
|
22
|
+
this.title = title;
|
|
23
|
+
this.inputPreview = inputPreview;
|
|
24
|
+
this.display = display;
|
|
25
|
+
this.theme = theme;
|
|
26
|
+
}
|
|
27
|
+
render(width) {
|
|
28
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
29
|
+
if (this.rendered?.width === safeWidth)
|
|
30
|
+
return this.rendered.lines;
|
|
31
|
+
const resultLines = this.display.lines.filter((line, index, lines) => {
|
|
32
|
+
return !(this.display.truncated && index === lines.length - 1 && line === "…");
|
|
33
|
+
});
|
|
34
|
+
const lines = resultLines.length > 0 ? resultLines : [""];
|
|
35
|
+
const bodies = lines.map((line, index) => {
|
|
36
|
+
const prefix = index === 0 ? this.renderPrefix(safeWidth) : "";
|
|
37
|
+
return `${prefix}${this.theme.fg("toolOutput", line)}`;
|
|
38
|
+
});
|
|
39
|
+
const hiddenText = this.display.truncated || bodies.some((body) => visibleWidth(body) > safeWidth);
|
|
40
|
+
const rendered = bodies.map((body, index) => {
|
|
41
|
+
const suffix = hiddenText && index === bodies.length - 1 ? " … (Ctrl+O to expand)" : "";
|
|
42
|
+
if (!suffix)
|
|
43
|
+
return truncateToWidth(body, safeWidth, "…");
|
|
44
|
+
if (safeWidth >= suffix.length + 20) {
|
|
45
|
+
return `${truncateToWidth(body, safeWidth - suffix.length, "…")}${this.theme.fg("muted", suffix)}`;
|
|
46
|
+
}
|
|
47
|
+
const shortSuffix = " (Ctrl+O)";
|
|
48
|
+
if (safeWidth >= shortSuffix.length + 5) {
|
|
49
|
+
return `${truncateToWidth(body, safeWidth - shortSuffix.length, "…")}${this.theme.fg("muted", shortSuffix)}`;
|
|
50
|
+
}
|
|
51
|
+
return truncateToWidth(this.theme.fg("muted", shortSuffix.trim()), safeWidth, "…");
|
|
52
|
+
});
|
|
53
|
+
this.rendered = { width: safeWidth, lines: rendered };
|
|
54
|
+
return rendered;
|
|
55
|
+
}
|
|
56
|
+
invalidate() {
|
|
57
|
+
this.rendered = null;
|
|
58
|
+
}
|
|
59
|
+
renderPrefix(width) {
|
|
60
|
+
if (!this.title)
|
|
61
|
+
return "";
|
|
62
|
+
const arrow = " → ";
|
|
63
|
+
if (!this.inputPreview)
|
|
64
|
+
return `${this.theme.fg("toolTitle", this.title)}${arrow}`;
|
|
65
|
+
const maxPrefixWidth = Math.max(12, Math.floor(width * 0.55));
|
|
66
|
+
const titleWidth = visibleWidth(this.title);
|
|
67
|
+
const inputWidth = Math.max(0, maxPrefixWidth - titleWidth - 1);
|
|
68
|
+
if (inputWidth <= 3) {
|
|
69
|
+
return `${this.theme.fg("toolTitle", truncateToWidth(this.title, maxPrefixWidth, "…"))}${arrow}`;
|
|
70
|
+
}
|
|
71
|
+
const input = truncateToWidth(this.inputPreview, inputWidth, "…");
|
|
72
|
+
return `${this.theme.fg("toolTitle", this.title)} ${this.theme.fg("muted", input)}${arrow}`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class CollapsibleText {
|
|
76
|
+
fullText;
|
|
77
|
+
footerText;
|
|
78
|
+
collapsedText = null;
|
|
79
|
+
collapsedRender = null;
|
|
80
|
+
text;
|
|
81
|
+
expanded;
|
|
82
|
+
maxCollapsedLines;
|
|
83
|
+
preTruncated;
|
|
84
|
+
constructor(text, expanded, maxCollapsedLines, ellipsis, expandHint, preTruncated = false) {
|
|
85
|
+
this.text = text;
|
|
86
|
+
this.expanded = expanded;
|
|
87
|
+
this.maxCollapsedLines = maxCollapsedLines;
|
|
88
|
+
this.preTruncated = preTruncated;
|
|
89
|
+
this.fullText = new Text(text, 0, 0);
|
|
90
|
+
this.footerText = new Text(`${ellipsis}\n${expandHint}`, 0, 0);
|
|
91
|
+
}
|
|
92
|
+
render(width) {
|
|
93
|
+
if (this.expanded) {
|
|
94
|
+
return this.fullText.render(width);
|
|
95
|
+
}
|
|
96
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
97
|
+
const charBudget = safeWidth * (this.maxCollapsedLines + 1) * COLLAPSED_RENDER_CHAR_SLACK;
|
|
98
|
+
if (!this.collapsedText || this.collapsedText.charBudget !== charBudget) {
|
|
99
|
+
const prefix = this.text.length > charBudget ? this.text.slice(0, charBudget) : this.text;
|
|
100
|
+
this.collapsedText = {
|
|
101
|
+
charBudget,
|
|
102
|
+
fullyIncluded: prefix === this.text,
|
|
103
|
+
text: new Text(prefix, 0, 0),
|
|
104
|
+
};
|
|
105
|
+
this.collapsedRender = null;
|
|
106
|
+
}
|
|
107
|
+
const lines = this.collapsedText.text.render(width);
|
|
108
|
+
if (!this.preTruncated && this.collapsedText.fullyIncluded && lines.length <= this.maxCollapsedLines)
|
|
109
|
+
return lines;
|
|
110
|
+
if (this.collapsedRender?.width === width && this.collapsedRender.charBudget === charBudget) {
|
|
111
|
+
return this.collapsedRender.lines;
|
|
112
|
+
}
|
|
113
|
+
const rendered = [...lines.slice(0, this.maxCollapsedLines), ...this.footerText.render(width)];
|
|
114
|
+
this.collapsedRender = { width, charBudget, lines: rendered };
|
|
115
|
+
return rendered;
|
|
116
|
+
}
|
|
117
|
+
invalidate() {
|
|
118
|
+
this.fullText.invalidate();
|
|
119
|
+
this.footerText.invalidate();
|
|
120
|
+
this.collapsedText?.text.invalidate();
|
|
121
|
+
this.collapsedRender = null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function truncateText(value, maxChars) {
|
|
125
|
+
if (value.length <= maxChars)
|
|
126
|
+
return value;
|
|
127
|
+
return `${value.slice(0, Math.max(0, maxChars - 1))}…`;
|
|
128
|
+
}
|
|
129
|
+
function formatJsonish(value, maxChars) {
|
|
130
|
+
if (typeof value === "string") {
|
|
131
|
+
try {
|
|
132
|
+
return truncateText(JSON.stringify(JSON.parse(value), null, 2), maxChars);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return truncateText(value, maxChars);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
return truncateText(JSON.stringify(value, null, 2), maxChars);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return truncateText(String(value), maxChars);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function hasUsefulObjectContent(value) {
|
|
146
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;
|
|
147
|
+
}
|
|
148
|
+
export function formatMcpProxyToolCallLines(args, maxInputChars = DEFAULT_MAX_CALL_INPUT_CHARS) {
|
|
149
|
+
if (args.action === "ui-messages")
|
|
150
|
+
return [`mcp ${args.action}`];
|
|
151
|
+
if (args.tool) {
|
|
152
|
+
const target = args.server ? `${args.tool} @ ${args.server}` : args.tool;
|
|
153
|
+
const lines = [`mcp call ${target}`];
|
|
154
|
+
if (args.args)
|
|
155
|
+
lines.push(formatJsonish(args.args, maxInputChars));
|
|
156
|
+
return lines;
|
|
157
|
+
}
|
|
158
|
+
if (args.connect)
|
|
159
|
+
return [`mcp connect ${args.connect}`];
|
|
160
|
+
if (args.describe)
|
|
161
|
+
return [`mcp describe ${args.describe}`];
|
|
162
|
+
if (args.search) {
|
|
163
|
+
let line = `mcp search ${args.search}`;
|
|
164
|
+
if (args.server)
|
|
165
|
+
line += ` @ ${args.server}`;
|
|
166
|
+
if (args.regex === true)
|
|
167
|
+
line += " (regex)";
|
|
168
|
+
if (args.includeSchemas === false)
|
|
169
|
+
line += " (schemas hidden)";
|
|
170
|
+
return [line];
|
|
171
|
+
}
|
|
172
|
+
if (args.server)
|
|
173
|
+
return [`mcp list ${args.server}`];
|
|
174
|
+
if (args.action)
|
|
175
|
+
return [`mcp ${args.action}`];
|
|
176
|
+
return ["mcp status"];
|
|
177
|
+
}
|
|
178
|
+
export function formatMcpDirectToolCallLines(displayName, args, maxInputChars = DEFAULT_MAX_CALL_INPUT_CHARS) {
|
|
179
|
+
if (!hasUsefulObjectContent(args))
|
|
180
|
+
return [displayName];
|
|
181
|
+
return [displayName, formatJsonish(args, maxInputChars)];
|
|
182
|
+
}
|
|
183
|
+
function renderToolCallLines(lines, theme) {
|
|
184
|
+
const activeTheme = theme ?? plainTheme;
|
|
185
|
+
const [title = "mcp", ...rest] = lines;
|
|
186
|
+
const styledTitle = activeTheme.fg("toolTitle", activeTheme.bold ? activeTheme.bold(title) : title);
|
|
187
|
+
const styledRest = rest.map((line) => activeTheme.fg("muted", line));
|
|
188
|
+
return new Text([styledTitle, ...styledRest].join("\n"), 0, 0);
|
|
189
|
+
}
|
|
190
|
+
function formatCompactInputPreview(lines, maxChars = DEFAULT_MAX_COMPACT_INPUT_CHARS) {
|
|
191
|
+
return truncateText(lines.slice(1).join(" ").replace(/\s+/g, " ").trim(), maxChars);
|
|
192
|
+
}
|
|
193
|
+
export function resolveMcpToolRenderOptions(settings) {
|
|
194
|
+
const resultRendering = settings?.toolResultRendering === "boxed" ? "boxed" : "compact";
|
|
195
|
+
const collapsedLines = settings?.collapsedResultLines;
|
|
196
|
+
const defaultLines = resultRendering === "boxed" ? DEFAULT_BOXED_COLLAPSED_LINES : DEFAULT_COMPACT_COLLAPSED_LINES;
|
|
197
|
+
return {
|
|
198
|
+
resultRendering,
|
|
199
|
+
collapsedResultLines: collapsedLines === 1 || collapsedLines === 2 || collapsedLines === 3 ? collapsedLines : defaultLines,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function shouldUseCompactFinalRender(options, context) {
|
|
203
|
+
return (options.resultRendering === "compact" &&
|
|
204
|
+
context !== undefined &&
|
|
205
|
+
context.isPartial === false &&
|
|
206
|
+
context.expanded !== true &&
|
|
207
|
+
context.isError !== true);
|
|
208
|
+
}
|
|
209
|
+
function renderToolCall(lines, theme, context, options) {
|
|
210
|
+
if (context?.state) {
|
|
211
|
+
context.state.compactTitle = lines[0] ?? "mcp";
|
|
212
|
+
context.state.compactInputPreview = formatCompactInputPreview(lines);
|
|
213
|
+
}
|
|
214
|
+
if (shouldUseCompactFinalRender(options, context))
|
|
215
|
+
return new EmptyComponent();
|
|
216
|
+
return renderToolCallLines(lines, theme);
|
|
217
|
+
}
|
|
218
|
+
export function renderMcpProxyToolCall(args, theme, context) {
|
|
219
|
+
return renderToolCall(formatMcpProxyToolCallLines(args), theme, context, resolveMcpToolRenderOptions());
|
|
220
|
+
}
|
|
221
|
+
export function createMcpProxyToolCallRenderer(options) {
|
|
222
|
+
return (args, theme, context) => {
|
|
223
|
+
return renderToolCall(formatMcpProxyToolCallLines(args), theme, context, options);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
export function createMcpDirectToolCallRenderer(displayName, options = resolveMcpToolRenderOptions()) {
|
|
227
|
+
return (args, theme, context) => {
|
|
228
|
+
return renderToolCall(formatMcpDirectToolCallLines(displayName, args), theme, context, options);
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function blockToLines(block) {
|
|
232
|
+
if (block.type === "text") {
|
|
233
|
+
return block.text.split("\n");
|
|
234
|
+
}
|
|
235
|
+
return [`[image: ${block.mimeType}]`];
|
|
236
|
+
}
|
|
237
|
+
function collectCollapsedResultLines(content, maxLines, maxChars) {
|
|
238
|
+
if (content.length === 0)
|
|
239
|
+
return { lines: ["(empty result)"], truncated: false };
|
|
240
|
+
const lines = [];
|
|
241
|
+
let remainingChars = maxChars;
|
|
242
|
+
let truncated = false;
|
|
243
|
+
const appendLine = (line) => {
|
|
244
|
+
if (lines.length === 0) {
|
|
245
|
+
const previewWidth = Math.min(line.length, remainingChars);
|
|
246
|
+
if (line.slice(0, previewWidth).trim() === "") {
|
|
247
|
+
if (line.length >= remainingChars) {
|
|
248
|
+
truncated = true;
|
|
249
|
+
remainingChars = 0;
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
remainingChars -= line.length + 1;
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (lines.length >= maxLines || remainingChars <= 0) {
|
|
257
|
+
truncated = true;
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
if (line.length > remainingChars) {
|
|
261
|
+
lines.push(line.slice(0, remainingChars));
|
|
262
|
+
truncated = true;
|
|
263
|
+
remainingChars = 0;
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
lines.push(line);
|
|
267
|
+
remainingChars -= line.length + 1;
|
|
268
|
+
return true;
|
|
269
|
+
};
|
|
270
|
+
for (const block of content) {
|
|
271
|
+
if (block.type !== "text") {
|
|
272
|
+
if (!appendLine(`[image: ${block.mimeType}]`))
|
|
273
|
+
break;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
let start = 0;
|
|
277
|
+
while (start <= block.text.length) {
|
|
278
|
+
const newline = block.text.indexOf("\n", start);
|
|
279
|
+
const line = newline === -1 ? block.text.slice(start) : block.text.slice(start, newline);
|
|
280
|
+
if (!appendLine(line))
|
|
281
|
+
break;
|
|
282
|
+
if (newline === -1)
|
|
283
|
+
break;
|
|
284
|
+
start = newline + 1;
|
|
285
|
+
}
|
|
286
|
+
if (truncated)
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
if (lines.length === 0)
|
|
290
|
+
lines.push(truncated ? "(leading blank output omitted)" : "");
|
|
291
|
+
if (truncated && lines.length >= maxLines)
|
|
292
|
+
lines.push("…");
|
|
293
|
+
return { lines, truncated };
|
|
294
|
+
}
|
|
295
|
+
export function formatMcpToolResultIdentity(details) {
|
|
296
|
+
if (details?.mode !== "call")
|
|
297
|
+
return null;
|
|
298
|
+
const server = typeof details.server === "string"
|
|
299
|
+
? details.server
|
|
300
|
+
: typeof details.hintServer === "string"
|
|
301
|
+
? details.hintServer
|
|
302
|
+
: null;
|
|
303
|
+
if (!server)
|
|
304
|
+
return null;
|
|
305
|
+
if (typeof details.tool === "string")
|
|
306
|
+
return `MCP ${server}/${details.tool}`;
|
|
307
|
+
if (typeof details.resourceUri === "string")
|
|
308
|
+
return `MCP ${server} resource ${details.resourceUri}`;
|
|
309
|
+
if (typeof details.requestedTool === "string")
|
|
310
|
+
return `MCP ${server}/${details.requestedTool}`;
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
export function formatMcpToolResultLines(result, expanded, maxCollapsedLines = DEFAULT_BOXED_COLLAPSED_LINES, maxCollapsedChars = DEFAULT_MAX_COLLAPSED_CHARS) {
|
|
314
|
+
if (!expanded) {
|
|
315
|
+
return collectCollapsedResultLines(result.content, maxCollapsedLines, maxCollapsedChars);
|
|
316
|
+
}
|
|
317
|
+
const allLines = result.content.flatMap(blockToLines);
|
|
318
|
+
const lines = allLines.length > 0 ? allLines : ["(empty result)"];
|
|
319
|
+
return { lines, truncated: false };
|
|
320
|
+
}
|
|
321
|
+
export function renderMcpToolResult(result, options, theme, context, renderOptions = resolveMcpToolRenderOptions()) {
|
|
322
|
+
const activeTheme = theme ?? plainTheme;
|
|
323
|
+
if (options.isPartial) {
|
|
324
|
+
return new Text(activeTheme.fg("warning", "Running MCP tool..."), 0, 0);
|
|
325
|
+
}
|
|
326
|
+
const hasErrorDetails = Boolean(result.details.error);
|
|
327
|
+
const expanded = options.expanded || context?.isError === true || hasErrorDetails;
|
|
328
|
+
if (!expanded && renderOptions.resultRendering === "compact") {
|
|
329
|
+
const display = formatMcpToolResultLines(result, false, renderOptions.collapsedResultLines);
|
|
330
|
+
const title = context?.state?.compactTitle ?? formatMcpToolResultIdentity(result.details) ?? "";
|
|
331
|
+
const inputPreview = context?.state?.compactInputPreview ?? "";
|
|
332
|
+
return new CompactMcpToolResult(title, inputPreview, display, activeTheme);
|
|
333
|
+
}
|
|
334
|
+
const display = formatMcpToolResultLines(result, expanded, renderOptions.collapsedResultLines);
|
|
335
|
+
const identity = formatMcpToolResultIdentity(result.details);
|
|
336
|
+
const output = [
|
|
337
|
+
...(identity ? [activeTheme.fg("muted", identity)] : []),
|
|
338
|
+
...display.lines.map((line) => activeTheme.fg("toolOutput", line)),
|
|
339
|
+
].join("\n");
|
|
340
|
+
return new CollapsibleText(output, expanded, renderOptions.collapsedResultLines + (identity ? 1 : 0), activeTheme.fg("muted", "…"), activeTheme.fg("muted", "(Ctrl+O to expand)"), display.truncated);
|
|
341
|
+
}
|
|
342
|
+
export function createMcpToolResultRenderer(renderOptions) {
|
|
343
|
+
return (result, options, theme, context) => renderMcpToolResult(result, options, theme, context, renderOptions);
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=tool-result-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-renderer.js","sourceRoot":"","sources":["../../../src/extensions/mcp/tool-result-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Text, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { AgentToolResult, ToolRenderResultOptions } from \"../../core/extensions/types.ts\";\n\ntype McpToolResultDetails = Record<string, unknown> & { error?: unknown };\ntype McpToolContentBlock = AgentToolResult<McpToolResultDetails>[\"content\"][number];\n\ninterface RenderTheme {\n\tfg: (name: string, text: string) => string;\n\tbold?: (text: string) => string;\n}\n\nconst plainTheme: RenderTheme = { fg: (_name, text) => text };\n\nexport interface McpProxyToolCallInput {\n\ttool?: string;\n\targs?: string | Record<string, unknown>;\n\tconnect?: string;\n\tdescribe?: string;\n\tsearch?: string;\n\tregex?: boolean;\n\tincludeSchemas?: boolean;\n\tserver?: string;\n\taction?: string;\n}\n\ninterface McpToolRenderState {\n\tcompactTitle?: string;\n\tcompactInputPreview?: string;\n}\n\ninterface McpToolRenderContext {\n\tisError: boolean;\n\tisPartial?: boolean;\n\texpanded?: boolean;\n\tstate?: McpToolRenderState;\n}\n\nexport type McpToolResultRendering = \"compact\" | \"boxed\";\n\nexport interface McpToolRenderOptions {\n\tresultRendering: McpToolResultRendering;\n\tcollapsedResultLines: 1 | 2 | 3;\n}\n\nexport interface McpToolRenderSettings {\n\ttoolResultRendering?: unknown;\n\tcollapsedResultLines?: unknown;\n}\n\nexport interface McpToolResultDisplay {\n\tlines: string[];\n\ttruncated: boolean;\n}\n\nconst DEFAULT_MAX_CALL_INPUT_CHARS = 1500;\nconst DEFAULT_MAX_COMPACT_INPUT_CHARS = 240;\nconst DEFAULT_BOXED_COLLAPSED_LINES = 3;\nconst DEFAULT_COMPACT_COLLAPSED_LINES = 1;\nconst DEFAULT_MAX_COLLAPSED_CHARS = 8000;\nconst COLLAPSED_RENDER_CHAR_SLACK = 8;\n\nclass EmptyComponent implements Component {\n\trender(): string[] {\n\t\treturn [];\n\t}\n\n\tinvalidate(): void {}\n}\n\nclass CompactMcpToolResult implements Component {\n\tprivate rendered: { width: number; lines: string[] } | null = null;\n\tprivate readonly title: string;\n\tprivate readonly inputPreview: string;\n\tprivate readonly display: McpToolResultDisplay;\n\tprivate readonly theme: RenderTheme;\n\n\tconstructor(title: string, inputPreview: string, display: McpToolResultDisplay, theme: RenderTheme) {\n\t\tthis.title = title;\n\t\tthis.inputPreview = inputPreview;\n\t\tthis.display = display;\n\t\tthis.theme = theme;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tif (this.rendered?.width === safeWidth) return this.rendered.lines;\n\n\t\tconst resultLines = this.display.lines.filter((line, index, lines) => {\n\t\t\treturn !(this.display.truncated && index === lines.length - 1 && line === \"…\");\n\t\t});\n\t\tconst lines = resultLines.length > 0 ? resultLines : [\"\"];\n\t\tconst bodies = lines.map((line, index) => {\n\t\t\tconst prefix = index === 0 ? this.renderPrefix(safeWidth) : \"\";\n\t\t\treturn `${prefix}${this.theme.fg(\"toolOutput\", line)}`;\n\t\t});\n\t\tconst hiddenText = this.display.truncated || bodies.some((body) => visibleWidth(body) > safeWidth);\n\t\tconst rendered = bodies.map((body, index) => {\n\t\t\tconst suffix = hiddenText && index === bodies.length - 1 ? \" … (Ctrl+O to expand)\" : \"\";\n\t\t\tif (!suffix) return truncateToWidth(body, safeWidth, \"…\");\n\t\t\tif (safeWidth >= suffix.length + 20) {\n\t\t\t\treturn `${truncateToWidth(body, safeWidth - suffix.length, \"…\")}${this.theme.fg(\"muted\", suffix)}`;\n\t\t\t}\n\t\t\tconst shortSuffix = \" (Ctrl+O)\";\n\t\t\tif (safeWidth >= shortSuffix.length + 5) {\n\t\t\t\treturn `${truncateToWidth(body, safeWidth - shortSuffix.length, \"…\")}${this.theme.fg(\"muted\", shortSuffix)}`;\n\t\t\t}\n\t\t\treturn truncateToWidth(this.theme.fg(\"muted\", shortSuffix.trim()), safeWidth, \"…\");\n\t\t});\n\t\tthis.rendered = { width: safeWidth, lines: rendered };\n\t\treturn rendered;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.rendered = null;\n\t}\n\n\tprivate renderPrefix(width: number): string {\n\t\tif (!this.title) return \"\";\n\t\tconst arrow = \" → \";\n\t\tif (!this.inputPreview) return `${this.theme.fg(\"toolTitle\", this.title)}${arrow}`;\n\n\t\tconst maxPrefixWidth = Math.max(12, Math.floor(width * 0.55));\n\t\tconst titleWidth = visibleWidth(this.title);\n\t\tconst inputWidth = Math.max(0, maxPrefixWidth - titleWidth - 1);\n\t\tif (inputWidth <= 3) {\n\t\t\treturn `${this.theme.fg(\"toolTitle\", truncateToWidth(this.title, maxPrefixWidth, \"…\"))}${arrow}`;\n\t\t}\n\n\t\tconst input = truncateToWidth(this.inputPreview, inputWidth, \"…\");\n\t\treturn `${this.theme.fg(\"toolTitle\", this.title)} ${this.theme.fg(\"muted\", input)}${arrow}`;\n\t}\n}\n\nclass CollapsibleText implements Component {\n\tprivate readonly fullText: Text;\n\tprivate readonly footerText: Text;\n\tprivate collapsedText: { charBudget: number; fullyIncluded: boolean; text: Text } | null = null;\n\tprivate collapsedRender: { width: number; charBudget: number; lines: string[] } | null = null;\n\tprivate readonly text: string;\n\tprivate readonly expanded: boolean;\n\tprivate readonly maxCollapsedLines: number;\n\tprivate readonly preTruncated: boolean;\n\n\tconstructor(\n\t\ttext: string,\n\t\texpanded: boolean,\n\t\tmaxCollapsedLines: number,\n\t\tellipsis: string,\n\t\texpandHint: string,\n\t\tpreTruncated = false,\n\t) {\n\t\tthis.text = text;\n\t\tthis.expanded = expanded;\n\t\tthis.maxCollapsedLines = maxCollapsedLines;\n\t\tthis.preTruncated = preTruncated;\n\t\tthis.fullText = new Text(text, 0, 0);\n\t\tthis.footerText = new Text(`${ellipsis}\\n${expandHint}`, 0, 0);\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.expanded) {\n\t\t\treturn this.fullText.render(width);\n\t\t}\n\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tconst charBudget = safeWidth * (this.maxCollapsedLines + 1) * COLLAPSED_RENDER_CHAR_SLACK;\n\t\tif (!this.collapsedText || this.collapsedText.charBudget !== charBudget) {\n\t\t\tconst prefix = this.text.length > charBudget ? this.text.slice(0, charBudget) : this.text;\n\t\t\tthis.collapsedText = {\n\t\t\t\tcharBudget,\n\t\t\t\tfullyIncluded: prefix === this.text,\n\t\t\t\ttext: new Text(prefix, 0, 0),\n\t\t\t};\n\t\t\tthis.collapsedRender = null;\n\t\t}\n\n\t\tconst lines = this.collapsedText.text.render(width);\n\t\tif (!this.preTruncated && this.collapsedText.fullyIncluded && lines.length <= this.maxCollapsedLines)\n\t\t\treturn lines;\n\t\tif (this.collapsedRender?.width === width && this.collapsedRender.charBudget === charBudget) {\n\t\t\treturn this.collapsedRender.lines;\n\t\t}\n\n\t\tconst rendered = [...lines.slice(0, this.maxCollapsedLines), ...this.footerText.render(width)];\n\t\tthis.collapsedRender = { width, charBudget, lines: rendered };\n\t\treturn rendered;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.fullText.invalidate();\n\t\tthis.footerText.invalidate();\n\t\tthis.collapsedText?.text.invalidate();\n\t\tthis.collapsedRender = null;\n\t}\n}\n\nfunction truncateText(value: string, maxChars: number): string {\n\tif (value.length <= maxChars) return value;\n\treturn `${value.slice(0, Math.max(0, maxChars - 1))}…`;\n}\n\nfunction formatJsonish(value: unknown, maxChars: number): string {\n\tif (typeof value === \"string\") {\n\t\ttry {\n\t\t\treturn truncateText(JSON.stringify(JSON.parse(value), null, 2), maxChars);\n\t\t} catch {\n\t\t\treturn truncateText(value, maxChars);\n\t\t}\n\t}\n\n\ttry {\n\t\treturn truncateText(JSON.stringify(value, null, 2), maxChars);\n\t} catch {\n\t\treturn truncateText(String(value), maxChars);\n\t}\n}\n\nfunction hasUsefulObjectContent(value: unknown): boolean {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;\n}\n\nexport function formatMcpProxyToolCallLines(\n\targs: McpProxyToolCallInput,\n\tmaxInputChars = DEFAULT_MAX_CALL_INPUT_CHARS,\n): string[] {\n\tif (args.action === \"ui-messages\") return [`mcp ${args.action}`];\n\n\tif (args.tool) {\n\t\tconst target = args.server ? `${args.tool} @ ${args.server}` : args.tool;\n\t\tconst lines = [`mcp call ${target}`];\n\t\tif (args.args) lines.push(formatJsonish(args.args, maxInputChars));\n\t\treturn lines;\n\t}\n\n\tif (args.connect) return [`mcp connect ${args.connect}`];\n\tif (args.describe) return [`mcp describe ${args.describe}`];\n\n\tif (args.search) {\n\t\tlet line = `mcp search ${args.search}`;\n\t\tif (args.server) line += ` @ ${args.server}`;\n\t\tif (args.regex === true) line += \" (regex)\";\n\t\tif (args.includeSchemas === false) line += \" (schemas hidden)\";\n\t\treturn [line];\n\t}\n\n\tif (args.server) return [`mcp list ${args.server}`];\n\tif (args.action) return [`mcp ${args.action}`];\n\n\treturn [\"mcp status\"];\n}\n\nexport function formatMcpDirectToolCallLines(\n\tdisplayName: string,\n\targs: Record<string, unknown>,\n\tmaxInputChars = DEFAULT_MAX_CALL_INPUT_CHARS,\n): string[] {\n\tif (!hasUsefulObjectContent(args)) return [displayName];\n\treturn [displayName, formatJsonish(args, maxInputChars)];\n}\n\nfunction renderToolCallLines(lines: string[], theme?: RenderTheme) {\n\tconst activeTheme = theme ?? plainTheme;\n\tconst [title = \"mcp\", ...rest] = lines;\n\tconst styledTitle = activeTheme.fg(\"toolTitle\", activeTheme.bold ? activeTheme.bold(title) : title);\n\tconst styledRest = rest.map((line) => activeTheme.fg(\"muted\", line));\n\treturn new Text([styledTitle, ...styledRest].join(\"\\n\"), 0, 0);\n}\n\nfunction formatCompactInputPreview(lines: string[], maxChars = DEFAULT_MAX_COMPACT_INPUT_CHARS): string {\n\treturn truncateText(lines.slice(1).join(\" \").replace(/\\s+/g, \" \").trim(), maxChars);\n}\n\nexport function resolveMcpToolRenderOptions(settings?: McpToolRenderSettings): McpToolRenderOptions {\n\tconst resultRendering = settings?.toolResultRendering === \"boxed\" ? \"boxed\" : \"compact\";\n\tconst collapsedLines = settings?.collapsedResultLines;\n\tconst defaultLines = resultRendering === \"boxed\" ? DEFAULT_BOXED_COLLAPSED_LINES : DEFAULT_COMPACT_COLLAPSED_LINES;\n\treturn {\n\t\tresultRendering,\n\t\tcollapsedResultLines:\n\t\t\tcollapsedLines === 1 || collapsedLines === 2 || collapsedLines === 3 ? collapsedLines : defaultLines,\n\t};\n}\n\nfunction shouldUseCompactFinalRender(options: McpToolRenderOptions, context?: McpToolRenderContext): boolean {\n\treturn (\n\t\toptions.resultRendering === \"compact\" &&\n\t\tcontext !== undefined &&\n\t\tcontext.isPartial === false &&\n\t\tcontext.expanded !== true &&\n\t\tcontext.isError !== true\n\t);\n}\n\nfunction renderToolCall(\n\tlines: string[],\n\ttheme: RenderTheme | undefined,\n\tcontext: McpToolRenderContext | undefined,\n\toptions: McpToolRenderOptions,\n) {\n\tif (context?.state) {\n\t\tcontext.state.compactTitle = lines[0] ?? \"mcp\";\n\t\tcontext.state.compactInputPreview = formatCompactInputPreview(lines);\n\t}\n\tif (shouldUseCompactFinalRender(options, context)) return new EmptyComponent();\n\treturn renderToolCallLines(lines, theme);\n}\n\nexport function renderMcpProxyToolCall(\n\targs: McpProxyToolCallInput,\n\ttheme?: RenderTheme,\n\tcontext?: McpToolRenderContext,\n) {\n\treturn renderToolCall(formatMcpProxyToolCallLines(args), theme, context, resolveMcpToolRenderOptions());\n}\n\nexport function createMcpProxyToolCallRenderer(options: McpToolRenderOptions) {\n\treturn (args: McpProxyToolCallInput, theme?: RenderTheme, context?: McpToolRenderContext) => {\n\t\treturn renderToolCall(formatMcpProxyToolCallLines(args), theme, context, options);\n\t};\n}\n\nexport function createMcpDirectToolCallRenderer(displayName: string, options = resolveMcpToolRenderOptions()) {\n\treturn (args: Record<string, unknown>, theme?: RenderTheme, context?: McpToolRenderContext) => {\n\t\treturn renderToolCall(formatMcpDirectToolCallLines(displayName, args), theme, context, options);\n\t};\n}\n\nfunction blockToLines(block: McpToolContentBlock): string[] {\n\tif (block.type === \"text\") {\n\t\treturn block.text.split(\"\\n\");\n\t}\n\treturn [`[image: ${block.mimeType}]`];\n}\n\nfunction collectCollapsedResultLines(\n\tcontent: AgentToolResult<McpToolResultDetails>[\"content\"],\n\tmaxLines: number,\n\tmaxChars: number,\n): McpToolResultDisplay {\n\tif (content.length === 0) return { lines: [\"(empty result)\"], truncated: false };\n\n\tconst lines: string[] = [];\n\tlet remainingChars = maxChars;\n\tlet truncated = false;\n\n\tconst appendLine = (line: string) => {\n\t\tif (lines.length === 0) {\n\t\t\tconst previewWidth = Math.min(line.length, remainingChars);\n\t\t\tif (line.slice(0, previewWidth).trim() === \"\") {\n\t\t\t\tif (line.length >= remainingChars) {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t\tremainingChars = 0;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tremainingChars -= line.length + 1;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tif (lines.length >= maxLines || remainingChars <= 0) {\n\t\t\ttruncated = true;\n\t\t\treturn false;\n\t\t}\n\n\t\tif (line.length > remainingChars) {\n\t\t\tlines.push(line.slice(0, remainingChars));\n\t\t\ttruncated = true;\n\t\t\tremainingChars = 0;\n\t\t\treturn false;\n\t\t}\n\n\t\tlines.push(line);\n\t\tremainingChars -= line.length + 1;\n\t\treturn true;\n\t};\n\n\tfor (const block of content) {\n\t\tif (block.type !== \"text\") {\n\t\t\tif (!appendLine(`[image: ${block.mimeType}]`)) break;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet start = 0;\n\t\twhile (start <= block.text.length) {\n\t\t\tconst newline = block.text.indexOf(\"\\n\", start);\n\t\t\tconst line = newline === -1 ? block.text.slice(start) : block.text.slice(start, newline);\n\t\t\tif (!appendLine(line)) break;\n\t\t\tif (newline === -1) break;\n\t\t\tstart = newline + 1;\n\t\t}\n\n\t\tif (truncated) break;\n\t}\n\n\tif (lines.length === 0) lines.push(truncated ? \"(leading blank output omitted)\" : \"\");\n\tif (truncated && lines.length >= maxLines) lines.push(\"…\");\n\treturn { lines, truncated };\n}\n\nexport function formatMcpToolResultIdentity(details: McpToolResultDetails | undefined): string | null {\n\tif (details?.mode !== \"call\") return null;\n\tconst server =\n\t\ttypeof details.server === \"string\"\n\t\t\t? details.server\n\t\t\t: typeof details.hintServer === \"string\"\n\t\t\t\t? details.hintServer\n\t\t\t\t: null;\n\tif (!server) return null;\n\tif (typeof details.tool === \"string\") return `MCP ${server}/${details.tool}`;\n\tif (typeof details.resourceUri === \"string\") return `MCP ${server} resource ${details.resourceUri}`;\n\tif (typeof details.requestedTool === \"string\") return `MCP ${server}/${details.requestedTool}`;\n\treturn null;\n}\n\nexport function formatMcpToolResultLines(\n\tresult: Pick<AgentToolResult<McpToolResultDetails>, \"content\">,\n\texpanded: boolean,\n\tmaxCollapsedLines = DEFAULT_BOXED_COLLAPSED_LINES,\n\tmaxCollapsedChars = DEFAULT_MAX_COLLAPSED_CHARS,\n): McpToolResultDisplay {\n\tif (!expanded) {\n\t\treturn collectCollapsedResultLines(result.content, maxCollapsedLines, maxCollapsedChars);\n\t}\n\n\tconst allLines = result.content.flatMap(blockToLines);\n\tconst lines = allLines.length > 0 ? allLines : [\"(empty result)\"];\n\treturn { lines, truncated: false };\n}\n\nexport function renderMcpToolResult(\n\tresult: AgentToolResult<McpToolResultDetails>,\n\toptions: ToolRenderResultOptions,\n\ttheme?: RenderTheme,\n\tcontext?: McpToolRenderContext,\n\trenderOptions = resolveMcpToolRenderOptions(),\n) {\n\tconst activeTheme = theme ?? plainTheme;\n\tif (options.isPartial) {\n\t\treturn new Text(activeTheme.fg(\"warning\", \"Running MCP tool...\"), 0, 0);\n\t}\n\n\tconst hasErrorDetails = Boolean(result.details.error);\n\tconst expanded = options.expanded || context?.isError === true || hasErrorDetails;\n\tif (!expanded && renderOptions.resultRendering === \"compact\") {\n\t\tconst display = formatMcpToolResultLines(result, false, renderOptions.collapsedResultLines);\n\t\tconst title = context?.state?.compactTitle ?? formatMcpToolResultIdentity(result.details) ?? \"\";\n\t\tconst inputPreview = context?.state?.compactInputPreview ?? \"\";\n\t\treturn new CompactMcpToolResult(title, inputPreview, display, activeTheme);\n\t}\n\n\tconst display = formatMcpToolResultLines(result, expanded, renderOptions.collapsedResultLines);\n\tconst identity = formatMcpToolResultIdentity(result.details);\n\tconst output = [\n\t\t...(identity ? [activeTheme.fg(\"muted\", identity)] : []),\n\t\t...display.lines.map((line) => activeTheme.fg(\"toolOutput\", line)),\n\t].join(\"\\n\");\n\n\treturn new CollapsibleText(\n\t\toutput,\n\t\texpanded,\n\t\trenderOptions.collapsedResultLines + (identity ? 1 : 0),\n\t\tactiveTheme.fg(\"muted\", \"…\"),\n\t\tactiveTheme.fg(\"muted\", \"(Ctrl+O to expand)\"),\n\t\tdisplay.truncated,\n\t);\n}\n\nexport function createMcpToolResultRenderer(renderOptions: McpToolRenderOptions) {\n\treturn (\n\t\tresult: AgentToolResult<McpToolResultDetails>,\n\t\toptions: ToolRenderResultOptions,\n\t\ttheme?: RenderTheme,\n\t\tcontext?: McpToolRenderContext,\n\t) => renderMcpToolResult(result, options, theme, context, renderOptions);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts-shape.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/ts-shape.ts"],"names":[],"mappings":"AAIA,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAuGjE","sourcesContent":["type Schema = Record<string, unknown>;\n\nconst UNSUPPORTED_KEYWORDS = [\"if\", \"then\", \"else\", \"allOf\", \"not\", \"patternProperties\", \"additionalProperties\"];\n\n/** Renders the useful JSON Schema subset as TypeScript, or null for unsupported schemas. */\nexport function renderTsShape(inputSchema: unknown): string | null {\n\ttry {\n\t\tif (!isSchema(inputSchema)) return null;\n\n\t\tconst definitions = new Map<string, Schema>();\n\t\tfor (const key of [\"$defs\", \"definitions\"]) {\n\t\t\tconst rawDefinitions = inputSchema[key];\n\t\t\tif (rawDefinitions === undefined) continue;\n\t\t\tif (!isSchema(rawDefinitions)) return null;\n\t\t\tfor (const [name, definition] of Object.entries(rawDefinitions)) {\n\t\t\t\tif (!isSchema(definition)) return null;\n\t\t\t\tdefinitions.set(`${key}/${decodePointerToken(name)}`, definition);\n\t\t\t}\n\t\t}\n\n\t\tconst aliases = new Map<string, string>();\n\t\tconst usedAliases = new Set<string>();\n\t\tlet aliasIndex = 0;\n\t\tconst aliasFor = (definitionKey: string) => {\n\t\t\tlet alias = aliases.get(definitionKey);\n\t\t\tif (alias) return alias;\n\t\t\tconst name = definitionKey.slice(definitionKey.indexOf(\"/\") + 1);\n\t\t\talias = /^[A-Za-z_$][\\w$]*$/.test(name) && !usedAliases.has(name) ? name : `Definition${++aliasIndex}`;\n\t\t\twhile (usedAliases.has(alias)) alias = `Definition${++aliasIndex}`;\n\t\t\taliases.set(definitionKey, alias);\n\t\t\tusedAliases.add(alias);\n\t\t\treturn alias;\n\t\t};\n\n\t\tconst render = (schema: unknown): string | null => {\n\t\t\tif (!isSchema(schema) || hasUnsupportedKeyword(schema)) return null;\n\n\t\t\tif (\"$ref\" in schema) {\n\t\t\t\tif (typeof schema.$ref !== \"string\") return null;\n\t\t\t\tconst match = schema.$ref.match(/^#\\/(\\$defs|definitions)\\/([^/]+)$/);\n\t\t\t\tif (!match) return null;\n\t\t\t\tconst definitionGroup = match[1];\n\t\t\t\tconst definitionName = match[2];\n\t\t\t\tif (definitionGroup === undefined || definitionName === undefined) return null;\n\t\t\t\tconst definitionKey = `${definitionGroup}/${decodePointerToken(definitionName)}`;\n\t\t\t\tif (!definitions.has(definitionKey)) return null;\n\t\t\t\treturn aliasFor(definitionKey);\n\t\t\t}\n\n\t\t\tif (Array.isArray(schema.enum)) {\n\t\t\t\tconst values = schema.enum.map(renderLiteral);\n\t\t\t\treturn values.every((value): value is string => value !== null) ? values.join(\" | \") : null;\n\t\t\t}\n\t\t\tif (Object.hasOwn(schema, \"const\")) return renderLiteral(schema.const);\n\n\t\t\tif (Array.isArray(schema.anyOf) || Array.isArray(schema.oneOf)) {\n\t\t\t\tconst variants = (schema.anyOf ?? schema.oneOf) as unknown[];\n\t\t\t\tif (variants.length === 0) return null;\n\t\t\t\tconst rendered = variants.map(render);\n\t\t\t\treturn rendered.every((value): value is string => value !== null) ? rendered.join(\" | \") : null;\n\t\t\t}\n\n\t\t\tif (schema.type === \"object\" || schema.properties !== undefined) {\n\t\t\t\tif (schema.properties === undefined) return \"{}\";\n\t\t\t\tif (!isSchema(schema.properties)) return null;\n\t\t\t\tconst required = new Set(\n\t\t\t\t\tArray.isArray(schema.required)\n\t\t\t\t\t\t? schema.required.filter((name): name is string => typeof name === \"string\")\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\tconst properties: string[] = [];\n\t\t\t\tfor (const [name, property] of Object.entries(schema.properties)) {\n\t\t\t\t\tconst rendered = render(property);\n\t\t\t\t\tif (rendered === null) return null;\n\t\t\t\t\tproperties.push(`${formatPropertyName(name)}${required.has(name) ? \"\" : \"?\"}: ${rendered};`);\n\t\t\t\t}\n\t\t\t\treturn properties.length === 0 ? \"{}\" : `{ ${properties.join(\" \")} }`;\n\t\t\t}\n\n\t\t\tif (schema.type === \"array\") {\n\t\t\t\tif (schema.items === undefined) return \"unknown[]\";\n\t\t\t\tconst item = render(schema.items);\n\t\t\t\treturn item === null ? null : `${needsParentheses(item) ? `(${item})` : item}[]`;\n\t\t\t}\n\n\t\t\tif (Array.isArray(schema.type)) {\n\t\t\t\tconst types = schema.type.map(renderType);\n\t\t\t\treturn types.every((type): type is string => type !== null) ? types.join(\" | \") : null;\n\t\t\t}\n\t\t\tif (typeof schema.type === \"string\") return renderType(schema.type);\n\t\t\treturn \"unknown\";\n\t\t};\n\n\t\tconst root = render(inputSchema);\n\t\tif (root === null) return null;\n\n\t\tconst definitionsText: string[] = [];\n\t\tfor (const [key, alias] of aliases) {\n\t\t\tconst definition = definitions.get(key);\n\t\t\tif (!definition) return null;\n\t\t\tconst rendered = render(definition);\n\t\t\tif (rendered === null) return null;\n\t\t\tdefinitionsText.push(`type ${alias} = ${rendered};`);\n\t\t}\n\t\treturn definitionsText.length > 0 ? `${definitionsText.join(\"\\n\")}\\n\\n${root}` : root;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction isSchema(value: unknown): value is Schema {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasUnsupportedKeyword(schema: Schema): boolean {\n\treturn UNSUPPORTED_KEYWORDS.some((keyword) => {\n\t\tif (!Object.hasOwn(schema, keyword)) return false;\n\t\t// `additionalProperties: false` is a closed-object constraint, not a shape that this renderer needs to understand.\n\t\treturn keyword !== \"additionalProperties\" || schema.additionalProperties !== false;\n\t});\n}\n\nfunction decodePointerToken(token: string): string {\n\treturn token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\nfunction renderType(type: unknown): string | null {\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"object\":\n\t\t\treturn \"{}\";\n\t\tcase \"array\":\n\t\t\treturn \"unknown[]\";\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction renderLiteral(value: unknown): string | null {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return JSON.stringify(value);\n\treturn typeof value === \"number\" && Number.isFinite(value) ? String(value) : null;\n}\n\nfunction formatPropertyName(name: string): string {\n\treturn /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction needsParentheses(type: string): boolean {\n\treturn type.includes(\" | \");\n}\n"]}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
const UNSUPPORTED_KEYWORDS = ["if", "then", "else", "allOf", "not", "patternProperties", "additionalProperties"];
|
|
2
|
+
/** Renders the useful JSON Schema subset as TypeScript, or null for unsupported schemas. */
|
|
3
|
+
export function renderTsShape(inputSchema) {
|
|
4
|
+
try {
|
|
5
|
+
if (!isSchema(inputSchema))
|
|
6
|
+
return null;
|
|
7
|
+
const definitions = new Map();
|
|
8
|
+
for (const key of ["$defs", "definitions"]) {
|
|
9
|
+
const rawDefinitions = inputSchema[key];
|
|
10
|
+
if (rawDefinitions === undefined)
|
|
11
|
+
continue;
|
|
12
|
+
if (!isSchema(rawDefinitions))
|
|
13
|
+
return null;
|
|
14
|
+
for (const [name, definition] of Object.entries(rawDefinitions)) {
|
|
15
|
+
if (!isSchema(definition))
|
|
16
|
+
return null;
|
|
17
|
+
definitions.set(`${key}/${decodePointerToken(name)}`, definition);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const aliases = new Map();
|
|
21
|
+
const usedAliases = new Set();
|
|
22
|
+
let aliasIndex = 0;
|
|
23
|
+
const aliasFor = (definitionKey) => {
|
|
24
|
+
let alias = aliases.get(definitionKey);
|
|
25
|
+
if (alias)
|
|
26
|
+
return alias;
|
|
27
|
+
const name = definitionKey.slice(definitionKey.indexOf("/") + 1);
|
|
28
|
+
alias = /^[A-Za-z_$][\w$]*$/.test(name) && !usedAliases.has(name) ? name : `Definition${++aliasIndex}`;
|
|
29
|
+
while (usedAliases.has(alias))
|
|
30
|
+
alias = `Definition${++aliasIndex}`;
|
|
31
|
+
aliases.set(definitionKey, alias);
|
|
32
|
+
usedAliases.add(alias);
|
|
33
|
+
return alias;
|
|
34
|
+
};
|
|
35
|
+
const render = (schema) => {
|
|
36
|
+
if (!isSchema(schema) || hasUnsupportedKeyword(schema))
|
|
37
|
+
return null;
|
|
38
|
+
if ("$ref" in schema) {
|
|
39
|
+
if (typeof schema.$ref !== "string")
|
|
40
|
+
return null;
|
|
41
|
+
const match = schema.$ref.match(/^#\/(\$defs|definitions)\/([^/]+)$/);
|
|
42
|
+
if (!match)
|
|
43
|
+
return null;
|
|
44
|
+
const definitionGroup = match[1];
|
|
45
|
+
const definitionName = match[2];
|
|
46
|
+
if (definitionGroup === undefined || definitionName === undefined)
|
|
47
|
+
return null;
|
|
48
|
+
const definitionKey = `${definitionGroup}/${decodePointerToken(definitionName)}`;
|
|
49
|
+
if (!definitions.has(definitionKey))
|
|
50
|
+
return null;
|
|
51
|
+
return aliasFor(definitionKey);
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(schema.enum)) {
|
|
54
|
+
const values = schema.enum.map(renderLiteral);
|
|
55
|
+
return values.every((value) => value !== null) ? values.join(" | ") : null;
|
|
56
|
+
}
|
|
57
|
+
if (Object.hasOwn(schema, "const"))
|
|
58
|
+
return renderLiteral(schema.const);
|
|
59
|
+
if (Array.isArray(schema.anyOf) || Array.isArray(schema.oneOf)) {
|
|
60
|
+
const variants = (schema.anyOf ?? schema.oneOf);
|
|
61
|
+
if (variants.length === 0)
|
|
62
|
+
return null;
|
|
63
|
+
const rendered = variants.map(render);
|
|
64
|
+
return rendered.every((value) => value !== null) ? rendered.join(" | ") : null;
|
|
65
|
+
}
|
|
66
|
+
if (schema.type === "object" || schema.properties !== undefined) {
|
|
67
|
+
if (schema.properties === undefined)
|
|
68
|
+
return "{}";
|
|
69
|
+
if (!isSchema(schema.properties))
|
|
70
|
+
return null;
|
|
71
|
+
const required = new Set(Array.isArray(schema.required)
|
|
72
|
+
? schema.required.filter((name) => typeof name === "string")
|
|
73
|
+
: []);
|
|
74
|
+
const properties = [];
|
|
75
|
+
for (const [name, property] of Object.entries(schema.properties)) {
|
|
76
|
+
const rendered = render(property);
|
|
77
|
+
if (rendered === null)
|
|
78
|
+
return null;
|
|
79
|
+
properties.push(`${formatPropertyName(name)}${required.has(name) ? "" : "?"}: ${rendered};`);
|
|
80
|
+
}
|
|
81
|
+
return properties.length === 0 ? "{}" : `{ ${properties.join(" ")} }`;
|
|
82
|
+
}
|
|
83
|
+
if (schema.type === "array") {
|
|
84
|
+
if (schema.items === undefined)
|
|
85
|
+
return "unknown[]";
|
|
86
|
+
const item = render(schema.items);
|
|
87
|
+
return item === null ? null : `${needsParentheses(item) ? `(${item})` : item}[]`;
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(schema.type)) {
|
|
90
|
+
const types = schema.type.map(renderType);
|
|
91
|
+
return types.every((type) => type !== null) ? types.join(" | ") : null;
|
|
92
|
+
}
|
|
93
|
+
if (typeof schema.type === "string")
|
|
94
|
+
return renderType(schema.type);
|
|
95
|
+
return "unknown";
|
|
96
|
+
};
|
|
97
|
+
const root = render(inputSchema);
|
|
98
|
+
if (root === null)
|
|
99
|
+
return null;
|
|
100
|
+
const definitionsText = [];
|
|
101
|
+
for (const [key, alias] of aliases) {
|
|
102
|
+
const definition = definitions.get(key);
|
|
103
|
+
if (!definition)
|
|
104
|
+
return null;
|
|
105
|
+
const rendered = render(definition);
|
|
106
|
+
if (rendered === null)
|
|
107
|
+
return null;
|
|
108
|
+
definitionsText.push(`type ${alias} = ${rendered};`);
|
|
109
|
+
}
|
|
110
|
+
return definitionsText.length > 0 ? `${definitionsText.join("\n")}\n\n${root}` : root;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function isSchema(value) {
|
|
117
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
118
|
+
}
|
|
119
|
+
function hasUnsupportedKeyword(schema) {
|
|
120
|
+
return UNSUPPORTED_KEYWORDS.some((keyword) => {
|
|
121
|
+
if (!Object.hasOwn(schema, keyword))
|
|
122
|
+
return false;
|
|
123
|
+
// `additionalProperties: false` is a closed-object constraint, not a shape that this renderer needs to understand.
|
|
124
|
+
return keyword !== "additionalProperties" || schema.additionalProperties !== false;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function decodePointerToken(token) {
|
|
128
|
+
return token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
129
|
+
}
|
|
130
|
+
function renderType(type) {
|
|
131
|
+
switch (type) {
|
|
132
|
+
case "string":
|
|
133
|
+
return "string";
|
|
134
|
+
case "number":
|
|
135
|
+
case "integer":
|
|
136
|
+
return "number";
|
|
137
|
+
case "boolean":
|
|
138
|
+
return "boolean";
|
|
139
|
+
case "null":
|
|
140
|
+
return "null";
|
|
141
|
+
case "object":
|
|
142
|
+
return "{}";
|
|
143
|
+
case "array":
|
|
144
|
+
return "unknown[]";
|
|
145
|
+
default:
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function renderLiteral(value) {
|
|
150
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
151
|
+
return JSON.stringify(value);
|
|
152
|
+
return typeof value === "number" && Number.isFinite(value) ? String(value) : null;
|
|
153
|
+
}
|
|
154
|
+
function formatPropertyName(name) {
|
|
155
|
+
return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
|
|
156
|
+
}
|
|
157
|
+
function needsParentheses(type) {
|
|
158
|
+
return type.includes(" | ");
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=ts-shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts-shape.js","sourceRoot":"","sources":["../../../src/extensions/mcp/ts-shape.ts"],"names":[],"mappings":"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","sourcesContent":["type Schema = Record<string, unknown>;\n\nconst UNSUPPORTED_KEYWORDS = [\"if\", \"then\", \"else\", \"allOf\", \"not\", \"patternProperties\", \"additionalProperties\"];\n\n/** Renders the useful JSON Schema subset as TypeScript, or null for unsupported schemas. */\nexport function renderTsShape(inputSchema: unknown): string | null {\n\ttry {\n\t\tif (!isSchema(inputSchema)) return null;\n\n\t\tconst definitions = new Map<string, Schema>();\n\t\tfor (const key of [\"$defs\", \"definitions\"]) {\n\t\t\tconst rawDefinitions = inputSchema[key];\n\t\t\tif (rawDefinitions === undefined) continue;\n\t\t\tif (!isSchema(rawDefinitions)) return null;\n\t\t\tfor (const [name, definition] of Object.entries(rawDefinitions)) {\n\t\t\t\tif (!isSchema(definition)) return null;\n\t\t\t\tdefinitions.set(`${key}/${decodePointerToken(name)}`, definition);\n\t\t\t}\n\t\t}\n\n\t\tconst aliases = new Map<string, string>();\n\t\tconst usedAliases = new Set<string>();\n\t\tlet aliasIndex = 0;\n\t\tconst aliasFor = (definitionKey: string) => {\n\t\t\tlet alias = aliases.get(definitionKey);\n\t\t\tif (alias) return alias;\n\t\t\tconst name = definitionKey.slice(definitionKey.indexOf(\"/\") + 1);\n\t\t\talias = /^[A-Za-z_$][\\w$]*$/.test(name) && !usedAliases.has(name) ? name : `Definition${++aliasIndex}`;\n\t\t\twhile (usedAliases.has(alias)) alias = `Definition${++aliasIndex}`;\n\t\t\taliases.set(definitionKey, alias);\n\t\t\tusedAliases.add(alias);\n\t\t\treturn alias;\n\t\t};\n\n\t\tconst render = (schema: unknown): string | null => {\n\t\t\tif (!isSchema(schema) || hasUnsupportedKeyword(schema)) return null;\n\n\t\t\tif (\"$ref\" in schema) {\n\t\t\t\tif (typeof schema.$ref !== \"string\") return null;\n\t\t\t\tconst match = schema.$ref.match(/^#\\/(\\$defs|definitions)\\/([^/]+)$/);\n\t\t\t\tif (!match) return null;\n\t\t\t\tconst definitionGroup = match[1];\n\t\t\t\tconst definitionName = match[2];\n\t\t\t\tif (definitionGroup === undefined || definitionName === undefined) return null;\n\t\t\t\tconst definitionKey = `${definitionGroup}/${decodePointerToken(definitionName)}`;\n\t\t\t\tif (!definitions.has(definitionKey)) return null;\n\t\t\t\treturn aliasFor(definitionKey);\n\t\t\t}\n\n\t\t\tif (Array.isArray(schema.enum)) {\n\t\t\t\tconst values = schema.enum.map(renderLiteral);\n\t\t\t\treturn values.every((value): value is string => value !== null) ? values.join(\" | \") : null;\n\t\t\t}\n\t\t\tif (Object.hasOwn(schema, \"const\")) return renderLiteral(schema.const);\n\n\t\t\tif (Array.isArray(schema.anyOf) || Array.isArray(schema.oneOf)) {\n\t\t\t\tconst variants = (schema.anyOf ?? schema.oneOf) as unknown[];\n\t\t\t\tif (variants.length === 0) return null;\n\t\t\t\tconst rendered = variants.map(render);\n\t\t\t\treturn rendered.every((value): value is string => value !== null) ? rendered.join(\" | \") : null;\n\t\t\t}\n\n\t\t\tif (schema.type === \"object\" || schema.properties !== undefined) {\n\t\t\t\tif (schema.properties === undefined) return \"{}\";\n\t\t\t\tif (!isSchema(schema.properties)) return null;\n\t\t\t\tconst required = new Set(\n\t\t\t\t\tArray.isArray(schema.required)\n\t\t\t\t\t\t? schema.required.filter((name): name is string => typeof name === \"string\")\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\tconst properties: string[] = [];\n\t\t\t\tfor (const [name, property] of Object.entries(schema.properties)) {\n\t\t\t\t\tconst rendered = render(property);\n\t\t\t\t\tif (rendered === null) return null;\n\t\t\t\t\tproperties.push(`${formatPropertyName(name)}${required.has(name) ? \"\" : \"?\"}: ${rendered};`);\n\t\t\t\t}\n\t\t\t\treturn properties.length === 0 ? \"{}\" : `{ ${properties.join(\" \")} }`;\n\t\t\t}\n\n\t\t\tif (schema.type === \"array\") {\n\t\t\t\tif (schema.items === undefined) return \"unknown[]\";\n\t\t\t\tconst item = render(schema.items);\n\t\t\t\treturn item === null ? null : `${needsParentheses(item) ? `(${item})` : item}[]`;\n\t\t\t}\n\n\t\t\tif (Array.isArray(schema.type)) {\n\t\t\t\tconst types = schema.type.map(renderType);\n\t\t\t\treturn types.every((type): type is string => type !== null) ? types.join(\" | \") : null;\n\t\t\t}\n\t\t\tif (typeof schema.type === \"string\") return renderType(schema.type);\n\t\t\treturn \"unknown\";\n\t\t};\n\n\t\tconst root = render(inputSchema);\n\t\tif (root === null) return null;\n\n\t\tconst definitionsText: string[] = [];\n\t\tfor (const [key, alias] of aliases) {\n\t\t\tconst definition = definitions.get(key);\n\t\t\tif (!definition) return null;\n\t\t\tconst rendered = render(definition);\n\t\t\tif (rendered === null) return null;\n\t\t\tdefinitionsText.push(`type ${alias} = ${rendered};`);\n\t\t}\n\t\treturn definitionsText.length > 0 ? `${definitionsText.join(\"\\n\")}\\n\\n${root}` : root;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction isSchema(value: unknown): value is Schema {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasUnsupportedKeyword(schema: Schema): boolean {\n\treturn UNSUPPORTED_KEYWORDS.some((keyword) => {\n\t\tif (!Object.hasOwn(schema, keyword)) return false;\n\t\t// `additionalProperties: false` is a closed-object constraint, not a shape that this renderer needs to understand.\n\t\treturn keyword !== \"additionalProperties\" || schema.additionalProperties !== false;\n\t});\n}\n\nfunction decodePointerToken(token: string): string {\n\treturn token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\nfunction renderType(type: unknown): string | null {\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"object\":\n\t\t\treturn \"{}\";\n\t\tcase \"array\":\n\t\t\treturn \"unknown[]\";\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction renderLiteral(value: unknown): string | null {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return JSON.stringify(value);\n\treturn typeof value === \"number\" && Number.isFinite(value) ? String(value) : null;\n}\n\nfunction formatPropertyName(name: string): string {\n\treturn /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction needsParentheses(type: string): boolean {\n\treturn type.includes(\" | \");\n}\n"]}
|