@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-setup-panel.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-setup-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { matchesKey, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { getConfigDirName } from \"./agent-dir.ts\";\nimport {\n\ttype ConfigWritePreview,\n\tKNOWN_SERVER_PRESETS,\n\ttype KnownServerPreset,\n\ttype McpDiscoverySummary,\n} from \"./config.ts\";\nimport type { McpOnboardingState } from \"./onboarding-state.ts\";\nimport { createPanelKeys, type PanelKeybindings, type PanelKeys } from \"./panel-keys.ts\";\nimport type { ImportKind } from \"./types.ts\";\n\ninterface SetupTheme {\n\tborder: string;\n\ttitle: string;\n\tselected: string;\n\thint: string;\n\tsuccess: string;\n\twarning: string;\n\tmuted: string;\n}\n\nconst DEFAULT_THEME: SetupTheme = {\n\tborder: \"2\",\n\ttitle: \"36\",\n\tselected: \"32\",\n\thint: \"2\",\n\tsuccess: \"32\",\n\twarning: \"33\",\n\tmuted: \"2;3\",\n};\n\nconst MIN_PANEL_WIDTH = 24;\nconst COMPACT_WIDTH = 60;\nconst COMPACT_ACTION_ROWS = 7;\nconst DESKTOP_PREVIEW_WIDTH = 74;\n\nfunction fg(code: string, text: string): string {\n\treturn code ? `\\x1b[${code}m${text}\\x1b[0m` : text;\n}\n\nfunction wrapText(text: string, width: number): string[] {\n\tif (width <= 8) return [text];\n\tconst words = text.split(/\\s+/).filter(Boolean);\n\tconst lines: string[] = [];\n\tlet current = \"\";\n\tfor (const word of words) {\n\t\tconst candidate = current ? `${current} ${word}` : word;\n\t\tif (visibleWidth(candidate) <= width) {\n\t\t\tcurrent = candidate;\n\t\t\tcontinue;\n\t\t}\n\t\tif (current) lines.push(current);\n\t\tcurrent = word;\n\t}\n\tif (current) lines.push(current);\n\treturn lines.length > 0 ? lines : [\"\"];\n}\n\nexport interface SetupPanelCallbacks {\n\tpreviewImports: (imports: ImportKind[]) => ConfigWritePreview;\n\tpreviewStarterProject: () => ConfigWritePreview;\n\tpreviewRepoPrompt: () => ConfigWritePreview | null;\n\tpreviewKnownServer: (preset: KnownServerPreset) => ConfigWritePreview;\n\tadoptImports: (imports: ImportKind[]) => Promise<{ added: ImportKind[]; path: string }>;\n\tscaffoldProjectConfig: () => Promise<{ path: string }>;\n\taddRepoPrompt: () => Promise<{ path: string; serverName: string }>;\n\taddKnownServer: (preset: KnownServerPreset) => Promise<{ path: string; serverName: string }>;\n\topenPath: (path: string) => Promise<void>;\n\tmarkSetupCompleted: () => void;\n}\n\nexport interface SetupPanelOptions {\n\tmode: \"empty\" | \"setup\";\n\tonboardingState: McpOnboardingState;\n\tkeybindings?: PanelKeybindings;\n}\n\ntype Screen = \"empty\" | \"setup\" | \"imports\" | \"paths\";\n\ntype ActionId =\n\t| \"run-setup\"\n\t| \"adopt-imports\"\n\t| \"view-example\"\n\t| \"show-precedence\"\n\t| \"open-paths\"\n\t| \"add-repoprompt\"\n\t| \"add-known-server\"\n\t| \"scaffold-project\"\n\t| \"close\";\n\ninterface Action {\n\tid: ActionId;\n\tlabel: string;\n\tdescription: string;\n\tpreset?: KnownServerPreset;\n}\n\nexport class McpSetupPanel {\n\tprivate screen: Screen;\n\tprivate actionCursor = 0;\n\tprivate importCursor = 0;\n\tprivate pathCursor = 0;\n\tprivate selectedImports = new Set<ImportKind>();\n\tprivate busy = false;\n\tprivate notice: { text: string; tone: \"success\" | \"warning\" | \"muted\" } | null = null;\n\tprivate tui: { requestRender(): void };\n\tprivate t = DEFAULT_THEME;\n\tprivate keys: PanelKeys;\n\tprivate inactivityTimeout: ReturnType<typeof setTimeout> | null = null;\n\tprivate discovery: McpDiscoverySummary;\n\tprivate callbacks: SetupPanelCallbacks;\n\tprivate options: SetupPanelOptions;\n\tprivate done: () => void;\n\tprivate static readonly INACTIVITY_MS = 60_000;\n\n\tconstructor(\n\t\tdiscovery: McpDiscoverySummary,\n\t\tcallbacks: SetupPanelCallbacks,\n\t\toptions: SetupPanelOptions,\n\t\ttui: { requestRender(): void },\n\t\tdone: () => void,\n\t) {\n\t\tthis.discovery = discovery;\n\t\tthis.callbacks = callbacks;\n\t\tthis.options = options;\n\t\tthis.done = done;\n\t\tthis.tui = tui;\n\t\tthis.keys = createPanelKeys(options.keybindings);\n\t\tthis.screen = options.mode;\n\t\tfor (const entry of discovery.imports) {\n\t\t\tthis.selectedImports.add(entry.kind);\n\t\t}\n\t\tthis.resetInactivityTimeout();\n\t}\n\n\tprivate resetInactivityTimeout(): void {\n\t\tif (this.inactivityTimeout) clearTimeout(this.inactivityTimeout);\n\t\tthis.inactivityTimeout = setTimeout(() => {\n\t\t\tthis.cleanup();\n\t\t\tthis.done();\n\t\t}, McpSetupPanel.INACTIVITY_MS);\n\t}\n\n\tprivate cleanup(): void {\n\t\tif (this.inactivityTimeout) {\n\t\t\tclearTimeout(this.inactivityTimeout);\n\t\t\tthis.inactivityTimeout = null;\n\t\t}\n\t}\n\n\tprivate getActions(): Action[] {\n\t\tconst actions: Action[] = [];\n\t\tif (this.screen === \"empty\") {\n\t\t\tactions.push({\n\t\t\t\tid: \"run-setup\",\n\t\t\t\tlabel: \"Run setup\",\n\t\t\t\tdescription: \"Inspect detected configs, adopt imports, and scaffold a minimal `.nexus/mcp.json`.\",\n\t\t\t});\n\t\t}\n\t\tif (this.discovery.imports.length > 0) {\n\t\t\tactions.push({\n\t\t\t\tid: \"adopt-imports\",\n\t\t\t\tlabel: \"Adopt detected compatibility imports\",\n\t\t\t\tdescription: `Choose which host-specific MCP configs Nexus should import into its own override file. ${this.discovery.imports.length} source${this.discovery.imports.length === 1 ? \"\" : \"s\"} found.`,\n\t\t\t});\n\t\t}\n\t\tactions.push({\n\t\t\tid: \"view-example\",\n\t\t\tlabel: \"View example `.nexus/mcp.json`\",\n\t\t\tdescription: \"Preview a working Nexus MCP config you can paste or adapt.\",\n\t\t});\n\t\tif (!this.discovery.sources.some((source) => source.id === \"nexus-project\" && source.exists)) {\n\t\t\tactions.push({\n\t\t\t\tid: \"scaffold-project\",\n\t\t\t\tlabel: \"Scaffold project `.nexus/mcp.json`\",\n\t\t\t\tdescription: \"Write a minimal Nexus project MCP config, then reload Nexus.\",\n\t\t\t});\n\t\t}\n\t\tactions.push({\n\t\t\tid: \"show-precedence\",\n\t\t\tlabel: \"Explain config precedence\",\n\t\t\tdescription: \"Show the read order and where Nexus writes compatibility settings.\",\n\t\t});\n\t\tif (this.getDetectedPaths().length > 0) {\n\t\t\tactions.push({\n\t\t\t\tid: \"open-paths\",\n\t\t\t\tlabel: \"Open detected config paths\",\n\t\t\t\tdescription: \"Browse the actual config files that Nexus discovered on this machine.\",\n\t\t\t});\n\t\t}\n\t\tfor (const preset of KNOWN_SERVER_PRESETS) {\n\t\t\tactions.push({ id: \"add-known-server\", label: preset.name, description: preset.summary, preset });\n\t\t}\n\t\tif (\n\t\t\t!this.discovery.repoPrompt.configured &&\n\t\t\tthis.discovery.repoPrompt.executablePath &&\n\t\t\tthis.discovery.repoPrompt.targetPath &&\n\t\t\tthis.discovery.repoPrompt.entry &&\n\t\t\tthis.discovery.repoPrompt.serverName\n\t\t) {\n\t\t\tactions.push({\n\t\t\t\tid: \"add-repoprompt\",\n\t\t\t\tlabel: \"Add RepoPrompt to Nexus MCP config\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"Write an MCP entry for RepoPrompt to the recommended Nexus target, then reload MCP in-session.\",\n\t\t\t});\n\t\t}\n\t\tactions.push({ id: \"close\", label: \"Close\", description: \"Exit the onboarding flow.\" });\n\t\treturn actions;\n\t}\n\n\tprivate getDetectedPaths(): string[] {\n\t\tconst paths = [\n\t\t\t...this.discovery.sources.filter((source) => source.exists).map((source) => source.path),\n\t\t\t...this.discovery.imports.map((entry) => entry.path),\n\t\t];\n\t\treturn [...new Set(paths)];\n\t}\n\n\tprivate getSelectedAction(): Action | undefined {\n\t\tconst actions = this.getActions();\n\t\treturn actions[this.actionCursor];\n\t}\n\n\thandleInput(data: string): void {\n\t\tthis.resetInactivityTimeout();\n\t\tif (!this.busy) this.notice = null;\n\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.cleanup();\n\t\t\tthis.done();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"escape\")) {\n\t\t\tif (this.screen === \"imports\" || this.screen === \"paths\") {\n\t\t\t\tthis.screen = this.discovery.hasAnyConfig ? \"setup\" : \"empty\";\n\t\t\t\tthis.tui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.cleanup();\n\t\t\tthis.done();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.busy) return;\n\n\t\tif (this.screen === \"imports\") {\n\t\t\tthis.handleImportsInput(data);\n\t\t\treturn;\n\t\t}\n\t\tif (this.screen === \"paths\") {\n\t\t\tthis.handlePathsInput(data);\n\t\t\treturn;\n\t\t}\n\n\t\tconst actions = this.getActions();\n\t\tif (this.keys.selectUp(data)) {\n\t\t\tthis.actionCursor = Math.max(0, this.actionCursor - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectDown(data)) {\n\t\t\tthis.actionCursor = Math.min(actions.length - 1, this.actionCursor + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectConfirm(data)) {\n\t\t\tconst selected = this.getSelectedAction();\n\t\t\tif (selected) void this.runAction(selected);\n\t\t}\n\t}\n\n\tprivate handleImportsInput(data: string): void {\n\t\tconst imports = this.discovery.imports;\n\t\tif (this.keys.selectUp(data)) {\n\t\t\tthis.importCursor = Math.max(0, this.importCursor - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectDown(data)) {\n\t\t\tthis.importCursor = Math.min(imports.length - 1, this.importCursor + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"space\")) {\n\t\t\tconst current = imports[this.importCursor];\n\t\t\tif (!current) return;\n\t\t\tif (this.selectedImports.has(current.kind)) {\n\t\t\t\tthis.selectedImports.delete(current.kind);\n\t\t\t} else {\n\t\t\t\tthis.selectedImports.add(current.kind);\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectConfirm(data)) {\n\t\t\tvoid this.applySelectedImports();\n\t\t}\n\t}\n\n\tprivate handlePathsInput(data: string): void {\n\t\tconst paths = this.getDetectedPaths();\n\t\tif (this.keys.selectUp(data)) {\n\t\t\tthis.pathCursor = Math.max(0, this.pathCursor - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectDown(data)) {\n\t\t\tthis.pathCursor = Math.min(paths.length - 1, this.pathCursor + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keys.selectConfirm(data)) {\n\t\t\tconst selected = paths[this.pathCursor];\n\t\t\tif (!selected) return;\n\t\t\tvoid this.runBusy(async () => {\n\t\t\t\tawait this.callbacks.openPath(selected);\n\t\t\t\tthis.notice = { text: `Opened ${selected}`, tone: \"success\" };\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async runAction(action: Action): Promise<void> {\n\t\tif (action.id === \"run-setup\") {\n\t\t\tthis.screen = \"setup\";\n\t\t\tthis.actionCursor = 0;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"adopt-imports\") {\n\t\t\tthis.screen = \"imports\";\n\t\t\tthis.importCursor = 0;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"open-paths\") {\n\t\t\tthis.screen = \"paths\";\n\t\t\tthis.pathCursor = 0;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"scaffold-project\") {\n\t\t\tawait this.runBusy(async () => {\n\t\t\t\tconst result = await this.callbacks.scaffoldProjectConfig();\n\t\t\t\tthis.callbacks.markSetupCompleted();\n\t\t\t\tthis.notice = {\n\t\t\t\t\ttext: `Wrote starter config to ${result.path}. Nexus will reload after this panel closes.`,\n\t\t\t\t\ttone: \"success\",\n\t\t\t\t};\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"add-repoprompt\") {\n\t\t\tawait this.runBusy(async () => {\n\t\t\t\tconst result = await this.callbacks.addRepoPrompt();\n\t\t\t\tthis.callbacks.markSetupCompleted();\n\t\t\t\tthis.notice = {\n\t\t\t\t\ttext: `Added ${result.serverName} to ${result.path}. Nexus will reload after this panel closes.`,\n\t\t\t\t\ttone: \"success\",\n\t\t\t\t};\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"add-known-server\" && action.preset) {\n\t\t\tconst preset = action.preset;\n\t\t\tawait this.runBusy(async () => {\n\t\t\t\tconst result = await this.callbacks.addKnownServer(preset);\n\t\t\t\tthis.callbacks.markSetupCompleted();\n\t\t\t\tthis.notice = {\n\t\t\t\t\ttext: `Added ${result.serverName} to ${result.path}. Nexus will reload after this panel closes.`,\n\t\t\t\t\ttone: \"success\",\n\t\t\t\t};\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (action.id === \"close\") {\n\t\t\tthis.cleanup();\n\t\t\tthis.done();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.notice = {\n\t\t\ttext: \"Review the details below. Press Enter on an action with a side effect to apply it.\",\n\t\t\ttone: \"muted\",\n\t\t};\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate async applySelectedImports(): Promise<void> {\n\t\tconst selected = this.discovery.imports\n\t\t\t.filter((entry) => this.selectedImports.has(entry.kind))\n\t\t\t.map((entry) => entry.kind);\n\t\tif (selected.length === 0) {\n\t\t\tthis.notice = { text: \"Select at least one compatibility import first.\", tone: \"warning\" };\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runBusy(async () => {\n\t\t\tconst result = await this.callbacks.adoptImports(selected);\n\t\t\tthis.callbacks.markSetupCompleted();\n\t\t\tthis.notice =\n\t\t\t\tresult.added.length > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttext: `Added ${result.added.join(\", \")} to ${result.path}. Nexus will reload after this panel closes.`,\n\t\t\t\t\t\t\ttone: \"success\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: { text: `No changes needed in ${result.path}.`, tone: \"muted\" };\n\t\t\tthis.screen = this.discovery.hasAnyConfig ? \"setup\" : \"empty\";\n\t\t\tthis.actionCursor = 0;\n\t\t});\n\t}\n\n\tprivate async runBusy(fn: () => Promise<void>): Promise<void> {\n\t\tthis.busy = true;\n\t\tthis.notice = { text: \"Working...\", tone: \"muted\" };\n\t\tthis.tui.requestRender();\n\t\ttry {\n\t\t\tawait fn();\n\t\t} catch (error) {\n\t\t\tthis.notice = {\n\t\t\t\ttext: error instanceof Error ? error.message : String(error),\n\t\t\t\ttone: \"warning\",\n\t\t\t};\n\t\t} finally {\n\t\t\tthis.busy = false;\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst panelW = Math.max(MIN_PANEL_WIDTH, width);\n\t\tconst innerW = panelW - 2;\n\t\tconst contentW = this.contentWidth(innerW);\n\t\tconst lines: string[] = [];\n\t\tconst border = fg(this.t.border, \"─\".repeat(innerW));\n\t\tlines.push(`┌${border}┐`);\n\t\tlines.push(this.padLine(fg(this.t.title, \"MCP setup\"), innerW));\n\t\tfor (const line of wrapText(this.discoverySummaryLine(), contentW)) {\n\t\t\tlines.push(this.padLine(line, innerW));\n\t\t}\n\t\tfor (const line of wrapText(this.secondarySummaryLine(), contentW)) {\n\t\t\tlines.push(this.padLine(fg(this.t.muted, line), innerW));\n\t\t}\n\t\tlines.push(this.padLine(\"\", innerW));\n\n\t\tif (this.notice) {\n\t\t\tconst tone =\n\t\t\t\tthis.notice.tone === \"success\"\n\t\t\t\t\t? this.t.success\n\t\t\t\t\t: this.notice.tone === \"warning\"\n\t\t\t\t\t\t? this.t.warning\n\t\t\t\t\t\t: this.t.hint;\n\t\t\tfor (const line of wrapText(this.notice.text, contentW)) {\n\t\t\t\tlines.push(this.padLine(fg(tone, line), innerW));\n\t\t\t}\n\t\t\tlines.push(this.padLine(\"\", innerW));\n\t\t}\n\n\t\tlines.push(`├${border}┤`);\n\n\t\tif (this.screen === \"imports\") {\n\t\t\tlines.push(...this.renderImports(innerW));\n\t\t} else if (this.screen === \"paths\") {\n\t\t\tlines.push(...this.renderPaths(innerW));\n\t\t} else {\n\t\t\tlines.push(...this.renderActions(innerW));\n\t\t}\n\n\t\tlines.push(`└${border}┘`);\n\t\treturn lines;\n\t}\n\n\tprivate renderActions(innerW: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst actions = this.getActions();\n\t\tconst compact = innerW < COMPACT_WIDTH;\n\t\tconst { start, end } = compact ? this.visibleActionRange(actions.length) : { start: 0, end: actions.length };\n\n\t\tif (start > 0) {\n\t\t\tlines.push(this.padLine(fg(this.t.muted, `… ${start} more above`), innerW));\n\t\t}\n\t\tfor (let index = start; index < end; index++) {\n\t\t\tconst action = actions[index];\n\t\t\tif (!action) continue;\n\t\t\tif (action.id === \"add-known-server\" && (index === start || actions[index - 1]?.id !== \"add-known-server\")) {\n\t\t\t\tlines.push(this.padLine(fg(this.t.title, \"Add a known server\"), innerW));\n\t\t\t}\n\t\t\tconst selected = index === this.actionCursor;\n\t\t\tconst cursor = selected ? fg(this.t.selected, \"›\") : \" \";\n\t\t\tlines.push(this.padLine(`${cursor} ${truncateToWidth(action.label, this.contentWidth(innerW) - 2)}`, innerW));\n\t\t}\n\t\tif (end < actions.length) {\n\t\t\tlines.push(this.padLine(fg(this.t.muted, `… ${actions.length - end} more below`), innerW));\n\t\t}\n\t\tlines.push(this.padLine(\"\", innerW));\n\n\t\tconst preview = this.getActionPreview(this.getSelectedAction(), this.previewWidth(innerW));\n\t\tfor (const line of preview) {\n\t\t\tlines.push(this.padLine(line, innerW));\n\t\t}\n\t\tlines.push(this.padLine(\"\", innerW));\n\t\tconst hint = compact ? \"Enter select · Esc back\" : \"Enter selects, Esc goes back, Ctrl+C closes.\";\n\t\tlines.push(this.padLine(fg(this.t.muted, hint), innerW));\n\t\treturn lines;\n\t}\n\n\tprivate renderImports(innerW: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlines.push(this.padLine(\"Select compatibility imports. Space toggles, Enter saves, Esc goes back.\", innerW));\n\t\tlines.push(this.padLine(\"\", innerW));\n\t\tfor (let index = 0; index < this.discovery.imports.length; index++) {\n\t\t\tconst entry = this.discovery.imports[index];\n\t\t\tif (!entry) continue;\n\t\t\tconst selected = this.selectedImports.has(entry.kind) ? \"[x]\" : \"[ ]\";\n\t\t\tconst cursor = index === this.importCursor ? fg(this.t.selected, \"›\") : \" \";\n\t\t\tlines.push(this.padLine(`${cursor} ${selected} ${entry.kind} ${entry.path}`, innerW));\n\t\t}\n\t\tlines.push(this.padLine(\"\", innerW));\n\t\tconst selected = this.discovery.imports\n\t\t\t.filter((entry) => this.selectedImports.has(entry.kind))\n\t\t\t.map((entry) => entry.kind);\n\t\tconst preview = this.callbacks.previewImports(selected);\n\t\tfor (const line of this.formatWritePreview(\n\t\t\t\"Compatibility import write preview\",\n\t\t\tpreview,\n\t\t\t[],\n\t\t\tthis.previewWidth(innerW),\n\t\t)) {\n\t\t\tlines.push(this.padLine(line, innerW));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate renderPaths(innerW: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlines.push(this.padLine(\"Select a detected config path to open. Enter opens it, Esc goes back.\", innerW));\n\t\tlines.push(this.padLine(\"\", innerW));\n\t\tconst paths = this.getDetectedPaths();\n\t\tfor (let index = 0; index < paths.length; index++) {\n\t\t\tconst cursor = index === this.pathCursor ? fg(this.t.selected, \"›\") : \" \";\n\t\t\tconst path = paths[index];\n\t\t\tif (path !== undefined) lines.push(this.padLine(`${cursor} ${path}`, innerW));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate discoverySummaryLine(): string {\n\t\tif (!this.discovery.hasAnyConfig) {\n\t\t\treturn fg(\n\t\t\t\tthis.t.warning,\n\t\t\t\tthis.options.onboardingState.setupCompleted\n\t\t\t\t\t? \"No MCP servers are active right now.\"\n\t\t\t\t\t: \"No MCP config is active yet.\",\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\tthis.discovery.totalServerCount === 0 &&\n\t\t\t(this.discovery.imports.length > 0 || !!this.discovery.repoPrompt.executablePath)\n\t\t) {\n\t\t\treturn fg(this.t.warning, \"Nexus found MCP-related setup options, but none are active in Nexus yet.\");\n\t\t}\n\n\t\tconst configuredSources = this.discovery.sources.filter((source) => source.serverCount > 0).length;\n\t\treturn fg(\n\t\t\tthis.t.hint,\n\t\t\t`Detected ${this.discovery.totalServerCount} configured servers across ${configuredSources} Nexus source${configuredSources === 1 ? \"\" : \"s\"}.`,\n\t\t);\n\t}\n\n\tprivate secondarySummaryLine(): string {\n\t\tconst hostNote =\n\t\t\tthis.discovery.hostConfigs.length > 0\n\t\t\t\t? ` Host discovery is ${this.discovery.hostConfigDiscovery}; ${this.discovery.hostConfigs.length} host source${this.discovery.hostConfigs.length === 1 ? \"\" : \"s\"} detected.`\n\t\t\t\t: \"\";\n\t\tconst conflictNote =\n\t\t\tthis.discovery.conflicts.length > 0\n\t\t\t\t? ` ${this.discovery.conflicts.length} same-name conflict${this.discovery.conflicts.length === 1 ? \"\" : \"s\"} reported.`\n\t\t\t\t: \"\";\n\t\tif (!this.discovery.hasAnyConfig) {\n\t\t\treturn `Create .nexus/mcp.json, adopt host imports, or quick-add RepoPrompt from this screen.${hostNote}${conflictNote}`;\n\t\t}\n\t\tif (this.discovery.totalServerCount === 0 && this.discovery.imports.length > 0) {\n\t\t\treturn `Detected ${this.discovery.imports.length} compatibility import source${this.discovery.imports.length === 1 ? \"\" : \"s\"}. Adopt them into Nexus or inspect the underlying files.${hostNote}${conflictNote}`;\n\t\t}\n\t\treturn `Nexus MCP files contain server definitions, compatibility imports, and MCP-specific overrides.${hostNote}${conflictNote}`;\n\t}\n\n\tprivate visibleActionRange(total: number): { start: number; end: number } {\n\t\tif (total <= COMPACT_ACTION_ROWS) return { start: 0, end: total };\n\t\tconst half = Math.floor(COMPACT_ACTION_ROWS / 2);\n\t\tconst start = Math.min(Math.max(0, this.actionCursor - half), Math.max(0, total - COMPACT_ACTION_ROWS));\n\t\treturn { start, end: Math.min(total, start + COMPACT_ACTION_ROWS) };\n\t}\n\n\tprivate contentWidth(innerW: number): number {\n\t\treturn Math.max(8, innerW - 4);\n\t}\n\n\tprivate previewWidth(innerW: number): number {\n\t\treturn Math.max(12, Math.min(DESKTOP_PREVIEW_WIDTH, this.contentWidth(innerW)));\n\t}\n\n\tprivate getActionPreview(action?: Action, previewW = DESKTOP_PREVIEW_WIDTH): string[] {\n\t\tswitch (action?.id) {\n\t\t\tcase \"run-setup\":\n\t\t\t\treturn this.formatPreview(\n\t\t\t\t\t[\n\t\t\t\t\t\t\"Run setup to adopt host-specific imports, inspect detected paths, and scaffold a minimal `.nexus/mcp.json` if needed.\",\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tcase \"adopt-imports\":\n\t\t\t\treturn this.formatWritePreview(\n\t\t\t\t\t\"Compatibility import write preview\",\n\t\t\t\t\tthis.callbacks.previewImports(\n\t\t\t\t\t\tthis.discovery.imports\n\t\t\t\t\t\t\t.filter((entry) => this.selectedImports.has(entry.kind))\n\t\t\t\t\t\t\t.map((entry) => entry.kind),\n\t\t\t\t\t),\n\t\t\t\t\t[\n\t\t\t\t\t\t`Detected imports: ${this.discovery.imports.map((entry) => `${entry.kind} (${entry.serverCount} servers)`).join(\", \")}`,\n\t\t\t\t\t\t\"Selected imports are written to the Nexus global MCP configuration shown above.\",\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tcase \"view-example\":\n\t\t\t\treturn this.formatPreview(\n\t\t\t\t\t[\n\t\t\t\t\t\t\"Example Nexus `.nexus/mcp.json`:\",\n\t\t\t\t\t\t\"{\",\n\t\t\t\t\t\t' \"mcpServers\": {',\n\t\t\t\t\t\t' \"chrome-devtools\": {',\n\t\t\t\t\t\t' \"command\": \"npx\",',\n\t\t\t\t\t\t' \"args\": [\"-y\", \"chrome-devtools-mcp@1.6.0\"]',\n\t\t\t\t\t\t\" }\",\n\t\t\t\t\t\t\" }\",\n\t\t\t\t\t\t\"}\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Use Scaffold project `.nexus/mcp.json` when you want a safe empty shell instead of a live example server.\",\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tcase \"show-precedence\":\n\t\t\t\treturn this.formatPreview(\n\t\t\t\t\t[\n\t\t\t\t\t\t\"Read order (later entries win):\",\n\t\t\t\t\t\t\"0. detected host configs (opt-in lowest-precedence fallback)\",\n\t\t\t\t\t\t\"1. ~/.config/nexus/mcp.json\",\n\t\t\t\t\t\t`2. ${getConfigDirName()}/mcp.json`,\n\t\t\t\t\t\t`Host discovery: ${this.discovery.hostConfigDiscovery}. Conflicts reported: ${this.discovery.conflicts.length}.`,\n\t\t\t\t\t\t...this.discovery.conflicts\n\t\t\t\t\t\t\t.slice(0, 8)\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(conflict) =>\n\t\t\t\t\t\t\t\t\t`${conflict.serverName}: ${conflict.sources.map((source) => source.path).join(\" -> \")} (winner: ${conflict.winner.path})`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\"Nexus writes global MCP state to ~/.config/nexus/mcp.json and project state to .nexus/mcp.json.\",\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tcase \"open-paths\":\n\t\t\t\treturn this.formatPreview(\n\t\t\t\t\tthis.getDetectedPaths().length > 0\n\t\t\t\t\t\t? [\"Detected paths:\", ...this.getDetectedPaths()]\n\t\t\t\t\t\t: [\"No config paths were detected.\"],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tcase \"add-repoprompt\": {\n\t\t\t\tconst repoPrompt = this.discovery.repoPrompt;\n\t\t\t\tconst preview = this.callbacks.previewRepoPrompt();\n\t\t\t\tif (!preview) {\n\t\t\t\t\treturn this.formatPreview([\"RepoPrompt is not available to add from this setup screen.\"], previewW);\n\t\t\t\t}\n\t\t\t\treturn this.formatWritePreview(\n\t\t\t\t\t\"RepoPrompt write preview\",\n\t\t\t\t\tpreview,\n\t\t\t\t\t[\n\t\t\t\t\t\t`Executable: ${repoPrompt.executablePath ?? \"not found\"}`,\n\t\t\t\t\t\t`Target: ${repoPrompt.targetPath ?? \"n/a\"}`,\n\t\t\t\t\t\t`Server name: ${repoPrompt.serverName ?? \"repoprompt\"}`,\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"add-known-server\": {\n\t\t\t\tconst preset = action.preset;\n\t\t\t\tif (!preset) return this.formatPreview([\"Known server preset is unavailable.\"], previewW);\n\t\t\t\treturn this.formatWritePreview(\n\t\t\t\t\t`${preset.name} write preview`,\n\t\t\t\t\tthis.callbacks.previewKnownServer(preset),\n\t\t\t\t\t[preset.summary],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"scaffold-project\":\n\t\t\t\treturn this.formatWritePreview(\n\t\t\t\t\t\"Starter project `.nexus/mcp.json` write preview\",\n\t\t\t\t\tthis.callbacks.previewStarterProject(),\n\t\t\t\t\t[\n\t\t\t\t\t\t\"This writes a minimal `.nexus/mcp.json` in the current project using the Nexus MCP layout.\",\n\t\t\t\t\t\t\"It intentionally avoids adding a fake placeholder server that would fail on first reload.\",\n\t\t\t\t\t],\n\t\t\t\t\tpreviewW,\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn this.formatPreview([\"Close the setup flow.\"], previewW);\n\t\t}\n\t}\n\n\tprivate formatPreview(lines: string[], width = DESKTOP_PREVIEW_WIDTH): string[] {\n\t\tconst preview: string[] = [];\n\t\tfor (const line of lines) {\n\t\t\tpreview.push(...wrapText(line, width));\n\t\t}\n\t\treturn preview;\n\t}\n\n\tprivate formatWritePreview(\n\t\ttitle: string,\n\t\tpreview: ConfigWritePreview,\n\t\tintro: string[] = [],\n\t\twidth = DESKTOP_PREVIEW_WIDTH,\n\t): string[] {\n\t\tconst lines: string[] = [];\n\t\tfor (const line of intro) {\n\t\t\tlines.push(...wrapText(line, width));\n\t\t}\n\t\tif (intro.length > 0) lines.push(\"\");\n\t\tlines.push(...wrapText(`${title}: ${preview.path}`, width));\n\t\tlines.push(\n\t\t\t...wrapText(\n\t\t\t\tpreview.existed\n\t\t\t\t\t? \"Existing file detected. Showing exact before/after diff.\"\n\t\t\t\t\t: \"New file will be created. Showing exact content diff.\",\n\t\t\t\twidth,\n\t\t\t),\n\t\t);\n\t\tlines.push(\"\");\n\t\tconst diffLines = preview.diffText.split(\"\\n\");\n\t\tconst maxLines = 18;\n\t\tconst shown = diffLines.slice(0, maxLines);\n\t\tfor (const line of shown) {\n\t\t\tlines.push(...wrapText(line, width));\n\t\t}\n\t\tif (diffLines.length > maxLines) {\n\t\t\tlines.push(\n\t\t\t\t...wrapText(\n\t\t\t\t\t`… ${diffLines.length - maxLines} more diff line${diffLines.length - maxLines === 1 ? \"\" : \"s\"}`,\n\t\t\t\t\twidth,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate padLine(text: string, innerW: number): string {\n\t\tconst inset = 2;\n\t\tconst contentW = Math.max(0, innerW - inset * 2);\n\t\tconst fitted = truncateToWidth(text, contentW, \"…\", true);\n\t\tconst plainWidth = visibleWidth(fitted);\n\t\tconst padding = Math.max(0, contentW - plainWidth);\n\t\treturn `│${\" \".repeat(inset)}${fitted}${\" \".repeat(padding)}${\" \".repeat(inset)}│`;\n\t}\n\n\tinvalidate(): void {}\n\n\tdispose(): void {\n\t\tthis.cleanup();\n\t}\n}\n\nexport function createMcpSetupPanel(\n\tdiscovery: McpDiscoverySummary,\n\tcallbacks: SetupPanelCallbacks,\n\toptions: SetupPanelOptions,\n\ttui: { requestRender(): void },\n\tdone: () => void,\n): McpSetupPanel & { dispose(): void } {\n\treturn new McpSetupPanel(discovery, callbacks, options, tui, done);\n}\n"]}
|