dsh-code-server-app 0.3.21 → 0.3.22

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.
Files changed (42) hide show
  1. package/README.en.md +77 -18
  2. package/README.md +70 -20
  3. package/assets/extensions/dshcs-editor-bridge/extension.js +83 -47
  4. package/assets/extensions/dshcs-editor-bridge/lib/ask-panel.js +343 -174
  5. package/assets/extensions/dshcs-editor-bridge/lib/bridge-client.js +30 -4
  6. package/assets/extensions/dshcs-editor-bridge/package.json +2 -2
  7. package/assets/extensions/dshcs-editor-bridge/webview/THIRD-PARTY.md +21 -0
  8. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  9. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  10. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  11. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  12. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  13. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  14. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  15. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  16. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  17. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  18. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  19. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  20. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  21. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  22. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  23. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  24. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  25. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  26. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  27. package/assets/extensions/dshcs-editor-bridge/webview/fonts/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  28. package/assets/extensions/dshcs-editor-bridge/webview/src/app.jsx +189 -0
  29. package/assets/extensions/dshcs-editor-bridge/webview/src/approval.jsx +53 -0
  30. package/assets/extensions/dshcs-editor-bridge/webview/src/official-tokens.css +8 -0
  31. package/assets/extensions/dshcs-editor-bridge/webview/src/panel.css +283 -0
  32. package/assets/extensions/dshcs-editor-bridge/webview/src/thread.jsx +72 -0
  33. package/assets/extensions/dshcs-editor-bridge/webview/thread.css +1 -0
  34. package/assets/extensions/dshcs-editor-bridge/webview/thread.js +462 -0
  35. package/lib/bridge-approval.mjs +189 -0
  36. package/lib/bridge-session.mjs +3 -1
  37. package/lib/bridge-thread.mjs +345 -0
  38. package/lib/bridge.mjs +15 -6
  39. package/lib/index.js +142 -17
  40. package/package.json +29 -6
  41. package/vendor/VENDOR.json +1 -1
  42. package/lib/bridge-answer.mjs +0 -155
@@ -0,0 +1,189 @@
1
+ // dshcs-editor-bridge / webview/src/app.jsx —— 「问 DSH」面板(0.2.3)
2
+ //
3
+ // 面板 = 外壳(上下文 / 状态 / 输入框 / 授权卡片)+ **DSH 官方渲染的对话内容**。
4
+ // 对话数据来自宿主 `/sync` 的 `thread` 字段:只有**新内容**(0.3.22 起,历史不重放),
5
+ // 助手正文逐条交给官方 markdown 渲染器(thread.jsx)。
6
+ //
7
+ // 与扩展侧的分工(消息协议,postMessage):
8
+ // 扩展 → 面板:`{type:'state', …}`(面板状态载荷,形状见 lib/ask-panel.js 的 panelPayload)
9
+ // 面板 → 扩展:`{type:'ready'}` / `{type:'ask', text}` / `{type:'approve', id, outcome}`
10
+ //
11
+ // 纯逻辑(状态合并 / 载荷解析)在 lib/ask-panel.js 里,与扩展侧同一份,可在 Node 里单测;
12
+ // 本文件只做"把状态画出来"。
13
+
14
+ import { useEffect, useRef, useState } from 'react';
15
+ import { createRoot } from 'react-dom/client';
16
+
17
+ import panel from '../../lib/ask-panel.js';
18
+ import { ThreadEntry } from './thread.jsx';
19
+ import { ApprovalCard } from './approval.jsx';
20
+ import './panel.css';
21
+
22
+ /** 打包时的官方渲染器版本(由 scripts/build-webview.mjs 注入)。 */
23
+ const RENDERER_VERSION = typeof __DSHCS_RENDERER_VERSION__ === 'string' ? __DSHCS_RENDERER_VERSION__ : '';
24
+ /** 打包时的官方 UI 包名(用于版本不一致时的提示文案)。 */
25
+ const RENDERER_PACKAGE = typeof __DSHCS_RENDERER_PACKAGE__ === 'string' ? __DSHCS_RENDERER_PACKAGE__ : '';
26
+
27
+ const vscode = acquireVsCodeApi();
28
+
29
+ /** 面板外壳的初始视图状态。 */
30
+ const INITIAL = panel.createViewState();
31
+
32
+ function App() {
33
+ const [view, setView] = useState(INITIAL);
34
+ const [now, setNow] = useState(() => Date.now());
35
+ const [draft, setDraft] = useState('');
36
+ const [sending, setSending] = useState(false);
37
+ const [scriptError, setScriptError] = useState(null);
38
+ const [decided, setDecided] = useState({});
39
+ const logRef = useRef(null);
40
+ const stickRef = useRef(true);
41
+ const boxRef = useRef(null);
42
+
43
+ // 扩展 → 面板的消息。
44
+ useEffect(() => {
45
+ const onMessage = (event) => {
46
+ const data = event.data;
47
+ if (data === null || typeof data !== 'object') return;
48
+ if (data.type === 'state') setView((prev) => panel.applyPayload(prev, data));
49
+ };
50
+ window.addEventListener('message', onMessage);
51
+ // 面板脚本自己出错也要说出来:静默空白是最难查的一种失败。
52
+ const onError = (event) => setScriptError(`面板脚本出错:${event && event.message ? event.message : '未知'}`);
53
+ const onRejection = (event) => setScriptError(`面板脚本出错:${event && event.reason ? String(event.reason) : '未知'}`);
54
+ window.addEventListener('error', onError);
55
+ window.addEventListener('unhandledrejection', onRejection);
56
+ vscode.postMessage({ type: 'ready' });
57
+ return () => {
58
+ window.removeEventListener('message', onMessage);
59
+ window.removeEventListener('error', onError);
60
+ window.removeEventListener('unhandledrejection', onRejection);
61
+ };
62
+ }, []);
63
+
64
+ // 暗色主题:官方令牌表用 body[data-ds-dark-theme] 切换调色板。
65
+ useEffect(() => {
66
+ const sync = () => {
67
+ const dark = document.body.classList.contains('vscode-dark')
68
+ || document.body.classList.contains('vscode-high-contrast');
69
+ if (dark) document.body.setAttribute('data-ds-dark-theme', '');
70
+ else document.body.removeAttribute('data-ds-dark-theme');
71
+ };
72
+ sync();
73
+ const observer = new MutationObserver(sync);
74
+ observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
75
+ return () => observer.disconnect();
76
+ }, []);
77
+
78
+ // 授权倒计时:只在有卡片时跑。
79
+ useEffect(() => {
80
+ if (view.approvals.length === 0) return undefined;
81
+ const timer = window.setInterval(() => setNow(Date.now()), 250);
82
+ return () => window.clearInterval(timer);
83
+ }, [view.approvals.length]);
84
+
85
+ // 已提交的决策:卡片消失后清掉(不然 decided 会一直涨)。
86
+ useEffect(() => {
87
+ setDecided((prev) => {
88
+ const ids = new Set(view.approvals.map((item) => item.id));
89
+ const next = {};
90
+ let changed = false;
91
+ for (const [id, value] of Object.entries(prev)) {
92
+ if (ids.has(id)) next[id] = value;
93
+ else changed = true;
94
+ }
95
+ return changed ? next : prev;
96
+ });
97
+ }, [view.approvals]);
98
+
99
+ // 贴底滚动:用户主动往上翻时不打扰。
100
+ useEffect(() => {
101
+ const node = logRef.current;
102
+ if (node !== null && stickRef.current) node.scrollTop = node.scrollHeight;
103
+ }, [view.entries]);
104
+
105
+ // 宿主状态回来了就解除"发送中"的按钮锁。
106
+ useEffect(() => {
107
+ if (view.status !== 'sending') setSending(false);
108
+ }, [view.status]);
109
+
110
+ const onScroll = () => {
111
+ const node = logRef.current;
112
+ if (node === null) return;
113
+ stickRef.current = node.scrollHeight - node.scrollTop - node.clientHeight < 48;
114
+ };
115
+
116
+ const submit = () => {
117
+ const text = draft.trim();
118
+ if (text === '' || sending) return;
119
+ setSending(true);
120
+ setDraft('');
121
+ vscode.postMessage({ type: 'ask', text });
122
+ };
123
+
124
+ const onKeyDown = (event) => {
125
+ if (event.key === 'Enter' && event.shiftKey === false) {
126
+ event.preventDefault();
127
+ submit();
128
+ }
129
+ };
130
+
131
+ const onDecide = (id, outcome) => {
132
+ setDecided((prev) => ({ ...prev, [id]: outcome }));
133
+ vscode.postMessage({ type: 'approve', id, outcome });
134
+ };
135
+
136
+ const status = scriptError === null ? view.statusText : scriptError;
137
+ const versionNote = view.uiVersion !== null && view.uiVersion !== undefined && RENDERER_VERSION !== ''
138
+ && view.uiVersion !== RENDERER_VERSION
139
+ ? `面板内置的渲染器是 ${RENDERER_PACKAGE}@${RENDERER_VERSION},而当前 DSH 界面是 ${view.uiVersion}:`
140
+ + '排版可能有差异(重建面板:pnpm run build:webview)。'
141
+ : null;
142
+
143
+ return (
144
+ <div className="dshcs-app">
145
+ <header className="dshcs-header">
146
+ <span className="dshcs-where">{view.contextText}</span>
147
+ {RENDERER_VERSION === '' ? null : <span className="dshcs-version">渲染器 {RENDERER_VERSION}</span>}
148
+ </header>
149
+
150
+ {view.threadError === null ? null : <div className="dshcs-warn">{view.threadError}</div>}
151
+ {versionNote === null ? null : <div className="dshcs-warn">{versionNote}</div>}
152
+
153
+ <main className="dshcs-log" ref={logRef} onScroll={onScroll}>
154
+ {view.entries.length === 0
155
+ ? <div className="dshcs-empty">在下面提问:DSH 的回答会像 DSH 界面那样显示在这里。</div>
156
+ : view.entries.map((entry, index) => (
157
+ <ThreadEntry key={`${entry.role}-${index}-${entry.callId ?? entry.approvalId ?? ''}`} entry={entry} />
158
+ ))}
159
+ </main>
160
+
161
+ {view.approvals.map((item) => (
162
+ <ApprovalCard
163
+ key={item.id}
164
+ item={item}
165
+ holdMs={view.approvalHoldMs}
166
+ now={now}
167
+ decided={decided[item.id] ?? null}
168
+ onDecide={onDecide}
169
+ />
170
+ ))}
171
+
172
+ <div className="dshcs-status" data-status={view.status}>{status}</div>
173
+
174
+ <footer className="dshcs-footer">
175
+ <textarea
176
+ ref={boxRef}
177
+ value={draft}
178
+ placeholder="问 DSH…(Enter 发送,Shift+Enter 换行)"
179
+ onChange={(event) => setDraft(event.target.value)}
180
+ onKeyDown={onKeyDown}
181
+ autoFocus
182
+ />
183
+ <button type="button" disabled={sending || draft.trim() === ''} onClick={submit}>发送</button>
184
+ </footer>
185
+ </div>
186
+ );
187
+ }
188
+
189
+ createRoot(document.getElementById('root')).render(<App />);
@@ -0,0 +1,53 @@
1
+ // dshcs-editor-bridge / webview/src/approval.jsx —— 待决授权卡片(0.2.3)
2
+ //
3
+ // 背景(见 lib/bridge-approval.mjs):DSH 的敏感动作(写工作区外的文件、执行命令)会走
4
+ // `approval/request` 这条 agent 作用域的 waterfall。面板在旁边看的时候先接住它:
5
+ // - 用户在这张卡片上点「允许一次 / 拒绝」→ 立刻生效(官方卡片不再出现);
6
+ // - 窗口内没人答(倒计时走完)→ 交回官方链路,DSH 界面里照旧弹同一张卡片。
7
+ //
8
+ // 卡片只做两件事:**显示**这次请求要干什么(工具名 + 原因),**回答**它。
9
+ // 没有任何"记住这次选择""以后都允许"的入口 —— 授权只对这一次动作有效。
10
+
11
+ /** 毫秒 → 剩余秒数(向上取整,0 表示已过期)。 */
12
+ function secondsLeft(item, holdMs, now) {
13
+ const deadline = (Number.isSafeInteger(item.at) ? item.at : now) + holdMs;
14
+ return Math.max(0, Math.ceil((deadline - now) / 1000));
15
+ }
16
+
17
+ export function ApprovalCard({ item, holdMs, now, decided, onDecide }) {
18
+ const left = secondsLeft(item, holdMs, now);
19
+ const expired = left <= 0;
20
+ const choice = decided ?? null;
21
+ const locked = expired || choice !== null;
22
+
23
+ return (
24
+ <div className="dshcs-approval" data-decided={choice ?? undefined}>
25
+ <div className="dshcs-approval-head">
26
+ <span className="dshcs-approval-title">需要你的授权</span>
27
+ <span className="dshcs-approval-timer">
28
+ {expired ? '已交给 DSH 界面' : `${left}s 后交给 DSH 界面`}
29
+ </span>
30
+ </div>
31
+ <div className="dshcs-approval-body">
32
+ <span className="dshcs-approval-tool">{item.toolName}</span>
33
+ {item.reason === '' ? null : <div className="dshcs-approval-reason">{item.reason}</div>}
34
+ </div>
35
+ <div className="dshcs-approval-actions">
36
+ <button type="button" disabled={locked} onClick={() => onDecide(item.id, 'allowed-once')}>
37
+ 允许一次
38
+ </button>
39
+ <button type="button" disabled={locked} onClick={() => onDecide(item.id, 'rejected')}>
40
+ 拒绝
41
+ </button>
42
+ {choice === null ? null : (
43
+ <span className="dshcs-approval-note">
44
+ {choice === 'allowed-once' ? '已允许一次(DSH 继续执行)' : '已拒绝'}
45
+ </span>
46
+ )}
47
+ {choice === null && expired ? (
48
+ <span className="dshcs-approval-note">这条请求已交给 DSH 界面,请在那边处理</span>
49
+ ) : null}
50
+ </div>
51
+ </div>
52
+ );
53
+ }
@@ -0,0 +1,8 @@
1
+ /* 官方设计令牌(DSh 界面同一套):由 scripts/build-webview.mjs 从
2
+ * @deepseek-ai/dsh-client-ui-theme@0.1.5-rc.2 的 lib/client.js 内联 CSS 原样抽出,
3
+ * 不要手改 —— 这个文件是生成物,重新构建会覆盖。 */
4
+ :root{--dsw-font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;--ds-font-family-code:"SF Mono", "JetBrains Mono", "Fira Code", Consolas, "Liberation Mono", Menlo, Courier, "PingFang SC", "Microsoft YaHei";--ds-ease-in-out:cubic-bezier(.4, 0, .2, 1);--ds-transition-duration:.2s;--ds-transition-duration-fast:.1s;--ds-transition-duration-slow:.3s}
5
+ body{--dsw-static-amber-100:#fef5e7;--dsw-static-amber-400:#f7ad31;--dsw-static-amber-500:#f59e0b;--dsw-static-amber-600:#dd8629;--dsw-static-amber-900:#27241f;--dsw-static-blue-100:#dbeafe;--dsw-static-blue-300:#93c5fd;--dsw-static-blue-400:#60a5fa;--dsw-static-blue-450:#4d93f8;--dsw-static-blue-500:#3b82f6;--dsw-static-blue-50:#eff6ff;--dsw-static-blue-50p:#eaf3ff;--dsw-static-blue-600:#2563eb;--dsw-static-blue-75:#e5f0ff;--dsw-static-blue-800:#1e40af;--dsw-static-blue-900:#0e3074;--dsw-static-blue-950:#172554;--dsw-static-deepseek-100:#e4edfd;--dsw-static-deepseek-200:#d3e2ff;--dsw-static-deepseek-300:#b7c8fe;--dsw-static-deepseek-400:#679efe;--dsw-static-deepseek-450:#5686fe;--dsw-static-deepseek-500:#4176e6;--dsw-static-deepseek-50:#edf3fe;--dsw-static-deepseek-600:#4868b2;--dsw-static-deepseek-700-delete:#2f4c8f;--dsw-static-deepseek-800:#34415b;--dsw-static-deepseek-900:#283142;--dsw-static-green-100:#e6faed;--dsw-static-green-400:#4ed17e;--dsw-static-green-500:#22c55e;--dsw-static-green-900:#233c2c;--dsw-static-neutral-00:#fff;--dsw-static-neutral-1000:#000;--dsw-static-neutral-100:#f5f5f5;--dsw-static-neutral-150:#ededed;--dsw-static-neutral-200:#e5e5e5;--dsw-static-neutral-250:#dcdcdc;--dsw-static-neutral-300:#d4d4d4;--dsw-static-neutral-400:#a2a4a6;--dsw-static-neutral-500:#7f8287;--dsw-static-neutral-50:#fafafa;--dsw-static-neutral-550:#65676b;--dsw-static-neutral-600:#545557;--dsw-static-neutral-700:#3c3c3d;--dsw-static-neutral-800:#292929;--dsw-static-neutral-850:#212123;--dsw-static-neutral-900:#0f0f0f;--dsw-static-neutral-bluish-00:#fff;--dsw-static-neutral-bluish-1000:#0f1115;--dsw-static-neutral-bluish-100:#ebeef2;--dsw-static-neutral-bluish-150:#e9ecf2;--dsw-static-neutral-bluish-200:#e1e5ee;--dsw-static-neutral-bluish-300:#cfd3d6;--dsw-static-neutral-bluish-400:#adb2b8;--dsw-static-neutral-bluish-500:#979da6;--dsw-static-neutral-bluish-50:#f9fafb;--dsw-static-neutral-bluish-600:#81858c;--dsw-static-neutral-bluish-60:#f5f6f7;--dsw-static-neutral-bluish-700:#61666b;--dsw-static-neutral-bluish-750:#43454a;--dsw-static-neutral-bluish-75:#f1f3f5;--dsw-static-neutral-bluish-800:#353638;--dsw-static-neutral-bluish-850:#2c2c2e;--dsw-static-neutral-bluish-875:#232324;--dsw-static-neutral-bluish-900:#1b1b1c;--dsw-static-neutral-bluish-950:#151517;--dsw-static-red-100:#fee2e2;--dsw-static-red-400:#f25a5a;--dsw-static-red-500:#ef4444;--dsw-static-red-50:#fef2f2;--dsw-static-red-600:#ec1313;--dsw-static-red-900:#570c0c}body[data-ds-dark-theme]{--dsw-static-amber-100:#fef5e7;--dsw-static-amber-400:#f7ad31;--dsw-static-amber-500:#f59e0b;--dsw-static-amber-600:#dd8629;--dsw-static-amber-900:#27241f;--dsw-static-blue-100:#dbeafe;--dsw-static-blue-300:#93c5fd;--dsw-static-blue-400:#60a5fa;--dsw-static-blue-450:#4d93f8;--dsw-static-blue-500:#3b82f6;--dsw-static-blue-50:#eff6ff;--dsw-static-blue-50p:#eaf3ff;--dsw-static-blue-600:#2563eb;--dsw-static-blue-75:#e5f0ff;--dsw-static-blue-800:#1e40af;--dsw-static-blue-900:#0e3074;--dsw-static-blue-950:#172554;--dsw-static-deepseek-100:#e4edfd;--dsw-static-deepseek-200:#d3e2ff;--dsw-static-deepseek-300:#b7c8fe;--dsw-static-deepseek-400:#679efe;--dsw-static-deepseek-450:#5686fe;--dsw-static-deepseek-500:#4176e6;--dsw-static-deepseek-50:#edf3fe;--dsw-static-deepseek-600:#4868b2;--dsw-static-deepseek-700-delete:#2f4c8f;--dsw-static-deepseek-800:#34415b;--dsw-static-deepseek-900:#283142;--dsw-static-green-100:#e6faed;--dsw-static-green-400:#4ed17e;--dsw-static-green-500:#22c55e;--dsw-static-green-900:#233c2c;--dsw-static-neutral-00:#fff;--dsw-static-neutral-1000:#000;--dsw-static-neutral-100:#f5f5f5;--dsw-static-neutral-150:#ededed;--dsw-static-neutral-200:#e5e5e5;--dsw-static-neutral-250:#dcdcdc;--dsw-static-neutral-300:#d4d4d4;--dsw-static-neutral-400:#a2a4a6;--dsw-static-neutral-500:#7f8287;--dsw-static-neutral-50:#fafafa;--dsw-static-neutral-550:#65676b;--dsw-static-neutral-600:#545557;--dsw-static-neutral-700:#3c3c3d;--dsw-static-neutral-800:#292929;--dsw-static-neutral-850:#212123;--dsw-static-neutral-900:#0f0f0f;--dsw-static-neutral-bluish-00:#fff;--dsw-static-neutral-bluish-1000:#0f1115;--dsw-static-neutral-bluish-100:#ebeef2;--dsw-static-neutral-bluish-150:#e9ecf2;--dsw-static-neutral-bluish-200:#e1e5ee;--dsw-static-neutral-bluish-300:#cfd3d6;--dsw-static-neutral-bluish-400:#adb2b8;--dsw-static-neutral-bluish-500:#979da6;--dsw-static-neutral-bluish-50:#f9fafb;--dsw-static-neutral-bluish-600:#81858c;--dsw-static-neutral-bluish-60:#f9fafb;--dsw-static-neutral-bluish-700:#61666b;--dsw-static-neutral-bluish-750:#43454a;--dsw-static-neutral-bluish-75:#f1f3f5;--dsw-static-neutral-bluish-800:#353638;--dsw-static-neutral-bluish-850:#2c2c2e;--dsw-static-neutral-bluish-875:#232324;--dsw-static-neutral-bluish-900:#1b1b1c;--dsw-static-neutral-bluish-950:#151517;--dsw-static-red-100:#fee2e2;--dsw-static-red-400:#f25a5a;--dsw-static-red-500:#ef4444;--dsw-static-red-50:#fef2f2;--dsw-static-red-600:#ec1313;--dsw-static-red-900:#570c0c}body{--dsw-alias-bg-base:var(--dsw-static-neutral-bluish-00);--dsw-alias-bg-layer-1:var(--dsw-static-neutral-bluish-00);--dsw-alias-bg-layer-2:var(--dsw-static-neutral-bluish-00);--dsw-alias-bg-layer-3:var(--dsw-static-neutral-bluish-00);--dsw-alias-bg-mask-1:#0000003d;--dsw-alias-bg-mask-2:#0000001f;--dsw-alias-bg-mask-3:#0000007a;--dsw-alias-bg-mask-photo:#000000e0;--dsw-alias-bg-mask-drop:#ffffffb3;--dsw-alias-bg-module-platform:var(--dsw-static-neutral-bluish-60);--dsw-alias-bg-multi-select:var(--dsw-static-neutral-bluish-60);--dsw-alias-bg-overlay:var(--dsw-static-neutral-bluish-150);--dsw-alias-bg-skeleton:#0000000a;--dsw-alias-border-inverted2:#0000;--dsw-alias-border-inverted:#0000;--dsw-alias-border-l1:#0000000a;--dsw-alias-border-l2-darkmode-thin:#0000001a;--dsw-alias-border-l2:#0000001a;--dsw-alias-border-l3:#0000001f;--dsw-alias-border-l4:#00000029;--dsw-alias-brand-primary-invert:var(--dsw-static-neutral-bluish-1000);--dsw-alias-brand-primary-new-colorprimary-new-color:#4176e6;--dsw-alias-brand-primary:var(--dsw-static-neutral-bluish-1000);--dsw-alias-brand-text:var(--dsw-static-neutral-bluish-1000);--dsw-alias-button-contrast-fill:var(--dsw-static-neutral-bluish-700);--dsw-alias-button-elevated-fill:var(--dsw-static-neutral-bluish-00);--dsw-alias-button-floating-fill:var(--dsw-static-neutral-bluish-00);--dsw-alias-button-floating-hover:var(--dsw-static-neutral-bluish-75);--dsw-alias-button-ghost-active-border:var(--dsw-static-neutral-bluish-500);--dsw-alias-button-ghost-active-fill:var(--dsw-static-neutral-bluish-100);--dsw-alias-button-ghost-active-hover:var(--dsw-static-neutral-bluish-150);--dsw-alias-button-info-fill:var(--dsw-static-deepseek-500);--dsw-alias-button-info-hover:var(--dsw-static-deepseek-400);--dsw-alias-button-primary-dimmed:var(--dsw-static-neutral-bluish-100);--dsw-alias-button-primary-fill:var(--dsw-alias-brand-primary);--dsw-alias-button-primary-hover:var(--dsw-static-neutral-bluish-750);--dsw-alias-button-tool-bar-fill-invisible:#1f1f1f5c;--dsw-alias-button-tool-bar-fill:#54555780;--dsw-alias-button-tool-bar-hover:#54555799;--dsw-alias-interactive-bg-active:#2631481a;--dsw-alias-interactive-bg-hover-accent:#26314824;--dsw-alias-interactive-bg-hover-danger:#ec13130d;--dsw-alias-interactive-bg-hover-solid:var(--dsw-static-neutral-bluish-75);--dsw-alias-interactive-bg-hover:#2631480f;--dsw-alias-label-caption:var(--dsw-static-neutral-bluish-400);--dsw-alias-label-dimmed:var(--dsw-static-neutral-bluish-200);--dsw-alias-label-primary-bluish:var(--dsw-static-blue-900);--dsw-alias-label-primary-dimmed:var(--dsw-static-neutral-bluish-950);--dsw-alias-label-primary-foreground:var(--dsw-static-neutral-bluish-00);--dsw-alias-label-primary-inverted:var(--dsw-static-neutral-bluish-00);--dsw-alias-label-primary:var(--dsw-static-neutral-bluish-1000);--dsw-alias-label-secondary:var(--dsw-static-neutral-bluish-700);--dsw-alias-label-tertiary:var(--dsw-static-neutral-bluish-600);--dsw-alias-link:var(--dsw-static-deepseek-500);--dsw-alias-markdown-citation:var(--dsw-static-neutral-bluish-100);--dsw-alias-markdown-code-block-banner:var(--dsw-static-neutral-bluish-50);--dsw-alias-markdown-code-block:var(--dsw-static-neutral-bluish-50);--dsw-alias-markdown-code-segment-selected:var(--dsw-static-neutral-bluish-00);--dsw-alias-markdown-code-segment-unselected:var(--dsw-static-neutral-bluish-75);--dsw-alias-markdown-inline-code:var(--dsw-static-neutral-50);--dsw-alias-markdown-placeholder:var(--dsw-static-neutral-bluish-60);--dsw-alias-markdown-tag:var(--dsw-static-neutral-bluish-75);--dsw-alias-scrollbar-bg-l1:var(--dsw-static-neutral-200);--dsw-alias-scrollbar-bg-l2:var(--dsw-static-neutral-200);--dsw-alias-scrollbar-hover-l1:var(--dsw-static-neutral-300);--dsw-alias-scrollbar-hover-l2:var(--dsw-static-neutral-300);--dsw-alias-state-business-primary:var(--dsw-static-deepseek-500);--dsw-alias-state-business-tertiary:var(--dsw-static-deepseek-100);--dsw-alias-state-error-primary:var(--dsw-static-red-600);--dsw-alias-state-error-secondary:var(--dsw-static-red-400);--dsw-alias-state-success-primary:var(--dsw-static-green-500);--dsw-alias-state-success-secondary:var(--dsw-static-green-400);--dsw-alias-state-success-tertiary:var(--dsw-static-green-100);--dsw-alias-state-warn-label:var(--dsw-static-amber-600);--dsw-alias-state-warn-primary:var(--dsw-static-amber-500);--dsw-alias-state-warn-secondary:var(--dsw-static-amber-400);--dsw-alias-state-warn-tertiary:var(--dsw-static-amber-100);--dsw-alias-toast-bg:var(--dsw-static-neutral-bluish-800);--dsw-alias-tooltip-bg:var(--dsw-static-neutral-bluish-850);--dsw-specific-bubble-highlight:var(--dsw-static-deepseek-200);--dsw-specific-bubble:var(--dsw-static-deepseek-50);--dsw-specific-input-major:var(--dsw-static-neutral-bluish-00);--dsw-specific-login-input:var(--dsw-static-neutral-bluish-50);--dsw-specific-menu:var(--dsw-alias-bg-layer-3);--dsw-specific-selector:var(--dsw-static-neutral-bluish-60);--dsw-specific-sidebar-fill:var(--dsw-static-neutral-bluish-50);--dsw-specific-sidebar-nav-item-active-accent:var(--dsw-static-deepseek-100);--dsw-specific-sidebar-nav-item-active:var(--dsw-static-neutral-bluish-100);--dsw-specific-sidebar-nav-item-hover:var(--dsw-static-neutral-bluish-75);--dsw-specific-tip:var(--dsw-static-neutral-bluish-60)}body[data-ds-dark-theme]{--dsw-alias-bg-base:var(--dsw-static-neutral-bluish-950);--dsw-alias-bg-layer-1:var(--dsw-static-neutral-bluish-875);--dsw-alias-bg-layer-2:var(--dsw-static-neutral-bluish-850);--dsw-alias-bg-layer-3:var(--dsw-static-neutral-bluish-800);--dsw-alias-bg-mask-1:#00000080;--dsw-alias-bg-mask-2:#0003;--dsw-alias-bg-mask-3:#0000007a;--dsw-alias-bg-mask-photo:#000000e0;--dsw-alias-bg-mask-drop:#272730b3;--dsw-alias-bg-module-platform:var(--dsw-static-neutral-bluish-800);--dsw-alias-bg-multi-select:var(--dsw-static-neutral-850);--dsw-alias-bg-overlay:var(--dsw-static-neutral-bluish-700);--dsw-alias-bg-skeleton:#ffffff14;--dsw-alias-border-inverted2:#ffffff14;--dsw-alias-border-inverted:#ffffff0f;--dsw-alias-border-l1:#ffffff0f;--dsw-alias-border-l2-darkmode-thin:#ffffff0f;--dsw-alias-border-l2:#ffffff1f;--dsw-alias-border-l3:#ffffff29;--dsw-alias-border-l4:#fff3;--dsw-alias-brand-primary-invert:var(--dsw-static-neutral-bluish-50);--dsw-alias-brand-primary-new-colorprimary-new-color:var(--dsw-static-deepseek-450);--dsw-alias-brand-primary:var(--dsw-static-neutral-bluish-50);--dsw-alias-brand-text:var(--dsw-static-neutral-bluish-50);--dsw-alias-button-contrast-fill:var(--dsw-static-neutral-bluish-50);--dsw-alias-button-elevated-fill:var(--dsw-static-neutral-bluish-750);--dsw-alias-button-floating-fill:var(--dsw-static-neutral-bluish-850);--dsw-alias-button-floating-hover:var(--dsw-static-neutral-bluish-800);--dsw-alias-button-ghost-active-border:var(--dsw-static-neutral-bluish-600);--dsw-alias-button-ghost-active-fill:var(--dsw-static-neutral-bluish-750);--dsw-alias-button-ghost-active-hover:var(--dsw-static-neutral-bluish-700);--dsw-alias-button-info-fill:var(--dsw-static-deepseek-400);--dsw-alias-button-info-hover:var(--dsw-static-deepseek-500);--dsw-alias-button-primary-dimmed:var(--dsw-static-neutral-bluish-750);--dsw-alias-button-primary-fill:var(--dsw-alias-brand-primary);--dsw-alias-button-primary-hover:var(--dsw-static-neutral-bluish-100);--dsw-alias-button-tool-bar-fill-invisible:#1f1f1f5c;--dsw-alias-button-tool-bar-fill:#54555780;--dsw-alias-button-tool-bar-hover:#54555799;--dsw-alias-interactive-bg-active:#ffffff24;--dsw-alias-interactive-bg-hover-accent:#ffffff3d;--dsw-alias-interactive-bg-hover-danger:#f25a5a26;--dsw-alias-interactive-bg-hover-solid:var(--dsw-static-neutral-bluish-800);--dsw-alias-interactive-bg-hover:#ffffff14;--dsw-alias-label-caption:var(--dsw-static-neutral-bluish-600);--dsw-alias-label-dimmed:var(--dsw-static-neutral-bluish-750);--dsw-alias-label-primary-bluish:var(--dsw-static-neutral-bluish-50);--dsw-alias-label-primary-dimmed:var(--dsw-static-neutral-bluish-100);--dsw-alias-label-primary-foreground:var(--dsw-static-neutral-bluish-1000);--dsw-alias-label-primary-inverted:var(--dsw-static-neutral-bluish-800);--dsw-alias-label-primary:var(--dsw-static-neutral-bluish-50);--dsw-alias-label-secondary:var(--dsw-static-neutral-bluish-300);--dsw-alias-label-tertiary:var(--dsw-static-neutral-bluish-400);--dsw-alias-link:var(--dsw-static-deepseek-400);--dsw-alias-markdown-citation:var(--dsw-static-neutral-bluish-800);--dsw-alias-markdown-code-block-banner:var(--dsw-static-neutral-bluish-850);--dsw-alias-markdown-code-block:var(--dsw-static-neutral-bluish-900);--dsw-alias-markdown-code-segment-selected:var(--dsw-static-neutral-bluish-800);--dsw-alias-markdown-code-segment-unselected:var(--dsw-static-neutral-bluish-900);--dsw-alias-markdown-inline-code:var(--dsw-static-neutral-800);--dsw-alias-markdown-placeholder:var(--dsw-static-neutral-bluish-850);--dsw-alias-markdown-tag:var(--dsw-static-neutral-bluish-850);--dsw-alias-scrollbar-bg-l1:var(--dsw-static-neutral-700);--dsw-alias-scrollbar-bg-l2:var(--dsw-static-neutral-600);--dsw-alias-scrollbar-hover-l1:var(--dsw-static-neutral-600);--dsw-alias-scrollbar-hover-l2:var(--dsw-static-neutral-550);--dsw-alias-state-business-primary:var(--dsw-static-deepseek-400);--dsw-alias-state-business-tertiary:var(--dsw-static-deepseek-800);--dsw-alias-state-error-primary:var(--dsw-static-red-400);--dsw-alias-state-error-secondary:var(--dsw-static-red-400);--dsw-alias-state-success-primary:var(--dsw-static-green-500);--dsw-alias-state-success-secondary:var(--dsw-static-green-400);--dsw-alias-state-success-tertiary:var(--dsw-static-green-900);--dsw-alias-state-warn-label:var(--dsw-static-amber-600);--dsw-alias-state-warn-primary:var(--dsw-static-amber-500);--dsw-alias-state-warn-secondary:var(--dsw-static-amber-400);--dsw-alias-state-warn-tertiary:var(--dsw-static-amber-900);--dsw-alias-toast-bg:var(--dsw-static-neutral-bluish-750);--dsw-alias-tooltip-bg:var(--dsw-static-neutral-bluish-750);--dsw-specific-bubble-highlight:var(--dsw-static-neutral-bluish-750);--dsw-specific-bubble:var(--dsw-static-neutral-bluish-850);--dsw-specific-input-major:var(--dsw-static-neutral-bluish-850);--dsw-specific-login-input:var(--dsw-static-neutral-bluish-900);--dsw-specific-menu:var(--dsw-alias-bg-layer-3);--dsw-specific-selector:var(--dsw-static-neutral-bluish-800);--dsw-specific-sidebar-fill:var(--dsw-static-neutral-bluish-900);--dsw-specific-sidebar-nav-item-active-accent:var(--dsw-static-neutral-bluish-800);--dsw-specific-sidebar-nav-item-active:var(--dsw-static-neutral-bluish-750);--dsw-specific-sidebar-nav-item-hover:var(--dsw-static-neutral-bluish-850);--dsw-specific-tip:var(--dsw-static-neutral-bluish-800)}
6
+ body{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l1);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l1);--dsh-scrollbar-width:8px}@supports not selector(::-webkit-scrollbar){body,body *{scrollbar-width:thin;scrollbar-color:var(--dsh-scrollbar-thumb) transparent}}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--dsh-scrollbar-thumb);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--dsh-scrollbar-thumb-hover)}::-webkit-scrollbar-corner{background:0 0}
7
+ body{--dsw-linear-gradient-think:linear-gradient(180deg, #fff 20.19%, #fff0 100%);--dsw-linear-think-select:linear-gradient(180deg, #f5f6f7 20.19%, #f5f6f700 100%);--dsw-shadow-lv1:0 2px 4px 0 #0000000d;--dsw-shadow-lv1-blur:0 4px 12px 0 #00000005;--dsw-shadow-lv2:0 4px 12px 0 #00000005, 0 2px 8px 0 #0000000a;--dsw-shadow-lv3:0 0 1px 0 #0003, 0 0 4px 0 #00000005, 0 12px 32px 0 #00000014;--dsw-elevation-stroke-color:var(--dsw-alias-border-l4);--dsw-mask-blur:blur(2px)}body,body *{--dsw-elevation-stroke:0 0 0 .5px var(--dsw-elevation-stroke-color);--dsw-elevation-panel:var(--dsw-elevation-stroke), 0 3px 8px 0 #00000008, 0 0 16px 0 #00000005;--dsw-elevation-prominent:var(--dsw-elevation-stroke), 0 3px 8px 0 #0000000a, 0 0 20px 0 #0000000d;--dsw-elevation-soft:var(--dsw-elevation-stroke), 0 4px 16px 0 #00000008, 0 0 24px 0 #00000008}body[data-ds-dark-theme]{--dsw-linear-gradient-think:linear-gradient(180deg, #151517 20.19%, #15151700 100%);--dsw-linear-think-select:linear-gradient(180deg, #232325 20.19%, #23232500 100%)}body{--dsh-content-font-delta:calc(var(--dsh-content-font-size,14px) - 14px);--dsh-content-font-size-secondary:min(calc(var(--dsh-content-font-size,14px) - 1px), max(13px, calc(var(--dsh-content-font-size,14px) - 2px)));--dsh-content-font-delta-secondary:calc(var(--dsh-content-font-size-secondary) - 13px);--dsw-font-markdown-h1:700 calc(21px + var(--dsh-content-font-delta)) / calc(30px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-h1-font-family:var(--dsw-font-family);--dsw-font-markdown-h1-font-weight:700;--dsw-font-markdown-h1-line-height:calc(30px + var(--dsh-content-font-delta));--dsw-font-markdown-h1-font-size:calc(21px + var(--dsh-content-font-delta));--dsw-font-markdown-h1-font-style:normal;--dsw-font-markdown-h2:700 calc(19px + var(--dsh-content-font-delta)) / calc(28px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-h2-font-family:var(--dsw-font-family);--dsw-font-markdown-h2-font-weight:700;--dsw-font-markdown-h2-line-height:calc(28px + var(--dsh-content-font-delta));--dsw-font-markdown-h2-font-size:calc(19px + var(--dsh-content-font-delta));--dsw-font-markdown-h2-font-style:normal;--dsw-font-markdown-h3:700 calc(18px + var(--dsh-content-font-delta)) / calc(26px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-h3-font-family:var(--dsw-font-family);--dsw-font-markdown-h3-font-weight:700;--dsw-font-markdown-h3-line-height:calc(26px + var(--dsh-content-font-delta));--dsw-font-markdown-h3-font-size:calc(18px + var(--dsh-content-font-delta));--dsw-font-markdown-h3-font-style:normal;--dsw-font-markdown-h4:600 var(--dsh-content-font-size,14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-h4-font-family:var(--dsw-font-family);--dsw-font-markdown-h4-font-weight:600;--dsw-font-markdown-h4-line-height:calc(24px + var(--dsh-content-font-delta));--dsw-font-markdown-h4-font-size:var(--dsh-content-font-size,14px);--dsw-font-markdown-h4-font-style:normal;--dsw-font-markdown-base:var(--dsh-content-font-size,14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-base-font-family:var(--dsw-font-family);--dsw-font-markdown-base-font-weight:400;--dsw-font-markdown-base-line-height:calc(24px + var(--dsh-content-font-delta));--dsw-font-markdown-base-font-size:var(--dsh-content-font-size,14px);--dsw-font-markdown-base-font-style:normal;--dsw-font-markdown-base-strong:600 var(--dsh-content-font-size,14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-base-strong-font-family:var(--dsw-font-family);--dsw-font-markdown-base-strong-font-weight:600;--dsw-font-markdown-base-strong-line-height:calc(24px + var(--dsh-content-font-delta));--dsw-font-markdown-base-strong-font-size:var(--dsh-content-font-size,14px);--dsw-font-markdown-base-strong-font-style:normal;--dsw-font-markdown-base-italic:italic var(--dsh-content-font-size,14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-base-italic-font-family:var(--dsw-font-family);--dsw-font-markdown-base-italic-font-weight:400;--dsw-font-markdown-base-italic-line-height:calc(24px + var(--dsh-content-font-delta));--dsw-font-markdown-base-italic-font-size:var(--dsh-content-font-size,14px);--dsw-font-markdown-base-italic-font-style:italic;--dsw-font-markdown-base-strong-italic:italic 600 var(--dsh-content-font-size,14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);--dsw-font-markdown-base-strong-italic-font-family:var(--dsw-font-family);--dsw-font-markdown-base-strong-italic-font-weight:600;--dsw-font-markdown-base-strong-italic-line-height:calc(24px + var(--dsh-content-font-delta));--dsw-font-markdown-base-strong-italic-font-size:var(--dsh-content-font-size,14px);--dsw-font-markdown-base-strong-italic-font-style:italic;--dsw-font-markdown-table:var(--dsh-content-font-size-secondary,13px)/calc(22px + var(--dsh-content-font-delta-secondary,0px)) var(--dsw-font-family);--dsw-font-markdown-table-font-family:var(--dsw-font-family);--dsw-font-markdown-table-font-weight:400;--dsw-font-markdown-table-line-height:calc(22px + var(--dsh-content-font-delta-secondary,0px));--dsw-font-markdown-table-font-size:var(--dsh-content-font-size-secondary,13px);--dsw-font-markdown-table-font-style:normal;--dsw-font-markdown-table-head:500 var(--dsh-content-font-size-secondary,13px)/calc(22px + var(--dsh-content-font-delta-secondary,0px)) var(--dsw-font-family);--dsw-font-markdown-table-head-font-family:var(--dsw-font-family);--dsw-font-markdown-table-head-font-weight:500;--dsw-font-markdown-table-head-line-height:calc(22px + var(--dsh-content-font-delta-secondary,0px));--dsw-font-markdown-table-head-font-size:var(--dsh-content-font-size-secondary,13px);--dsw-font-markdown-table-head-font-style:normal;--dsw-font-markdown-small:12px/20px var(--dsw-font-family);--dsw-font-markdown-small-font-family:var(--dsw-font-family);--dsw-font-markdown-small-font-weight:400;--dsw-font-markdown-small-line-height:20px;--dsw-font-markdown-small-font-size:12px;--dsw-font-markdown-small-font-style:normal;--dsw-font-markdown-small-strong:600 12px/20px var(--dsw-font-family);--dsw-font-markdown-small-strong-font-family:var(--dsw-font-family);--dsw-font-markdown-small-strong-font-weight:600;--dsw-font-markdown-small-strong-line-height:20px;--dsw-font-markdown-small-strong-font-size:12px;--dsw-font-markdown-small-strong-font-style:normal;--dsw-font-markdown-small-italic:italic 12px/20px var(--dsw-font-family);--dsw-font-markdown-small-italic-font-family:var(--dsw-font-family);--dsw-font-markdown-small-italic-font-weight:400;--dsw-font-markdown-small-italic-line-height:20px;--dsw-font-markdown-small-italic-font-size:12px;--dsw-font-markdown-small-italic-font-style:italic;--dsw-font-markdown-small-strong-italic:italic 600 12px/20px var(--dsw-font-family);--dsw-font-markdown-small-strong-italic-font-family:var(--dsw-font-family);--dsw-font-markdown-small-strong-italic-font-weight:600;--dsw-font-markdown-small-strong-italic-line-height:20px;--dsw-font-markdown-small-strong-italic-font-size:12px;--dsw-font-markdown-small-strong-italic-font-style:italic;--dsw-font-markdown-code:12px/19px var(--ds-font-family-code);--dsw-font-markdown-code-font-family:var(--ds-font-family-code);--dsw-font-markdown-code-font-weight:400;--dsw-font-markdown-code-line-height:19px;--dsw-font-markdown-code-font-size:12px;--dsw-font-markdown-code-font-style:normal;--dsw-font-markdown-code-block:11px/19px var(--ds-font-family-code);--dsw-font-markdown-code-block-font-family:var(--ds-font-family-code);--dsw-font-markdown-code-block-font-weight:400;--dsw-font-markdown-code-block-line-height:19px;--dsw-font-markdown-code-block-font-size:11px;--dsw-font-markdown-code-block-font-style:normal;--dsw-font-markdown-code-block-small:11px/16px var(--ds-font-family-code);--dsw-font-markdown-code-block-small-font-family:var(--ds-font-family-code);--dsw-font-markdown-code-block-small-font-weight:400;--dsw-font-markdown-code-block-small-line-height:16px;--dsw-font-markdown-code-block-small-font-size:11px;--dsw-font-markdown-code-block-small-font-style:normal;--dsw-font-xl-24:600 24px/32px var(--dsw-font-family);--dsw-font-xl-24-font-family:var(--dsw-font-family);--dsw-font-xl-24-font-weight:600;--dsw-font-xl-24-line-height:32px;--dsw-font-xl-24-font-size:24px;--dsw-font-xl-24-font-style:normal;--dsw-font-l-20:500 20px/28px var(--dsw-font-family);--dsw-font-l-20-font-family:var(--dsw-font-family);--dsw-font-l-20-font-weight:500;--dsw-font-l-20-line-height:28px;--dsw-font-l-20-font-size:20px;--dsw-font-l-20-font-style:normal;--dsw-font-m-18:500 16px/28px var(--dsw-font-family);--dsw-font-m-18-font-family:var(--dsw-font-family);--dsw-font-m-18-font-weight:500;--dsw-font-m-18-line-height:28px;--dsw-font-m-18-font-size:16px;--dsw-font-m-18-font-style:normal;--dsw-font-base-16:16px/24px var(--dsw-font-family);--dsw-font-base-16-font-family:var(--dsw-font-family);--dsw-font-base-16-font-weight:400;--dsw-font-base-16-line-height:24px;--dsw-font-base-16-font-size:16px;--dsw-font-base-16-font-style:normal;--dsw-font-base-strong-16:500 16px/24px var(--dsw-font-family);--dsw-font-base-strong-16-font-family:var(--dsw-font-family);--dsw-font-base-strong-16-font-weight:500;--dsw-font-base-strong-16-line-height:24px;--dsw-font-base-strong-16-font-size:16px;--dsw-font-base-strong-16-font-style:normal;--dsw-font-s-14:14px/22px var(--dsw-font-family);--dsw-font-s-14-font-family:var(--dsw-font-family);--dsw-font-s-14-font-weight:400;--dsw-font-s-14-line-height:22px;--dsw-font-s-14-font-size:14px;--dsw-font-s-14-font-style:normal;--dsw-font-s-strong-14:500 14px/22px var(--dsw-font-family);--dsw-font-s-strong-14-font-family:var(--dsw-font-family);--dsw-font-s-strong-14-font-weight:500;--dsw-font-s-strong-14-line-height:22px;--dsw-font-s-strong-14-font-size:14px;--dsw-font-s-strong-14-font-style:normal;--dsw-font-xs-13:13px/20px var(--dsw-font-family);--dsw-font-xs-13-font-family:var(--dsw-font-family);--dsw-font-xs-13-font-weight:400;--dsw-font-xs-13-line-height:20px;--dsw-font-xs-13-font-size:13px;--dsw-font-xs-13-font-style:normal;--dsw-font-xs-strong-13:500 13px/20px var(--dsw-font-family);--dsw-font-xs-strong-13-font-family:var(--dsw-font-family);--dsw-font-xs-strong-13-font-weight:500;--dsw-font-xs-strong-13-line-height:20px;--dsw-font-xs-strong-13-font-size:13px;--dsw-font-xs-strong-13-font-style:normal;--dsw-font-xxs-12:12px/18px var(--dsw-font-family);--dsw-font-xxs-12-font-family:var(--dsw-font-family);--dsw-font-xxs-12-font-weight:400;--dsw-font-xxs-12-line-height:18px;--dsw-font-xxs-12-font-size:12px;--dsw-font-xxs-12-font-style:normal;--dsw-font-xxs-strong-12:500 12px/18px var(--dsw-font-family);--dsw-font-xxs-strong-12-font-family:var(--dsw-font-family);--dsw-font-xxs-strong-12-font-weight:500;--dsw-font-xxs-strong-12-line-height:18px;--dsw-font-xxs-strong-12-font-size:12px;--dsw-font-xxs-strong-12-font-style:normal;--dsw-font-xxxs-11:11px/14px var(--dsw-font-family);--dsw-font-xxxs-11-font-family:var(--dsw-font-family);--dsw-font-xxxs-11-font-weight:400;--dsw-font-xxxs-11-line-height:14px;--dsw-font-xxxs-11-font-size:11px;--dsw-font-xxxs-11-font-style:normal;--dsw-font-xxxs-strong-11:500 11px/14px var(--dsw-font-family);--dsw-font-xxxs-strong-11-font-family:var(--dsw-font-family);--dsw-font-xxxs-strong-11-font-weight:500;--dsw-font-xxxs-strong-11-line-height:14px;--dsw-font-xxxs-strong-11-font-size:11px;--dsw-font-xxxs-strong-11-font-style:normal}
8
+ :root{--shiki-foreground:var(--dsw-alias-label-primary);--shiki-background:var(--dsw-alias-markdown-code-block);--shiki-token-constant:#1c7ed6;--shiki-token-string:#2f9e44;--shiki-token-comment:#868e96;--shiki-token-keyword:#d6336c;--shiki-token-parameter:#e8590c;--shiki-token-function:#6741d9;--shiki-token-string-expression:#2b8a3e;--shiki-token-punctuation:#495057;--shiki-token-link:#1971c2}body[data-ds-dark-theme]{--shiki-token-constant:#4dabf7;--shiki-token-string:#69db7c;--shiki-token-comment:#adb5bd;--shiki-token-keyword:#faa2c1;--shiki-token-parameter:#ffa94d;--shiki-token-function:#b197fc;--shiki-token-string-expression:#8ce99a;--shiki-token-punctuation:#ced4da;--shiki-token-link:#74c0fc}
@@ -0,0 +1,283 @@
1
+ /* dshcs-editor-bridge / webview/src/panel.css —— 「问 DSH」面板自己的样式(0.2.3)
2
+ *
3
+ * 面板的外壳(标题 / 状态 / 输入框 / 授权卡片)用 VS Code 主题变量,跟编辑器原生面板一致;
4
+ * 消息正文**不在这里排版** —— 交给 DSH 官方渲染器的 CSS(MarkdownText.module.css /
5
+ * CodeBlock.module.css),它依赖一套设计令牌(--dsw-* / --dsl-* / --shiki-*),
6
+ * 由下面这行提供:构建脚本从官方发布物
7
+ * (`@deepseek-ai/dsh-client-ui-theme` 的 lib/client.js 里内联的 CSS)原样抽出来,
8
+ * 所以与 DSH 界面用的是同一套令牌(见 scripts/build-webview.mjs)。
9
+ *
10
+ * 顺序要紧:@import 必须在最前(官方令牌先落地),后面的覆盖规则才生效。
11
+ */
12
+
13
+ @import "./official-tokens.css";
14
+
15
+ :root {
16
+ color-scheme: light dark;
17
+ }
18
+
19
+ html,
20
+ body,
21
+ #root {
22
+ height: 100%;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ /* 官方令牌表会设 body 的背景与前景(DSH 的颜色);面板跟随编辑器主题,所以覆盖掉。 */
28
+ background: var(--vscode-editor-background);
29
+ color: var(--vscode-foreground);
30
+ font-family: var(--vscode-font-family);
31
+ font-size: var(--vscode-font-size, 13px);
32
+ overflow: hidden;
33
+ }
34
+
35
+ .dshcs-app {
36
+ display: flex;
37
+ flex-direction: column;
38
+ height: 100%;
39
+ }
40
+
41
+ .dshcs-header {
42
+ display: flex;
43
+ align-items: baseline;
44
+ gap: 8px;
45
+ padding: 8px 12px;
46
+ border-bottom: 1px solid var(--vscode-panel-border, rgba(128, 128, 128, 0.35));
47
+ font-size: 12px;
48
+ opacity: 0.9;
49
+ }
50
+
51
+ .dshcs-header .dshcs-where {
52
+ flex: 1;
53
+ overflow: hidden;
54
+ text-overflow: ellipsis;
55
+ white-space: nowrap;
56
+ }
57
+
58
+ .dshcs-header .dshcs-version {
59
+ opacity: 0.7;
60
+ font-family: var(--vscode-editor-font-family, monospace);
61
+ font-size: 11px;
62
+ }
63
+
64
+ .dshcs-warn {
65
+ margin: 8px 12px 0;
66
+ padding: 6px 8px;
67
+ border: 1px solid var(--vscode-inputValidation-warningBorder, #b89500);
68
+ background: var(--vscode-inputValidation-warningBackground, rgba(184, 149, 0, 0.15));
69
+ border-radius: 4px;
70
+ font-size: 12px;
71
+ white-space: pre-wrap;
72
+ }
73
+
74
+ .dshcs-log {
75
+ flex: 1;
76
+ overflow-y: auto;
77
+ padding: 12px 14px 4px;
78
+ }
79
+
80
+ .dshcs-empty {
81
+ opacity: 0.6;
82
+ font-size: 12px;
83
+ padding: 4px 0;
84
+ }
85
+
86
+ /* ---- 消息条目:排版交给官方渲染器,这里只管气泡与间距 ---- */
87
+
88
+ .dshcs-msg {
89
+ margin-bottom: 14px;
90
+ }
91
+
92
+ .dshcs-user {
93
+ display: flex;
94
+ justify-content: flex-end;
95
+ }
96
+
97
+ .dshcs-bubble {
98
+ max-width: 88%;
99
+ padding: 6px 10px;
100
+ border-radius: 8px;
101
+ background: var(--vscode-input-background, rgba(128, 128, 128, 0.12));
102
+ border: 1px solid var(--vscode-input-border, rgba(128, 128, 128, 0.25));
103
+ white-space: pre-wrap;
104
+ word-break: break-word;
105
+ }
106
+
107
+ .dshcs-bubble[data-status="sending"] {
108
+ opacity: 0.6;
109
+ }
110
+
111
+ .dshcs-bubble[data-status="error"] {
112
+ border-color: var(--vscode-inputValidation-errorBorder, #be1100);
113
+ }
114
+
115
+ .dshcs-assistant {
116
+ word-break: break-word;
117
+ }
118
+
119
+ .dshcs-tool {
120
+ display: flex;
121
+ align-items: baseline;
122
+ gap: 8px;
123
+ margin: 4px 0 10px;
124
+ padding: 4px 8px;
125
+ border-left: 2px solid var(--vscode-panel-border, rgba(128, 128, 128, 0.4));
126
+ font-size: 12px;
127
+ opacity: 0.85;
128
+ }
129
+
130
+ .dshcs-tool .dshcs-tool-name {
131
+ font-family: var(--vscode-editor-font-family, monospace);
132
+ }
133
+
134
+ .dshcs-tool .dshcs-tool-summary {
135
+ flex: 1;
136
+ overflow: hidden;
137
+ text-overflow: ellipsis;
138
+ white-space: nowrap;
139
+ opacity: 0.8;
140
+ }
141
+
142
+ .dshcs-tool .dshcs-tool-state[data-state="error"] {
143
+ color: var(--vscode-errorForeground, #f48771);
144
+ }
145
+
146
+ /* ---- 授权卡片:桥里唯一的"非只读"操作,必须一眼看清 ---- */
147
+
148
+ .dshcs-approval {
149
+ margin: 8px 12px;
150
+ padding: 8px 10px;
151
+ border: 1px solid var(--vscode-inputValidation-warningBorder, #b89500);
152
+ background: var(--vscode-inputValidation-warningBackground, rgba(184, 149, 0, 0.12));
153
+ border-radius: 6px;
154
+ }
155
+
156
+ .dshcs-approval[data-decided] {
157
+ opacity: 0.75;
158
+ }
159
+
160
+ .dshcs-approval-head {
161
+ display: flex;
162
+ align-items: baseline;
163
+ gap: 8px;
164
+ font-size: 12px;
165
+ margin-bottom: 4px;
166
+ }
167
+
168
+ .dshcs-approval-title {
169
+ font-weight: 600;
170
+ }
171
+
172
+ .dshcs-approval-timer {
173
+ flex: 1;
174
+ text-align: right;
175
+ opacity: 0.8;
176
+ }
177
+
178
+ .dshcs-approval-body {
179
+ font-size: 12px;
180
+ margin-bottom: 6px;
181
+ word-break: break-word;
182
+ }
183
+
184
+ .dshcs-approval-tool {
185
+ font-family: var(--vscode-editor-font-family, monospace);
186
+ }
187
+
188
+ .dshcs-approval-reason {
189
+ margin-top: 2px;
190
+ opacity: 0.9;
191
+ white-space: pre-wrap;
192
+ }
193
+
194
+ .dshcs-approval-actions {
195
+ display: flex;
196
+ align-items: center;
197
+ gap: 8px;
198
+ flex-wrap: wrap;
199
+ }
200
+
201
+ .dshcs-approval-actions button {
202
+ padding: 3px 10px;
203
+ border: 1px solid var(--vscode-button-border, transparent);
204
+ border-radius: 4px;
205
+ cursor: pointer;
206
+ color: var(--vscode-button-foreground);
207
+ background: var(--vscode-button-background);
208
+ font-family: inherit;
209
+ font-size: 12px;
210
+ }
211
+
212
+ .dshcs-approval-actions button + button {
213
+ color: var(--vscode-button-secondaryForeground, var(--vscode-foreground));
214
+ background: var(--vscode-button-secondaryBackground, rgba(128, 128, 128, 0.2));
215
+ }
216
+
217
+ .dshcs-approval-actions button:disabled {
218
+ opacity: 0.5;
219
+ cursor: default;
220
+ }
221
+
222
+ .dshcs-approval-note {
223
+ font-size: 12px;
224
+ opacity: 0.85;
225
+ }
226
+
227
+ /* ---- 状态行 + 输入框 ---- */
228
+
229
+ .dshcs-status {
230
+ padding: 0 12px 6px;
231
+ font-size: 12px;
232
+ min-height: 16px;
233
+ opacity: 0.85;
234
+ }
235
+
236
+ .dshcs-status[data-status="error"] {
237
+ color: var(--vscode-errorForeground, #f48771);
238
+ opacity: 1;
239
+ }
240
+
241
+ .dshcs-footer {
242
+ display: flex;
243
+ align-items: flex-end;
244
+ gap: 8px;
245
+ padding: 8px 12px;
246
+ border-top: 1px solid var(--vscode-panel-border, rgba(128, 128, 128, 0.35));
247
+ }
248
+
249
+ .dshcs-footer textarea {
250
+ flex: 1;
251
+ min-height: 46px;
252
+ max-height: 40vh;
253
+ resize: vertical;
254
+ box-sizing: border-box;
255
+ padding: 6px 8px;
256
+ border: 1px solid var(--vscode-input-border, rgba(128, 128, 128, 0.35));
257
+ border-radius: 4px;
258
+ color: var(--vscode-input-foreground);
259
+ background: var(--vscode-input-background);
260
+ font-family: inherit;
261
+ font-size: inherit;
262
+ }
263
+
264
+ .dshcs-footer textarea:focus {
265
+ outline: 1px solid var(--vscode-focusBorder);
266
+ outline-offset: -1px;
267
+ }
268
+
269
+ .dshcs-footer button {
270
+ padding: 6px 14px;
271
+ border: none;
272
+ border-radius: 4px;
273
+ cursor: pointer;
274
+ color: var(--vscode-button-foreground);
275
+ background: var(--vscode-button-background);
276
+ font-family: inherit;
277
+ font-size: inherit;
278
+ }
279
+
280
+ .dshcs-footer button:disabled {
281
+ opacity: 0.5;
282
+ cursor: default;
283
+ }