cc-viewer 1.6.340 → 1.6.341

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.
@@ -1,4 +1,4 @@
1
- import { readFileSync, existsSync } from 'node:fs';
1
+ import { readFileSync, existsSync, realpathSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { getClaudeConfigDir } from '../../findcc.js';
@@ -60,6 +60,26 @@ export function getContextSizeForModel(apiModelName) {
60
60
  return getModelMaxTokens(apiModelName);
61
61
  }
62
62
 
63
+ function pickBestModel(entries) {
64
+ const withOneM = entries.find(([k]) => /\[1m\]/i.test(k));
65
+ if (withOneM) return withOneM[0];
66
+ entries.sort((a, b) => (b[1]?.costUSD || 0) - (a[1]?.costUSD || 0));
67
+ return entries[0][0];
68
+ }
69
+
70
+ // Pick a model from one lastModelUsage record: drop aux (haiku) entries, then
71
+ // pickBestModel. Shared by both lookup strategies so the selection heuristic
72
+ // cannot silently diverge between them.
73
+ function modelFromUsage(lmu) {
74
+ if (!lmu || typeof lmu !== 'object') return null;
75
+ const entries = Object.entries(lmu).filter(([k]) => typeof k === 'string' && !/haiku/i.test(k));
76
+ return entries.length ? pickBestModel(entries) : null;
77
+ }
78
+
79
+ // Single definition of key canonicalization used on BOTH sides of every
80
+ // comparison below (cwd and projects key), so the two can never drift apart.
81
+ const stripTrailingSlash = (p) => p.replace(/\/+$/, '');
82
+
63
83
  /**
64
84
  * 读 ~/.claude.json 里 projects[cwd].lastModelUsage,挑出 cwd 下"用得最多/最显式"的模型。
65
85
  * 给 cc-viewer UI 血条 calibration 在启动期(lastMainAgent 仅有 haiku init ping 时)
@@ -73,7 +93,7 @@ export function getContextSizeForModel(apiModelName) {
73
93
  *
74
94
  * 任何 IO / 解析异常返回 null;调用方应当作"没找到偏好"处理(auto 走冷启动 1M)。
75
95
  *
76
- * @param {string} cwd - 绝对路径,必须与 claude 写入 ~/.claude.json projects key 完全一致
96
+ * @param {string} cwd - 绝对路径;尾部斜杠 / symlink / 大小写差异会被归一化后匹配
77
97
  * @param {string} [filePath] - 可选注入文件路径,默认 CLAUDE_USER_CONFIG_FILE;单测用
78
98
  * @returns {string|null} model id(含 [1m] 后缀,例 "claude-opus-4-7[1m]")或 null
79
99
  */
@@ -83,14 +103,43 @@ export function readClaudeProjectModel(cwd, filePath = CLAUDE_USER_CONFIG_FILE)
83
103
  if (!existsSync(filePath)) return null;
84
104
  const raw = readFileSync(filePath, 'utf-8');
85
105
  const data = JSON.parse(raw);
86
- const lmu = data?.projects?.[cwd]?.lastModelUsage;
87
- if (!lmu || typeof lmu !== 'object') return null;
88
- const entries = Object.entries(lmu).filter(([k]) => typeof k === 'string' && !/haiku/i.test(k));
89
- if (!entries.length) return null;
90
- const withOneM = entries.find(([k]) => /\[1m\]/i.test(k));
91
- if (withOneM) return withOneM[0];
92
- entries.sort((a, b) => (b[1]?.costUSD || 0) - (a[1]?.costUSD || 0));
93
- return entries[0][0];
106
+ const projects = data?.projects;
107
+ if (!projects || typeof projects !== 'object') return null;
108
+
109
+ // Claude Code keys projects by its own getcwd() (canonical), but the cwd we
110
+ // receive from spawnClaude may differ (macOS /tmp→/private/tmp symlinks,
111
+ // trailing slashes, or case on case-insensitive filesystems).
112
+ let normalized = cwd;
113
+ try { normalized = realpathSync(cwd); } catch { /* path doesn't exist → use cwd as-is */ }
114
+
115
+ // Strategy 1: exact key match — raw cwd first (any key that matched before
116
+ // normalization existed keeps matching), then the realpath'd form. When a
117
+ // usage record exists for this exact path, decide from it alone: haiku-only
118
+ // means "no preference here", not "go search other projects' keys".
119
+ let exactHit = false;
120
+ for (const key of new Set([stripTrailingSlash(cwd), stripTrailingSlash(normalized)])) {
121
+ const lmu = projects[key]?.lastModelUsage;
122
+ if (!lmu || typeof lmu !== 'object') continue;
123
+ exactHit = true;
124
+ const model = modelFromUsage(lmu);
125
+ if (model) return model;
126
+ }
127
+ if (exactHit) return null;
128
+
129
+ // Strategy 2: case-insensitive fallback. Default macOS/Windows filesystems
130
+ // are case-insensitive, so a stale-cased key (e.g. after a directory rename)
131
+ // still refers to the same directory. Only reached when no exact key had a
132
+ // usage record, so it can never override an exact match. Note this folds
133
+ // case on darwin unlike norm/normDir elsewhere in the repo (which are
134
+ // win32-only): those guard file access, this only rescues a display hint,
135
+ // so a false positive on a case-sensitive APFS volume is low-stakes.
136
+ if (process.platform === 'darwin' || process.platform === 'win32') {
137
+ const lower = stripTrailingSlash(normalized).toLowerCase();
138
+ const matchKey = Object.keys(projects).find((k) => stripTrailingSlash(k).toLowerCase() === lower);
139
+ if (matchKey) return modelFromUsage(projects[matchKey]?.lastModelUsage);
140
+ }
141
+
142
+ return null;
94
143
  } catch {
95
144
  return null;
96
145
  }
@@ -76,6 +76,8 @@ export function buildSystemPromptFileArgs(projectDir, existingArgs = [], env = p
76
76
  }
77
77
  return out; // 命中即返回:默认 sentinel 不再参与(含手动 flag 抑制注入的情况)。
78
78
  }
79
+ // No matching entry: fall through to the default sentinels. Diagnostics for
80
+ // this case live in the caller (pty-manager) — this stays a pure function.
79
81
  }
80
82
 
81
83
  // 整段替换:CC_SYSTEM.md → --system-prompt-file (用户已传 --system-prompt[-file] 则跳过)
@@ -1,7 +1,7 @@
1
1
  import { resolveNativePath, LOG_DIR } from '../findcc.js';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { join, dirname, sep } from 'node:path';
4
- import { chmodSync, statSync } from 'node:fs';
4
+ import { chmodSync, statSync, existsSync } from 'node:fs';
5
5
  import { platform, arch, homedir } from 'node:os';
6
6
  import { createRequire } from 'node:module';
7
7
  import { prepareEmbeddedShellSpawn, stripClaudeNoFlickerUnlessOptedIn, applyClaudeAltScreenPref } from './lib/terminal-env.js';
@@ -300,11 +300,21 @@ async function _spawnClaudeImpl(proxyPort, cwd, extraArgs = [], claudePath = nul
300
300
  // IM 人格依赖默认 sentinel CC_APPEND_SYSTEM.md 注入,全局模型条目不得静默取代它。
301
301
  const spawnDir = cwd || process.cwd();
302
302
  const insideLogDir = spawnDir === LOG_DIR || spawnDir.startsWith(LOG_DIR + sep);
303
+ const resolvedModelId = insideLogDir ? null : _spawnModelReader(spawnDir);
303
304
  let sysPrompt = buildSystemPromptFileArgs(spawnDir, finalExtraArgs, process.env, {
304
- modelId: insideLogDir ? null : _spawnModelReader(spawnDir),
305
+ modelId: resolvedModelId,
305
306
  globalModelDir: join(LOG_DIR, MODEL_PROMPT_DIR),
306
307
  });
307
- if (_systemPromptFileRejectedPaths.has(claudePath)) sysPrompt = { args: [], loaded: [], model: null };
308
+ if (_systemPromptFileRejectedPaths.has(claudePath)) {
309
+ sysPrompt = { args: [], loaded: [], model: null };
310
+ } else if (resolvedModelId && !sysPrompt.model
311
+ && (existsSync(join(spawnDir, MODEL_PROMPT_DIR)) || existsSync(join(LOG_DIR, MODEL_PROMPT_DIR)))) {
312
+ // The one diagnostic case worth a warning: a system_prompt dir is configured
313
+ // but the resolved model matched no entry (likely a misnamed file). The
314
+ // successful-injection notice is emitted below via emitSpawnNotice (with
315
+ // internal-restart suppression); no-modelId spawns are the normal quiet path.
316
+ console.warn(`[CC Viewer] model-specific prompt: modelId="${resolvedModelId}" resolved but no matching entry found in workspace or global ${MODEL_PROMPT_DIR}/`);
317
+ }
308
318
  const launchArgs = sysPrompt.args.length ? [...finalExtraArgs, ...sysPrompt.args] : finalExtraArgs;
309
319
 
310
320
  let command = claudePath;
@@ -0,0 +1,133 @@
1
+ // Codebase text search + replace routes — POST /api/search, POST /api/search-replace.
2
+ // Scopes to the project root and delegates to lib/code-search.js and lib/code-replace.js.
3
+ import { searchCode } from '../lib/code-search.js';
4
+ import { searchReplace } from '../lib/code-replace.js';
5
+
6
+ const VALID_ENGINES = new Set(['auto', 'ripgrep', 'node']);
7
+ const VALID_SCOPES = new Set(['all', 'file', 'match']);
8
+
9
+ // Cap glob count/length to bound compile cost and glob-regex backtracking.
10
+ function toGlobs(v) {
11
+ return (Array.isArray(v)
12
+ ? v.map((s) => String(s).trim())
13
+ : String(v || '').split(',').map((s) => s.trim()))
14
+ .filter((s) => s && s.length <= 200)
15
+ .slice(0, 20);
16
+ }
17
+
18
+ // Body reader + disconnect-aborter shared by both handlers. NOTE: aborts on res 'close' guarded
19
+ // by writableFinished — the request's own 'close' fires on NORMAL completion once the body is
20
+ // read, which would abort every request.
21
+ function withBody(req, res, deps, run) {
22
+ let body = '';
23
+ req.on('data', (chunk) => { body += chunk; if (body.length > deps.MAX_POST_BODY) req.destroy(); });
24
+ req.on('end', async () => {
25
+ let parsed;
26
+ try { parsed = JSON.parse(body); } catch {
27
+ res.writeHead(400, { 'Content-Type': 'application/json' });
28
+ res.end(JSON.stringify({ error: 'Invalid request body' }));
29
+ return;
30
+ }
31
+ const ac = new AbortController();
32
+ let aborted = false;
33
+ const onClose = () => { if (!res.writableFinished) { aborted = true; ac.abort(); } };
34
+ res.on('close', onClose);
35
+ try {
36
+ await run(parsed, ac.signal, () => aborted);
37
+ } finally {
38
+ res.off('close', onClose);
39
+ }
40
+ });
41
+ }
42
+
43
+ function searchHandler(req, res, parsedUrl, isLocal, deps) {
44
+ withBody(req, res, deps, async (parsed, signal, isAborted) => {
45
+ const query = typeof parsed.query === 'string' ? parsed.query : '';
46
+ if (!query) {
47
+ res.writeHead(200, { 'Content-Type': 'application/json' });
48
+ res.end(JSON.stringify({ results: [], truncated: false, engine: 'none', filesScanned: 0 }));
49
+ return;
50
+ }
51
+
52
+ const engine = VALID_ENGINES.has(parsed.engine) ? parsed.engine : 'auto';
53
+ const root = process.env.CCV_PROJECT_DIR || process.cwd();
54
+
55
+ try {
56
+ const result = await searchCode({
57
+ query,
58
+ root,
59
+ caseSensitive: !!parsed.caseSensitive,
60
+ wholeWord: !!parsed.wholeWord,
61
+ regex: !!parsed.regex,
62
+ includeGlobs: toGlobs(parsed.includeGlobs),
63
+ excludeGlobs: toGlobs(parsed.excludeGlobs),
64
+ engine,
65
+ signal,
66
+ });
67
+ if (isAborted() || res.writableEnded) return; // client gone — nothing to send
68
+ if (result.error === 'invalid_regex') {
69
+ res.writeHead(400, { 'Content-Type': 'application/json' });
70
+ res.end(JSON.stringify({ error: 'invalid_regex' }));
71
+ return;
72
+ }
73
+ res.writeHead(200, { 'Content-Type': 'application/json' });
74
+ res.end(JSON.stringify(result));
75
+ } catch {
76
+ if (isAborted() || res.writableEnded) return;
77
+ res.writeHead(500, { 'Content-Type': 'application/json' });
78
+ res.end(JSON.stringify({ error: 'search_failed' }));
79
+ }
80
+ });
81
+ }
82
+
83
+ function replaceHandler(req, res, parsedUrl, isLocal, deps) {
84
+ withBody(req, res, deps, async (parsed, signal, isAborted) => {
85
+ const query = typeof parsed.query === 'string' ? parsed.query : '';
86
+ const scope = VALID_SCOPES.has(parsed.scope) ? parsed.scope : null;
87
+ if (!query || !scope || typeof parsed.replacement !== 'string') {
88
+ res.writeHead(400, { 'Content-Type': 'application/json' });
89
+ res.end(JSON.stringify({ error: 'Invalid request' }));
90
+ return;
91
+ }
92
+ const root = process.env.CCV_PROJECT_DIR || process.cwd();
93
+ try {
94
+ const result = await searchReplace({
95
+ query,
96
+ root,
97
+ caseSensitive: !!parsed.caseSensitive,
98
+ wholeWord: !!parsed.wholeWord,
99
+ regex: !!parsed.regex,
100
+ includeGlobs: toGlobs(parsed.includeGlobs),
101
+ excludeGlobs: toGlobs(parsed.excludeGlobs),
102
+ replacement: parsed.replacement,
103
+ scope,
104
+ file: typeof parsed.file === 'string' ? parsed.file : undefined,
105
+ line: Number.isInteger(parsed.line) ? parsed.line : undefined,
106
+ col: Number.isInteger(parsed.col) ? parsed.col : undefined,
107
+ expectText: typeof parsed.expectText === 'string' ? parsed.expectText : undefined,
108
+ skipPaths: Array.isArray(parsed.skipPaths) ? parsed.skipPaths.map(String) : [],
109
+ dryRun: !!parsed.dryRun,
110
+ // Deliberately NOT wired to `signal`: once a destructive batch starts we let it finish
111
+ // rather than leave committed-but-unreported partial writes on a client disconnect. The
112
+ // per-file event-loop yield keeps the server responsive; the wall-clock budget bounds it.
113
+ });
114
+ if (isAborted() || res.writableEnded) return;
115
+ if (result.error === 'invalid_regex') {
116
+ res.writeHead(400, { 'Content-Type': 'application/json' });
117
+ res.end(JSON.stringify({ error: 'invalid_regex' }));
118
+ return;
119
+ }
120
+ res.writeHead(200, { 'Content-Type': 'application/json' });
121
+ res.end(JSON.stringify(result));
122
+ } catch {
123
+ if (isAborted() || res.writableEnded) return;
124
+ res.writeHead(500, { 'Content-Type': 'application/json' });
125
+ res.end(JSON.stringify({ error: 'replace_failed' }));
126
+ }
127
+ });
128
+ }
129
+
130
+ export const searchRoutes = [
131
+ { method: 'POST', match: 'exact', path: '/api/search', handler: searchHandler },
132
+ { method: 'POST', match: 'exact', path: '/api/search-replace', handler: replaceHandler },
133
+ ];
@@ -67,9 +67,10 @@ function workspacesLaunch(req, res, parsedUrl, isLocal, deps) {
67
67
  deps.setWorkspaceLaunched(true);
68
68
 
69
69
  // 通知所有 SSE 客户端
70
+ const startedPayload = `event: workspace_started\ndata: ${JSON.stringify({ projectName: result.projectName, path: wsPath, claudeProjectModel: readClaudeProjectModel(wsPath) })}\n\n`;
70
71
  deps.clients.forEach(client => {
71
72
  try {
72
- client.write(`event: workspace_started\ndata: ${JSON.stringify({ projectName: result.projectName, path: wsPath, claudeProjectModel: readClaudeProjectModel(wsPath) })}\n\n`);
73
+ client.write(startedPayload);
73
74
  } catch {}
74
75
  });
75
76
 
package/server/server.js CHANGED
@@ -29,6 +29,7 @@ import { ultraAgentsRoutes } from './routes/ultra-agents.js';
29
29
  import { filesContentRoutes } from './routes/files-content.js';
30
30
  import { workflowJournalRoutes } from './routes/workflow-journal.js';
31
31
  import { filesFsRoutes } from './routes/files-fs.js';
32
+ import { searchRoutes } from './routes/search.js';
32
33
  import { workspacesRoutes } from './routes/workspaces.js';
33
34
  import { expertRoutes } from './routes/expert.js';
34
35
  import { eventsRoutes } from './routes/events.js';
@@ -602,6 +603,7 @@ const _routes = [
602
603
  ...filesContentRoutes,
603
604
  ...workflowJournalRoutes,
604
605
  ...filesFsRoutes,
606
+ ...searchRoutes,
605
607
  ...workspacesRoutes,
606
608
  ...expertRoutes,
607
609
  ...eventsRoutes,
@@ -1 +0,0 @@
1
- ._liveTag_8g4c3_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_8g4c3_23{position:absolute;left:0;top:0;bottom:0;width:var(--ctx-percent, 0);background-color:var(--ctx-color);background-image:repeating-linear-gradient(135deg,rgba(255,255,255,.25) 0,rgba(255,255,255,.25) 2px,transparent 2px,transparent 7px);opacity:.35;transition:width .5s ease,background-color .3s;pointer-events:none}._liveTagContent_8g4c3_44{position:relative;z-index:1;display:inline-flex;align-items:center}._liveTagHistory_8g4c3_52{background:var(--bg-surface);border-color:var(--border-light);color:var(--text-primary)}._liveTagText_8g4c3_59{margin-left:4px;font-variant-numeric:tabular-nums}._cachePopoverPlaceholder_8g4c3_65{min-width:300px}._modeRow_4r8la_1{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:10px}._modeLeft_4r8la_9{display:flex;align-items:center;gap:10px}._modeRight_4r8la_15{display:flex;align-items:center;gap:8px}._overrideWarn_4r8la_22{font-size:12px;color:var(--color-warning, #d4810a)}._previewLabel_4r8la_27{font-size:13px;color:var(--text-secondary, #888)}._previewBox_4r8la_36{border:1px solid var(--border-primary);border-radius:8px;background:transparent;padding:12px 14px;min-height:320px;max-height:60vh;overflow:auto}._previewEmpty_4r8la_46{font-size:13px;color:var(--text-secondary, #888)}._hint_4r8la_51{margin-top:10px;font-size:12px;color:var(--text-secondary, #888);line-height:1.6}._dirLine_4r8la_58{word-break:break-all}._warn_4r8la_62{margin-top:10px;font-size:12px;color:var(--color-warning, #d4810a)}._tabRow_4r8la_71{display:flex;align-items:flex-end;gap:8px;padding:0 4px;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}._tabRow_4r8la_71::-webkit-scrollbar{display:none}._tabBtn_4r8la_90{display:inline-flex;align-items:center;gap:5px;padding:9px 14px;font-size:12px;line-height:1.6;border:1px solid transparent;border-radius:14px;background:transparent;color:var(--text-secondary);cursor:pointer;transition:all .2s;-webkit-user-select:none;user-select:none;white-space:nowrap;flex-shrink:0}._tabBtn_4r8la_90:hover{color:var(--color-primary)}._tabBtn_4r8la_90:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}._tabBtn_4r8la_90._tabActive_4r8la_118{background:var(--bg-container);color:var(--color-primary);border-color:var(--border-primary);border-bottom-color:var(--bg-container);border-radius:10px 10px 0 0;font-weight:500;margin-bottom:-1px;position:relative;z-index:1}._tabRow_4r8la_71>._tabBtn_4r8la_90._tabActive_4r8la_118,._tabWrap_4r8la_132:has(>._tabBtn_4r8la_90._tabActive_4r8la_118){position:sticky;left:0;right:0;z-index:2}[data-theme=light] ._tabBtn_4r8la_90._tabActive_4r8la_118{box-shadow:0 -3px 8px #0000000f}._editorBox_4r8la_33{background:var(--bg-container);border-radius:8px;overflow:hidden;padding:4px;position:relative}[data-theme=light] ._editorBox_4r8la_33{box-shadow:0 3px 8px #00000014}._editorBox_4r8la_33 .ant-input{background:transparent;border:1px solid var(--border-primary);border-radius:8px;box-shadow:none;padding:12px 14px;font-size:12px;line-height:1.5;color:var(--text-primary)}._editorBox_4r8la_33 .ant-input:hover{border-color:var(--border-primary);background:transparent}._editorBox_4r8la_33 .ant-input:focus{border-color:var(--color-primary-pale);box-shadow:none}._editorBox_4r8la_33 .ant-input[disabled]{color:var(--text-muted);background:transparent}._tabWrap_4r8la_132{position:relative;display:inline-flex;align-items:center;flex-shrink:0}._tabTitle_4r8la_197{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._tabDelete_4r8la_205{position:absolute;top:-2px;inset-inline-end:-4px;width:14px;height:14px;border-radius:50%;background:var(--bg-elevated);border:1px solid var(--border-primary);color:var(--text-secondary);font-size:10px;line-height:1;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .15s;z-index:2}._tabWrap_4r8la_132:hover ._tabDelete_4r8la_205{opacity:1}._tabDelete_4r8la_205:hover{color:var(--color-error, #d4380d);border-color:var(--color-error, #d4380d)}@media(max-width:768px){._tabDelete_4r8la_205{opacity:1}}._addBtn_4r8la_238{display:inline-flex;align-items:center;align-self:center;gap:5px;padding:6px 14px;font-size:12px;line-height:1.6;margin-left:4px;margin-bottom:2px;border:none;border-radius:14px;background:transparent;color:var(--text-muted);cursor:pointer;transition:background .15s,color .15s;-webkit-user-select:none;user-select:none;white-space:nowrap;flex-shrink:0}._addBtn_4r8la_238:hover{color:var(--color-primary);background:var(--bg-surface)}._addBtn_4r8la_238:disabled{cursor:not-allowed;opacity:.5}[data-theme=light] ._addBtn_4r8la_238{color:var(--text-secondary)}._scopeBadge_4r8la_271{font-size:10px;line-height:1.4;padding:0 4px;border-radius:6px;background:var(--bg-surface);color:var(--text-muted)}._dirtyDot_4r8la_281{width:6px;height:6px;border-radius:50%;background:var(--color-primary);flex-shrink:0}._titleRow_4r8la_290{display:inline-flex;align-items:center;gap:8px}._helpBtn_4r8la_299{align-self:center;width:16px;height:16px;border-radius:50%;border:1px solid var(--border-primary);background:var(--bg-elevated);color:var(--text-secondary);font-size:11px;line-height:1;display:inline-flex;align-items:center;justify-content:center;cursor:help;flex-shrink:0;-webkit-user-select:none;user-select:none}._helpBtn_4r8la_299:hover{color:var(--color-primary);border-color:var(--color-primary)}._addPopover_4r8la_322{display:flex;flex-direction:column;gap:8px;width:240px}._addError_4r8la_328{font-size:12px;color:var(--color-error, #d4380d)}._editButton_1r9yr_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_1r9yr_10 .anticon{display:inline-flex;align-items:center;line-height:1;position:relative;top:-1px}._editButton_1r9yr_10:hover,._editButton_1r9yr_10:focus-visible{opacity:1;color:var(--text-primary, #333);background-color:var(--bg-hover, rgba(0, 0, 0, .04));outline:none}._editButton_1r9yr_10:focus-visible{box-shadow:0 0 0 2px var(--focus-ring, rgba(64, 158, 255, .4))}._footer_1r9yr_55{display:flex;justify-content:space-between;align-items:center;gap:8px}._footerLeft_1r9yr_61,._footerRight_1r9yr_65{display:flex;gap:8px}._projectNameRow_1r9yr_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_1r9yr_80{color:var(--text-secondary, #888)}._projectNameValue_1r9yr_83{color:var(--text-primary, #333);font-family:var(--font-mono);word-break:break-all}._panel_1nxl3_1{display:flex;flex-direction:column;gap:14px}._required_1nxl3_7{margin-left:2px;color:var(--color-error-light, #ff7b7b)}._optional_1nxl3_12{margin-left:6px;font-size:12px;font-weight:400;color:var(--text-secondary)}._row_1nxl3_19{display:flex;align-items:center;justify-content:space-between;gap:12px}._label_1nxl3_26{font-size:14px;font-weight:500}._control_1nxl3_31{display:inline-flex;align-items:center;gap:10px}._field_1nxl3_37{display:flex;flex-direction:column;gap:6px}._fieldLabel_1nxl3_43{font-size:13px;color:var(--text-secondary)}._help_1nxl3_48{font-size:12px;color:var(--text-secondary);line-height:1.4}._warn_1nxl3_54{font-size:12px;line-height:1.5;color:var(--color-error-light, #ff7b7b)}._hint_1nxl3_60{font-size:12px;line-height:1.5;color:var(--text-secondary)}._helpIcon_1nxl3_67{margin-left:6px;color:var(--text-tertiary, #999);cursor:help;font-size:13px}._detailsToggle_1nxl3_74{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_1nxl3_74:hover{color:var(--text-primary, var(--text-secondary))}._details_1nxl3_74{display:flex;flex-direction:column;gap:10px}._actions_1nxl3_98{display:flex;justify-content:flex-end;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-secondary)}._testBtn_1nxl3_108{margin-right:auto}._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_riojj_1{height:100%;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable;padding:4px 2px;background:var(--bg-container)}._headerBar_riojj_15{display:flex;align-items:center;gap:8px}._refreshBtn_riojj_21{flex:0 0 auto}._statusTag_riojj_27{display:inline-flex;align-items:center;margin-left:auto}._statusTag_riojj_27 .ant-tag{margin-inline-end:0}._center_riojj_36{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:40px 0;color:var(--text-secondary)}._hint_riojj_46{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_1vshv_3{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;background:var(--bg-container)}._modelName_1vshv_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_1vshv_17{width:100%;border-collapse:collapse}._th_1vshv_21{padding:2px 12px;font-size:12px;font-family:var(--font-mono);white-space:nowrap;color:var(--text-tertiary);font-weight:400;text-align:right}._td_1vshv_30{padding:2px 12px;font-size:12px;font-family:var(--font-mono);white-space:nowrap;color:var(--text-primary);text-align:right}._label_1vshv_38{padding:2px 12px;font-size:12px;font-family:var(--font-mono);white-space:nowrap;color:var(--text-light);font-weight:400;text-align:left}._rowBorder_1vshv_47{border-bottom:1px solid var(--border-primary)}._rebuildTotalRow_1vshv_50{border-top:1px solid var(--border-light)}._rebuildTotalRow_1vshv_50 td{font-weight:600}._cachePopoverEmpty_1vshv_56{padding:8px 4px;color:var(--text-tertiary);font-size:13px}._toolChipGrid_1vshv_61{display:flex;flex-wrap:wrap;gap:4px;padding:2px 0 6px 2px}._cacheToolChip_1vshv_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_1vshv_81{margin-right:8px}._detailMarkdownCard_1vshv_86{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;background:var(--bg-container)}._memoryMarkdown_1vshv_93{font-size:12.5px;line-height:1.55;color:var(--text-primary);word-break:break-word}._memoryMarkdown_1vshv_93 p{margin:0 0 6px}._memoryMarkdown_1vshv_93 ul,._memoryMarkdown_1vshv_93 ol{margin:4px 0 6px;padding-left:20px}._memoryMarkdown_1vshv_93 li{margin:2px 0}._memoryMarkdown_1vshv_93 h1,._memoryMarkdown_1vshv_93 h2,._memoryMarkdown_1vshv_93 h3,._memoryMarkdown_1vshv_93 h4{font-size:13px;font-weight:600;margin:8px 0 4px;color:var(--text-primary)}._memoryMarkdown_1vshv_93 h1{font-size:14px}._memoryMarkdown_1vshv_93 a{color:var(--primary-color, #1677ff);text-decoration:none;cursor:pointer}._memoryMarkdown_1vshv_93 a:hover{text-decoration:underline}._memoryMarkdown_1vshv_93 code{font-family:var(--font-mono);font-size:12px;padding:1px 4px;border-radius:3px;background:var(--bg-surface);color:var(--text-primary)}._memoryMarkdown_1vshv_93 pre{margin:6px 0;padding:8px 10px;border-radius:4px;background:var(--bg-surface);overflow-x:auto}._memoryMarkdown_1vshv_93 pre code{padding:0;background:transparent;font-size:12px}._memoryMarkdown_1vshv_93 blockquote{margin:4px 0;padding:2px 8px;border-left:3px solid var(--border-hover);color:var(--text-secondary)}._memoryMarkdown_1vshv_93 hr{margin:8px 0;border:none;border-top:1px solid var(--border-secondary)}._quickMenuGroup_1vshv_164{position:relative}._quickMenuRow_1vshv_168{display:flex;align-items:center;gap:6px;width:100%;background:none;border:none;color:var(--text-primary);font-size:13px;padding:6px 12px;text-align:left;cursor:pointer;border-radius:4px;white-space:nowrap}._quickMenuGroup_1vshv_164:hover ._quickMenuRow_1vshv_168,._quickMenuGroupOpen_1vshv_185 ._quickMenuRow_1vshv_168{background:var(--border-secondary)}._quickMenuRowIcon_1vshv_189{display:flex;align-items:center;color:var(--text-tertiary)}._quickMenuRowIcon_1vshv_189 svg{width:14px;height:14px}._quickMenuLabel_1vshv_200{flex:1}._quickMenuValue_1vshv_205{color:var(--text-tertiary);font-size:12px}._quickMenuCaret_1vshv_210{color:var(--text-tertiary);font-size:10px}._quickMenuSubWrap_1vshv_218{display:none;position:absolute;left:100%;bottom:-5px;padding-left:6px;z-index:1}._quickMenuGroupOpen_1vshv_185 ._quickMenuSubWrap_1vshv_218{display:block}._quickMenuSub_1vshv_218{display:flex;flex-direction:column;background:var(--bg-elevated);border:1px solid var(--border-hover);border-radius:8px;padding:4px;min-width:76px;max-height:60vh;overflow-y:auto;box-shadow:0 6px 16px #0000002e}._quickMenuOption_1vshv_248{background:none;border:none;color:var(--text-primary);font-size:13px;padding:5px 12px;text-align:left;cursor:pointer;border-radius:4px;white-space:nowrap}._quickMenuOption_1vshv_248:hover{background:var(--border-secondary)}._quickMenuOption_1vshv_248._quickMenuOptionActive_1vshv_264{color:var(--color-primary);font-weight:500}._quickMenuSubTipBox_1vshv_270{padding:8px 12px;width:300px;white-space:normal}._headerBar_18pw5_2{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%}._logoWrap_18pw5_10{display:inline-flex;align-items:center;position:relative;margin-top:14px}._logoWrapActive_18pw5_17:after{content:"";position:absolute;top:-10px;bottom:-10px;left:0;right:-200px}._logoImage_18pw5_26{height:24px;width:24px;border-radius:3px;vertical-align:middle;opacity:.75;transition:opacity .2s;cursor:pointer}._logoImageActive_18pw5_36{opacity:1}._compactBtn_18pw5_43{font-size:12px;height:30px;display:inline-flex;align-items:center;justify-content:center}._compactBtnNoBorder_18pw5_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_18pw5_52 .anticon{display:inline-flex;align-items:center;justify-content:center;line-height:0}._headerProjectName_18pw5_79{font-size:12px;color:inherit;white-space:nowrap}._headerProjectName_18pw5_79:hover [data-alias-edit-trigger],._headerProjectName_18pw5_79:focus-within [data-alias-edit-trigger]{opacity:.55}._countdownStrong_18pw5_96{font-variant-numeric:tabular-nums}._qrcodePopover_18pw5_101{display:flex;flex-direction:column;align-items:center;padding:8px}._qrcodeSection_18pw5_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_18pw5_119{font-size:14px;font-weight:600;color:var(--text-primary);margin-bottom:12px}._qrcodeUrlInput_18pw5_126{margin-top:12px;font-size:12px;font-family:var(--font-mono)}._qrcodeUrlCopy_18pw5_132{cursor:pointer;color:var(--text-tertiary);transition:color .2s}._qrcodeUrlCopy_18pw5_132:hover{color:var(--color-primary-light)}._authSection_18pw5_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_18pw5_157{display:flex;align-items:center;justify-content:space-between}._authTitle_18pw5_163{font-size:13px;font-weight:600;color:var(--text-primary)}._authPasswordLabel_18pw5_169{font-size:12px;color:var(--text-secondary)}._authPasswordInput_18pw5_174{font-size:12px;font-family:var(--font-mono)}._authSaveBtn_18pw5_179{align-self:flex-end}._authEmptyWarn_18pw5_183{font-size:12px;color:var(--color-error-light);line-height:1.4}._settingsGroupBox_18pw5_191{border:1px solid var(--border-secondary);border-radius:8px;background:var(--bg-container);padding:4px 16px;margin-bottom:12px}._settingsGroupTitle_18pw5_199{font-size:14px;font-weight:600;color:var(--text-primary);padding:12px 0 4px;border-bottom:1px solid var(--border-secondary)}._settingsItem_18pw5_208{display:flex;justify-content:space-between;align-items:center;padding:12px 0}._settingsLabel_18pw5_215{font-size:14px}._settingsHelpIcon_18pw5_220{font-size:16px;color:var(--text-disabled);cursor:help;margin-left:4px}._settingsDivider_18pw5_227{border-top:1px solid var(--border-primary);margin:12px 0}._logDirInput_18pw5_232{margin-top:8px;background:var(--bg-base-alt);border-color:var(--border-light);color:var(--text-primary);font-family:var(--font-mono);font-size:13px}._tokenStatsEmpty_18pw5_242{padding:8px 4px;color:var(--text-tertiary);font-size:13px}._tokenStatsContainer_18pw5_249{display:flex;gap:12px;align-items:flex-start}._tokenStatsColumn_18pw5_255{min-width:240px}._toolStatsColumn_18pw5_259{min-width:180px}._modelCardSpaced_18pw5_265{margin-bottom:10px}._rebuildCard_18pw5_274{border:1px solid var(--border-secondary);border-radius:6px;padding:8px 10px;margin-top:10px;background:var(--bg-container)}._promptExportBar_18pw5_283{margin-bottom:12px}._promptScrollArea_18pw5_287{max-height:500px;overflow:auto}._promptEmpty_18pw5_292{color:var(--text-tertiary);padding:12px}._promptTimestamp_18pw5_298{color:var(--text-muted);font-size:12px;margin:12px 0 4px;padding-bottom:6px}._textPromptCard_18pw5_306{margin:4px 0;background:var(--bg-container);border-radius:6px;border:1px solid var(--border-secondary);padding:10px 14px}._preText_18pw5_315{white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.6;color:var(--text-primary);margin:4px 0}._systemCollapse_18pw5_325{margin:4px 0;background:var(--bg-elevated);border:1px solid var(--border-secondary);border-radius:6px}._systemLabel_18pw5_332{color:var(--text-tertiary);font-size:12px}._preSys_18pw5_337{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:var(--text-tertiary);margin:0}._promptTextarea_18pw5_347{box-sizing:border-box;background:var(--bg-base-pure);width:100%;min-height:400px;color:var(--text-primary);font-family:var(--font-mono);font-size:13px;line-height:1.6;border:none;resize:vertical;padding:10px 14px;outline:none}._projectStatsCenter_18pw5_363{display:flex;justify-content:center;padding:40px 0}._projectStatsEmpty_18pw5_369{color:var(--text-tertiary);padding:40px 0;text-align:center;font-size:13px}._projectStatsContent_18pw5_376{display:flex;flex-direction:column;gap:16px}._projectStatsUpdated_18pw5_382{color:var(--text-muted);font-size:12px;text-align:right}._projectStatsSummary_18pw5_388{display:grid;grid-template-columns:1fr 1fr;gap:10px}._projectStatCard_18pw5_394{background:var(--bg-container);border:1px solid var(--border-secondary);border-radius:8px;padding:14px 12px;text-align:center}._projectStatValue_18pw5_402{font-size:22px;font-weight:700;color:var(--text-primary);font-family:var(--font-mono);font-variant-numeric:tabular-nums}._projectStatLabel_18pw5_410{font-size:12px;color:var(--text-tertiary);margin-top:4px}._projectStatsSection_18pw5_416{display:flex;flex-direction:column;gap:10px}._projectStatsSectionTitle_18pw5_422{font-size:14px;font-weight:600;color:var(--text-secondary);padding-bottom:4px;border-bottom:1px solid var(--border-secondary)}._projectStatsModelCard_18pw5_430{background:var(--bg-container);border:1px solid var(--border-secondary);border-radius:6px;padding:10px 12px}._projectStatsModelHeader_18pw5_437{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid var(--border-secondary)}._projectStatsModelName_18pw5_446{font-size:13px;font-weight:600;color:var(--text-primary)}._projectStatsModelCount_18pw5_452{font-size:12px;color:var(--text-tertiary);font-family:var(--font-mono)}._cacheCopyBtn_18pw5_460{font-size:14px;color:var(--text-tertiary);cursor:pointer;transition:color .2s;margin-left:8px}._cacheCopyBtn_18pw5_460:hover{color:var(--text-primary)}._cacheTokenInfo_18pw5_472{display:flex;align-items:center;font-size:12px;font-family:var(--font-mono);color:var(--text-light);margin-bottom:8px}._cacheCodeBlock_18pw5_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:var(--font-mono)}._cacheCodeBlockSystem_18pw5_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:var(--font-mono)}._cacheNavBtn_18pw5_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_18pw5_513:hover{background:var(--color-primary-bg-light)}._cacheNavList_18pw5_528{width:600px;max-height:300px;overflow-y:auto}._cacheNavItem_18pw5_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_18pw5_534:hover{background:var(--color-primary-bg-lighter);color:var(--text-white)}._cacheBlockHighlight_18pw5_550{box-shadow:0 0 10px var(--color-primary-shadow);transition:box-shadow .2s ease-in}._cacheBlockHighlightFading_18pw5_555{box-shadow:0 0 10px transparent;transition:box-shadow 3s ease-out}._cacheBorderSvg_18pw5_560{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none;overflow:visible}._cacheBorderSvgFading_18pw5_569{opacity:0;transition:opacity 3s ease-out}._cacheBorderRect_18pw5_574{animation:_cacheDashRotate_18pw5_1 4s linear infinite}@keyframes _cacheDashRotate_18pw5_1{0%{stroke-dashoffset:0}to{stroke-dashoffset:-100}}._thLeft_18pw5_584{text-align:left}._cacheWriteToken_18pw5_599{color:var(--color-code-orange)}._cacheReadToken_18pw5_603{color:var(--color-success)}._cacheCtxPercent_18pw5_607{color:var(--text-tertiary);margin-left:6px}._qrcodeIcon_18pw5_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_18pw5_627:hover{color:var(--text-primary);background:var(--bg-hover, rgba(0, 0, 0, .04))}._qrcodeIcon_18pw5_627:focus-visible{outline:2px solid var(--primary-color, #1677ff);outline-offset:1px}._approvalBell_18pw5_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_18pw5_653:hover{color:var(--text-primary);background:var(--bg-hover, rgba(0, 0, 0, .04))}._approvalBell_18pw5_653:focus-visible{outline:2px solid var(--primary-color, #1677ff);outline-offset:1px}._approvalBellBadge_18pw5_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_18pw5_695{margin-right:4px;font-size:11px}._proxyProfileTag_18pw5_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_18pw5_701:hover{color:var(--text-secondary);border-color:var(--text-disabled)}._pinnedShortcut_18pw5_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_18pw5_717:hover{opacity:1;color:var(--text-secondary)}._pinnedShortcut_18pw5_717 .anticon{display:inline-flex;align-items:center;justify-content:center;line-height:0}._themeToggle_18pw5_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_18pw5_746:hover{background:var(--color-bg-hover, rgba(127, 127, 127, .12));color:var(--text-primary)}._themeToggle_18pw5_746:focus-visible{box-shadow:0 0 0 2px var(--primary-color, #1677ff)}._themeToggleIcon_18pw5_772{display:block}._headerRightRow_18pw5_777 .ant-space-item{display:inline-flex;align-items:center}._headerCountdownTag_18pw5_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_1ivpu_1{display:flex;align-items:center;justify-content:center;height:100%}._scrollContainer_1ivpu_8{overflow:auto;height:100%;-webkit-overflow-scrolling:touch;will-change:scroll-position}._listItem_1ivpu_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_1ivpu_15:hover{border-left-color:var(--border-hover)}._listItemActive_1ivpu_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_1ivpu_29,._listItemActive_1ivpu_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_1ivpu_46{width:100%;min-width:0}._itemHeader_1ivpu_51{display:flex;align-items:center;gap:6px;margin-bottom:4px;font-size:12px}._tagNoMargin_1ivpu_59{margin:0;font-size:12px}._modelName_1ivpu_64{font-size:12px;color:var(--text-tertiary)}._modelNameMain_1ivpu_69{color:var(--color-code-orange)}._time_1ivpu_73{font-size:12px;color:var(--text-gray);margin-left:auto}._detailRow_1ivpu_79{display:flex;gap:8px;font-size:12px;align-items:center}._urlText_1ivpu_86{color:var(--text-disabled);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}._duration_1ivpu_95{color:var(--text-gray);flex-shrink:0}._statusOk_1ivpu_100{color:var(--color-success);opacity:.5;flex-shrink:0}._statusErr_1ivpu_106{color:var(--color-error);flex-shrink:0}._statusDefault_1ivpu_111{color:var(--text-tertiary);flex-shrink:0}._usageBox_1ivpu_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_1ivpu_126{display:inline-block;width:6px;height:6px;border-radius:50%;margin:0 3px;vertical-align:middle}._cacheDotLoss_1ivpu_135{background-color:var(--color-red-dark-bg);cursor:help}._cacheDotNormal_1ivpu_140{background-color:var(--border-hover)}._cacheDotTools_1ivpu_145{background-color:var(--color-code-purple);box-shadow:0 0 0 1.5px var(--color-purple-border)}._tagMainAgent_1ivpu_150{color:var(--color-code-orange);border-color:var(--color-code-orange-border);background:var(--color-code-orange-bg)}._tagPlan_1ivpu_156{color:var(--color-error-muted);border-color:var(--color-error-muted);background-color:var(--bg-base-pure)}._tagMuted_1ivpu_162{color:var(--text-muted);border-color:var(--border-light);background-color:var(--bg-base-pure)}._tooltipPreLine_1ivpu_168{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_b5r6a_1{background:var(--bg-container);border-radius:6px;border:1px solid var(--border-primary);padding:12px;font-size:13px;font-family:var(--font-mono);overflow:auto}._root_re2ot_1{display:flex;height:100%;min-height:0;gap:0}._sidebar_re2ot_9{width:220px;flex-shrink:0;border-right:1px solid var(--border-primary);overflow-y:auto;padding:4px 0;-webkit-overflow-scrolling:touch}._section_re2ot_18{-webkit-user-select:none;user-select:none}._sectionHeader_re2ot_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_re2ot_22:hover{background:var(--overlay-light-faint)}._sectionHeader_re2ot_22:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._arrow_re2ot_48{font-size:10px;color:var(--text-tertiary);flex-shrink:0}._sectionTitle_re2ot_54{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._sectionCount_re2ot_62{font-size:11px;color:var(--text-muted);background:var(--bg-elevated);border-radius:10px;padding:0 6px;line-height:18px}._sectionBody_re2ot_71{padding:2px 0}._historyToggle_re2ot_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_re2ot_76:hover{color:var(--text-tertiary);background:var(--overlay-light-faint)}._historyToggle_re2ot_76:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._historyToggleLabel_re2ot_102{flex:1}._item_re2ot_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_re2ot_107:hover{background:var(--overlay-light-faint);color:var(--text-primary)}._item_re2ot_107:focus-visible{outline:1px solid var(--color-primary-outline);outline-offset:-1px}._itemActive_re2ot_135,._itemActive_re2ot_135:hover{background:var(--color-primary-bg-faint);color:var(--color-primary);border-color:var(--color-primary-light)}._itemContent_re2ot_142{flex:1;min-width:0;overflow:hidden}._itemLabel_re2ot_148{font-family:var(--font-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}._itemSublabel_re2ot_156{font-size:10px;color:var(--text-disabled);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}._itemTime_re2ot_165{font-size:9px;color:var(--text-disabled);flex-shrink:0;margin-left:4px;font-family:var(--font-mono)}._contentWrap_re2ot_176{flex:1;min-width:0;display:flex;flex-direction:column}._content_re2ot_174{flex:1;min-width:0;min-height:0;overflow:auto;padding:12px 16px;-webkit-overflow-scrolling:touch}._contentEmpty_re2ot_192{height:100%;display:flex;align-items:center;justify-content:center}._contentInner_re2ot_199{padding-bottom:20px}._emptyWrap_re2ot_203{display:flex;align-items:center;justify-content:center;height:200px}._roleHeader_re2ot_211{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:nowrap}._roleBadge_re2ot_219{font-size:10px;font-weight:600;letter-spacing:.04em;padding:2px 7px;border-radius:4px;flex-shrink:0}._role_user_re2ot_228{background:var(--color-primary-bg-lighter);color:var(--color-primary-lighter);border:1px solid var(--color-primary-bg-medium)}._role_assistant_re2ot_234{background:var(--color-purple-bg);color:var(--color-code-purple);border:1px solid var(--color-purple-border)}._roleLabel_re2ot_240{font-size:11px;color:var(--text-muted);flex:1;min-width:0}._contentTime_re2ot_247{margin-left:auto;font-size:10px;color:var(--text-disabled);font-family:var(--font-mono);flex-shrink:0}._turnDivider_re2ot_255{border:none;border-top:1px solid var(--border-primary);margin:14px 0}._textBlock_re2ot_262{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._textBlockBar_re2ot_269{display:flex;align-items:center;gap:6px;padding:4px 10px;background:var(--bg-container);border-bottom:1px solid var(--border-primary)}._textBlockBody_re2ot_278{padding:10px 12px;font-size:13px;line-height:1.7;color:var(--text-primary);word-break:break-word}._textBlockCompact_re2ot_286{position:relative;padding:8px 10px;font-size:12px;color:var(--text-light)}._textBlockCompactFloat_re2ot_293{float:right;margin-left:6px;margin-bottom:2px}._thinkingBlock_re2ot_300{margin-bottom:8px;border:1px solid var(--color-thinking-border);border-radius:6px;overflow:hidden;background:var(--color-thinking-bg)}._thinkingHeader_re2ot_308{display:flex;align-items:center;gap:6px;padding:5px 10px;cursor:pointer;font-size:12px;color:var(--text-tertiary);transition:background .15s}._thinkingHeader_re2ot_308:hover{background:var(--overlay-light-faint)}._thinkingPreview_re2ot_323{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted);font-size:11px}._thinkingBody_re2ot_333{padding:8px 12px;border-top:1px solid var(--color-thinking-border)}._toolBlock_re2ot_339{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._toolBlockResult_re2ot_346{border-color:var(--color-green-border)}._toolBlockError_re2ot_350{border-color:var(--color-red-dark-border)}._toolBlockHeader_re2ot_354{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_re2ot_365{padding:8px 10px;font-size:12px}._toolName_re2ot_370{color:var(--text-primary);font-weight:500;font-family:var(--font-mono)}._toolId_re2ot_376{color:var(--text-disabled);font-size:10px;font-family:var(--font-mono);margin-left:auto}._errorLabel_re2ot_383{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_re2ot_393{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_re2ot_406{background:var(--color-primary-bg-faint);color:var(--color-primary-lighter);border-color:var(--color-primary-bg-lighter)}._blockTagThinking_re2ot_412{background:var(--color-warning-bg-faint);color:var(--color-warning);border-color:var(--color-warning-border-light)}._blockTagResult_re2ot_418{background:var(--color-green-dark-bg);color:var(--color-success);border-color:var(--color-green-dark-border)}._blockTagError_re2ot_424{background:var(--color-error-bg-faint);color:var(--color-error-light);border-color:var(--color-error-border-light)}._jsonBlock_re2ot_431{margin-bottom:8px;border:1px solid var(--border-primary);border-radius:6px;overflow:hidden}._jsonBlockLabel_re2ot_438{font-size:10px;color:var(--text-muted);padding:3px 10px;background:var(--bg-container);border-bottom:1px solid var(--border-primary);font-family:var(--font-mono)}._blockSeparator_re2ot_448{border:none;border-top:1px solid var(--border-primary);margin:16px 0}._markdownBody_re2ot_455{font-size:13px;line-height:1.7;color:var(--text-primary);word-break:break-word}._contentToolbar_re2ot_463{display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:8px 16px 0;flex-shrink:0}._contentToolbarLabel_re2ot_472{font-size:11px;color:var(--text-muted)}._rawPre_re2ot_478{background:var(--bg-code-dark);border:1px solid var(--border-primary);border-radius:6px;padding:12px;font-size:12px;color:var(--text-primary);white-space:pre-wrap;word-break:break-all;margin:0}._toolAdded_re2ot_491{color:var(--color-success)}._toolRemoved_re2ot_495{color:var(--color-error);text-decoration:line-through}._toolDiffTag_re2ot_500{margin-left:6px;font-size:9px;font-family:var(--font-ui);text-decoration:none;opacity:.85}._toolDiffSummary_re2ot_508{margin-left:6px;font-size:11px;font-family:var(--font-mono);display:inline-flex;gap:4px;flex-shrink:0}._toolDiffSummaryAdd_re2ot_517{color:var(--color-success)}._toolDiffSummaryRemove_re2ot_521{color:var(--color-error)}._container_1958y_1{height:100%;overflow:hidden;padding:0 16px;display:flex;flex-direction:column;background:var(--bg-base)}._emptyState_1958y_10{display:flex;align-items:center;justify-content:center;height:100%}._urlSection_1958y_17{padding:12px 0;border-bottom:1px solid var(--border-primary);display:flex;align-items:flex-start;flex-shrink:0}._urlLeft_1958y_25{flex:1;min-width:0}._tokenStatsBox_1958y_30{flex-shrink:0;padding-left:12px;display:flex;align-items:center}._tokenGrid_1958y_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_1958y_47{flex:1}._tokenRow_1958y_47{display:flex}._tokenRowBorder_1958y_55{border-top:1px solid var(--border-secondary)}._tokenLabel_1958y_59{color:var(--text-tertiary);padding:4px 8px;white-space:nowrap;font-weight:600}._tokenTd_1958y_66{flex:1;color:var(--text-primary);text-align:right;padding:4px 8px;font-family:var(--font-mono);white-space:nowrap}._tokenHitRate_1958y_75{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--text-primary);padding:4px 8px;font-family:var(--font-mono);white-space:nowrap;border-left:1px solid var(--border-secondary);min-width:100px}._tokenHitRateLabel_1958y_88{color:var(--text-tertiary);font-size:10px;font-family:var(--font-ui)}._tokenRowBorder_1958y_55 td{border-top:1px solid var(--border-secondary)}._urlText_1958y_98{color:var(--text-primary);font-size:13px;margin-bottom:8px;word-break:break-all}._metaText_1958y_105,._headersContainer_1958y_109{font-size:12px}._headerRow_1958y_113{display:flex;padding:4px 0;border-bottom:1px solid var(--border-primary)}._headerKey_1958y_119{min-width:200px;flex-shrink:0}._headerValue_1958y_124{word-break:break-all;margin-left:8px}._streamingBox_1958y_129{padding:20px;background:var(--bg-elevated);border-radius:6px;border:1px solid var(--border-primary)}._bodyToolbar_1958y_136{display:flex;gap:8px;margin-bottom:8px}._rawTextPre_1958y_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_1958y_155{padding:16px 0 0;height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}._collapseSpacing_1958y_163{margin-bottom:16px}._bodyLabel_1958y_167{margin:0}._bodyHeader_1958y_171{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}._diffSection_1958y_178{margin-bottom:16px}._diffToggle_1958y_182{display:inline-block;margin-bottom:8px;cursor:pointer}._diffIcon_1958y_188{font-size:12px;margin-left:4px}._viewInChatBtn_1958y_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_1958y_193:hover{border-color:var(--text-muted);color:var(--text-primary);background:var(--overlay-light-faint)}._reminderSelect_1958y_214{min-width:140px;font-size:12px}._reminderSelect_1958y_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:var(--font-mono)}._reminderSelect_1958y_214 .ant-select-selection-placeholder{font-size:11px}._diffHeaderRow_1958y_233{display:flex;align-items:center;gap:8px}._diffSpaceRight_1958y_239{margin-left:auto}._reminderFilterWrapper_1958y_243{display:inline-flex;align-items:center;gap:4px}._reminderLabel_1958y_249{color:var(--text-tertiary);font-size:12px;font-family:var(--font-mono)}._cacheTabContent_1958y_255{padding-top:0;overflow:hidden}._userPromptList_1958y_260{width:600px;max-height:300px;overflow-y:auto}._userPromptItem_1958y_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_1958y_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_1958y_288{padding:8px 0;height:100%;display:flex;flex-direction:column}._cacheTokenBar_1958y_295{display:flex;align-items:center;font-size:12px;font-family:var(--font-mono);color:var(--text-light);margin-bottom:12px;flex-shrink:0}._cacheTokenWrite_1958y_305{color:var(--color-code-orange)}._cacheTokenRead_1958y_309{color:var(--color-success)}._cacheCopyIcon_1958y_313{margin-left:8px;cursor:pointer;color:var(--text-tertiary);transition:color .2s}._cacheScrollArea_1958y_320{flex:1;overflow-y:auto;min-height:0}._cacheSectionBlock_1958y_326{margin-bottom:12px}._cacheSectionHeader_1958y_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_1958y_342{display:inline-block;transition:transform .2s;font-size:10px}._cachePre_1958y_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:var(--font-mono)}._cacheHighlightSvg_1958y_362{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none;overflow:visible}._cachePreSystem_1958y_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:var(--font-mono)}._container_1958y_1 .ant-tabs>.ant-tabs-nav{margin-bottom:0}._container_1958y_1 .ant-tabs{flex:1;min-height:0;display:flex;flex-direction:column}._container_1958y_1 .ant-tabs>.ant-tabs-content-holder{flex:1;min-height:0}._container_1958y_1 .ant-tabs-content,._container_1958y_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_18dz6_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_18dz6_12{position:absolute;left:0;top:0;bottom:0;width:var(--usage-percent, 0);background-color:#999;opacity:.2;transition:width .5s ease;pointer-events:none}._usageContent_18dz6_38{position:relative;z-index:1;display:inline-flex;align-items:center}._usageText_18dz6_45{font-variant-numeric:tabular-nums}._muted_18dz6_50{border-color:var(--border-light);color:var(--text-disabled);background:var(--bg-surface)}._pop_18dz6_57{min-width:220px;font-size:12px;color:var(--text-primary)}._popTitle_18dz6_63{font-weight:600;margin-bottom:6px}._popTable_18dz6_69{border-collapse:collapse}._popTable_18dz6_69 td{padding-top:3px;padding-bottom:3px;vertical-align:middle}._tdName_18dz6_74{color:var(--text-secondary);padding-right:5px;white-space:nowrap}._tdBar_18dz6_74{padding-right:5px;white-space:nowrap}._tdReset_18dz6_92{color:var(--text-secondary);font-variant-numeric:tabular-nums;white-space:nowrap}._bar_18dz6_101{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_18dz6_115{position:absolute;left:0;top:0;bottom:0;background-color:var(--text-secondary);opacity:.15;pointer-events:none}._barText_18dz6_125{position:relative;z-index:1;font-size:11px;line-height:1;font-variant-numeric:tabular-nums;color:var(--text-primary)}