cc-viewer 1.6.293 → 1.6.295
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/cli.js +7 -2
- package/dist/assets/App-Br-u2TKk.js +2 -0
- package/dist/assets/App-eFrjLzF_.css +1 -0
- package/dist/assets/{MdxEditorPanel-Cf01KF6Z.js → MdxEditorPanel-Cy4egsQx.js} +1 -1
- package/dist/assets/{Mobile-BJlGkvAP.js → Mobile-ZHF74GQs.js} +1 -1
- package/dist/assets/{_baseUniq-CPUnJ5bQ.js → _baseUniq-r3p3rodd.js} +1 -1
- package/dist/assets/{arc-WhuJ-oY5.js → arc-CjTV5gxc.js} +1 -1
- package/dist/assets/{architectureDiagram-Q4EWVU46-CWx77Yhd.js → architectureDiagram-Q4EWVU46-BqzjXpCq.js} +1 -1
- package/dist/assets/{blockDiagram-DXYQGD6D-D7AQLCoj.js → blockDiagram-DXYQGD6D-CLyFfeHh.js} +1 -1
- package/dist/assets/{c4Diagram-AHTNJAMY-BoPHNqCF.js → c4Diagram-AHTNJAMY-BaO-0tuc.js} +1 -1
- package/dist/assets/{channel-B9Ja6Xkc.js → channel-yOyhvOLV.js} +1 -1
- package/dist/assets/{chunk-4BX2VUAB-B-b0RYab.js → chunk-4BX2VUAB-CMTnvZkS.js} +1 -1
- package/dist/assets/{chunk-4TB4RGXK-BK_V34yf.js → chunk-4TB4RGXK-QI41m9WP.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-D-kMbu-2.js → chunk-55IACEB6-C4ZO8bM3.js} +1 -1
- package/dist/assets/{chunk-EDXVE4YY-CEtSkZzd.js → chunk-EDXVE4YY-Bo8P4o65.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-BXa_7Pn3.js → chunk-FMBD7UC4-CTHLGcHh.js} +1 -1
- package/dist/assets/{chunk-OYMX7WX6-tvM_OApS.js → chunk-OYMX7WX6-D0OHxKGd.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-DrEmcVHf.js → chunk-QZHKN3VN-CoYnjUpS.js} +1 -1
- package/dist/assets/{chunk-YZCP3GAM-D2M9T_R5.js → chunk-YZCP3GAM-BY71mTXM.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-C9o5ip5q.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-C9o5ip5q.js +1 -0
- package/dist/assets/clone-GDqN3kwT.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-H7bkwu5F.js → cose-bilkent-S5V4N54A-DUNsA_MT.js} +1 -1
- package/dist/assets/{dagre-KV5264BT-DKXEGN18.js → dagre-KV5264BT-BzlT2Exr.js} +1 -1
- package/dist/assets/{diagram-5BDNPKRD-DZFhwpI3.js → diagram-5BDNPKRD-CiqQK3Ci.js} +1 -1
- package/dist/assets/{diagram-G4DWMVQ6-Crg9GlIk.js → diagram-G4DWMVQ6-BciK18tQ.js} +1 -1
- package/dist/assets/{diagram-MMDJMWI5-B8Qn1fKP.js → diagram-MMDJMWI5-C1WH1vfU.js} +1 -1
- package/dist/assets/{diagram-TYMM5635-BHE1LjtY.js → diagram-TYMM5635-CR5RzJ6u.js} +1 -1
- package/dist/assets/{erDiagram-SMLLAGMA-BaEqFWLd.js → erDiagram-SMLLAGMA-NJQKXu51.js} +1 -1
- package/dist/assets/{flowDiagram-DWJPFMVM-b2ukTawV.js → flowDiagram-DWJPFMVM-Cjx5t_1H.js} +1 -1
- package/dist/assets/{ganttDiagram-T4ZO3ILL-D5quyFgK.js → ganttDiagram-T4ZO3ILL-YFTDBBiU.js} +1 -1
- package/dist/assets/{gitGraphDiagram-UUTBAWPF-BE1H5_fN.js → gitGraphDiagram-UUTBAWPF-C2muKahz.js} +1 -1
- package/dist/assets/{graph-D_JLoOax.js → graph-I1olozIg.js} +1 -1
- package/dist/assets/{index-Cx8bk0Tp.js → index-7vxIrUNA.js} +1 -1
- package/dist/assets/{index-BDUs32pN.css → index-Be9T-kDq.css} +1 -1
- package/dist/assets/{index-CtrY6gFZ.js → index-C1RNAzAB.js} +1 -1
- package/dist/assets/{index-CQrdpZQb.js → index-Cf4FBg-V.js} +1 -1
- package/dist/assets/{index-B8UmlA4F.js → index-D-HPuqxB.js} +1 -1
- package/dist/assets/{index-k0AH8cvI.js → index-D2QUxu18.js} +1 -1
- package/dist/assets/index-DMuCrfTo.js +2 -0
- package/dist/assets/{index-DiZ9CErG.js → index-DhzoJ5wE.js} +1 -1
- package/dist/assets/{index-CWjqMDrs.js → index-fhI0i2p3.js} +1 -1
- package/dist/assets/{infoDiagram-42DDH7IO-DQKlrVkw.js → infoDiagram-42DDH7IO-C9bza97c.js} +1 -1
- package/dist/assets/{ishikawaDiagram-UXIWVN3A-BchFlpPc.js → ishikawaDiagram-UXIWVN3A-BtZGipfW.js} +1 -1
- package/dist/assets/{journeyDiagram-VCZTEJTY-Dg1mt4df.js → journeyDiagram-VCZTEJTY-CKTp590c.js} +1 -1
- package/dist/assets/{jszip.min-LIb2SFoK.js → jszip.min-DDU-_oA-.js} +1 -1
- package/dist/assets/{kanban-definition-6JOO6SKY-226va2PS.js → kanban-definition-6JOO6SKY-BHLNWfr5.js} +1 -1
- package/dist/assets/{layout-rSa8rcPi.js → layout-DBmqcl9N.js} +1 -1
- package/dist/assets/{linear-BeARi8nH.js → linear-Br9n7mCI.js} +1 -1
- package/dist/assets/{mermaid.core-CDgdx9l7.js → mermaid.core-BV3ugHFm.js} +2 -2
- package/dist/assets/{min-B9yebCuj.js → min-D-YA3MGY.js} +1 -1
- package/dist/assets/{mindmap-definition-QFDTVHPH-C3apVbdg.js → mindmap-definition-QFDTVHPH-CzrYj3cB.js} +1 -1
- package/dist/assets/{pieDiagram-DEJITSTG-xjOQoQeL.js → pieDiagram-DEJITSTG-BAvtfiT3.js} +1 -1
- package/dist/assets/{quadrantDiagram-34T5L4WZ-Dq8x_VN2.js → quadrantDiagram-34T5L4WZ-i4zhnBJq.js} +1 -1
- package/dist/assets/{requirementDiagram-MS252O5E-CLmO1Gai.js → requirementDiagram-MS252O5E-Cb2wX9Sk.js} +1 -1
- package/dist/assets/{sankeyDiagram-XADWPNL6-BuUP1Eqq.js → sankeyDiagram-XADWPNL6-CcpbP6z5.js} +1 -1
- package/dist/assets/seqResourceLoaders-C7X23dCJ.js +2 -0
- package/dist/assets/{seqResourceLoaders-DWKAvGtj.css → seqResourceLoaders-De_-fYhE.css} +2 -2
- package/dist/assets/{sequenceDiagram-FGHM5R23-B18koU20.js → sequenceDiagram-FGHM5R23-BcbUxMmI.js} +1 -1
- package/dist/assets/{stateDiagram-FHFEXIEX-Cj57OCcO.js → stateDiagram-FHFEXIEX-CpIa1qoO.js} +1 -1
- package/dist/assets/{stateDiagram-v2-QKLJ7IA2-C01a2p--.js → stateDiagram-v2-QKLJ7IA2-d3GoyW9S.js} +1 -1
- package/dist/assets/{timeline-definition-GMOUNBTQ-cOlsEN_F.js → timeline-definition-GMOUNBTQ-BfQPSOuT.js} +1 -1
- package/dist/assets/{vendor-antd-DqFS7Zj9.js → vendor-antd-Bur5ZxWE.js} +1 -1
- package/dist/assets/{vendor-codemirror-B_pF4DrA.js → vendor-codemirror-Si44UqBp.js} +1 -1
- package/dist/assets/{vendor-mdxeditor-B_IrHcWH.js → vendor-mdxeditor-Cco3AQJS.js} +2 -2
- package/dist/assets/{vendor-qrcode-C4PneAS5.js → vendor-qrcode-Dn3GYC4l.js} +1 -1
- package/dist/assets/{vendor-virtuoso-CEGeJyDP.js → vendor-virtuoso-CW9EqKMt.js} +1 -1
- package/dist/assets/{vennDiagram-DHZGUBPP-BCjdwiDk.js → vennDiagram-DHZGUBPP-hTgiYDQL.js} +1 -1
- package/dist/assets/{wardley-RL74JXVD-CRmLlBwn.js → wardley-RL74JXVD-ByDpAPp1.js} +1 -1
- package/dist/assets/{wardleyDiagram-NUSXRM2D-BJYVDJ4F.js → wardleyDiagram-NUSXRM2D-D7LJTuWq.js} +1 -1
- package/dist/assets/{xychartDiagram-5P7HB3ND-el5C4S1Z.js → xychartDiagram-5P7HB3ND-MW_KOomO.js} +1 -1
- package/dist/index.html +5 -5
- package/findcc.js +3 -3
- package/package.json +1 -1
- package/server/i18n.js +224 -8
- package/server/interceptor.js +21 -18
- package/server/lib/adapters/dingtalk-adapter.js +69 -0
- package/server/lib/adapters/discord-adapter.js +44 -1
- package/server/lib/adapters/feishu-adapter.js +56 -0
- package/server/lib/adapters/wecom-adapter.js +4 -0
- package/server/lib/ask-store.js +19 -90
- package/server/lib/async-file-lock.js +123 -0
- package/server/lib/async-write-queue.js +131 -0
- package/server/lib/git-diff.js +4 -1
- package/server/lib/im-bridge-core.js +178 -21
- package/server/lib/im-claude-md.js +37 -1
- package/server/lib/im-config.js +11 -6
- package/server/lib/im-process-manager.js +1 -1
- package/server/lib/im-senders.js +73 -0
- package/server/lib/jsonl-archive.js +0 -1
- package/server/lib/log-watcher.js +224 -177
- package/server/lib/plugin-manager.js +1 -1
- package/server/lib/updater.js +4 -2
- package/server/pty-manager.js +1 -1
- package/server/routes/ask-perm.js +2 -2
- package/server/routes/dingtalk.js +2 -0
- package/server/routes/files-fs.js +4 -4
- package/server/routes/im.js +117 -3
- package/server/routes/project-meta.js +18 -1
- package/server/routes/skills.js +180 -165
- package/server/routes/workspaces.js +7 -10
- package/server/server.js +23 -20
- package/server/workspace-registry.js +9 -53
- package/dist/assets/App-DRvRd96X.css +0 -1
- package/dist/assets/App-OM2oqZRW.js +0 -1
- package/dist/assets/classDiagram-6PBFFD2Q-CCwGJXEA.js +0 -1
- package/dist/assets/classDiagram-v2-HSJHXN6E-CCwGJXEA.js +0 -1
- package/dist/assets/clone-BuQbTPQO.js +0 -1
- package/dist/assets/index-CnWSVlWW.js +0 -2
- package/dist/assets/seqResourceLoaders-BZ6M3Jb-.js +0 -2
package/server/server.js
CHANGED
|
@@ -40,13 +40,18 @@ import './lib/adapters/wecom-adapter.js'; // side-effect: registers the WeCom
|
|
|
40
40
|
import './lib/adapters/discord-adapter.js'; // side-effect: registers the Discord adapter
|
|
41
41
|
import { loadConfig } from './lib/im-config.js';
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
// Windows:git.exe / cmd.exe 等 console-subsystem 子进程从无控制台的 worker node.exe 启动时
|
|
44
|
+
// 会各弹一个可见控制台窗口(diff/status 轮询路径高频闪现)。在 promisify 包装层统一默认
|
|
45
|
+
// windowsHide(POSIX 上为 no-op,调用方传入可覆盖)。deps.execFileAsync 注入下游路由同样受益。
|
|
46
|
+
const _execFileAsyncRaw = promisify(execFile);
|
|
47
|
+
const execFileAsync = (cmd, args, opts) => _execFileAsyncRaw(cmd, args, { windowsHide: true, ...opts });
|
|
48
|
+
const _execAsyncRaw = promisify(exec);
|
|
49
|
+
const execAsync = (cmd, opts) => _execAsyncRaw(cmd, { windowsHide: true, ...opts });
|
|
45
50
|
|
|
46
51
|
// execFile with stdin input support (for git check-ignore --stdin)
|
|
47
52
|
function execWithStdin(cmd, args, input, options) {
|
|
48
53
|
return new Promise((resolve, reject) => {
|
|
49
|
-
const child = spawn(cmd, args, { ...options, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
54
|
+
const child = spawn(cmd, args, { ...options, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
50
55
|
let stdout = '';
|
|
51
56
|
let stderr = '';
|
|
52
57
|
child.stdout.on('data', d => { stdout += d; });
|
|
@@ -70,7 +75,7 @@ import { loadAuthConfig, loadAuthState, saveAuthConfig, clearProjectOverride, ge
|
|
|
70
75
|
import { checkAndUpdate } from './lib/updater.js';
|
|
71
76
|
import { loadPlugins, runWaterfallHook, runParallelHook } from './lib/plugin-loader.js';
|
|
72
77
|
import { CONTEXT_WINDOW_FILE, readModelContextSize } from './lib/context-watcher.js';
|
|
73
|
-
import { watchLogFile, startWatching,
|
|
78
|
+
import { watchLogFile, startWatching, unwatchAll, sendEventToClients, sendToClients } from './lib/log-watcher.js';
|
|
74
79
|
import { cleanupExtractCache } from './lib/jsonl-archive.js';
|
|
75
80
|
|
|
76
81
|
|
|
@@ -156,14 +161,13 @@ const ASK_HOOK_TIMEOUT_MS = ASK_TIMEOUT_MS;
|
|
|
156
161
|
// 任何 pendingAskHooks.set(...) 后必须调 _persistAskEntry;.delete(...) 后必须调 _persistAskDelete。
|
|
157
162
|
function _persistAskEntry(id, entry) {
|
|
158
163
|
if (!entry || !Array.isArray(entry.questions)) return;
|
|
159
|
-
// 异步触发:磁盘 IO 不阻塞 ask 主流程(落盘失败不影响业务)
|
|
160
164
|
setImmediate(() => {
|
|
161
|
-
|
|
165
|
+
askStoreSetEntry(id, { questions: entry.questions, createdAt: entry.createdAt }).catch(() => {});
|
|
162
166
|
});
|
|
163
167
|
}
|
|
164
168
|
function _persistAskDelete(id) {
|
|
165
169
|
setImmediate(() => {
|
|
166
|
-
|
|
170
|
+
askStoreDeleteEntry(id).catch(() => {});
|
|
167
171
|
});
|
|
168
172
|
}
|
|
169
173
|
|
|
@@ -770,11 +774,11 @@ export async function startViewer() {
|
|
|
770
774
|
// 内存 Map 不 hydrate:旧 res 已死、新 ask-bridge 重连同 toolUseId 会自动复用槽位
|
|
771
775
|
// (server.js 已有"旧 res 已断 → 复用"分支),无需在这里主动重建内存态。
|
|
772
776
|
// 留下来的 disk 镜像供 /api/pending-asks 端点查询,让浏览器重连后仍能看见 pending 列表。
|
|
773
|
-
setImmediate(() => {
|
|
777
|
+
setImmediate(() => { askStorePruneStale(ASK_HOOK_TIMEOUT_MS).catch(() => {}); });
|
|
774
778
|
// 长跑进程兜底:短轮询路径下 markAnswered 标的终态 entry 若 ask-bridge 已死(GET 不再来 consume),
|
|
775
779
|
// 仅靠启动 prune 永远清不掉。1h 周期触发一次,.unref() 不阻塞进程退出。
|
|
776
780
|
const _pruneAskStoreInterval = setInterval(() => {
|
|
777
|
-
|
|
781
|
+
askStorePruneStale(ASK_HOOK_TIMEOUT_MS).catch(() => {});
|
|
778
782
|
}, 60 * 60 * 1000);
|
|
779
783
|
_pruneAskStoreInterval.unref();
|
|
780
784
|
|
|
@@ -1263,7 +1267,7 @@ async function setupTerminalWebSocket(httpServer) {
|
|
|
1263
1267
|
// Phase 3: short-poll 模式不立即删 disk —— 落 answered 让 GET listener / disk consume 拿
|
|
1264
1268
|
if (askEntry.shortPoll) {
|
|
1265
1269
|
let wrote = false;
|
|
1266
|
-
try { wrote = askStoreMarkAnswered(askId, msg.answers); } catch {}
|
|
1270
|
+
try { wrote = await askStoreMarkAnswered(askId, msg.answers); } catch {}
|
|
1267
1271
|
if (wrote) {
|
|
1268
1272
|
_notifyShortPollAnswer(askId, msg.answers);
|
|
1269
1273
|
askAnswered = true;
|
|
@@ -1296,7 +1300,7 @@ async function setupTerminalWebSocket(httpServer) {
|
|
|
1296
1300
|
// 不唤醒 listener(让 listener 等到 GET hit disk 拿到真实抢答者答案)—— 自然 idempotent。
|
|
1297
1301
|
// 给当前 ws 发 ack-already-answered 让前端关 modal、不误覆盖灰态。
|
|
1298
1302
|
let wrote = false;
|
|
1299
|
-
try { wrote = askStoreMarkAnswered(askId, msg.answers); } catch {}
|
|
1303
|
+
try { wrote = await askStoreMarkAnswered(askId, msg.answers); } catch {}
|
|
1300
1304
|
if (wrote) {
|
|
1301
1305
|
_notifyShortPollAnswer(askId, msg.answers);
|
|
1302
1306
|
askAnswered = true;
|
|
@@ -1406,7 +1410,7 @@ async function setupTerminalWebSocket(httpServer) {
|
|
|
1406
1410
|
pendingAskHooks.delete(cancelId);
|
|
1407
1411
|
// Phase 3: short-poll 同样要让 disk + listener 知道,否则 ask-bridge 永远收不到 cancelled
|
|
1408
1412
|
if (askEntry.shortPoll) {
|
|
1409
|
-
try { askStoreMarkCancelled(cancelId, cancelReason); } catch {}
|
|
1413
|
+
try { await askStoreMarkCancelled(cancelId, cancelReason); } catch {}
|
|
1410
1414
|
_notifyShortPollCancel(cancelId, cancelReason);
|
|
1411
1415
|
} else {
|
|
1412
1416
|
_persistAskDelete(cancelId);
|
|
@@ -1424,7 +1428,7 @@ async function setupTerminalWebSocket(httpServer) {
|
|
|
1424
1428
|
// first-wins:disk 已是终态(如另一 client 抢先 answer)时 markCancelled 返 false,
|
|
1425
1429
|
// 不能唤醒 listener 用 cancel 覆盖真实 answer —— 让 listener 下次 GET consumeIfFinal
|
|
1426
1430
|
// 拿到真实 disk 终态自然投递。
|
|
1427
|
-
const wrote = askStoreMarkCancelled(cancelId, cancelReason);
|
|
1431
|
+
const wrote = await askStoreMarkCancelled(cancelId, cancelReason);
|
|
1428
1432
|
if (wrote) {
|
|
1429
1433
|
_notifyShortPollCancel(cancelId, cancelReason);
|
|
1430
1434
|
handled = true;
|
|
@@ -1640,10 +1644,12 @@ const _pendingTurnEndTimers = new Map(); // key: sessionId(string) | null → {
|
|
|
1640
1644
|
// 空串 / 非数 / 范围外都回 default + warn 一次。
|
|
1641
1645
|
const TURN_END_DEBOUNCE_MS = (() => {
|
|
1642
1646
|
const raw = process.env.CCV_TURN_END_DEBOUNCE_MS;
|
|
1643
|
-
|
|
1647
|
+
// IM worker 需要快速 turn_end 以驱动队列——默认 200ms(够 coalesce 重复 POST,不拖延回复)。
|
|
1648
|
+
const imDefault = process.env.CCV_IM_PLATFORM ? 200 : 10_000;
|
|
1649
|
+
if (raw === undefined || raw === '' || /^\s*$/.test(raw)) return imDefault;
|
|
1644
1650
|
const n = Number(raw);
|
|
1645
|
-
if (!Number.isFinite(n)) { console.warn(`[turn-end] CCV_TURN_END_DEBOUNCE_MS=${raw} not finite, using
|
|
1646
|
-
if (n < 100 || n > 60_000) { console.warn(`[turn-end] CCV_TURN_END_DEBOUNCE_MS=${n} out of [100,60000], using
|
|
1651
|
+
if (!Number.isFinite(n)) { console.warn(`[turn-end] CCV_TURN_END_DEBOUNCE_MS=${raw} not finite, using ${imDefault}`); return imDefault; }
|
|
1652
|
+
if (n < 100 || n > 60_000) { console.warn(`[turn-end] CCV_TURN_END_DEBOUNCE_MS=${n} out of [100,60000], using ${imDefault}`); return imDefault; }
|
|
1647
1653
|
return n;
|
|
1648
1654
|
})();
|
|
1649
1655
|
let _isStopping = false;
|
|
@@ -1819,11 +1825,8 @@ async function _doStop() {
|
|
|
1819
1825
|
}
|
|
1820
1826
|
} catch { }
|
|
1821
1827
|
}
|
|
1822
|
-
|
|
1823
|
-
unwatchFile(logFile);
|
|
1824
|
-
}
|
|
1828
|
+
unwatchAll();
|
|
1825
1829
|
unwatchFile(CONTEXT_WINDOW_FILE);
|
|
1826
|
-
getWatchedFiles().clear();
|
|
1827
1830
|
clients.forEach(client => client.end());
|
|
1828
1831
|
// Truncate in place (not `clients = []`) so the array reference stays stable across
|
|
1829
1832
|
// stop/start cycles — deps.clients and _logWatcherOpts() hold this same reference.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Workspace Registry - 工作区持久化管理
|
|
2
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, readdirSync,
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, readdirSync, unlinkSync } from 'node:fs';
|
|
3
3
|
import { renameSyncWithRetry } from './lib/file-api.js';
|
|
4
|
+
import { withFileLockAsync } from './lib/async-file-lock.js';
|
|
4
5
|
import { join, basename, resolve } from 'node:path';
|
|
5
6
|
import { randomBytes } from 'node:crypto';
|
|
6
7
|
import { LOG_DIR } from '../findcc.js';
|
|
@@ -9,51 +10,6 @@ import { LOG_DIR } from '../findcc.js';
|
|
|
9
10
|
function getWorkspacesFile() { return join(LOG_DIR, 'workspaces.json'); }
|
|
10
11
|
function getLockFile() { return join(LOG_DIR, 'workspaces.lock'); }
|
|
11
12
|
|
|
12
|
-
function sleep(ms) {
|
|
13
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function withLock(fn) {
|
|
17
|
-
mkdirSync(LOG_DIR, { recursive: true });
|
|
18
|
-
const deadline = Date.now() + 2000;
|
|
19
|
-
// 如果锁文件超过 5 秒未更新,认为它是死锁(前一个进程崩溃)
|
|
20
|
-
const STALE_THRESHOLD = 5000;
|
|
21
|
-
|
|
22
|
-
while (true) {
|
|
23
|
-
try {
|
|
24
|
-
const fd = openSync(getLockFile(), 'wx');
|
|
25
|
-
closeSync(fd);
|
|
26
|
-
break;
|
|
27
|
-
} catch (err) {
|
|
28
|
-
if (err?.code === 'EEXIST') {
|
|
29
|
-
if (Date.now() < deadline) {
|
|
30
|
-
// 检查是否为陈旧锁
|
|
31
|
-
try {
|
|
32
|
-
const stats = statSync(getLockFile());
|
|
33
|
-
if (Date.now() - stats.mtimeMs > STALE_THRESHOLD) {
|
|
34
|
-
// 尝试强制移除锁
|
|
35
|
-
try { unlinkSync(getLockFile()); } catch { }
|
|
36
|
-
// 立即重试获取
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
} catch {
|
|
40
|
-
// stat 失败可能意味着锁刚被释放,继续循环尝试获取
|
|
41
|
-
}
|
|
42
|
-
sleep(25);
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
throw err;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
return fn();
|
|
52
|
-
} finally {
|
|
53
|
-
try { unlinkSync(getLockFile()); } catch { }
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
13
|
export function loadWorkspaces() {
|
|
58
14
|
try {
|
|
59
15
|
if (!existsSync(getWorkspacesFile())) return [];
|
|
@@ -69,7 +25,7 @@ export function saveWorkspaces(list) {
|
|
|
69
25
|
try {
|
|
70
26
|
mkdirSync(LOG_DIR, { recursive: true });
|
|
71
27
|
writeFileSync(tmpFile, JSON.stringify({ workspaces: list }, null, 2));
|
|
72
|
-
|
|
28
|
+
|
|
73
29
|
// Windows 上 renameSync 可能会因为目标文件存在或被占用而失败。统一走 server/lib/file-api.js
|
|
74
30
|
// renameSyncWithRetry helper(同款重试策略,跟 interceptor / log-management 一致)。
|
|
75
31
|
renameSyncWithRetry(tmpFile, getWorkspacesFile());
|
|
@@ -87,8 +43,8 @@ function _invalidatePolicyCache() {
|
|
|
87
43
|
.catch(() => { /* policy 模块可能在某些 entry 下未加载,无副作用即可 */ });
|
|
88
44
|
}
|
|
89
45
|
|
|
90
|
-
export function registerWorkspace(absolutePath) {
|
|
91
|
-
const result =
|
|
46
|
+
export async function registerWorkspace(absolutePath) {
|
|
47
|
+
const result = await withFileLockAsync(getLockFile(), () => {
|
|
92
48
|
const resolvedPath = resolve(absolutePath);
|
|
93
49
|
const projectName = basename(resolvedPath).replace(/[^a-zA-Z0-9_\-\.]/g, '_');
|
|
94
50
|
const list = loadWorkspaces();
|
|
@@ -113,13 +69,13 @@ export function registerWorkspace(absolutePath) {
|
|
|
113
69
|
list.push(entry);
|
|
114
70
|
saveWorkspaces(list);
|
|
115
71
|
return entry;
|
|
116
|
-
});
|
|
72
|
+
}, { ensureDir: LOG_DIR });
|
|
117
73
|
_invalidatePolicyCache();
|
|
118
74
|
return result;
|
|
119
75
|
}
|
|
120
76
|
|
|
121
|
-
export function removeWorkspace(id) {
|
|
122
|
-
const result =
|
|
77
|
+
export async function removeWorkspace(id) {
|
|
78
|
+
const result = await withFileLockAsync(getLockFile(), () => {
|
|
123
79
|
const list = loadWorkspaces();
|
|
124
80
|
const filtered = list.filter(w => w.id !== id);
|
|
125
81
|
if (filtered.length !== list.length) {
|
|
@@ -127,7 +83,7 @@ export function removeWorkspace(id) {
|
|
|
127
83
|
return true;
|
|
128
84
|
}
|
|
129
85
|
return false;
|
|
130
|
-
});
|
|
86
|
+
}, { ensureDir: LOG_DIR });
|
|
131
87
|
if (result) _invalidatePolicyCache();
|
|
132
88
|
return result;
|
|
133
89
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
._liveTag_sg7sp_3{position:relative;display:inline-flex;align-items:center;justify-content:flex-start;border-radius:999px;border:1px solid;border-color:var(--ctx-color);color:var(--ctx-color);padding:0 10px;height:100%;font-size:12px;line-height:1;overflow:hidden;transition:border-color .3s,color .3s;white-space:nowrap;background:var(--bg-base-pure)}._liveTagFill_sg7sp_23{position:absolute;left:0;top:0;bottom:0;width:var(--ctx-percent, 0);background-color:var(--ctx-color);opacity:.35;transition:width .5s ease,background-color .3s;pointer-events:none}._liveTagContent_sg7sp_36{position:relative;z-index:1;display:inline-flex;align-items:center}._liveTagHistory_sg7sp_44{background:var(--bg-surface);border-color:var(--border-light);color:var(--text-primary)}._liveTagText_sg7sp_51{margin-left:4px;font-variant-numeric:tabular-nums}._cachePopoverPlaceholder_sg7sp_57{min-width:300px}._editButton_31hdb_10{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;background:transparent;border:none;padding:0 2px;margin-left:4px;cursor:pointer;font-size:inherit;line-height:1;color:var(--text-secondary, #888);opacity:0;border-radius:3px;transition:opacity .12s ease,color .12s ease,background-color .12s ease}._editButton_31hdb_10 .anticon{display:inline-flex;align-items:center;line-height:1;position:relative;top:-1px}._editButton_31hdb_10:hover,._editButton_31hdb_10:focus-visible{opacity:1;color:var(--text-primary, #333);background-color:var(--bg-hover, rgba(0, 0, 0, .04));outline:none}._editButton_31hdb_10:focus-visible{box-shadow:0 0 0 2px var(--focus-ring, rgba(64, 158, 255, .4))}._footer_31hdb_55{display:flex;justify-content:space-between;align-items:center;gap:8px}._footerLeft_31hdb_61,._footerRight_31hdb_65{display:flex;gap:8px}._projectNameRow_31hdb_70{display:flex;align-items:center;gap:8px;margin-bottom:12px;padding:6px 10px;background:var(--bg-secondary, rgba(0, 0, 0, .03));border-radius:4px;font-size:12px}._projectNameLabel_31hdb_80{color:var(--text-secondary, #888)}._projectNameValue_31hdb_83{color:var(--text-primary, #333);font-family:var(--font-mono, ui-monospace, SFMono-Regular, monospace);word-break:break-all}._panel_ziacd_1{display:flex;flex-direction:column;gap:14px}._required_ziacd_7{margin-left:2px;color:var(--color-error-light, #ff7b7b)}._optional_ziacd_12{margin-left:6px;font-size:12px;font-weight:400;color:var(--text-secondary)}._row_ziacd_19{display:flex;align-items:center;justify-content:space-between;gap:12px}._label_ziacd_26{font-size:14px;font-weight:500}._control_ziacd_31{display:inline-flex;align-items:center;gap:10px}._field_ziacd_37{display:flex;flex-direction:column;gap:6px}._fieldLabel_ziacd_43{font-size:13px;color:var(--text-secondary)}._help_ziacd_48{font-size:12px;color:var(--text-secondary);line-height:1.4}._warn_ziacd_54{font-size:12px;line-height:1.5;color:var(--color-error-light, #ff7b7b)}._hint_ziacd_60{font-size:12px;line-height:1.5;color:var(--text-secondary)}._detailsToggle_ziacd_66{display:inline-flex;align-items:center;gap:5px;align-self:flex-start;padding:0;border:none;background:none;cursor:pointer;font-size:12px;color:var(--text-secondary)}._detailsToggle_ziacd_66:hover{color:var(--text-primary, var(--text-secondary))}._details_ziacd_66{display:flex;flex-direction:column;gap:10px}._actions_ziacd_89{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}._tabRow_1q32a_4{display:flex;align-items:flex-end;gap:6px;padding:0 8px;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}._tabRow_1q32a_4::-webkit-scrollbar{display:none}._tabBtn_1q32a_24{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:14px;line-height:1.5;border:1px solid transparent;border-radius:10px;background:transparent;color:var(--text-secondary);cursor:pointer;transition:color .18s,border-color .18s,background .18s;white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none}._tabBtn_1q32a_24:hover{color:var(--color-primary)}._tabBtn_1q32a_24._tabBtnActive_1q32a_52,._tabBtn_1q32a_24._tabBtnActive_1q32a_52:hover{background:var(--bg-container);color:var(--color-primary);border-color:var(--border-primary);border-bottom:2px solid var(--bg-container);border-radius:10px 10px 0 0;font-weight:500;margin-bottom:-1px;position:relative;z-index:2}._toolBody_1q32a_8{border:1px solid var(--border-primary);border-top:none;border-radius:8px;background:var(--bg-container);padding:18px 20px;min-width:0}[data-theme=light] ._toolBody_1q32a_8{box-shadow:0 3px 8px #00000014}[data-theme=light] ._tabBtnActive_1q32a_52{box-shadow:0 -3px 8px #0000000f}[data-theme=dark] ._toolBody_1q32a_8 .ant-input,[data-theme=dark] ._toolBody_1q32a_8 .ant-input-affix-wrapper,[data-theme=dark] ._toolBody_1q32a_8 .ant-select-selector{background-color:var(--bg-elevated)}._scrollBody_1c36l_1{max-height:70vh;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable;padding:4px 2px;background:var(--bg-container);border-radius:8px}._headerBar_1c36l_14{display:flex;align-items:center;gap:8px}._titleIcon_1c36l_20{display:inline-flex;align-items:center;width:18px;height:18px}._refreshBtn_1c36l_27{flex:0 0 auto}._center_1c36l_32{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:40px 0;color:var(--text-secondary)}._hint_1c36l_42{color:var(--text-secondary);font-size:13px}._chip_bvaji_4{position:relative;line-height:0;cursor:pointer;-webkit-user-select:none;user-select:none;transition:opacity .15s}._chip_bvaji_4:hover{opacity:.75}._logo_bvaji_16{display:block;transition:color .15s}._connecting_bvaji_22{opacity:.5}._dotError_bvaji_27{position:absolute;right:-2px;top:-2px;width:6px;height:6px;border-radius:50%;background:var(--color-error, #ff4d4f);pointer-events:none}._modelCard_1gpju_3{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;background:var(--bg-container)}._modelName_1gpju_9{font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid var(--border-secondary)}._statsTable_1gpju_17{width:100%;border-collapse:collapse}._th_1gpju_21{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:var(--text-tertiary);font-weight:400;text-align:right}._td_1gpju_30{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:var(--text-primary);text-align:right}._label_1gpju_38{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:var(--text-light);font-weight:400;text-align:left}._rowBorder_1gpju_47{border-bottom:1px solid var(--border-primary)}._rebuildTotalRow_1gpju_50{border-top:1px solid var(--border-light)}._rebuildTotalRow_1gpju_50 td{font-weight:600}._cachePopoverEmpty_1gpju_56{padding:8px 4px;color:var(--text-tertiary);font-size:13px}._toolChipGrid_1gpju_61{display:flex;flex-wrap:wrap;gap:4px;padding:2px 0 6px 2px}._cacheToolChip_1gpju_67{font-size:11px;padding:0 6px;border-radius:3px;background:var(--bg-surface);color:var(--text-secondary);line-height:18px;max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:1px solid var(--border-primary);cursor:help}._titleIcon_1gpju_81{margin-right:8px}._detailMarkdownCard_1gpju_86{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;background:var(--bg-container)}._memoryMarkdown_1gpju_93{font-size:12.5px;line-height:1.55;color:var(--text-primary);word-break:break-word}._memoryMarkdown_1gpju_93 p{margin:0 0 6px}._memoryMarkdown_1gpju_93 ul,._memoryMarkdown_1gpju_93 ol{margin:4px 0 6px;padding-left:20px}._memoryMarkdown_1gpju_93 li{margin:2px 0}._memoryMarkdown_1gpju_93 h1,._memoryMarkdown_1gpju_93 h2,._memoryMarkdown_1gpju_93 h3,._memoryMarkdown_1gpju_93 h4{font-size:13px;font-weight:600;margin:8px 0 4px;color:var(--text-primary)}._memoryMarkdown_1gpju_93 h1{font-size:14px}._memoryMarkdown_1gpju_93 a{color:var(--primary-color, #1677ff);text-decoration:none;cursor:pointer}._memoryMarkdown_1gpju_93 a:hover{text-decoration:underline}._memoryMarkdown_1gpju_93 code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;padding:1px 4px;border-radius:3px;background:var(--bg-surface);color:var(--text-primary)}._memoryMarkdown_1gpju_93 pre{margin:6px 0;padding:8px 10px;border-radius:4px;background:var(--bg-surface);overflow-x:auto}._memoryMarkdown_1gpju_93 pre code{padding:0;background:transparent;font-size:12px}._memoryMarkdown_1gpju_93 blockquote{margin:4px 0;padding:2px 8px;border-left:3px solid var(--border-hover);color:var(--text-secondary)}._memoryMarkdown_1gpju_93 hr{margin:8px 0;border:none;border-top:1px solid var(--border-secondary)}._headerBar_uzc7r_2{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%}._logoWrap_uzc7r_10{display:inline-flex;align-items:center;position:relative;margin-top:14px}._logoWrapActive_uzc7r_17:after{content:"";position:absolute;top:-10px;bottom:-10px;left:0;right:-200px}._logoImage_uzc7r_26{height:24px;width:24px;border-radius:3px;vertical-align:middle;opacity:.75;transition:opacity .2s;cursor:pointer}._logoImageActive_uzc7r_36{opacity:1}._compactBtn_uzc7r_43{font-size:12px;height:30px;display:inline-flex;align-items:center;justify-content:center}._compactBtnNoBorder_uzc7r_52{width:30px;height:30px;min-width:30px;padding:0;border:none;font-size:18px;line-height:1;display:inline-flex;align-items:center;justify-content:center}._compactBtnNoBorder_uzc7r_52 .anticon{display:inline-flex;align-items:center;justify-content:center;line-height:0}._headerProjectName_uzc7r_79{font-size:12px;color:inherit;white-space:nowrap}._headerProjectName_uzc7r_79:hover [data-alias-edit-trigger],._headerProjectName_uzc7r_79:focus-within [data-alias-edit-trigger]{opacity:.55}._countdownStrong_uzc7r_96{font-variant-numeric:tabular-nums}._qrcodePopover_uzc7r_101{display:flex;flex-direction:column;align-items:center;padding:8px}._qrcodeSection_uzc7r_108{display:flex;flex-direction:column;align-items:center;padding:16px;margin-bottom:12px;border:1px solid var(--border-secondary);border-radius:8px;background:var(--bg-container)}._qrcodeTitle_uzc7r_119{font-size:14px;font-weight:600;color:var(--text-primary);margin-bottom:12px}._qrcodeUrlInput_uzc7r_126{margin-top:12px;font-size:12px;font-family:Menlo,Monaco,monospace}._qrcodeUrlCopy_uzc7r_132{cursor:pointer;color:var(--text-tertiary);transition:color .2s}._qrcodeUrlCopy_uzc7r_132:hover{color:var(--color-primary-light)}._authSection_uzc7r_143{display:flex;flex-direction:column;align-items:stretch;box-sizing:border-box;width:100%;margin-top:12px;padding:12px;border:1px solid var(--border-secondary);border-radius:8px;background:var(--bg-container);gap:8px}._authHeaderRow_uzc7r_157{display:flex;align-items:center;justify-content:space-between}._authTitle_uzc7r_163{font-size:13px;font-weight:600;color:var(--text-primary)}._authPasswordLabel_uzc7r_169{font-size:12px;color:var(--text-secondary)}._authPasswordInput_uzc7r_174{font-size:12px;font-family:Menlo,Monaco,monospace}._authSaveBtn_uzc7r_179{align-self:flex-end}._authEmptyWarn_uzc7r_183{font-size:12px;color:var(--color-error-light);line-height:1.4}._settingsGroupBox_uzc7r_191{border:1px solid var(--border-secondary);border-radius:8px;background:var(--bg-container);padding:4px 16px;margin-bottom:12px}._settingsGroupTitle_uzc7r_199{font-size:14px;font-weight:600;color:var(--text-primary);padding:12px 0 4px;border-bottom:1px solid var(--border-secondary)}._settingsItem_uzc7r_208{display:flex;justify-content:space-between;align-items:center;padding:12px 0}._settingsLabel_uzc7r_215{font-size:14px}._settingsHelpIcon_uzc7r_220{font-size:16px;color:var(--text-disabled);cursor:help;margin-left:4px}._settingsDivider_uzc7r_227{border-top:1px solid var(--border-primary);margin:12px 0}._logDirInput_uzc7r_232{margin-top:8px;background:var(--bg-base-alt);border-color:var(--border-light);color:var(--text-primary);font-family:monospace;font-size:13px}._tokenStatsEmpty_uzc7r_242{padding:8px 4px;color:var(--text-tertiary);font-size:13px}._tokenStatsContainer_uzc7r_249{display:flex;gap:12px;align-items:flex-start}._tokenStatsColumn_uzc7r_255{min-width:240px}._toolStatsColumn_uzc7r_259{min-width:180px}._modelCardSpaced_uzc7r_265{margin-bottom:10px}._rebuildCard_uzc7r_274{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;margin-top:10px;background:var(--bg-container)}._promptExportBar_uzc7r_283{margin-bottom:12px}._promptScrollArea_uzc7r_287{max-height:500px;overflow:auto}._promptEmpty_uzc7r_292{color:var(--text-tertiary);padding:12px}._promptTimestamp_uzc7r_298{color:var(--text-muted);font-size:12px;margin:12px 0 4px;padding-bottom:6px}._textPromptCard_uzc7r_306{margin:4px 0;background:var(--bg-container);border-radius:6px;border:1px solid var(--border-secondary);padding:10px 14px}._preText_uzc7r_315{white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.6;color:var(--text-primary);margin:4px 0}._systemCollapse_uzc7r_325{margin:4px 0;background:var(--bg-elevated);border:1px solid var(--border-secondary);border-radius:6px}._systemLabel_uzc7r_332{color:var(--text-tertiary);font-size:12px}._preSys_uzc7r_337{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-tertiary);margin:0}._promptTextarea_uzc7r_347{box-sizing:border-box;background:var(--bg-base-pure);width:100%;min-height:400px;color:var(--text-primary);font-family:monospace;font-size:13px;line-height:1.6;border:none;resize:vertical;padding:10px 14px;outline:none}._projectStatsCenter_uzc7r_363{display:flex;justify-content:center;padding:40px 0}._projectStatsEmpty_uzc7r_369{color:var(--text-tertiary);padding:40px 0;text-align:center;font-size:13px}._projectStatsContent_uzc7r_376{display:flex;flex-direction:column;gap:16px}._projectStatsUpdated_uzc7r_382{color:var(--text-muted);font-size:12px;text-align:right}._projectStatsSummary_uzc7r_388{display:grid;grid-template-columns:1fr 1fr;gap:10px}._projectStatCard_uzc7r_394{background:var(--bg-container);border:1px solid var(--border-secondary);border-radius:8px;padding:14px 12px;text-align:center}._projectStatValue_uzc7r_402{font-size:22px;font-weight:700;color:var(--text-primary);font-family:monospace;font-variant-numeric:tabular-nums}._projectStatLabel_uzc7r_410{font-size:12px;color:var(--text-tertiary);margin-top:4px}._projectStatsSection_uzc7r_416{display:flex;flex-direction:column;gap:10px}._projectStatsSectionTitle_uzc7r_422{font-size:14px;font-weight:600;color:var(--text-secondary);padding-bottom:4px;border-bottom:1px solid var(--border-secondary)}._projectStatsModelCard_uzc7r_430{background:var(--bg-container);border:1px solid var(--border-secondary);border-radius:6px;padding:10px 12px}._projectStatsModelHeader_uzc7r_437{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid var(--border-secondary)}._projectStatsModelName_uzc7r_446{font-size:13px;font-weight:600;color:var(--text-primary)}._projectStatsModelCount_uzc7r_452{font-size:12px;color:var(--text-tertiary);font-family:monospace}._cacheCopyBtn_uzc7r_460{font-size:14px;color:var(--text-tertiary);cursor:pointer;transition:color .2s;margin-left:8px}._cacheCopyBtn_uzc7r_460:hover{color:var(--text-primary)}._cacheTokenInfo_uzc7r_472{display:flex;align-items:center;font-size:12px;font-family:monospace;color:var(--text-light);margin-bottom:8px}._cacheCodeBlock_uzc7r_485{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-secondary);background:var(--bg-container);border:1px solid var(--border-primary);border-radius:4px;padding:8px;margin:4px 0;font-family:Menlo,Monaco,monospace}._cacheCodeBlockSystem_uzc7r_499{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-secondary);background:var(--bg-code-system);border:1px solid var(--border-code-system);border-radius:4px;padding:8px;margin:4px 0;font-family:Menlo,Monaco,monospace}._cacheNavBtn_uzc7r_513{margin-left:auto;font-size:11px;color:var(--color-primary);cursor:pointer;border:1px solid var(--color-primary);border-radius:3px;padding:1px 6px;white-space:nowrap}._cacheNavBtn_uzc7r_513:hover{background:var(--color-primary-bg-light)}._cacheNavList_uzc7r_528{width:600px;max-height:300px;overflow-y:auto}._cacheNavItem_uzc7r_534{padding:4px 8px;font-size:12px;color:var(--text-secondary);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-radius:3px}._cacheNavItem_uzc7r_534:hover{background:var(--color-primary-bg-lighter);color:var(--text-white)}._cacheBlockHighlight_uzc7r_550{box-shadow:0 0 10px var(--color-primary-shadow);transition:box-shadow .2s ease-in}._cacheBlockHighlightFading_uzc7r_555{box-shadow:0 0 10px transparent;transition:box-shadow 3s ease-out}._cacheBorderSvg_uzc7r_560{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none;overflow:visible}._cacheBorderSvgFading_uzc7r_569{opacity:0;transition:opacity 3s ease-out}._cacheBorderRect_uzc7r_574{animation:_cacheDashRotate_uzc7r_1 4s linear infinite}@keyframes _cacheDashRotate_uzc7r_1{0%{stroke-dashoffset:0}to{stroke-dashoffset:-100}}._thLeft_uzc7r_584{text-align:left}._cacheWriteToken_uzc7r_599{color:var(--color-code-orange)}._cacheReadToken_uzc7r_603{color:var(--color-success)}._cacheCtxPercent_uzc7r_607{color:var(--text-tertiary);margin-left:6px}._qrcodeIcon_uzc7r_627{width:30px;height:30px;padding:6px;box-sizing:border-box;color:var(--text-secondary);cursor:pointer;border-radius:6px;transition:color .15s ease,background-color .15s ease;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;background:none;border:none}._qrcodeIcon_uzc7r_627:hover{color:var(--text-primary);background:var(--bg-hover, rgba(0, 0, 0, .04))}._qrcodeIcon_uzc7r_627:focus-visible{outline:2px solid var(--primary-color, #1677ff);outline-offset:1px}._approvalBell_uzc7r_653{position:relative;width:30px;height:30px;padding:6px;box-sizing:border-box;color:var(--color-warning, #faad14);cursor:pointer;border-radius:6px;transition:color .15s ease,background-color .15s ease;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;background:none;border:none}._approvalBell_uzc7r_653:hover{color:var(--text-primary);background:var(--bg-hover, rgba(0, 0, 0, .04))}._approvalBell_uzc7r_653:focus-visible{outline:2px solid var(--primary-color, #1677ff);outline-offset:1px}._approvalBellBadge_uzc7r_678{position:absolute;top:0;right:0;min-width:14px;height:14px;padding:0 3px;box-sizing:border-box;background:var(--color-error, #ff4d4f);color:#fff;font-size:9px;line-height:14px;border-radius:7px;text-align:center;font-weight:600}._proxySwapIcon_uzc7r_695{margin-right:4px;font-size:11px}._proxyProfileTag_uzc7r_701{border-radius:12px;background:var(--border-secondary);border:1px solid var(--border-light);color:var(--text-tertiary);font-size:12px;cursor:pointer;transition:color .2s,border-color .2s}._proxyProfileTag_uzc7r_701:hover{color:var(--text-secondary);border-color:var(--text-disabled)}._pinnedShortcut_uzc7r_717{height:24px;margin-top:11px;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1;color:var(--text-tertiary);opacity:.75;cursor:pointer;transition:opacity .2s,color .2s}._pinnedShortcut_uzc7r_717:hover{opacity:1;color:var(--text-secondary)}._pinnedShortcut_uzc7r_717 .anticon{display:inline-flex;align-items:center;justify-content:center;line-height:0}._themeToggle_uzc7r_746{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;width:30px;height:30px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--text-secondary);cursor:pointer;transition:background-color .2s ease,color .2s ease;flex-shrink:0;outline:none}._themeToggle_uzc7r_746:hover{background:var(--color-bg-hover, rgba(127, 127, 127, .12));color:var(--text-primary)}._themeToggle_uzc7r_746:focus-visible{box-shadow:0 0 0 2px var(--primary-color, #1677ff)}._themeToggleIcon_uzc7r_772{display:block}._headerRightRow_uzc7r_777 .ant-space-item{display:inline-flex;align-items:center}._headerCountdownTag_uzc7r_783{height:30px;margin:0;padding:0 10px;display:inline-flex;align-items:center;background:var(--bg-surface);border:1px solid var(--border-hover);border-radius:6px;line-height:1}._centerEmpty_midza_1{display:flex;align-items:center;justify-content:center;height:100%}._scrollContainer_midza_8{overflow:auto;height:100%;-webkit-overflow-scrolling:touch;will-change:scroll-position}._listItem_midza_15{cursor:pointer;padding:8px 12px;border-left:6px solid transparent;border-right:1px solid var(--border-primary);border-top:1px solid transparent;border-bottom:1px solid var(--border-primary);transition:background .15s}._listItem_midza_15:hover{border-left-color:var(--border-hover)}._listItemActive_midza_29{background:var(--color-primary-bg-faint);border-left-color:var(--color-primary-light);border-right:1px solid var(--color-primary-light);border-top:1px solid var(--color-primary-light);border-bottom:1px solid var(--color-primary-light)}._listItemActive_midza_29,._listItemActive_midza_29:hover{background:var(--color-primary-bg-faint);border-left-color:var(--color-primary-light);border-right-color:var(--color-primary-light);border-top-color:var(--color-primary-light);border-bottom-color:var(--color-primary-light)}._itemContent_midza_46{width:100%;min-width:0}._itemHeader_midza_51{display:flex;align-items:center;gap:6px;margin-bottom:4px;font-size:12px}._tagNoMargin_midza_59{margin:0;font-size:12px}._modelName_midza_64{font-size:12px;color:var(--text-tertiary)}._modelNameMain_midza_69{color:var(--color-code-orange)}._time_midza_73{font-size:12px;color:var(--text-gray);margin-left:auto}._detailRow_midza_79{display:flex;gap:8px;font-size:12px;align-items:center}._urlText_midza_86{color:var(--text-disabled);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}._duration_midza_95{color:var(--text-gray);flex-shrink:0}._statusOk_midza_100{color:var(--color-success);opacity:.5;flex-shrink:0}._statusErr_midza_106{color:var(--color-error);flex-shrink:0}._statusDefault_midza_111{color:var(--text-tertiary);flex-shrink:0}._usageBox_midza_116{background:var(--bg-container);border-radius:4px;padding:3px 6px;margin-top:4px;font-size:12px;color:var(--text-gray);line-height:1.6}._cacheDot_midza_126{display:inline-block;width:6px;height:6px;border-radius:50%;margin:0 3px;vertical-align:middle}._cacheDotLoss_midza_135{background-color:var(--color-red-dark-bg);cursor:help}._cacheDotNormal_midza_140{background-color:var(--border-hover)}._tagMainAgent_midza_144{color:var(--color-code-orange);border-color:var(--color-code-orange-border);background:var(--color-code-orange-bg)}._tagPlan_midza_150{color:var(--color-error-muted);border-color:var(--color-error-muted);background-color:var(--bg-base-pure)}._tagMuted_midza_156{color:var(--text-muted);border-color:var(--border-light);background-color:var(--bg-base-pure)}._tooltipPreLine_midza_162{white-space:pre-line}._GzYRV{line-height:1.2;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}._3eOF8{margin-right:5px;font-weight:700}._3eOF8+._3eOF8{margin-left:-5px}._1MFti{cursor:pointer}._f10Tu{font-size:1.2em;margin-right:5px;-webkit-user-select:none;-moz-user-select:none;user-select:none}._1UmXx:after{content:"▸"}._1LId0:after{content:"▾"}._1pNG9{margin-right:5px}._1pNG9:after{content:"...";font-size:.8em}._2IvMF{background:#eee}._2bkNM{margin:0;padding:0 10px}._1BXBN{margin:0;padding:0}._1MGIk{font-weight:600;margin-right:5px;color:#000}._3uHL6{color:#000}._2T6PJ,._1Gho6{color:#df113a}._vGjyY{color:#2a3f3c}._1bQdo{color:#0b75f5}._3zQKs{color:#469038}._1xvuR{color:#43413d}._oLqym,._2AXVT,._2KJWg{color:#000}._11RoI{background:#002b36}._17H2C,._3QHg2,._3fDAz{color:#fdf6e3}._2bSDX{font-weight:bolder;margin-right:5px;color:#fdf6e3}._gsbQL{color:#fdf6e3}._LaAZe,._GTKgm{color:#81b5ac}._Chy1W{color:#cb4b16}._2bveF{color:#d33682}._2vRm-{color:#ae81ff}._1prJR{color:#268bd2}._container_qeuid_1{background:var(--bg-container);border-radius:6px;border:1px solid var(--border-primary);padding:12px;font-size:13px;font-family:monospace;overflow:auto}._root_17dqd_1{display:flex;height:100%;min-height:0;gap:0}._sidebar_17dqd_9{width:220px;flex-shrink:0;border-right:1px solid var(--border-primary);overflow-y:auto;padding:4px 0;-webkit-overflow-scrolling:touch}._section_17dqd_18{-webkit-user-select:none;user-select:none}._sectionHeader_17dqd_22{display:flex;align-items:center;gap:6px;width:100%;padding:6px 10px;cursor:pointer;color:var(--text-primary);font-size:12px;font-weight:600;transition:background .15s;background:none;border:0;text-align:left;font:inherit}._sectionHeader_17dqd_22:hover{background:var(--overlay-light-faint)}._sectionHeader_17dqd_22:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._arrow_17dqd_48{font-size:10px;color:var(--text-tertiary);flex-shrink:0}._sectionTitle_17dqd_54{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._sectionCount_17dqd_62{font-size:11px;color:var(--text-muted);background:var(--bg-elevated);border-radius:10px;padding:0 6px;line-height:18px}._sectionBody_17dqd_71{padding:2px 0}._historyToggle_17dqd_76{display:flex;align-items:center;gap:6px;width:100%;padding:4px 10px 4px 14px;cursor:pointer;color:var(--text-muted);font-size:11px;transition:color .15s,background .15s;background:none;border:0;text-align:left;font:inherit}._historyToggle_17dqd_76:hover{color:var(--text-tertiary);background:var(--overlay-light-faint)}._historyToggle_17dqd_76:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._historyToggleLabel_17dqd_102{flex:1}._item_17dqd_107{display:flex;align-items:center;justify-content:space-between;width:100%;padding:4px 9px 4px 23px;font-size:12px;color:var(--text-tertiary);cursor:pointer;transition:background .15s,color .15s;background:none;border:1px solid transparent;border-radius:4px;box-sizing:border-box;text-align:left;font:inherit}._item_17dqd_107:hover{background:var(--overlay-light-faint);color:var(--text-primary)}._item_17dqd_107:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._itemActive_17dqd_135,._itemActive_17dqd_135:hover{background:var(--color-primary-bg-faint);color:var(--color-primary);border-color:var(--color-primary-light)}._itemContent_17dqd_142{flex:1;min-width:0;overflow:hidden}._itemLabel_17dqd_148{font-family:monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}._itemSublabel_17dqd_156{font-size:10px;color:var(--text-disabled);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}._itemTime_17dqd_165{font-size:9px;color:var(--text-disabled);flex-shrink:0;margin-left:4px;font-family:monospace}._content_17dqd_174{flex:1;min-width:0;overflow:auto;padding:12px 16px;-webkit-overflow-scrolling:touch}._contentEmpty_17dqd_182{height:100%;display:flex;align-items:center;justify-content:center}._contentInner_17dqd_189{padding-bottom:20px}._emptyWrap_17dqd_193{display:flex;align-items:center;justify-content:center;height:200px}._roleHeader_17dqd_201{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:nowrap}._roleBadge_17dqd_209{font-size:10px;font-weight:600;letter-spacing:.04em;padding:2px 7px;border-radius:4px;flex-shrink:0}._role_user_17dqd_218{background:var(--color-primary-bg-lighter);color:var(--color-primary-lighter);border:1px solid var(--color-primary-bg-medium)}._role_assistant_17dqd_224{background:var(--color-purple-bg);color:var(--color-code-purple);border:1px solid var(--color-purple-border)}._roleLabel_17dqd_230{font-size:11px;color:var(--text-muted);flex:1;min-width:0}._contentTime_17dqd_237{margin-left:auto;font-size:10px;color:var(--text-disabled);font-family:monospace;flex-shrink:0}._turnDivider_17dqd_245{border:none;border-top:1px solid var(--border-primary);margin:14px 0}._textBlock_17dqd_252{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._textBlockBar_17dqd_259{display:flex;align-items:center;gap:6px;padding:4px 10px;background:var(--bg-container);border-bottom:1px solid var(--border-primary)}._textBlockBody_17dqd_268{padding:10px 12px;font-size:13px;line-height:1.7;color:var(--text-primary);word-break:break-word}._textBlockCompact_17dqd_276{position:relative;padding:8px 10px;font-size:12px;color:var(--text-light)}._textBlockCompactFloat_17dqd_283{float:right;margin-left:6px;margin-bottom:2px}._thinkingBlock_17dqd_290{margin-bottom:8px;border:1px solid var(--color-thinking-border);border-radius:6px;overflow:hidden;background:var(--color-thinking-bg)}._thinkingHeader_17dqd_298{display:flex;align-items:center;gap:6px;padding:5px 10px;cursor:pointer;font-size:12px;color:var(--text-tertiary);transition:background .15s}._thinkingHeader_17dqd_298:hover{background:var(--overlay-light-faint)}._thinkingPreview_17dqd_313{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted);font-size:11px}._thinkingBody_17dqd_323{padding:8px 12px;border-top:1px solid var(--color-thinking-border)}._toolBlock_17dqd_329{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._toolBlockResult_17dqd_336{border-color:var(--color-green-border)}._toolBlockError_17dqd_340{border-color:var(--color-red-dark-border)}._toolBlockHeader_17dqd_344{display:flex;align-items:center;gap:8px;padding:5px 10px;background:var(--bg-container);border-bottom:1px solid var(--border-primary);font-size:12px;flex-wrap:wrap}._toolBlockBody_17dqd_355{padding:8px 10px;font-size:12px}._toolName_17dqd_360{color:var(--text-primary);font-weight:500;font-family:monospace}._toolId_17dqd_366{color:var(--text-disabled);font-size:10px;font-family:monospace;margin-left:auto}._errorLabel_17dqd_373{font-size:10px;color:var(--color-error-light);background:var(--color-error-bg-light);border:1px solid var(--color-error-border);border-radius:3px;padding:1px 5px}._blockTag_17dqd_383{font-size:9px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;padding:1px 5px;border-radius:3px;background:var(--bg-elevated);color:var(--text-muted);border:1px solid var(--border-primary);flex-shrink:0}._blockTagText_17dqd_396{background:var(--color-primary-bg-faint);color:var(--color-primary-lighter);border-color:var(--color-primary-bg-lighter)}._blockTagThinking_17dqd_402{background:var(--color-warning-bg-faint);color:var(--color-warning);border-color:var(--color-warning-border-light)}._blockTagResult_17dqd_408{background:var(--color-green-dark-bg);color:var(--color-success);border-color:var(--color-green-dark-border)}._blockTagError_17dqd_414{background:var(--color-error-bg-faint);color:var(--color-error-light);border-color:var(--color-error-border-light)}._jsonBlock_17dqd_421{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._jsonBlockLabel_17dqd_428{font-size:10px;color:var(--text-muted);padding:3px 10px;background:var(--bg-container);border-bottom:1px solid var(--border-primary);font-family:monospace}._blockSeparator_17dqd_438{border:none;border-top:1px solid var(--border-primary);margin:16px 0}._markdownBody_17dqd_445{font-size:13px;line-height:1.7;color:var(--text-primary);word-break:break-word}._container_rg6mx_1{height:100%;overflow:hidden;padding:0 16px;display:flex;flex-direction:column;background:var(--bg-base)}._emptyState_rg6mx_10{display:flex;align-items:center;justify-content:center;height:100%}._urlSection_rg6mx_17{padding:12px 0;border-bottom:1px solid var(--border-primary);display:flex;align-items:flex-start;flex-shrink:0}._urlLeft_rg6mx_25{flex:1;min-width:0}._tokenStatsBox_rg6mx_30{flex-shrink:0;padding-left:12px;display:flex;align-items:center}._tokenGrid_rg6mx_37{display:flex;border:1px solid var(--border-secondary);border-radius:6px;overflow:hidden;min-width:360px;font-size:11px;line-height:1.6}._tokenRows_rg6mx_47{flex:1}._tokenRow_rg6mx_47{display:flex}._tokenRowBorder_rg6mx_55{border-top:1px solid var(--border-secondary)}._tokenLabel_rg6mx_59{color:var(--text-tertiary);padding:4px 8px;white-space:nowrap;font-weight:600}._tokenTd_rg6mx_66{flex:1;color:var(--text-primary);text-align:right;padding:4px 8px;font-family:monospace;white-space:nowrap}._tokenHitRate_rg6mx_75{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--text-primary);padding:4px 8px;font-family:monospace;white-space:nowrap;border-left:1px solid var(--border-secondary);min-width:100px}._tokenHitRateLabel_rg6mx_88{color:var(--text-tertiary);font-size:10px;font-family:sans-serif}._tokenRowBorder_rg6mx_55 td{border-top:1px solid var(--border-secondary)}._urlText_rg6mx_98{color:var(--text-primary);font-size:13px;margin-bottom:8px;word-break:break-all}._metaText_rg6mx_105,._headersContainer_rg6mx_109{font-size:12px}._headerRow_rg6mx_113{display:flex;padding:4px 0;border-bottom:1px solid var(--border-primary)}._headerKey_rg6mx_119{min-width:200px;flex-shrink:0}._headerValue_rg6mx_124{word-break:break-all;margin-left:8px}._streamingBox_rg6mx_129{padding:20px;background:var(--bg-elevated);border-radius:6px;border:1px solid var(--border-primary)}._bodyToolbar_rg6mx_136{display:flex;gap:8px;margin-bottom:8px}._rawTextPre_rg6mx_142{background:var(--bg-code-dark);border:1px solid var(--border-primary);border-radius:6px;padding:12px;font-size:12px;color:var(--text-primary);overflow:auto;max-height:600px;white-space:pre-wrap;word-break:break-all}._tabContent_rg6mx_155{padding:16px 0 0;height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}._collapseSpacing_rg6mx_163{margin-bottom:16px}._bodyLabel_rg6mx_167{margin:0}._bodyHeader_rg6mx_171{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}._diffSection_rg6mx_178{margin-bottom:16px}._diffToggle_rg6mx_182{display:inline-block;margin-bottom:8px;cursor:pointer}._diffIcon_rg6mx_188{font-size:12px;margin-left:4px}._viewInChatBtn_rg6mx_193{display:inline-flex;align-items:center;height:26px;border-radius:13px;border:1px solid var(--border-light);background:#0000;color:var(--text-tertiary);cursor:pointer;font-size:12px;transition:all .2s;padding:0 10px;white-space:nowrap}._viewInChatBtn_rg6mx_193:hover{border-color:var(--text-muted);color:var(--text-primary);background:var(--overlay-light-faint)}._reminderSelect_rg6mx_214{min-width:140px;font-size:12px}._reminderSelect_rg6mx_214 .ant-select-selector.ant-select-selector{border-radius:2px;border-color:var(--border-light);background:#0000;min-height:26px;height:auto;padding:0 8px;font-family:monospace}._reminderSelect_rg6mx_214 .ant-select-selection-placeholder{font-size:11px}._diffHeaderRow_rg6mx_233{display:flex;align-items:center;gap:8px}._diffSpaceRight_rg6mx_239{margin-left:auto}._reminderFilterWrapper_rg6mx_243{display:inline-flex;align-items:center;gap:4px}._reminderLabel_rg6mx_249{color:var(--text-tertiary);font-size:12px;font-family:monospace}._cacheTabContent_rg6mx_255{padding-top:0;overflow:hidden}._userPromptList_rg6mx_260{width:600px;max-height:300px;overflow-y:auto}._userPromptItem_rg6mx_266{padding:4px 8px;font-size:12px;color:var(--text-secondary);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-radius:3px}._userPromptNavBtn_rg6mx_277{margin-left:auto;font-size:11px;color:var(--color-primary);cursor:pointer;border:1px solid var(--color-primary);border-radius:3px;padding:1px 6px;white-space:nowrap}._cacheContent_rg6mx_288{padding:8px 0;height:100%;display:flex;flex-direction:column}._cacheTokenBar_rg6mx_295{display:flex;align-items:center;font-size:12px;font-family:monospace;color:var(--text-light);margin-bottom:12px;flex-shrink:0}._cacheTokenWrite_rg6mx_305{color:var(--color-code-orange)}._cacheTokenRead_rg6mx_309{color:var(--color-success)}._cacheCopyIcon_rg6mx_313{margin-left:8px;cursor:pointer;color:var(--text-tertiary);transition:color .2s}._cacheScrollArea_rg6mx_320{flex:1;overflow-y:auto;min-height:0}._cacheSectionBlock_rg6mx_326{margin-bottom:12px}._cacheSectionHeader_rg6mx_330{font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:6px;cursor:pointer;-webkit-user-select:none;user-select:none;display:flex;align-items:center;gap:4px}._cacheCollapseArrow_rg6mx_342{display:inline-block;transition:transform .2s;font-size:10px}._cachePre_rg6mx_348{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-secondary);background:var(--bg-container);border:1px solid var(--border-primary);border-radius:4px;padding:8px;margin:4px 0;font-family:Menlo,Monaco,monospace}._cacheHighlightSvg_rg6mx_362{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none;overflow:visible}._cachePreSystem_rg6mx_371{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-secondary);background:var(--bg-code-system);border:1px solid var(--border-code-system);border-radius:4px;padding:8px;margin:4px 0;font-family:Menlo,Monaco,monospace}._container_rg6mx_1 .ant-tabs>.ant-tabs-nav{margin-bottom:0}._container_rg6mx_1 .ant-tabs{flex:1;min-height:0;display:flex;flex-direction:column}._container_rg6mx_1 .ant-tabs>.ant-tabs-content-holder{flex:1;min-height:0}._container_rg6mx_1 .ant-tabs-content,._container_rg6mx_1 .ant-tabs-tabpane-active{height:100%}._resizer_pzn4b_1{width:6px;cursor:col-resize;background:var(--bg-elevated);flex-shrink:0;transition:background .2s}._resizer_pzn4b_1:hover{background:var(--color-primary-light)}._flag_1q4ri_3{display:inline-flex;align-items:center;justify-content:center;font-size:13px;line-height:1;cursor:help;-webkit-user-select:none;user-select:none;height:14px;background:none;border:none;padding:0;color:inherit;font-family:inherit}._flag_1q4ri_3:focus-visible{outline:2px solid var(--primary-color, #1677ff);outline-offset:2px;border-radius:2px}._popover_1q4ri_27{color:var(--text-secondary);font-size:13px;line-height:22px}._meta_1q4ri_33{color:var(--text-tertiary);font-size:12px}._usagePill_srdlo_4{position:relative;display:inline-flex;align-items:center;justify-content:flex-start;border-radius:999px;border:1px solid;border-color:var(--text-disabled);color:var(--text-disabled);padding:0 7px;height:15px;font-size:11px;line-height:1;overflow:hidden;white-space:nowrap;cursor:default;background:var(--bg-base-pure)}._usageFill_srdlo_25{position:absolute;left:0;top:0;bottom:0;width:var(--usage-percent, 0);background-color:var(--text-disabled);opacity:.25;transition:width .5s ease;pointer-events:none}._usageContent_srdlo_37{position:relative;z-index:1;display:inline-flex;align-items:center}._usageText_srdlo_44{font-variant-numeric:tabular-nums}._muted_srdlo_49{border-color:var(--border-light);color:var(--text-disabled);background:var(--bg-surface)}._pop_srdlo_56{min-width:220px;font-size:12px;color:var(--text-primary)}._popTitle_srdlo_62{font-weight:600;margin-bottom:6px}._popTable_srdlo_68{border-collapse:collapse}._popTable_srdlo_68 td{padding-top:3px;padding-bottom:3px;vertical-align:middle}._tdName_srdlo_73{color:var(--text-secondary);padding-right:5px;white-space:nowrap}._tdBar_srdlo_73{padding-right:5px;white-space:nowrap}._tdReset_srdlo_91{color:var(--text-secondary);font-variant-numeric:tabular-nums;white-space:nowrap}._bar_srdlo_98{position:relative;display:inline-flex;align-items:center;justify-content:center;width:100px;height:14px;border-radius:999px;border:1px solid var(--text-disabled);overflow:hidden;background:var(--bg-base-pure);vertical-align:middle}._barFill_srdlo_112{position:absolute;left:0;top:0;bottom:0;background-color:var(--text-disabled);opacity:.25;pointer-events:none}._barText_srdlo_122{position:relative;z-index:1;font-size:11px;line-height:1;font-variant-numeric:tabular-nums;color:var(--text-primary)}
|