/** * dsh-ui-tweaks — MCP manager (browser half). * * Renders the "MCP 管理" settings section (usable when the mcpManagerEnabled * toggle in 界面调整 is on — otherwise it shows an invite card). The section * lists every configured MCP server with its status (active / failed / loading * / stopped / stopping / disabled), command / url, env names, registered * tools, and offers per-server actions: **启用/停用**, **编辑**, and **删除** * (two-click confirm). An **添加服务器** button opens the editor, which * supports BOTH a structured **表单** and a raw **YAML** mode (the config is * validated on the server before the profile's `cordis.patch.yml` is * rewritten; DSH's patch watcher then hot-reloads the loader so the server * starts/stops live). * * Every mutation rewrites the profile patch, which kicks off an asynchronous * chain (patch watcher → loader reload → MCP process spawn/teardown). The UI * treats that as first-class: the clicked row enters a pending state until a * poll observes a terminal status, and `mcpRequest` rides out the patch-reload * restart window instead of alarming the user mid-toggle. * @module dsh-ui-tweaks/client/mcp */ import type { SettingsClient } from './index.tsx'; /** Locale keys the MCP manager reads off the `ui-tweaks` dictionary. */ type McpLabelKey = 'mcpTitle' | 'mcpEmpty' | 'mcpStatusActive' | 'mcpStatusFailed' | 'mcpStatusLoading' | 'mcpStatusStopped' | 'mcpStatusStopping' | 'mcpStatusDisabled' | 'mcpTools' | 'mcpEnv' | 'mcpUnavailable' | 'mcpDisabledHint' | 'mcpEnable' | 'mcpServerDetail' | 'mcpAdd' | 'mcpAddTitle' | 'mcpEditTitle' | 'mcpEdit' | 'mcpDelete' | 'mcpEnabledAction' | 'mcpDisabledAction' | 'mcpSaved' | 'mcpRemoved' | 'mcpFormTab' | 'mcpYamlTab' | 'mcpYamlHint' | 'mcpYamlPlaceholder' | 'mcpFieldId' | 'mcpFieldIdHint' | 'mcpFieldName' | 'mcpFieldNameHint' | 'mcpFieldType' | 'mcpFieldTimeout' | 'mcpFieldCommand' | 'mcpFieldCommandPlaceholder' | 'mcpFieldArgs' | 'mcpFieldEnv' | 'mcpFieldUrl' | 'mcpFieldHeaders' | 'mcpFieldEnabled' | 'mcpSave' | 'mcpCancel' | 'mcpInvalidId' | 'mcpInvalidName' | 'mcpInvalidTimeout' | 'mcpInvalidUrl' | 'mcpInvalidCommand' | 'unavailable' | 'loading'; type Translate = (key: McpLabelKey) => string; export declare const MCP_CSS = "\n.dut-mcp{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}\n.dut-mcp-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}\n.dut-mcp-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}\n.dut-mcp-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-spacer{flex:1}\n.dut-mcp-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}\n.dut-mcp-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dut-mcp-btn:disabled{opacity:.5;cursor:default}\n.dut-mcp-btn.dut-mcp-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}\n.dut-mcp-btn.dut-mcp-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}\n.dut-mcp-body{display:grid;gap:2px;margin-top:4px}\n.dut-mcp-row{display:grid;gap:6px;padding:10px 16px;border-radius:12px}\n.dut-mcp-row:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dut-mcp-row-main{display:flex;align-items:center;gap:8px;min-width:0}\n.dut-mcp-name{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n.dut-mcp-badge{flex:none;font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}\n.dut-mcp-badge.dut-mcp-ok{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-success-primary)}\n.dut-mcp-badge.dut-mcp-err{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-error-primary)}\n.dut-mcp-badge.dut-mcp-warn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 14%,transparent);border-color:transparent;color:var(--dsw-alias-state-warn-label)}\n.dut-mcp-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n.dut-mcp-toggle{flex:none;font-size:11.5px;color:var(--dsw-alias-label-tertiary);background:transparent;border:none;padding:0;cursor:pointer;text-align:left}\n.dut-mcp-toggle:hover{color:var(--dsw-alias-label-primary)}\n.dut-mcp-tools{margin-left:2px;display:flex;flex-wrap:wrap;gap:4px}\n.dut-mcp-tool{font-size:11px;line-height:1;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}\n.dut-mcp-note{margin:2px 16px 0;padding:8px 12px;border-radius:10px;font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}\n.dut-mcp-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dut-mcp-notice{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);color:var(--dsw-alias-state-success-primary)}\n.dut-mcp-off{padding:20px 16px;display:grid;gap:12px}\n.dut-mcp-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}\n.dut-mcp-overlay{z-index:1100;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}\n.dut-mcp-mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}\n.dut-mcp-panel{z-index:1;background:var(--dsw-alias-bg-layer-2);box-sizing:border-box;width:720px;max-width:calc(100vw - 48px);height:min(700px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;display:flex;flex-direction:column;overflow:hidden}\n.dut-mcp-panel-head{box-sizing:border-box;flex:none;display:flex;align-items:center;gap:10px;height:52px;padding:0 12px 0 20px}\n.dut-mcp-panel-head h2{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}\n.dut-mcp-panel-close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:transparent;border:none;border-radius:28px;display:inline-flex;justify-content:center;align-items:center;padding:0;font-size:13px}\n.dut-mcp-panel-close:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dut-mcp-tabs{flex:none;display:inline-flex;padding:3px;gap:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin:0 20px 10px;align-self:flex-start}\n.dut-mcp-tabs button{border:none;border-radius:7px;padding:5px 14px;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12.5px;cursor:pointer}\n.dut-mcp-tabs button.dut-mcp-tab-on{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}\n.dut-mcp-form{flex:1;min-height:0;overflow-y:auto;padding:0 20px 20px;display:grid;gap:12px;align-content:start}\n.dut-mcp-field{display:grid;gap:6px}\n.dut-mcp-field>span{font-size:12px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dut-mcp-field small{font-size:11px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}\n.dut-mcp-input{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}\n.dut-mcp-input:focus{outline:none;border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 55%,transparent)}\n.dut-mcp-input:disabled{opacity:.55;cursor:not-allowed}\ntextarea.dut-mcp-input{height:auto;min-height:72px;padding:8px 10px;line-height:1.5;resize:vertical;font-family:var(--dsw-font-markdown-code-block-font-family, Consolas, monospace);font-size:12px}\ntextarea.dut-mcp-input-lg{min-height:120px}\ntextarea.dut-mcp-yaml{min-height:320px}\n.dut-mcp-row2{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}\n.dut-mcp-field .dut-seg{width:fit-content}\n.dut-mcp-row2 .dut-seg{height:34px;box-sizing:border-box;align-items:center}\n.dut-mcp-row2 .dut-seg button{flex:none;white-space:nowrap;padding:0 16px;height:26px}\n.dut-mcp-foot{flex:none;display:flex;align-items:center;gap:8px;justify-content:flex-end;padding:12px 20px 16px;border-top:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-error{margin:0 20px 10px;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n"; /** Install the MCP stylesheet once (idempotent); returns the disposer. */ export declare function installMcpStyles(): () => void; export interface McpSectionProps { controller: SettingsClient; t: Translate; } export declare function McpSection({ controller, t }: McpSectionProps): import("react").JSX.Element; export {}; //# sourceMappingURL=mcp.d.ts.map