dshb-ui 0.0.1
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/LICENSE +21 -0
- package/cordis.patch.yml +9 -0
- package/lib/client.js +1868 -0
- package/lib/client.js.map +1 -0
- package/lib/index-CLOUBKxU.d.ts +1125 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/picker.d.ts +10 -0
- package/lib/picker.js +58 -0
- package/lib/picker.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["inputStyle","buttonStyle","primaryButtonStyle","secondaryButtonStyle","useState","useCallback","useState","useCallback"],"sources":["../src/client/directory-flow.tsx","../src/client/mobile.tsx","../src/client/index.tsx"],"sourcesContent":["import type { DirectoryFlowOwnerProps } from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n status?: { reachable?: boolean }\n}\n\ninterface DirEntry {\n name: string\n path: string\n isDirectory: boolean\n}\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--dsw-alias-overlay-mask, rgba(0,0,0,0.45))',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n}\nconst dialogStyle: CSSProperties = {\n width: 'min(92vw, 560px)',\n maxWidth: '100%',\n maxHeight: '80vh',\n overflow: 'auto',\n overflowX: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: 20,\n boxSizing: 'border-box',\n color: 'var(--dsw-alias-label-primary)',\n}\n\nfunction joinPath(base: string, name: string): string {\n return `${base.replace(/\\/+$/, '')}/${name}`\n}\n\nexport function DirectoryFlowOccupant(props: DirectoryFlowOwnerProps): ReactElement | null {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n const [nodeId, setNodeId] = useState<string>('')\n const [path, setPath] = useState('')\n const [entries, setEntries] = useState<DirEntry[]>([])\n const [error, setError] = useState<string | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [newDirName, setNewDirName] = useState('')\n\n useEffect(() => {\n if (!props.open) return\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n setNodes((data.nodes ?? []).filter((n) => n.type === 'local-host' || n.status?.reachable === true))\n } catch {}\n })()\n }, [props.open])\n\n const browse = useCallback(async (id: string, dir: string) => {\n setError(undefined)\n try {\n const res = await fetch(`/api/dshb/nodes/${id}/browse?path=${encodeURIComponent(dir)}`)\n const data = (await res.json()) as { ok?: boolean; path?: string; entries?: DirEntry[]; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '目录读取失败')\n return\n }\n setPath(data.path ?? dir)\n setEntries((data.entries ?? []).filter((e) => e.isDirectory))\n } catch {\n setError('网络错误')\n }\n }, [])\n\n const selectNode = useCallback(\n (id: string) => {\n setNodeId(id)\n setPath('')\n setEntries([])\n setError(undefined)\n void browse(id, '/')\n },\n [browse],\n )\n\n const mkdir = useCallback(async () => {\n if (!newDirName.trim()) return\n setBusy(true)\n setError(undefined)\n try {\n const target = joinPath(path, newDirName.trim())\n const res = await fetch(`/api/dshb/nodes/${nodeId}/mkdir`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path: target }),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (!res.ok || !data.ok) {\n setError(data.error ?? '创建目录失败')\n return\n }\n setNewDirName('')\n void browse(nodeId, target)\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [newDirName, nodeId, path, browse])\n\n const confirm = useCallback(async () => {\n if (!nodeId || !path) {\n setError('请选择节点与目录')\n return\n }\n setBusy(true)\n setError(undefined)\n try {\n const node = nodes.find((n) => n.id === nodeId)\n if (!node) return\n if (node.type === 'local-host') {\n props.onPicked(path)\n return\n }\n const res = await fetch('/api/dshb/workspaces/bind', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ nodeId, remotePath: path }),\n })\n const data = (await res.json()) as { ok?: boolean; mirrorPath?: string; error?: string }\n if (!res.ok || !data.ok || !data.mirrorPath) {\n setError(data.error ?? '工作区注册失败')\n return\n }\n props.onPicked(data.mirrorPath)\n } catch {\n setError('网络错误')\n } finally {\n setBusy(false)\n }\n }, [nodeId, path, nodes, props])\n\n if (!props.open) return null\n\n const node = nodes.find((n) => n.id === nodeId)\n\n return (\n <div style={overlayStyle} role=\"dialog\" aria-label=\"添加工作区\">\n <div style={dialogStyle}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>\n <h2 style={{ margin: 0, fontSize: 16, color: 'var(--dsw-alias-label-primary)' }}>添加工作区</h2>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 关闭\n </button>\n </div>\n\n <label style={{ display: 'block', fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 4 }}>工作节点</label>\n <select style={{ ...inputStyle, marginBottom: 14 }} value={nodeId} onChange={(e) => selectNode(e.target.value)} disabled={props.busy || busy}>\n <option value=\"\">选择节点…</option>\n {nodes.map((n) => {\n const typeLabel =\n n.type === 'local-host' ? '本地' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type\n return (\n <option key={n.id} value={n.id}>\n {n.name}({typeLabel})\n </option>\n )\n })}\n </select>\n\n {nodeId !== '' && (\n <>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>\n <label style={{ fontSize: 12, color: 'var(--dsw-alias-label-secondary)' }}>当前目录({node?.type === 'local-host' ? '本机' : '远端'})</label>\n <button type=\"button\" onClick={() => void browse(nodeId, dirnameOf(path))} disabled={busy} style={secondaryButtonStyle}>\n 上一级\n </button>\n </div>\n <div style={{ ...inputStyle, marginBottom: 8, height: 'auto', minHeight: 32, display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 2, cursor: 'pointer', lineHeight: '32px', overflow: 'hidden' }} onClick={() => void browse(nodeId, path)}>\n {path.split('/').filter(Boolean).length === 0 ? (\n <span style={{ opacity: 0.5 }}>根目录</span>\n ) : (\n <>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, '/') }} style={{ cursor: 'pointer', color: 'var(--dsw-alias-label-secondary)' }}>/</span>\n {path.split('/').filter(Boolean).map((seg, i, arr) => {\n const dir = '/' + arr.slice(0, i + 1).join('/')\n return (\n <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 2 }}>\n <span onClick={(ev) => { ev.stopPropagation(); void browse(nodeId, dir) }} style={{ cursor: 'pointer' }}>{seg}</span>\n {i < arr.length - 1 && <span style={{ opacity: 0.4 }}>/</span>}\n </span>\n )\n })}\n </>\n )}\n </div>\n <div style={{ maxHeight: 200, overflow: 'auto', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 6, marginBottom: 10 }}>\n {entries.map((e) => (\n <div key={e.path} onClick={() => void browse(nodeId, e.path)} style={{ padding: '7px 10px', cursor: 'pointer', fontSize: 13, borderRadius: 6, color: 'var(--dsw-alias-label-primary)', display: 'flex', alignItems: 'center', gap: 6, overflow: 'hidden' }} onMouseEnter={(ev) => (ev.currentTarget.style.background = 'var(--dsw-alias-interactive-bg-hover)')} onMouseLeave={(ev) => (ev.currentTarget.style.background = 'transparent')}>\n <span style={{ flexShrink: 0 }}>📁</span>\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</span>\n </div>\n ))}\n {entries.length === 0 && <div style={{ padding: 12, fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>无子目录</div>}\n </div>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <input style={{ ...inputStyle, flex: 1, minWidth: 0 }} value={newDirName} onChange={(e) => setNewDirName(e.target.value)} placeholder=\"在当前目录下新建子目录…\" onKeyDown={(e) => { if (e.key === 'Enter') void mkdir() }} />\n <button type=\"button\" onClick={() => void mkdir()} disabled={busy || !newDirName.trim()} style={{ ...secondaryButtonStyle, flexShrink: 0, whiteSpace: 'nowrap' }}>\n 新建\n </button>\n </div>\n </>\n )}\n\n {error && <div style={{ fontSize: 13, color: 'var(--dsw-alias-state-error-primary)', marginBottom: 10 }}>{error}</div>}\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>\n <button type=\"button\" onClick={props.onCancel} style={secondaryButtonStyle}>\n 取消\n </button>\n <button type=\"button\" onClick={() => void confirm()} disabled={busy || props.busy || !nodeId || !path} style={primaryButtonStyle}>\n 设为工作区\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nfunction dirnameOf(path: string): string {\n const parts = path.split('/').filter(Boolean)\n parts.pop()\n return parts.length === 0 ? '/' : `/${parts.join('/')}`\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n\n/**\n * dshb 移动端屏幕适配(参考 dsh-web-mobile 实现,仅保留页面适配与目录抽屉\n * 切换,不含文件浏览 / 导出会话日志等功能按钮)。\n *\n * 机制与上游一致:dsh 客户端在窄屏会自动给 AppFrame 加 data-sidebar-collapsed\n * 折叠侧边栏;这里把侧边栏列(frame 的第一个 grid 子元素)用 CSS 抽屉化\n * (绝对定位 + transform 移出/滑入),并在会话头部注入一个切换按钮调用\n * ctx.layout.toggleSidebar()。窄屏判定与上游一致(<1024 且粗指针,避免桌面\n * 小窗误触发)。\n */\nexport const MOBILE_QUERY = '(max-width: 1023px) and (pointer: coarse)'\n\nconst FRAME_ATTR = 'data-dshb-mobile'\nconst COLLAPSED_ATTR = 'data-sidebar-collapsed'\n\nconst MOBILE_CSS = `\n@media (max-width: 1023px) and (pointer: coarse) {\n html, body { touch-action: pan-y pinch-zoom !important; overscroll-behavior-x: none !important; }\n\n [${FRAME_ATTR}=\"frame\"] {\n box-sizing: border-box !important;\n position: relative !important;\n grid-template-columns: minmax(0, 1fr) 0 0 !important;\n padding-top: env(safe-area-inset-top, 0px) !important;\n }\n\n /* 侧边栏列 -> 抽屉:默认移出屏幕,展开(无 collapsed)时滑入 */\n [${FRAME_ATTR}=\"frame\"] > :first-child {\n position: absolute !important;\n inset: 0 auto 0 0 !important;\n width: max-content;\n max-width: 92vw;\n z-index: 40 !important;\n transform: translateX(-110%);\n transition: transform .28s ease-in-out;\n background: var(--dsw-alias-bg-base, #ffffff);\n padding-top: env(safe-area-inset-top, 0px) !important;\n border-right: none !important;\n touch-action: pan-y pinch-zoom !important;\n }\n [${FRAME_ATTR}=\"frame\"]:not([${COLLAPSED_ATTR}]) > :first-child { transform: none !important; }\n @media (prefers-reduced-motion: reduce) {\n [${FRAME_ATTR}=\"frame\"] > :first-child { transition: none !important; }\n }\n\n /* 拖拽手柄在触屏上无用 */\n [data-side=\"sidebar\"], [data-side=\"details\"] { display: none !important; }\n\n /* 对话区:去桌面滚动条占位,收窄 gutter,字号降一档 */\n [data-phase] [class*=\"_scrollBody\"] { scrollbar-gutter: auto !important; scrollbar-width: none; }\n [data-phase] [class*=\"_scrollBody\"]::-webkit-scrollbar { display: none !important; width: 0; height: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) { padding-left: 20px; padding-right: 20px; font-size: 15px !important; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) p,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) li,\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]):has(p) [class*=\"_text_\"] { font-size: 15px !important; }\n [data-phase] table { width: 100%; max-width: 100%; }\n [data-phase] th, [data-phase] td { max-width: none; min-width: 0; }\n [data-phase] [class*=\"_scroll\"]:not([class*=\"_scrollBody\"]) img { width: auto !important; max-width: 100% !important; height: auto !important; max-height: 220px !important; }\n [data-phase] [class*=\"_userStack\"], [data-phase] [class*=\"_userStack\"] [class*=\"_bubble\"] { box-sizing: border-box; width: fit-content; max-width: 100%; }\n [data-phase] [class*=\"_actions\"] { overflow: hidden; }\n\n /* 统计行(turns/steps/LLM/TPS):窄屏横向滚动,指标可滑动看全 */\n [${FRAME_ATTR}=\"stats\"] {\n display: flex !important;\n flex-wrap: nowrap !important;\n align-items: center;\n gap: 6px;\n overflow-x: auto !important;\n max-width: 100% !important;\n scrollbar-width: none;\n -webkit-overflow-scrolling: touch;\n }\n [${FRAME_ATTR}=\"stats\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"stats\"] > * { flex-shrink: 0 !important; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"stats\"] { gap: 6px !important; }\n [class*=\"composerStack\"] { gap: 4px !important; }\n /* stats line 竖线分隔符(|)两边 margin 10px 太松,适度收紧 */\n [data-phase] [class*=\"_sep\"] { margin: 0 3px !important; }\n\n /* 每轮回复下方的统计文字(footer):收紧 actions 内部 gap 与气泡到 footer 间距,减少松散感 */\n [data-phase] [class*=\"_actions\"] { gap: 4px !important; }\n [data-phase] [class*=\"_actions\"] [class*=\"_timeEnd\"] { gap: 4px !important; padding-left: 6px !important; }\n [data-phase] [class*=\"userRow\"], [data-phase] [class*=\"assistantRow\"] { gap: 4px !important; }\n /* 点号(·)左右 margin 10px 太松,收紧并抵消前后空格 */\n [data-phase] [class*=\"_runTimeDot\"] { margin: 0 -2px !important; }\n /* footer 容器各项间距 16px 偏松 */\n [data-phase] [class*=\"_root\"][class*=\"osXY9a\"] { gap: 8px !important; }\n /* footer 统计行窄屏可横向滑动看全,不溢出页面 */\n [data-phase] [class*=\"_actions\"] { max-width: 100% !important; overflow-x: auto !important; scrollbar-width: none; touch-action: pan-x !important; }\n [data-phase] [class*=\"_actions\"]::-webkit-scrollbar { display: none; }\n\n /* 上下文用量弹窗(ContextMeter .JObwrW_panel):上游 dsh-client-ui-trajectory 的\n [class*=\"panel\"] 全局规则给它加了 max-width:100%!important,命中本弹窗,使宽度\n 从 264px 塌缩到包含块(.root 28px)宽,内容竖排成竖条。窄屏解除该误伤。 */\n .JObwrW_panel { max-width: none !important; overflow-x: visible !important; }\n\n /* 头部:标题省略,tab 条横向滚动 */\n [${FRAME_ATTR}=\"frame\"] [data-phase] header { padding-left: 44px; padding-right: 8px; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [class*=\"_crumbs\"] { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap !important; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] { flex-wrap: nowrap; gap: 0 16px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"]::-webkit-scrollbar { display: none; }\n [${FRAME_ATTR}=\"frame\"] [data-phase] header [role=\"tablist\"] > button { flex-shrink: 0; white-space: nowrap; }\n\n /* 设置对话框:窄屏近全宽 sheet(排除导出等普通对话框与目录选择器) */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) {\n position: absolute !important;\n left: 8px !important;\n top: calc(env(safe-area-inset-top, 0px) + 12px) !important;\n width: calc(100vw - 16px) !important;\n max-width: calc(100vw - 16px) !important;\n height: auto !important;\n max-height: calc(100dvh - 24px - env(safe-area-inset-top, 0px)) !important;\n flex-direction: column !important;\n border-radius: 14px !important;\n }\n [aria-modal=\"true\"]:not(:has(> :first-child > :last-child > button)) { max-width: calc(100vw - 32px) !important; }\n /* nav:横排换行(避免 CJK 标签竖排楼梯状),隐藏冗余 caption */\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child {\n width: 100%;\n flex-direction: row !important;\n align-items: center;\n gap: 6px;\n padding: 10px 12px 8px;\n }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :first-child > :first-child { display: none !important; }\n [aria-modal=\"true\"] [class*=\"_navList\"] { flex: 1 1 auto; min-width: 0; flex-direction: row !important; flex-wrap: wrap; gap: 6px; overflow: visible; }\n [aria-modal=\"true\"] [class*=\"_navList\"] > button { flex-shrink: 0; white-space: nowrap; }\n /* 外观模式卡片横排 */\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] { gap: 6px; }\n [aria-modal=\"true\"] [class*=\"_cubeRow\"] > * { flex: 1 1 0; flex-direction: row !important; align-items: center; justify-content: center; gap: 6px; padding: 10px 8px; min-height: 0; }\n /* section 填充 sheet 宽度 */\n [aria-modal=\"true\"] [class*=\"_section\"] { width: 100% !important; max-width: none !important; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child { flex: 1 1 auto; min-height: 0; }\n [aria-modal=\"true\"]:has(> :first-child > :last-child > button):not(:has([role=\"navigation\"])):not(:has([class*=\"ZuhsRW\"])) > :last-child > :last-child { padding: 0 12px 24px; }\n\n /* 切换按钮:固定头部左侧 */\n [${FRAME_ATTR}=\"toggle\"] {\n position: absolute !important;\n left: 8px !important;\n top: 12px !important;\n z-index: 2 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 28px; height: 28px;\n padding: 0; border: none; background: none; cursor: pointer; color: inherit;\n -webkit-tap-highlight-color: transparent;\n }\n\n /* 首页/hero(无活跃会话,session header 不存在)的抽屉切换 FAB:\n 浮在顶部相机带下方,避免与 hero 头部内容重叠 */\n [${FRAME_ATTR}=\"fab\"] {\n position: absolute !important;\n top: calc(env(safe-area-inset-top, 0px) + 72px) !important;\n left: 10px !important;\n z-index: 21 !important;\n display: inline-flex !important;\n align-items: center; justify-content: center;\n width: 38px; height: 38px;\n padding: 0;\n border: 1px solid var(--dsw-alias-border-l1, rgba(0, 0, 0, .12)) !important;\n border-radius: 50% !important;\n background: var(--dsw-alias-button-floating-fill, #ffffff) !important;\n color: var(--dsw-alias-label-primary, inherit) !important;\n cursor: pointer !important;\n box-shadow: 0 2px 12px rgba(0, 0, 0, .18) !important;\n -webkit-tap-highlight-color: transparent;\n }\n}\n\n/* 宽屏 / 鼠标指针:隐藏切换按钮 */\n@media (min-width: 1024px), (pointer: fine) {\n [${FRAME_ATTR}=\"toggle\"], [${FRAME_ATTR}=\"fab\"] { display: none !important; }\n}\n`\n\nfunction findFrame(): HTMLElement | null {\n return document.querySelector('[data-shell-overlay]')?.parentElement ?? null\n}\n\nfunction getFrame(): HTMLElement | null {\n return document.querySelector(`[${FRAME_ATTR}=\"frame\"]`) ?? findFrame()\n}\n\n/** viewport-fit=cover:让 safe-area-inset 生效,内容避开刘海/状态栏。 */\nfunction installViewport(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const viewport = document.querySelector<HTMLMetaElement>('meta[name=\"viewport\"]')\n if (viewport === null) return () => {}\n const original = viewport.content\n const sync = (): void => {\n viewport.content = narrow.matches\n ? 'width=device-width, initial-scale=1, viewport-fit=cover'\n : original\n }\n sync()\n narrow.addEventListener('change', sync)\n return () => {\n narrow.removeEventListener('change', sync)\n viewport.content = original\n }\n }, 'dshb-mobile: viewport')\n}\n\nfunction installStyles(ctx: ClientContext): void {\n ctx.effect(() => {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dshb-mobile'\n tag.textContent = MOBILE_CSS\n document.head.appendChild(tag)\n // 保持在 head 最后,确保覆盖宿主样式\n setTimeout(() => { if (tag.isConnected) document.head.appendChild(tag) }, 0)\n return () => { tag.remove() }\n }, 'dshb-mobile: styles')\n}\n\n/** 给 AppFrame 打标记(drawer CSS 选择器挂载点),窄屏才打。 */\nfunction installFrameMarker(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let frame: HTMLElement | null = null\n const clear = (): void => {\n if (frame !== null) frame.removeAttribute(FRAME_ATTR)\n frame = null\n }\n const ensure = (): void => {\n if (!narrow.matches) return\n frame = findFrame()\n if (frame !== null && !frame.hasAttribute(FRAME_ATTR)) frame.setAttribute(FRAME_ATTR, 'frame')\n }\n ensure()\n const mo = new MutationObserver(ensure)\n mo.observe(document.documentElement, { childList: true, subtree: true })\n const onChange = (): void => { if (narrow.matches) ensure(); else clear() }\n narrow.addEventListener('change', onChange)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', onChange)\n clear()\n }\n }, 'dshb-mobile: frame marker')\n}\n\n/**\n * 抽屉打开时覆盖内容区的半透明遮罩,点击关闭;Escape 同样关闭;\n * 点击抽屉内的会话/导航项后关闭抽屉。\n */\nfunction installDrawerInteractions(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n let backdrop: HTMLElement | null = null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return narrow.matches && frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n const sync = (): void => {\n if (drawerOpen() && backdrop === null) {\n backdrop = document.createElement('div')\n backdrop.setAttribute(`${FRAME_ATTR}-backdrop`, '')\n backdrop.style.cssText = 'position:fixed;inset:0;z-index:39;background:rgba(0,0,0,.4);-webkit-tap-highlight-color:transparent;'\n backdrop.addEventListener('click', () => toggleSidebar())\n document.body.appendChild(backdrop)\n } else if (!drawerOpen() && backdrop !== null) {\n backdrop.remove()\n backdrop = null\n }\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n if (document.querySelector('[aria-modal=\"true\"]') !== null) return\n if (drawerOpen()) toggleSidebar()\n }\n const onClick = (event: MouseEvent): void => {\n if (!drawerOpen()) return\n const target = event.target\n if (!(target instanceof Element)) return\n const drawer = document.querySelector(`[${FRAME_ATTR}=\"frame\"] > :first-child`)\n if (drawer === null || !drawer.contains(target)) return\n if (target.closest('[class*=\"sessionRow\"] button') !== null) return\n if (target.closest('[class*=\"newSession\"], [class*=\"sessionRow\"], [role=\"treeitem\"], [class*=\"searchResult\"]') !== null) toggleSidebar()\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: [COLLAPSED_ATTR] })\n document.addEventListener('keydown', onKeyDown, true)\n document.addEventListener('click', onClick, true)\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n document.removeEventListener('keydown', onKeyDown, true)\n document.removeEventListener('click', onClick, true)\n narrow.removeEventListener('change', sync)\n backdrop?.remove()\n }\n }, 'dshb-mobile: drawer interactions')\n}\n\n/** 对话/输入框下方的统计行(turns/steps/LLM/TPS):hashed class 无法直接选,按文本特征标记后由 CSS 横向滚动,避免溢出。 */\nfunction installStatsLine(ctx: ClientContext): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n // 统计行文本特征(\"3 轮 · 5 步 · LLM 2.1s · 缓存命中 80%\" 等),hashed class 无法直接选,按文本识别。\n // 含\"轮/步/turns/steps\"即可(footer 不含这些),无需额外排除 footer。\n const STATS_LINE_RE = /(\\d+\\s*轮|\\d+\\s*步|\\bturns\\b|\\bsteps\\b)/\n const isStatsText = (el: Element): boolean => {\n const text = (el.textContent ?? '').trim()\n if (text.length === 0 || text.length > 160) return false\n if (!STATS_LINE_RE.test(text)) return false\n if (el.querySelector('textarea, input, button, select, a') !== null) return false\n return true\n }\n const mark = (): void => {\n if (!narrow.matches) return\n // 清除失效标记:行容器仍含统计特征(轮/步)才保留\n document.querySelectorAll(`[${FRAME_ATTR}=\"stats\"]`).forEach((el) => {\n if (!el.isConnected || !STATS_LINE_RE.test((el.textContent ?? '').trim())) el.removeAttribute(FRAME_ATTR)\n })\n // 候选:含统计特征的短文本元素(全文档搜索,含 composer 内的 stats line),取最浅容器标记\n // 排除 display:contents(无 box,overflow 无效,会误占最浅候选)\n const cands = Array.from(document.querySelectorAll('span, div')).filter((el) => {\n if (!isStatsText(el)) return false\n if (getComputedStyle(el).display === 'contents') return false\n return true\n })\n for (const el of cands) {\n if (el.hasAttribute(FRAME_ATTR)) continue\n let anc = el.parentElement\n let hasOuterCand = false\n while (anc) {\n if (cands.includes(anc)) { hasOuterCand = true; break }\n anc = anc.parentElement\n }\n if (!hasOuterCand) {\n // 标最浅含统计的容器本身(整行),使其可横向滚动\n if (!el.hasAttribute(FRAME_ATTR)) el.setAttribute(FRAME_ATTR, 'stats')\n }\n }\n }\n mark()\n const mo = new MutationObserver(() => { if (narrow.matches) mark() })\n mo.observe(document.documentElement, { childList: true, subtree: true })\n narrow.addEventListener('change', mark)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', mark)\n }\n }, 'dshb-mobile: stats line')\n}\n\ninterface LayoutLike { toggleSidebar(): void }\ninterface SlotsLike {\n inject(name: string, fn: () => unknown): unknown\n register(spec: Record<string, unknown>, component: unknown): unknown\n}\n\n/** 目录抽屉切换按钮(仅切换,不含文件浏览/日志导出等功能按钮)。 */\nfunction DrawerToggle({ toggleSidebar }: { toggleSidebar: () => void }) {\n return (\n <button type=\"button\" data-dshb-mobile=\"toggle\" aria-label=\"打开目录\" title=\"打开目录\" onClick={() => toggleSidebar()}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n </button>\n )\n}\n\nconst PANEL_ICON_SVG =\n '<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">' +\n '<rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '<path d=\"M6 2.5v11\" stroke=\"currentColor\" strokeWidth=\"1.5\"/>' +\n '</svg>'\n\n/**\n * 首页 / hero(无活跃会话)没有 session header,header 上的切换按钮不渲染;\n * 这里在 frame 上注入一个浮动切换按钮(FAB),仅 hero 且抽屉收起时显示。\n */\nfunction installFab(ctx: ClientContext, toggleSidebar: () => void): void {\n ctx.effect(() => {\n const narrow = window.matchMedia(MOBILE_QUERY)\n const FAB_ATTR = 'fab'\n const heroPhase = (): boolean => document.querySelector('[data-phase=\"active\"]') === null\n const drawerOpen = (): boolean => {\n const frame = getFrame()\n return frame !== null && !frame.hasAttribute(COLLAPSED_ATTR)\n }\n let fab: HTMLButtonElement | null = null\n const sync = (): void => {\n if (!narrow.matches || !heroPhase() || drawerOpen()) {\n if (fab !== null) {\n fab.remove()\n fab = null\n }\n return\n }\n const frame = getFrame()\n if (frame === null) return\n if (fab !== null && fab.parentElement === frame) return\n fab?.remove()\n fab = document.createElement('button')\n fab.type = 'button'\n fab.setAttribute(FRAME_ATTR, FAB_ATTR)\n fab.setAttribute('aria-label', '打开目录')\n fab.setAttribute('title', '打开目录')\n fab.innerHTML = PANEL_ICON_SVG\n fab.addEventListener('click', toggleSidebar)\n frame.appendChild(fab)\n }\n sync()\n const mo = new MutationObserver(sync)\n mo.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-phase', 'data-sidebar-collapsed', 'class'],\n })\n narrow.addEventListener('change', sync)\n return () => {\n mo.disconnect()\n narrow.removeEventListener('change', sync)\n fab?.remove()\n }\n }, 'dshb-mobile: hero fab')\n}\n\n/** 安装移动端适配:样式 + viewport + 抽屉标记 + 抽屉交互 + 切换按钮。 */\nexport function installMobile(ctx: ClientContext): void {\n installStyles(ctx)\n installViewport(ctx)\n installFrameMarker(ctx)\n installStatsLine(ctx)\n const layout = (ctx as unknown as { layout?: LayoutLike }).layout\n const slots = (ctx as unknown as { slots?: SlotsLike }).slots\n if (layout && typeof layout.toggleSidebar === 'function') {\n const toggleSidebar = (): void => layout.toggleSidebar()\n installDrawerInteractions(ctx, toggleSidebar)\n installFab(ctx, toggleSidebar)\n }\n if (slots && layout) {\n slots.inject('conversation.session.header.actions', () =>\n slots.register(\n {\n name: 'conversation.session.header.actions',\n id: 'dshb-mobile-toggle',\n order: 10,\n inject: () => ({ toggleSidebar: () => layout.toggleSidebar() }),\n },\n DrawerToggle,\n ),\n )\n }\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { DirectoryFlowOccupant } from './directory-flow.js'\nimport { installMobile } from './mobile.js'\n\nexport const inject = ['connection', 'workspaces', 'slots', 'layout', 'conversation']\n\nconst SECTION_ID = 'dshb-nodes'\n\ninterface NodeProfileView {\n id: string\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n ssh?: {\n host: string\n port: number\n username: string\n auth: { kind: 'password' | 'key' | 'agent'; keyPath?: string }\n }\n docker?: {\n image?: string\n containerId?: string\n mode?: string\n resources?: { cpus?: number; memoryMB?: number }\n }\n hasSecret: { hasPassword: boolean; hasKey: boolean; hasPassphrase: boolean }\n status?: { reachable?: boolean; lastCheckedAt?: string; error?: string }\n provision?: { state: 'provisioning' | 'ready' | 'failed'; error?: string; containerId?: string; updatedAt: string }\n}\n\ninterface SshConfigEntryView {\n host: string\n port: number\n username: string\n identityFile?: string\n hasIdentityFile: boolean\n hasProxyJump: boolean\n}\n\ninterface FormState {\n name: string\n type: 'local-host' | 'local-docker' | 'remote-ssh' | 'remote-docker'\n host: string\n port: string\n username: string\n authKind: 'password' | 'key' | 'agent'\n password: string\n privateKey: string\n passphrase: string\n keyPath: string\n dockerImage: string\n dockerCpus: string\n dockerMemory: string\n}\n\nconst EMPTY_FORM: FormState = {\n name: '',\n type: 'remote-ssh',\n host: '',\n port: '22',\n username: '',\n authKind: 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: '',\n dockerImage: '',\n dockerCpus: '',\n dockerMemory: '',\n}\n\ntype Notice = { kind: 'ok' | 'error'; text: string } | undefined\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '0 10px',\n height: 32,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n fontSize: 14,\n fontFamily: 'inherit',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n outline: 'none',\n}\nconst buttonStyle: CSSProperties = {\n boxSizing: 'border-box',\n height: 36,\n padding: '0 14px',\n borderRadius: 18,\n fontSize: 14,\n lineHeight: '22px',\n fontFamily: 'inherit',\n cursor: 'pointer',\n border: 'none',\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 4,\n}\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-primary)',\n background: 'transparent',\n}\nconst dangerOutlineButtonStyle: CSSProperties = {\n ...buttonStyle,\n border: '1px solid var(--dsw-alias-state-error-primary)',\n color: 'var(--dsw-alias-state-error-primary)',\n background: 'transparent',\n}\n\nfunction useNodes(reloadKey: number): NodeProfileView[] {\n const [nodes, setNodes] = useState<NodeProfileView[]>([])\n useEffect(() => {\n let cancelled = false\n void (async () => {\n try {\n const res = await fetch('/api/dshb/nodes')\n if (!res.ok) return\n const data = (await res.json()) as { nodes?: NodeProfileView[] }\n if (!cancelled) setNodes(data.nodes ?? [])\n } catch {}\n })()\n return () => {\n cancelled = true\n }\n }, [reloadKey])\n return nodes\n}\n\nexport function NodeSection(_props: PropsRuntime<'settings.section'>): ReactElement {\n const [reloadKey, setReloadKey] = useState(0)\n const nodes = useNodes(reloadKey)\n const [selectedId, setSelectedId] = useState<string | 'new'>('new')\n const [form, setForm] = useState<FormState>(EMPTY_FORM)\n const [notice, setNotice] = useState<Notice>(undefined)\n const [busy, setBusy] = useState(false)\n const [testing, setTesting] = useState(false)\n const [testResult, setTestResult] = useState<string | undefined>(undefined)\n const [sshConfigEntries, setSshConfigEntries] = useState<SshConfigEntryView[]>([])\n const [dockerBusy, setDockerBusy] = useState(false)\n\n const flash = useCallback((n: Notice) => {\n setNotice(n)\n if (n) setTimeout(() => setNotice(undefined), 6000)\n }, [])\n\n const reload = useCallback(() => setReloadKey((k) => k + 1), [])\n\n useEffect(() => {\n void (async () => {\n try {\n const res = await fetch('/api/dshb/ssh-config')\n if (!res.ok) return\n const data = (await res.json()) as { entries?: SshConfigEntryView[] }\n setSshConfigEntries(data.entries ?? [])\n } catch {}\n })()\n }, [])\n\n const selectNode = useCallback(\n (id: string | 'new') => {\n setSelectedId(id)\n setTestResult(undefined)\n setTesting(false)\n setDockerBusy(false)\n if (id === 'new') {\n setForm(EMPTY_FORM)\n return\n }\n const node = nodes.find((n) => n.id === id)\n if (!node) return\n setForm({\n name: node.name,\n type: node.type,\n host: node.ssh?.host ?? '',\n port: String(node.ssh?.port ?? 22),\n username: node.ssh?.username ?? '',\n authKind: node.ssh?.auth.kind ?? 'password',\n password: '',\n privateKey: '',\n passphrase: '',\n keyPath: node.ssh?.auth.keyPath ?? '',\n dockerImage: node.docker?.image ?? '',\n dockerCpus: node.docker?.resources?.cpus != null ? String(node.docker?.resources?.cpus) : '',\n dockerMemory: node.docker?.resources?.memoryMB != null ? String(node.docker?.resources?.memoryMB) : '',\n })\n },\n [nodes],\n )\n\n const importSshConfig = useCallback((entry: SshConfigEntryView) => {\n setForm((f) => ({\n ...f,\n type: 'remote-ssh',\n host: entry.host,\n port: String(entry.port),\n username: entry.username,\n authKind: entry.hasIdentityFile ? 'key' : f.authKind,\n keyPath: entry.identityFile ?? f.keyPath,\n name: f.name || entry.host,\n }))\n setTestResult(undefined)\n flash({ kind: 'ok', text: `已从 ~/.ssh/config 导入 ${entry.host}` })\n }, [flash])\n\n const save = useCallback(async () => {\n if (!form.name.trim()) {\n flash({ kind: 'error', text: '请填写节点名称' })\n return\n }\n setBusy(true)\n try {\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n const isDocker = form.type === 'local-docker' || form.type === 'remote-docker'\n const payload: Record<string, unknown> = {\n name: form.name.trim(),\n type: form.type,\n ssh: isRemote\n ? {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n }\n : undefined,\n secrets: isRemote\n ? {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n }\n : undefined,\n docker: isDocker\n ? {\n mode: 'managed' as const,\n ...(form.dockerImage.trim() ? { image: form.dockerImage.trim() } : {}),\n ...(form.dockerCpus ? { resources: { cpus: Number(form.dockerCpus) || undefined } } : {}),\n ...(form.dockerMemory ? { resources: { memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n ...(form.dockerCpus && form.dockerMemory ? { resources: { cpus: Number(form.dockerCpus) || undefined, memoryMB: Number(form.dockerMemory) || undefined } } : {}),\n }\n : undefined,\n }\n const url = selectedId === 'new' ? '/api/dshb/nodes' : `/api/dshb/nodes/${selectedId}`\n const res = await fetch(url, {\n method: selectedId === 'new' ? 'POST' : 'PATCH',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; error?: string; node?: NodeProfileView }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: selectedId === 'new' ? '节点已创建' : '节点已保存' })\n reload()\n if (data.node) setSelectedId(data.node.id)\n } else {\n flash({ kind: 'error', text: data.error ?? '保存失败' })\n }\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setBusy(false)\n }\n }, [form, selectedId, flash, reload])\n\n const remove = useCallback(async () => {\n if (selectedId === 'new') return\n setBusy(true)\n try {\n // 容器类型节点:先删除关联容器(失败不阻断节点删除)\n const node = nodes.find((n) => n.id === selectedId)\n if (node && (node.type === 'local-docker' || node.type === 'remote-docker') && node.docker?.containerId) {\n try {\n await fetch(`/api/dshb/docker/${selectedId}/delete`, { method: 'POST' })\n } catch {\n // 容器删除失败仍继续删节点配置\n }\n }\n const res = await fetch(`/api/dshb/nodes/${selectedId}`, { method: 'DELETE' })\n if (res.ok) {\n flash({ kind: 'ok', text: '节点已删除' })\n setSelectedId('new')\n setForm(EMPTY_FORM)\n reload()\n }\n } catch {\n flash({ kind: 'error', text: '删除失败' })\n } finally {\n setBusy(false)\n }\n }, [selectedId, nodes, flash, reload])\n\n const test = useCallback(async () => {\n if (form.type === 'local-host') {\n flash({ kind: 'error', text: '本地节点无需测试连接' })\n return\n }\n const isRemote = form.type === 'remote-ssh' || form.type === 'remote-docker'\n if (isRemote && !form.host.trim()) {\n flash({ kind: 'error', text: '请填写主机地址' })\n return\n }\n setTesting(true)\n setTestResult(undefined)\n try {\n const payload = isRemote ? {\n ssh: {\n host: form.host.trim(),\n port: Number(form.port) || 22,\n username: form.username.trim(),\n auth: { kind: form.authKind, ...(form.keyPath.trim() ? { keyPath: form.keyPath.trim() } : {}) },\n },\n secrets: {\n ...(form.password ? { password: form.password } : {}),\n ...(form.privateKey ? { privateKey: form.privateKey } : {}),\n ...(form.passphrase ? { passphrase: form.passphrase } : {}),\n },\n } : {}\n const url = selectedId === 'new' ? '/api/dshb/nodes/test-unsaved' : `/api/dshb/nodes/${selectedId}/test`\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const data = (await res.json()) as { ok?: boolean; report?: { ok?: boolean; reachable?: boolean; error?: string; category?: string } }\n const r = data.report\n if (r?.ok && r.reachable) {\n setTestResult('连接成功')\n } else {\n const cat = r?.category ? `(${r.category})` : ''\n setTestResult(`${r?.error ?? '连接失败'}${cat}`)\n }\n reload()\n } catch {\n setTestResult('网络错误')\n } finally {\n setTesting(false)\n }\n }, [form, selectedId, reload])\n\n const dockerAction = useCallback(async (action: 'restart' | 'stop' | 'start' | 'provision') => {\n if (selectedId === 'new') return\n if (action === 'provision') {\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/provision`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string; containerId?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: `容器已就绪:${data.containerId?.slice(0, 12) ?? ''}` })\n } else {\n flash({ kind: 'error', text: data.error ?? '拉起失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n return\n }\n setDockerBusy(true)\n try {\n const res = await fetch(`/api/dshb/docker/${selectedId}/${action}`, { method: 'POST' })\n const data = (await res.json()) as { ok?: boolean; error?: string }\n if (res.ok && data.ok) {\n flash({ kind: 'ok', text: action === 'restart' ? '容器已重启' : action === 'stop' ? '容器已停止' : '容器已启动' })\n } else {\n flash({ kind: 'error', text: data.error ?? '操作失败' })\n }\n reload()\n } catch {\n flash({ kind: 'error', text: '网络错误' })\n } finally {\n setDockerBusy(false)\n }\n }, [selectedId, flash, reload])\n\n const selectedNode = selectedId === 'new' ? undefined : nodes.find((n) => n.id === selectedId)\n\n return (\n <>\n <style>{`\n @media (max-width:767px){\n .dshb-node-section{flex-direction:column!important}\n .dshb-node-section>div:first-child{width:100%!important;border-right:none!important;border-bottom:1px solid var(--dsw-alias-border-l2);padding-right:0!important;padding-bottom:12px;margin-bottom:12px}\n .dshb-node-section>div:last-child{max-width:100%!important}\n .dshb-form-row{flex-direction:column!important;gap:8px!important}\n .dshb-form-row>label{width:100%!important;flex:none!important}\n }\n `}</style>\n <div className=\"dshb-node-section\" style={{ display: 'flex', gap: 20, minHeight: 320, overflow: 'hidden', maxWidth: '100%', width: '100%', boxSizing: 'border-box' }}>\n <div style={{ width: 200, flexShrink: 0, borderRight: '1px solid var(--dsw-alias-border-l2)', paddingRight: 16 }}>\n <button type=\"button\" onClick={() => selectNode('new')} style={{ ...primaryButtonStyle, width: '100%', marginBottom: 10 }}>\n 新建节点\n </button>\n {nodes.map((n) => (\n <div\n key={n.id}\n onClick={() => selectNode(n.id)}\n style={{\n padding: '8px 10px',\n borderRadius: 6,\n cursor: 'pointer',\n marginBottom: 4,\n background: selectedId === n.id ? 'var(--dsw-alias-interactive-bg-active, var(--dsw-alias-interactive-bg-hover))' : 'transparent',\n fontSize: 13,\n }}\n >\n <div style={{ fontWeight: 500 }}>{n.name}</div>\n <div style={{ fontSize: 11, opacity: 0.7, display: 'flex', alignItems: 'center', gap: 4 }}>\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n background: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n {n.type === 'local-host' ? '默认环境(本地)' : n.type === 'remote-ssh' ? '远程 SSH' : n.type === 'local-docker' ? '本地 Docker' : n.type === 'remote-docker' ? '远程 Docker' : n.type}\n <span style={{ marginLeft: 4, color: n.status?.reachable === true ? 'var(--dsw-alias-state-success-primary)' : n.status?.reachable === false ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-dimmed)' }}>\n {n.status?.reachable === true ? '在线' : n.status?.reachable === false ? '离线' : '未知'}\n </span>\n </div>\n {n.provision && (\n <div style={{ fontSize: 11, marginTop: 2, color: n.provision.state === 'ready' ? 'var(--dsw-alias-state-success-primary)' : n.provision.state === 'failed' ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-state-warn-label)' }}>\n {n.provision.state === 'provisioning' ? '容器拉起中…' : n.provision.state === 'ready' ? '容器已就绪' : `容器拉起失败:${n.provision.error ?? '未知错误'}`}\n </div>\n )}\n </div>\n ))}\n {nodes.length === 0 && <div style={{ fontSize: 12, opacity: 0.6 }}>暂无节点</div>}\n </div>\n\n <div style={{ flex: 1, maxWidth: 480, minWidth: 0, overflow: 'hidden' }}>\n {sshConfigEntries.length > 0 && (\n <div style={{ marginBottom: 14 }}>\n <label style={{ fontSize: 12, opacity: 0.75, display: 'block', marginBottom: 4 }}>从 ~/.ssh/config 导入</label>\n <select\n style={inputStyle}\n value=\"\"\n onChange={(e) => {\n const entry = sshConfigEntries[Number(e.target.value)]\n if (entry) importSshConfig(entry)\n e.target.value = ''\n }}\n >\n <option value=\"\">选择主机…</option>\n {sshConfigEntries.map((entry, i) => (\n <option key={entry.host} value={i}>\n {entry.host}:{entry.port}{entry.username ? ` (${entry.username})` : ''}{entry.hasProxyJump ? ' 跳板' : ''}\n </option>\n ))}\n </select>\n </div>\n )}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点名称\n <input style={inputStyle} value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))} placeholder=\"例如:构建机\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 节点类型\n <select style={inputStyle} value={form.type} onChange={(e) => setForm((f) => ({ ...f, type: e.target.value as FormState['type'] }))}>\n <option value=\"remote-ssh\">远程 SSH 宿主机</option>\n <option value=\"remote-docker\">远程 Docker(SSH 通道)</option>\n <option value=\"local-host\">默认环境(本地)</option>\n <option value=\"local-docker\">本地 Docker 容器</option>\n </select>\n </label>\n\n {(form.type === 'remote-ssh' || form.type === 'remote-docker') && (\n <>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 主机地址\n <input style={inputStyle} value={form.host} onChange={(e) => setForm((f) => ({ ...f, host: e.target.value }))} placeholder=\"192.168.1.10\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, width: 90 }}>\n 端口\n <input style={inputStyle} value={form.port} onChange={(e) => setForm((f) => ({ ...f, port: e.target.value }))} />\n </label>\n </div>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 用户名\n <input style={inputStyle} value={form.username} onChange={(e) => setForm((f) => ({ ...f, username: e.target.value }))} placeholder=\"root\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 认证方式\n <select style={inputStyle} value={form.authKind} onChange={(e) => setForm((f) => ({ ...f, authKind: e.target.value as FormState['authKind'] }))}>\n <option value=\"password\">密码</option>\n <option value=\"key\">私钥</option>\n <option value=\"agent\">ssh-agent</option>\n </select>\n </label>\n {form.authKind === 'password' && (\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 密码{selectedNode?.hasSecret.hasPassword ? '(已保存,留空保持不变)' : ''}\n <input style={inputStyle} type=\"password\" value={form.password} onChange={(e) => setForm((f) => ({ ...f, password: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n )}\n {form.authKind === 'key' && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥内容{selectedNode?.hasSecret.hasKey ? '(已保存,留空保持不变)' : ''}\n <textarea style={{ ...inputStyle, minHeight: 90, resize: 'vertical' }} value={form.privateKey} onChange={(e) => setForm((f) => ({ ...f, privateKey: e.target.value }))} placeholder=\"-----BEGIN OPENSSH PRIVATE KEY-----\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 私钥 passphrase(可选)\n <input style={inputStyle} type=\"password\" value={form.passphrase} onChange={(e) => setForm((f) => ({ ...f, passphrase: e.target.value }))} autoComplete=\"new-password\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 或私钥文件路径(可选,优先使用内容)\n <input style={inputStyle} value={form.keyPath} onChange={(e) => setForm((f) => ({ ...f, keyPath: e.target.value }))} placeholder=\"~/.ssh/id_ed25519\" />\n </label>\n </>\n )}\n </>\n )}\n\n {(form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13 }}>\n 镜像地址\n <input style={inputStyle} value={form.dockerImage} onChange={(e) => setForm((f) => ({ ...f, dockerImage: e.target.value }))} placeholder=\"alpine:latest\" />\n </label>\n <div className=\"dshb-form-row\" style={{ display: 'flex', gap: 10 }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n CPU 核数(可选)\n <input style={inputStyle} value={form.dockerCpus} onChange={(e) => setForm((f) => ({ ...f, dockerCpus: e.target.value }))} placeholder=\"2\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, flex: 1, minWidth: 0 }}>\n 内存 MB(可选)\n <input style={inputStyle} value={form.dockerMemory} onChange={(e) => setForm((f) => ({ ...f, dockerMemory: e.target.value }))} placeholder=\"512\" />\n </label>\n </div>\n </>\n )}\n\n {testResult !== undefined && (\n <div style={{ fontSize: 13, color: testResult === '连接成功' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{testResult}</div>\n )}\n\n <div style={{ display: 'flex', gap: 10, marginTop: 6, flexWrap: 'wrap' }}>\n <button type=\"button\" onClick={() => void save()} disabled={busy} style={primaryButtonStyle}>\n {selectedId === 'new' ? '创建节点' : '保存'}\n </button>\n {(form.type === 'remote-ssh' || form.type === 'remote-docker' || (selectedId !== 'new' && form.type === 'local-docker')) && (\n <button type=\"button\" onClick={() => void test()} disabled={busy || testing} style={secondaryButtonStyle}>\n {testing ? '测试中…' : '测试连接'}\n </button>\n )}\n {selectedId !== 'new' && (form.type === 'local-docker' || form.type === 'remote-docker') && (\n <>\n <button type=\"button\" onClick={() => void dockerAction('provision')} disabled={busy || dockerBusy} style={primaryButtonStyle}>\n {dockerBusy ? '操作中…' : '拉起容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('restart')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '重启容器'}\n </button>\n <button type=\"button\" onClick={() => void dockerAction('stop')} disabled={busy || dockerBusy} style={secondaryButtonStyle}>\n {dockerBusy ? '操作中…' : '停止容器'}\n </button>\n </>\n )}\n {selectedId !== 'new' && (\n <button type=\"button\" onClick={() => void remove()} disabled={busy} style={dangerOutlineButtonStyle}>\n 删除\n </button>\n )}\n {notice && <span style={{ fontSize: 13, alignSelf: 'center', color: notice.kind === 'ok' ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' }}>{notice.text}</span>}\n </div>\n </div>\n </div>\n </div>\n </>\n )\n}\n\nexport function apply(ctx: ClientContext): void {\n const globalStyle = document.createElement('style')\n globalStyle.textContent = `\n html, body { overflow-x: hidden !important; max-width: 100vw !important }\n * { min-width: 0 !important; }\n table { display: block !important; overflow-x: auto !important; }\n img, video, canvas, svg { max-width: 100% !important; height: auto !important }\n pre, code { white-space: pre-wrap !important; word-break: break-all !important }\n input, select, textarea { max-width: 100% !important; }\n [class*=\"content\"], [class*=\"main\"], [class*=\"panel\"], [class*=\"page\"], [class*=\"wrapper\"], [class*=\"container\"] { max-width: 100% !important; overflow-x: hidden !important }\n body > div { max-width: 100vw !important; overflow-x: hidden !important; }\n body > div > div { max-width: 100vw !important; overflow-x: hidden !important; }\n `\n document.head.appendChild(globalStyle)\n\n const fixOverflow = () => {\n const vw = document.documentElement.clientWidth\n const walk = (el: Element) => {\n if (!(el instanceof HTMLElement)) return\n if (el.scrollWidth > vw && el !== document.documentElement && el !== document.body) {\n el.style.maxWidth = '100vw'\n el.style.overflowX = 'hidden'\n }\n for (const child of el.children) walk(child)\n }\n walk(document.documentElement)\n }\n fixOverflow()\n new MutationObserver(() => requestAnimationFrame(fixOverflow)).observe(document.body, { childList: true, subtree: true })\n\n installMobile(ctx)\n\n ctx.plugin({\n inject: ['slots', 'settingsScope'],\n apply: (sub: ClientContext): void => {\n sub.slots.inject('settings.section', () =>\n sub.slots.register({ name: 'settings.section', id: SECTION_ID, order: 110, label: () => '工作节点' }, NodeSection),\n )\n sub.slots.inject('conversation.hero.workspace.directoryFlow', () =>\n sub.slots.register({ name: 'conversation.hero.workspace.directoryFlow' }, DirectoryFlowOccupant),\n )\n sub.slots.inject('sidebar.workspaces.directoryFlow', () =>\n sub.slots.register({ name: 'sidebar.workspaces.directoryFlow' }, DirectoryFlowOccupant),\n )\n },\n })\n\n const workspaces = (ctx as unknown as { workspaces?: { openPath(p: string): Promise<void> } }).workspaces\n if (workspaces && typeof workspaces.openPath === 'function') {\n const originalOpenPath = workspaces.openPath.bind(workspaces)\n workspaces.openPath = async (path: string): Promise<void> => {\n try {\n const res = await fetch(`/api/dshb/remote/bound?path=${encodeURIComponent(path)}`)\n if (res.ok) {\n const data = (await res.json()) as { bound?: boolean; kind?: 'file' | 'dir'; error?: string }\n if (data.bound) {\n if (data.kind !== 'file') return originalOpenPath(path)\n const a = document.createElement('a')\n a.href = `/api/dshb/remote/file?path=${encodeURIComponent(path)}`\n a.download = ''\n document.body.appendChild(a)\n a.click()\n a.remove()\n return\n }\n }\n } catch {\n // 探测失败则回退宿主原生打开\n }\n return originalOpenPath(path)\n }\n }\n\n const ICON_SVG: Record<string, string> = {\n auth: `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 7C9.3807 7 10.5 5.8807 10.5 4.5C10.5 3.1193 9.3807 2 8 2C6.6193 2 5.5 3.1193 5.5 4.5C5.5 5.8807 6.6193 7 8 7Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 14C3 11.2386 5.2386 9 8 9C10.7614 9 13 11.2386 13 14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n 'dshb-nodes': `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"12.5\" cy=\"4\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"8\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M3.5 6V8C3.5 9.1 4.4 10 5.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/><path d=\"M12.5 6V8C12.5 9.1 11.6 10 10.5 10H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>`,\n }\n const ICON_LABELS: Record<string, string> = { '认证': 'auth', '工作节点': 'dshb-nodes' }\n\n const observer = new MutationObserver(() => {\n const cells = document.querySelectorAll('button[class*=\"navCell\"]')\n for (const cell of Array.from(cells)) {\n const label = cell.querySelector('span[class*=\"navLabel\"]')\n if (!label) continue\n const text = label.textContent ?? ''\n const iconKey = ICON_LABELS[text]\n if (!iconKey) continue\n const iconSlot = cell.querySelector('[class*=\"navIcon\"]')\n if (!iconSlot) continue\n if (iconSlot.getAttribute('data-dshb-icon') === iconKey) continue\n iconSlot.innerHTML = ICON_SVG[iconKey] ?? ''\n iconSlot.setAttribute('data-dshb-icon', iconKey)\n }\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n"],"mappings":"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"}
|