dsh-context 0.36.0 → 0.38.0

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/lib/client.js CHANGED
@@ -20,7 +20,7 @@ window.__ModuleLoader__.load({
20
20
  "overview.ofUsed": "占已用上下文",
21
21
  "overview.compactReserve": "自动压缩预留:占用达 {pct}% 窗口时触发压缩,此区域一般不实际占用",
22
22
  "stats.title": "上下文统计",
23
- "stats.hint": "当前上下文存在和包含的内容",
23
+ "stats.hint": "轮次、步骤与上下文事件",
24
24
  "stats.turns": "轮次",
25
25
  "stats.steps": "步数",
26
26
  "stats.injects": "注入",
@@ -28,22 +28,38 @@ window.__ModuleLoader__.load({
28
28
  "stats.prunes": "剪枝",
29
29
  "stats.toolCalls": "工具调用",
30
30
  "stats.images": "图片",
31
- "stats.cacheHit": "缓存命中",
32
31
  "stats.cost": "预估费用",
33
32
  "stats.costTip": "按 DeepSeek 官方刊例价估算整个会话的累计费用:输入区分缓存命中/未命中,输出含思考;按请求时间区分高峰(北京时间工作日 9:00–12:00、14:00–18:00)与空闲时段(半价,周末全天均为空闲时段)。适用于 deepseek-v4-flash / deepseek-v4-pro(不限 provider),价格写死在代码中,仅供参考。",
34
33
  "stats.costPriceHead": "每百万 tokens 价格(高峰 | 空闲半价):",
35
34
  "stats.costHit": "命中",
36
35
  "stats.costMiss": "未命中",
37
36
  "stats.costOut": "输出",
37
+ "timing.title": "耗时统计",
38
+ "timing.hint": "整个会话的活跃时长分布",
39
+ "timing.total": "总活跃时长",
40
+ "timing.lm": "模型调用",
41
+ "timing.tools": "工具执行",
42
+ "timing.other": "其他开销",
43
+ "timing.times": "{n}次",
44
+ "timing.empty": "暂无耗时数据 · 对话开始后这里会显示时长分布",
45
+ "tokens.title": "Token 统计",
46
+ "tokens.hint": "供应商上报的累计计费用量",
47
+ "tokens.cacheHit": "缓存命中",
48
+ "tokens.cacheRead": "缓存读取",
49
+ "tokens.cacheWrite": "缓存写入",
50
+ "tokens.uncached": "未命中输入",
51
+ "tokens.output": "输出(含思考)",
38
52
  "plugin.title": "插件信息",
39
53
  "plugin.hint": "The best DSH context plugin ⭐",
40
54
  "plugin.name": "插件",
41
55
  "plugin.github": "GitHub",
56
+ "plugin.settings": "设置",
57
+ "plugin.settingsOpen": "打开设置",
42
58
  "trend.title": "上下文趋势",
43
59
  "gran.step": "步骤",
44
60
  "gran.turn": "轮次",
45
61
  "settings.title": "上下文",
46
- "settings.desc": "上下文面板的展示偏好",
62
+ "settings.desc": "dsh-context 插件中上下文面板的偏好设置",
47
63
  "settings.gran": "趋势图默认粒度",
48
64
  "settings.mode": "趋势图默认展示",
49
65
  "settings.fileSort": "文件活动默认排序",
@@ -68,6 +84,7 @@ window.__ModuleLoader__.load({
68
84
  "brief.more": "+{n}",
69
85
  "brief.noInputs": "(无新增)",
70
86
  "brief.locate": "在上下文浏览器中查看",
87
+ "jump.title": "在上下文标签页中查看此轮",
71
88
  "brief.turnTip": "这一轮开场时用户发送的消息;回合内的每一步都会回显同一条",
72
89
  "brief.inputTip": "上一步回复之后、本次请求发出前新进入上下文的内容——通常是上一步所调工具的结果;每轮的第一步无新增",
73
90
  "brief.replyTip": "这一步模型返回的内容(文本回复或工具调用);此步发起的调用,其结果会出现在下一柱的「输入」行",
@@ -271,7 +288,7 @@ window.__ModuleLoader__.load({
271
288
  "overview.ofUsed": "of used context",
272
289
  "overview.compactReserve": "Auto-compaction reserve: auto-compaction triggers at {pct}% of the window — this area is normally kept as headroom, not actually used",
273
290
  "stats.title": "Context Stats",
274
- "stats.hint": "Present in the current context",
291
+ "stats.hint": "Turns, steps, and context events",
275
292
  "stats.turns": "Turns",
276
293
  "stats.steps": "Steps",
277
294
  "stats.injects": "Injections",
@@ -279,22 +296,38 @@ window.__ModuleLoader__.load({
279
296
  "stats.prunes": "Prunes",
280
297
  "stats.toolCalls": "Tool Calls",
281
298
  "stats.images": "Images",
282
- "stats.cacheHit": "Cache Hit",
283
299
  "stats.cost": "Cost",
284
300
  "stats.costTip": "Rough cumulative cost of the whole session at DeepSeek’s list prices: input split by cache hit/miss, output includes reasoning; each request is priced at the peak (Beijing Time weekdays 09:00–12:00, 14:00–18:00) or half-price off-peak rate by its time — weekends bill at off-peak all day. Applies to deepseek-v4-flash / deepseek-v4-pro on any provider; prices are hardcoded, for reference only.",
285
301
  "stats.costPriceHead": "Per-1M-token rates (peak | off-peak at half price):",
286
302
  "stats.costHit": "hit",
287
303
  "stats.costMiss": "miss",
288
304
  "stats.costOut": "output",
305
+ "timing.title": "Timing Stats",
306
+ "timing.hint": "Whole-session active-time split",
307
+ "timing.total": "active time",
308
+ "timing.lm": "Model calls",
309
+ "timing.tools": "Tool runs",
310
+ "timing.other": "Overhead",
311
+ "timing.times": "{n}×",
312
+ "timing.empty": "No timing data yet — durations appear as the conversation runs",
313
+ "tokens.title": "Token Stats",
314
+ "tokens.hint": "Cumulative provider-reported usage",
315
+ "tokens.cacheHit": "Cache hit",
316
+ "tokens.cacheRead": "Cache read",
317
+ "tokens.cacheWrite": "Cache write",
318
+ "tokens.uncached": "Uncached input",
319
+ "tokens.output": "Output (incl. reasoning)",
289
320
  "plugin.title": "Plugin Info",
290
321
  "plugin.hint": "The best DSH context plugin ⭐",
291
322
  "plugin.name": "Plugin",
292
323
  "plugin.github": "GitHub",
324
+ "plugin.settings": "Settings",
325
+ "plugin.settingsOpen": "Open in Settings",
293
326
  "trend.title": "Context Trend",
294
327
  "gran.step": "Step",
295
328
  "gran.turn": "Turn",
296
329
  "settings.title": "Context",
297
- "settings.desc": "Display preferences for the Context panel",
330
+ "settings.desc": "Preferences for Context panel in dsh-context plugin",
298
331
  "settings.gran": "Default trend granularity",
299
332
  "settings.mode": "Default trend display",
300
333
  "settings.fileSort": "File Activity default sort",
@@ -319,6 +352,7 @@ window.__ModuleLoader__.load({
319
352
  "brief.more": "+{n}",
320
353
  "brief.noInputs": "(nothing new)",
321
354
  "brief.locate": "Reveal in Context Browser",
355
+ "jump.title": "View this turn in the Context tab",
322
356
  "brief.turnTip": "The user message that opened this turn — every step of the turn recalls it",
323
357
  "brief.inputTip": "What entered after the previous reply and before this request went out — usually the previous tool-call results; a turn opener has nothing new",
324
358
  "brief.replyTip": "What the model returned on this step (a text reply or tool calls) — results of calls made here appear in the In row of the next bar",
@@ -557,10 +591,10 @@ window.__ModuleLoader__.load({
557
591
  const COMMAND = "context";
558
592
  const LINE = "/context";
559
593
  function registerContextCommand(ctx, kit) {
560
- ctx.effect(() => {
561
- const inputTriggers = ctx.get("inputTriggers");
562
- if (inputTriggers === void 0) return () => {};
563
- return inputTriggers.registerSource({
594
+ ctx.inject(["inputTriggers"], (ictx) => {
595
+ const inputTriggers = ictx.get("inputTriggers");
596
+ if (inputTriggers === void 0 || typeof inputTriggers.registerSource !== "function") return;
597
+ ictx.effect(() => inputTriggers.registerSource({
564
598
  trigger: "/",
565
599
  name: COMMAND,
566
600
  order: 1,
@@ -590,8 +624,8 @@ window.__ModuleLoader__.load({
590
624
  modalStoreOf(session.sessionId).set(true);
591
625
  return Promise.resolve("handled");
592
626
  }
593
- });
594
- }, "dsh-context: /context command");
627
+ }), "dsh-context: /context command");
628
+ });
595
629
  }
596
630
  //#endregion
597
631
  //#region src/client/categories.ts
@@ -723,6 +757,57 @@ window.__ModuleLoader__.load({
723
757
  //#endregion
724
758
  //#region src/client/services.ts
725
759
  /**
760
+ * A session-authorized durable-image loader over whichever conversation
761
+ * face the running harness provides (`resolveImage` pre-0.1.2, `imageUrl`
762
+ * since), or undefined when neither service is composed — the caller
763
+ * degrades to metadata-only cards. Hostile snapshots and throwing service
764
+ * reads are caught: this helper can never take a render down.
765
+ */
766
+ function imageLoaderOf(ctx, sessionId) {
767
+ if (typeof sessionId !== "string" || sessionId === "") return void 0;
768
+ try {
769
+ const legacy = ctx.get("conversation");
770
+ if (legacy !== void 0 && typeof legacy.resolveImage === "function") {
771
+ const resolveImage = legacy.resolveImage.bind(legacy);
772
+ return (attachment) => resolveImage(sessionId, attachment);
773
+ }
774
+ const modern = ctx.get("uiConversation");
775
+ if (modern !== void 0 && typeof modern.imageUrl === "function") {
776
+ const imageUrl = modern.imageUrl.bind(modern);
777
+ return (attachment) => imageUrl(sessionId, attachment);
778
+ }
779
+ } catch {}
780
+ }
781
+ /**
782
+ * The conversation-window nodes this plugin joins on, from whichever seat
783
+ * the running harness provides — `useChat` (`ChatSnapshot.legacy.nodes`) on
784
+ * dsh 0.1.2+, the session snapshot's own `nodes` before that. Returns
785
+ * undefined when neither seat delivers a real array (absent seat, older or
786
+ * foreign harness, hostile snapshot) — callers render without the join,
787
+ * never an error.
788
+ *
789
+ * Hook-order contract: the seats are real React hooks, so BOTH are invoked
790
+ * on every call whenever present (the chat seat first, the session seat
791
+ * second) and only the RESULT is picked conditionally — a stable call order
792
+ * across renders. Selectors return stable slice references so the
793
+ * framework's snapshot equality can gate re-renders.
794
+ */
795
+ function conversationNodesOf(props) {
796
+ const useChat = props.useChat;
797
+ let chatNodes;
798
+ if (typeof useChat === "function") try {
799
+ const slice = useChat((s) => s !== null && typeof s === "object" ? s.legacy : void 0);
800
+ chatNodes = slice !== null && typeof slice === "object" ? slice.nodes : void 0;
801
+ } catch {}
802
+ const useSession = props.useSession;
803
+ let sessionNodes;
804
+ if (typeof useSession === "function") try {
805
+ sessionNodes = useSession((s) => s.nodes);
806
+ } catch {}
807
+ if (Array.isArray(chatNodes)) return chatNodes;
808
+ if (Array.isArray(sessionNodes)) return sessionNodes;
809
+ }
810
+ /**
726
811
  * Narrow an unknown projection value to a string-keyed record, or null when
727
812
  * it is not one. The boundary type is Record<string, unknown> on purpose:
728
813
  * every field read below must re-prove itself (the no-white-screen
@@ -768,9 +853,10 @@ window.__ModuleLoader__.load({
768
853
  "assistant",
769
854
  "tool",
770
855
  "total"
771
- ].every((k) => typeof current[k] === "number") && Array.isArray(data.requests) && Array.isArray(data.events) && Array.isArray(data.nodes) && Array.isArray(data.archive)) return data;
856
+ ].every((k) => typeof current[k] === "number") && Array.isArray(data.requests) && Array.isArray(data.events) && Array.isArray(data.nodes) && Array.isArray(data.archive) && timingFastOk(data.timing)) return data;
772
857
  const safeCurrent = current !== null && typeof current === "object" ? current : {};
773
858
  const cost = typeof data.cost === "object" && data.cost !== null && !Array.isArray(data.cost) ? data.cost : void 0;
859
+ const timing = timingOf(data.timing);
774
860
  return {
775
861
  ok: true,
776
862
  ...typeof data.model === "string" ? { model: data.model } : {},
@@ -793,6 +879,7 @@ window.__ModuleLoader__.load({
793
879
  ...typeof data.toolCalls === "number" ? { toolCalls: data.toolCalls } : {},
794
880
  archive: objectsOf(data.archive),
795
881
  ...cost !== void 0 ? { cost } : {},
882
+ ...timing !== null ? { timing } : {},
796
883
  ...typeof data.surfaceFloor === "number" ? { surfaceFloor: data.surfaceFloor } : {},
797
884
  ...typeof data.archiveFloor === "number" ? { archiveFloor: data.archiveFloor } : {}
798
885
  };
@@ -837,6 +924,73 @@ window.__ModuleLoader__.load({
837
924
  return asRecord$1(value);
838
925
  }
839
926
  /**
927
+ * A non-negative finite number (the timing totals' every field): NaN or a
928
+ * negative degrades to 0 instead of leaking into donut shares.
929
+ */
930
+ function msNumOf(value) {
931
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
932
+ }
933
+ /**
934
+ * Cheap whole-value check for the pass-through path of `timelineOf`: absent
935
+ * timing passes; present timing must already be well-formed (every scalar
936
+ * numeric, every per-name row shaped) — anything else sends the payload down
937
+ * the sanitizing slow path.
938
+ */
939
+ function timingFastOk(value) {
940
+ if (value === void 0) return true;
941
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
942
+ const t = value;
943
+ for (const k of [
944
+ "wallMs",
945
+ "lmMs",
946
+ "calls",
947
+ "toolsMs",
948
+ "toolCalls"
949
+ ]) if (typeof t[k] !== "number") return false;
950
+ const tools = t.tools;
951
+ if (tools === null || typeof tools !== "object" || Array.isArray(tools)) return false;
952
+ for (const k in tools) {
953
+ const row = tools[k];
954
+ if (row === null || typeof row !== "object") return false;
955
+ if (typeof row.calls !== "number") return false;
956
+ if (typeof row.ms !== "number") return false;
957
+ }
958
+ return true;
959
+ }
960
+ /**
961
+ * Narrow a delivered timing totals value (see TimingTotals) to a RENDER-SAFE
962
+ * shape — the timing card's no-white-screen guarantee. A value that is not a
963
+ * record stays null (the card renders its empty state); wrong-typed scalars
964
+ * zero out and per-name rows failing the shape drop individually, so one
965
+ * hostile row never blanks the ranking.
966
+ */
967
+ function timingOf(value) {
968
+ const data = asRecord$1(value);
969
+ if (data === null) return null;
970
+ const tools = {};
971
+ const rawTools = data.tools;
972
+ if (rawTools !== null && typeof rawTools === "object" && !Array.isArray(rawTools)) for (const k in rawTools) {
973
+ if (k === "__proto__" || !Object.hasOwn(rawTools, k)) continue;
974
+ const row = rawTools[k];
975
+ if (row === null || typeof row !== "object") continue;
976
+ const calls = row.calls;
977
+ const ms = row.ms;
978
+ if (typeof calls !== "number" || !(calls >= 0) || typeof ms !== "number" || !(ms >= 0)) continue;
979
+ tools[k] = {
980
+ calls,
981
+ ms
982
+ };
983
+ }
984
+ return {
985
+ wallMs: msNumOf(data.wallMs),
986
+ lmMs: msNumOf(data.lmMs),
987
+ calls: msNumOf(data.calls),
988
+ toolsMs: msNumOf(data.toolsMs),
989
+ toolCalls: msNumOf(data.toolCalls),
990
+ tools
991
+ };
992
+ }
993
+ /**
840
994
  * Narrow a delivered projection value to the plugin's `contextHeaders`
841
995
  * (request-header content epochs). Absent key = an older Host half without
842
996
  * the companion unit — the Context browser degrades its system/tools
@@ -908,9 +1062,9 @@ window.__ModuleLoader__.load({
908
1062
  /** Narrow one served row to a validated durable event envelope, or null. */
909
1063
  function eventOf(entry) {
910
1064
  if (entry === null || typeof entry !== "object") return null;
911
- const ev = entry.event;
912
- if (ev === null || typeof ev !== "object") return null;
913
- const e = ev;
1065
+ const inner = entry.event ?? entry;
1066
+ if (typeof inner !== "object") return null;
1067
+ const e = inner;
914
1068
  if (typeof e.type !== "string" || typeof e.seq !== "number" || !Number.isFinite(e.seq)) return null;
915
1069
  const data = e.data !== null && typeof e.data === "object" ? e.data : {};
916
1070
  return {
@@ -1030,26 +1184,65 @@ window.__ModuleLoader__.load({
1030
1184
  }
1031
1185
  return nodes;
1032
1186
  }
1187
+ /** Read a service off the client context without letting an absent/foreign
1188
+ * cordis service (a throwing `ctx.get`) escape: returns undefined instead. */
1189
+ function serviceOf(ctx, name) {
1190
+ try {
1191
+ return ctx.get(name);
1192
+ } catch {
1193
+ return;
1194
+ }
1195
+ }
1196
+ /** The rows array of a history/page response, under every served envelope. */
1197
+ function rowsOf(response) {
1198
+ let payload = response;
1199
+ if (payload !== null && typeof payload === "object") {
1200
+ const nested = payload.result;
1201
+ if (nested !== null && typeof nested === "object") payload = nested;
1202
+ }
1203
+ if (payload !== null && typeof payload === "object" && "ok" in payload) {
1204
+ const r = payload;
1205
+ if (r.ok !== true || r.value === null || typeof r.value !== "object") throw new Error("history rpc failed");
1206
+ payload = r.value;
1207
+ }
1208
+ if (payload === null || typeof payload !== "object") throw new Error("history rpc failed");
1209
+ const rows = payload.records ?? payload.events;
1210
+ if (!Array.isArray(rows)) throw new Error("history rpc failed");
1211
+ return rows;
1212
+ }
1033
1213
  /**
1034
- * Build the browser's per-session fetcher over the shared api client.
1035
- * Undefined when the connection face or the history verb is absent (older
1214
+ * Build the browser's per-session fetcher over whichever history face the
1215
+ * running harness serves the 0.1.2+ gateway remotes (`remote.session.page`)
1216
+ * first, the pre-0.1.2 api client verb (`connection.api.sessions.history`)
1217
+ * beneath it. Both cut message-aligned pages, so `beforeSeq: seq + 1` (with
1218
+ * the inclusive cut pinned to `seq` on the newer face) covers the seq whenever
1219
+ * the durable log still holds it. Undefined when no face exists (older
1036
1220
  * hosts) — the caller keeps its static preview-plus-hint degradation. Found
1037
1221
  * nodes cache in the closure: one mount re-reading a row never re-fetches.
1038
1222
  */
1039
1223
  function makeContentFetcher(ctx, sessionId) {
1040
- const sessions = ctx.get("connection")?.api?.sessions;
1041
- if (typeof sessions?.history !== "function") return void 0;
1224
+ const pageFace = serviceOf(ctx, "remote.session");
1225
+ const page = pageFace !== void 0 && typeof pageFace.page === "function" ? pageFace.page.bind(pageFace) : void 0;
1226
+ const historyFace = serviceOf(ctx, "connection")?.api?.sessions;
1227
+ const history = historyFace !== void 0 && typeof historyFace.history === "function" ? historyFace.history.bind(historyFace) : void 0;
1228
+ if (page === void 0 && history === void 0) return void 0;
1229
+ const pageRequest = (seq) => ({
1230
+ address: {
1231
+ kind: "session",
1232
+ sessionId
1233
+ },
1234
+ throughSeq: seq,
1235
+ beforeSeq: seq + 1
1236
+ });
1237
+ const historyCall = (seq) => history({
1238
+ sessionId,
1239
+ beforeSeq: seq + 1
1240
+ });
1042
1241
  const cache = /* @__PURE__ */ new Map();
1043
1242
  return async (seq) => {
1044
1243
  const hit = cache.get(seq);
1045
1244
  if (hit !== void 0) return hit;
1046
- const result = (await sessions.history({
1047
- sessionId,
1048
- beforeSeq: seq + 1
1049
- })).result;
1050
- if (result === null || typeof result !== "object" || result.ok !== true || result.value === null || typeof result.value !== "object") throw new Error("history rpc failed");
1051
- const events = result.value.events;
1052
- const node = pageNodesOf(Array.isArray(events) ? events : []).get(seq) ?? null;
1245
+ const node = pageNodesOf(rowsOf(page !== void 0 ? await page(pageRequest(seq), new AbortController().signal) : await historyCall(seq))).get(seq) ?? null;
1053
1246
  if (node !== null) cache.set(seq, node);
1054
1247
  return node;
1055
1248
  };
@@ -1181,7 +1374,7 @@ window.__ModuleLoader__.load({
1181
1374
  * nothing was billed. The 1e-9 epsilon absorbs only float noise (integer
1182
1375
  * token counts never sit that close to a boundary).
1183
1376
  */
1184
- function cacheHitPercent$1(reads, billed) {
1377
+ function cacheHitPercent(reads, billed) {
1185
1378
  if (!(billed > 0)) return null;
1186
1379
  const hundredths = Math.trunc(reads / billed * 1e4 + 1e-9);
1187
1380
  return `${Math.floor(hundredths / 100)}.${String(hundredths % 100).padStart(2, "0")}`;
@@ -1191,6 +1384,37 @@ window.__ModuleLoader__.load({
1191
1384
  if (isNaN(d.getTime())) return "—";
1192
1385
  return d.toLocaleTimeString("en-GB", { hour12: false });
1193
1386
  }
1387
+ /**
1388
+ * Share of a whole as a compact leading percentage for the slice rows:
1389
+ * '—' when nothing totals, '0%' for empty slices, '<1%' for non-zero crumbs
1390
+ * a rounded-down integer would erase. Shares cap at 100% (parallel tool time
1391
+ * can over-run the wall it belongs to).
1392
+ */
1393
+ function fmtShare(part, total) {
1394
+ if (!Number.isFinite(part) || !Number.isFinite(total) || total <= 0) return "—";
1395
+ if (part <= 0) return "0%";
1396
+ const pct = Math.min(1, part / total) * 100;
1397
+ if (pct < 1) return "<1%";
1398
+ return `${Math.round(pct)}%`;
1399
+ }
1400
+ /**
1401
+ * Whole-session durations for the timing card, in the locale's units: raw ms
1402
+ * under a second, one-decimal seconds under a minute, then m/s and h/m.
1403
+ * Non-finite or non-positive input shows the dash (callers render their empty
1404
+ * state anyway).
1405
+ */
1406
+ function fmtDuration$1(ms, lang) {
1407
+ if (!Number.isFinite(ms) || ms <= 0) return "—";
1408
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
1409
+ const zh = lang === "zh";
1410
+ if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}${zh ? "秒" : "s"}`;
1411
+ const totalSec = Math.floor(ms / 1e3);
1412
+ const m = Math.floor(totalSec / 60);
1413
+ const s = totalSec % 60;
1414
+ if (ms < 36e5) return zh ? `${m}分${s}秒` : `${m}m ${s}s`;
1415
+ const h = Math.floor(m / 60);
1416
+ return zh ? `${h}时${m % 60}分` : `${h}h ${m % 60}m`;
1417
+ }
1194
1418
  //#endregion
1195
1419
  //#region src/shared/imageTokens.ts
1196
1420
  /**
@@ -1499,9 +1723,19 @@ window.__ModuleLoader__.load({
1499
1723
  }, label);
1500
1724
  return /* @__PURE__ */ React.createElement("span", { className: "lc-rich-seg" }, seg("raw", t("rich.raw"), t("rich.toRaw")), seg("md", t("rich.md"), t("rich.toMd")));
1501
1725
  }
1726
+ function RawText(props) {
1727
+ const lines = React.useMemo(() => {
1728
+ const parts = props.text.split("\n");
1729
+ return parts.length > 1 && parts[parts.length - 1] === "" ? parts.slice(0, -1) : parts;
1730
+ }, [props.text]);
1731
+ return /* @__PURE__ */ React.createElement("pre", { className: "lc-ts-desc-body lc-ts-lines" }, lines.map((line, index) => /* @__PURE__ */ React.createElement("span", {
1732
+ key: index,
1733
+ className: "lc-ts-line"
1734
+ }, line)));
1735
+ }
1502
1736
  function RichText(props) {
1503
1737
  if (props.mode === "md") return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-desc-md" }, /* @__PURE__ */ React.createElement(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: props.text }));
1504
- return /* @__PURE__ */ React.createElement("pre", { className: "lc-ts-desc-body" }, props.text);
1738
+ return /* @__PURE__ */ React.createElement(RawText, { text: props.text });
1505
1739
  }
1506
1740
  return {
1507
1741
  RichText,
@@ -1906,7 +2140,7 @@ window.__ModuleLoader__.load({
1906
2140
  const [openElem, setOpenElem] = React.useState(null);
1907
2141
  const [rowQuery, setRowQuery] = React.useState("");
1908
2142
  const [toolSort, setToolSort] = React.useState("size");
1909
- const convNodes = typeof props.useSession === "function" ? props.useSession((s) => s.nodes) : void 0;
2143
+ const convNodes = props.convNodes;
1910
2144
  const [fetched, setFetched] = React.useState(() => /* @__PURE__ */ new Map());
1911
2145
  const bySeq = React.useMemo(() => {
1912
2146
  const m = /* @__PURE__ */ new Map();
@@ -1935,7 +2169,8 @@ window.__ModuleLoader__.load({
1935
2169
  return next;
1936
2170
  });
1937
2171
  setMissState("idle");
1938
- }, () => {
2172
+ }, (error) => {
2173
+ console.warn("dsh-context: targeted history read failed", error);
1939
2174
  if (live) setMissState("failed");
1940
2175
  });
1941
2176
  return () => {
@@ -1995,6 +2230,17 @@ window.__ModuleLoader__.load({
1995
2230
  const prevByCat = prevView !== null ? byCatOf(prevView) : null;
1996
2231
  const byCat = byCatOf(view);
1997
2232
  const toolCount = (c) => countOf(view, byCat, c);
2233
+ const singleKeyOf = (c) => {
2234
+ if (c === "system") return view.header?.system !== void 0 ? "sys" : null;
2235
+ if (c === "tools") {
2236
+ const tools = view.header?.tools;
2237
+ return tools !== void 0 && tools.length === 1 ? "tool:" + tools[0].name : null;
2238
+ }
2239
+ /* v8 ignore next 1 -- reached only through toggleCat's openable guard
2240
+ (count > 0 ⟺ byCat[c] exists); the fallback is defensive. */
2241
+ const nodes = byCat[c] ?? [];
2242
+ return nodes.length === 1 ? "n" + String(nodes[0].seq) : null;
2243
+ };
1998
2244
  const toggleCat = (c) => {
1999
2245
  if (!(toolCount(c) > 0 || (c === "system" || c === "tools") && view.header === null)) return;
2000
2246
  if (openCat === c) {
@@ -2004,7 +2250,7 @@ window.__ModuleLoader__.load({
2004
2250
  }
2005
2251
  setOpenCat(c);
2006
2252
  setRowQuery("");
2007
- setOpenElem(c === "system" && view.header?.system !== void 0 ? "sys" : null);
2253
+ setOpenElem(singleKeyOf(c));
2008
2254
  };
2009
2255
  const toggleElem = (key) => {
2010
2256
  setOpenElem(openElem === key ? null : key);
@@ -2373,7 +2619,6 @@ window.__ModuleLoader__.load({
2373
2619
  //#region src/client/components/contextModal.tsx
2374
2620
  function makeContextModal(ctx, kit) {
2375
2621
  const { t } = kit;
2376
- const sessions = ctx.get("sessions");
2377
2622
  const StackedBar = makeStackedBar(kit);
2378
2623
  const CurrentComposition = makeCurrentComposition(kit, StackedBar, makeLegend(kit));
2379
2624
  const ContextBrowser = makeContextBrowser(kit, StackedBar);
@@ -2385,16 +2630,18 @@ window.__ModuleLoader__.load({
2385
2630
  const pressure = typeof props.useProjection === "function" ? contextPressureOf(props.useProjection("contextPressure")) : null;
2386
2631
  const breakdown = typeof props.useProjection === "function" ? contextBreakdownOf(props.useProjection("contextBreakdown")) : null;
2387
2632
  const headers = typeof props.useProjection === "function" ? headersOf(props.useProjection("contextHeaders")) : null;
2633
+ const convNodes = conversationNodesOf(props);
2388
2634
  const [hoverCat, setHoverCat] = React.useState(null);
2389
2635
  const fetchContent = React.useMemo(() => sessionId !== "" ? makeContentFetcher(ctx, sessionId) : void 0, [ctx, sessionId]);
2390
2636
  const close = React.useCallback(() => {
2391
2637
  if (sessionId === "") return;
2392
2638
  modalStoreOf(sessionId).set(false);
2393
2639
  const guard = takePendingConsume(sessionId);
2640
+ const sessions = ctx.get("sessions");
2394
2641
  if (guard === void 0 || sessions === void 0) return;
2395
2642
  const scope = sessions.scope(sessionId);
2396
2643
  if (scope !== void 0) scope.bail(scope, "slash/input-consume-token", { guard });
2397
- }, [sessionId]);
2644
+ }, [ctx, sessionId]);
2398
2645
  React.useEffect(() => {
2399
2646
  if (!open) return void 0;
2400
2647
  const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -2433,7 +2680,7 @@ window.__ModuleLoader__.load({
2433
2680
  }), /* @__PURE__ */ React.createElement(ContextBrowser, {
2434
2681
  data,
2435
2682
  headers,
2436
- useSession: props.useSession,
2683
+ convNodes,
2437
2684
  fetchContent,
2438
2685
  hoverKey: hoverCat,
2439
2686
  onHoverKey: setHoverCat
@@ -4122,6 +4369,58 @@ window.__ModuleLoader__.load({
4122
4369
  return /* @__PURE__ */ React.createElement("div", { className: "lc-agents-inspector" }, /* @__PURE__ */ React.createElement("b", { className: "lc-agents-inspector-name" }, node.label), node.isCurrent ? /* @__PURE__ */ React.createElement("span", { className: "lc-agents-badge" }, t("agents.self")) : null, node.running ? /* @__PURE__ */ React.createElement("span", { className: "lc-agents-badge lc-agents-badge-on" }, t("agents.running")) : null, node.identity !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-agents-badge" }, t(node.identity.mode === "one-shot" ? "agents.oneshot" : "agents.continuable")) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-agents-inspector-stats" }, bits.join(" · ")), !node.isCurrent ? /* @__PURE__ */ React.createElement("span", { className: "lc-agents-inspector-open" }, t("agents.open")) : null);
4123
4370
  }
4124
4371
  //#endregion
4372
+ //#region src/client/components/donut.tsx
4373
+ function makeDonut(kit) {
4374
+ return function Donut(props) {
4375
+ const size = props.size ?? 118;
4376
+ let total = 0;
4377
+ for (const s of props.segments) if (Number.isFinite(s.value) && s.value > 0) total += s.value;
4378
+ const arcs = [];
4379
+ let acc = 0;
4380
+ if (total > 0) for (const s of props.segments) {
4381
+ const v = Number.isFinite(s.value) && s.value > 0 ? s.value : 0;
4382
+ if (v === 0) continue;
4383
+ const pct = v / total * 100;
4384
+ arcs.push({
4385
+ key: s.key,
4386
+ color: s.color,
4387
+ pct,
4388
+ offset: 100 - acc + 25
4389
+ });
4390
+ acc += pct;
4391
+ }
4392
+ return /* @__PURE__ */ React.createElement("div", {
4393
+ className: "lc-donut",
4394
+ style: {
4395
+ width: size,
4396
+ height: size
4397
+ }
4398
+ }, /* @__PURE__ */ React.createElement("svg", {
4399
+ viewBox: "0 0 42 42",
4400
+ width: size,
4401
+ height: size,
4402
+ "aria-hidden": "true"
4403
+ }, arcs.length === 0 ? /* @__PURE__ */ React.createElement("circle", {
4404
+ className: "lc-donut-track",
4405
+ cx: "21",
4406
+ cy: "21",
4407
+ r: "15.9155",
4408
+ fill: "none",
4409
+ strokeWidth: "4"
4410
+ }) : arcs.map((a) => /* @__PURE__ */ React.createElement("circle", {
4411
+ key: a.key,
4412
+ cx: "21",
4413
+ cy: "21",
4414
+ r: "15.9155",
4415
+ fill: "none",
4416
+ stroke: a.color,
4417
+ strokeWidth: "4",
4418
+ strokeDasharray: `${a.pct} ${100 - a.pct}`,
4419
+ strokeDashoffset: a.offset
4420
+ }))), /* @__PURE__ */ React.createElement("div", { className: "lc-donut-center" }, /* @__PURE__ */ React.createElement("b", { style: { fontSize: Math.max(11, Math.round(size * .13)) } }, props.centerTop), props.centerSub !== void 0 ? /* @__PURE__ */ React.createElement("span", { style: { fontSize: Math.max(9, Math.round(size * .105)) } }, props.centerSub) : null));
4421
+ };
4422
+ }
4423
+ //#endregion
4125
4424
  //#region src/client/components/events.tsx
4126
4425
  const EVENT_ICONS = {
4127
4426
  compaction: "✂",
@@ -4443,6 +4742,46 @@ window.__ModuleLoader__.load({
4443
4742
  return false;
4444
4743
  }
4445
4744
  //#endregion
4745
+ //#region src/client/settingsJump.ts
4746
+ /**
4747
+ * Best-effort jump to this plugin's settings page (Settings → Plugins →
4748
+ * Plugin configuration). The harness settings panel keeps its open state
4749
+ * inside the shell component — no plugin-facing open face exists — so the
4750
+ * jump drives the real chrome: click the sidebar's settings trigger, then
4751
+ * the Plugins section nav row, both found by their shipped attributes and
4752
+ * labels. EVERY step is individually guarded: a shell that doesn't match
4753
+ * (older host, different layout, missing sidebar) degrades the whole jump
4754
+ * to a silent no-op — this path must never throw into the caller's render.
4755
+ */
4756
+ /** The Plugins settings section's shipped nav labels (en/zh locales). */
4757
+ const SECTION_LABELS = /* @__PURE__ */ new Set(["Plugins", "插件"]);
4758
+ /** Buttons the jump may operate on, in document order. */
4759
+ function buttonsOf(doc) {
4760
+ return [...doc.querySelectorAll("button")];
4761
+ }
4762
+ /** The sidebar's settings triggers: dialog semantics plus an expanded flag. */
4763
+ function findTriggers(doc) {
4764
+ return buttonsOf(doc).filter((b) => b.getAttribute("aria-haspopup") === "dialog" && b.hasAttribute("aria-expanded"));
4765
+ }
4766
+ /** The Plugins section's nav row, matched by its shipped label. */
4767
+ function findSectionRow(doc) {
4768
+ return buttonsOf(doc).find((b) => SECTION_LABELS.has(b.textContent.trim()));
4769
+ }
4770
+ function openPluginSettings(doc = document, schedule = (run, ms) => {
4771
+ window.setTimeout(run, ms);
4772
+ }) {
4773
+ try {
4774
+ const triggers = findTriggers(doc);
4775
+ if (triggers.find((b) => b.getAttribute("aria-expanded") === "true") === void 0 && triggers.length === 0) return;
4776
+ triggers.find((b) => b.getAttribute("aria-expanded") !== "true")?.click();
4777
+ schedule(() => {
4778
+ try {
4779
+ findSectionRow(doc)?.click();
4780
+ } catch {}
4781
+ }, 80);
4782
+ } catch {}
4783
+ }
4784
+ //#endregion
4446
4785
  //#region src/client/components/pluginInfo.tsx
4447
4786
  function makePluginInfo(kit) {
4448
4787
  const { t } = kit;
@@ -4455,7 +4794,7 @@ window.__ModuleLoader__.load({
4455
4794
  return function PluginInfo() {
4456
4795
  const [latest, setLatest] = React.useState(null);
4457
4796
  React.useEffect(() => {
4458
- if ("0.36.0".includes("-dev")) return;
4797
+ if ("0.38.0".includes("-dev")) return;
4459
4798
  let on = true;
4460
4799
  fetchLatestVersion().then((v) => {
4461
4800
  if (on && v) setLatest(v);
@@ -4464,8 +4803,8 @@ window.__ModuleLoader__.load({
4464
4803
  on = false;
4465
4804
  };
4466
4805
  }, []);
4467
- const update = latest !== null && isNewerVersion(latest, "0.36.0") ? latest : null;
4468
- const nameValue = ["dsh-context (v0.36.0)"];
4806
+ const update = latest !== null && isNewerVersion(latest, "0.38.0") ? latest : null;
4807
+ const nameValue = ["dsh-context (v0.38.0)"];
4469
4808
  if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", {
4470
4809
  key: "update",
4471
4810
  className: "lc-pi-update"
@@ -4475,7 +4814,13 @@ window.__ModuleLoader__.load({
4475
4814
  href: PLUGIN_REPO,
4476
4815
  target: "_blank",
4477
4816
  rel: "noreferrer"
4478
- }, t("plugin.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-pi-grid" }, row(t("plugin.name"), nameValue, PLUGIN_REPO + "/releases"), row(t("plugin.github"), PLUGIN_REPO_SHORT, PLUGIN_REPO)));
4817
+ }, t("plugin.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-pi-grid" }, row(t("plugin.name"), nameValue, PLUGIN_REPO + "/releases"), row(t("plugin.github"), PLUGIN_REPO_SHORT, PLUGIN_REPO), /* @__PURE__ */ React.createElement("button", {
4818
+ type: "button",
4819
+ className: "lc-pi-row lc-pi-row-btn",
4820
+ onClick: () => {
4821
+ openPluginSettings();
4822
+ }
4823
+ }, /* @__PURE__ */ React.createElement("div", { className: "lc-pi-label" }, t("plugin.settings")), /* @__PURE__ */ React.createElement("div", { className: "lc-pi-value" }, t("plugin.settingsOpen")))));
4479
4824
  };
4480
4825
  }
4481
4826
  //#endregion
@@ -4657,19 +5002,21 @@ window.__ModuleLoader__.load({
4657
5002
  return /* @__PURE__ */ React.createElement("div", { className: "lc-detail" }, /* @__PURE__ */ React.createElement("div", { className: "lc-detail-head" }, /* @__PURE__ */ React.createElement("b", null, head), marker !== null && markerAt !== null ? /* @__PURE__ */ React.createElement("span", {
4658
5003
  className: "lc-detail-marker",
4659
5004
  title: eventLabel(marker)
4660
- }, "✂ " + markerAt) : null, isTurn ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("detail.lastStep")) : null, delta ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("gran.delta")) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-detail-time" }, fmtTime(req.time)), delta ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" + (net > 0 ? " lc-detail-metric-up" : net < 0 ? " lc-detail-metric-down" : "") }, t("tip.delta", { n: (net > 0 ? "+" : "") + fmt(net) })) : null, !delta && req.prompt !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.actual", { n: fmt(req.prompt) })) : null, !delta && req.output !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.output", { n: fmt(req.output) })) : null, !delta && req.prompt !== void 0 && req.cacheRead !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.cache", { n: cacheHitPercent$1(req.cacheRead, req.prompt) ?? "—" })) : null), /* @__PURE__ */ React.createElement(BriefSection, {
5005
+ }, "✂ " + markerAt) : null, isTurn ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("detail.lastStep")) : null, delta ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("gran.delta")) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-detail-time" }, fmtTime(req.time)), delta ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" + (net > 0 ? " lc-detail-metric-up" : net < 0 ? " lc-detail-metric-down" : "") }, t("tip.delta", { n: (net > 0 ? "+" : "") + fmt(net) })) : null, !delta && req.prompt !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.actual", { n: fmt(req.prompt) })) : null, !delta && req.output !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.output", { n: fmt(req.output) })) : null, !delta && req.prompt !== void 0 && req.cacheRead !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-metric" }, t("detail.cache", { n: cacheHitPercent(req.cacheRead, req.prompt) ?? "—" })) : null), /* @__PURE__ */ React.createElement(BriefSection, {
4661
5006
  brief: props.brief,
4662
5007
  convOf: props.convOf,
4663
5008
  onLocate: props.onLocate
4664
5009
  }), /* @__PURE__ */ React.createElement(StackedBar, {
4665
5010
  parts,
4666
- height: 10
5011
+ height: 10,
5012
+ hoverKey: props.hoverKey,
5013
+ tip: false
4667
5014
  }), /* @__PURE__ */ React.createElement("div", { className: "lc-detail-rows" }, CATS.map((c, i) => {
4668
5015
  const v = delta ? deltas[i] : req[c.key] || 0;
4669
5016
  const mag = Math.abs(v);
4670
5017
  return /* @__PURE__ */ React.createElement("div", {
4671
5018
  key: c.key,
4672
- className: "lc-detail-row"
5019
+ className: "lc-detail-row" + (props.hoverKey === c.key ? " lc-detail-row-on" : "")
4673
5020
  }, /* @__PURE__ */ React.createElement("i", { style: { background: c.color } }), /* @__PURE__ */ React.createElement("span", { className: "lc-detail-label" }, catLabel(c.key)), /* @__PURE__ */ React.createElement("span", { className: "lc-bar-track" }, delta ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "lc-bar-zero" }), v !== 0 ? /* @__PURE__ */ React.createElement("span", {
4674
5021
  className: "lc-bar-fill " + (v > 0 ? "lc-bar-fill-up" : "lc-bar-fill-down"),
4675
5022
  style: {
@@ -4787,40 +5134,20 @@ window.__ModuleLoader__.load({
4787
5134
  return formatCost(amount, currency).replace(/0+$/, "").replace(/\.$/, "");
4788
5135
  }
4789
5136
  //#endregion
4790
- //#region src/client/components/statsBoard.tsx
4791
- /**
4792
- * Cache-hit share of billed prompt-side input — same three disjoint buckets
4793
- * as the harness chat line (`cacheReadTokens` over uncached + reads + writes)
4794
- * and the step line's 缓存 figure; null when nothing was billed.
4795
- */
4796
- function cacheHitPercent(usage) {
4797
- const uncached = numOf(usage.uncachedInputTokens);
4798
- const reads = numOf(usage.cacheReadTokens);
4799
- const writes = numOf(usage.cacheWriteTokens);
4800
- return cacheHitPercent$1(reads, uncached + reads + writes);
4801
- }
4802
- function cell(label, value, tip) {
4803
- return /* @__PURE__ */ React.createElement("div", { className: "lc-stat" + (tip === void 0 ? "" : " lc-stat-tipped") }, /* @__PURE__ */ React.createElement("span", { className: "lc-stat-label" }, label, tip !== void 0 && /* @__PURE__ */ React.createElement("i", {
4804
- className: "lc-stat-q",
4805
- "aria-hidden": "true"
4806
- }, "?")), /* @__PURE__ */ React.createElement("b", { className: "lc-stat-value" }, value), tip !== void 0 && /* @__PURE__ */ React.createElement("span", {
4807
- className: "lc-stat-tip",
4808
- role: "tooltip"
4809
- }, tip));
4810
- }
4811
- function makeStatsBoard(kit) {
5137
+ //#region src/client/components/statsContext.tsx
5138
+ function makeStatsContext(kit) {
4812
5139
  const { t, fmt } = kit;
4813
- return function StatsBoard(props) {
5140
+ return function StatsContext(props) {
4814
5141
  const turns = /* @__PURE__ */ new Set();
4815
- let steps = 0, compactions = 0, prunes = 0, injects = 0;
5142
+ let steps = 0;
4816
5143
  for (const req of props.requests) {
4817
5144
  turns.add(req.turn ?? 0);
4818
5145
  steps++;
4819
5146
  }
4820
- for (const ev of props.events) if (ev.kind === "compaction") compactions++;
5147
+ let injects = 0, compactions = 0, prunes = 0;
5148
+ for (const ev of props.events) if (ev.kind === "inject") injects++;
5149
+ else if (ev.kind === "compaction") compactions++;
4821
5150
  else if (ev.kind === "prune") prunes++;
4822
- else if (ev.kind === "inject") injects++;
4823
- const hit = props.usage !== null ? cacheHitPercent(props.usage) : null;
4824
5151
  const currency = props.locale === "zh" ? "cny" : "usd";
4825
5152
  const cost = estimateSessionCost(props.cost, currency);
4826
5153
  const fmtRate = (n) => formatPriceRate(n, currency);
@@ -4831,7 +5158,149 @@ window.__ModuleLoader__.load({
4831
5158
  key: r.family,
4832
5159
  className: "lc-stat-tip-row"
4833
5160
  }, /* @__PURE__ */ React.createElement("b", { className: "lc-stat-tip-model" }, r.family), " ", t("stats.costHit"), " ", fmtRate(r.peak.hit), "/", fmtRate(r.off.hit), " · ", t("stats.costMiss"), " ", fmtRate(r.peak.miss), "/", fmtRate(r.off.miss), " · ", t("stats.costOut"), " ", fmtRate(r.peak.out), "/", fmtRate(r.off.out))))];
4834
- return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col lc-col-stats" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("stats.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("stats.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-stats" }, cell(t("stats.turns"), fmt(turns.size)), cell(t("stats.steps"), fmt(steps)), cell(t("stats.injects"), fmt(injects)), cell(t("stats.compactions"), fmt(compactions)), cell(t("stats.prunes"), fmt(prunes)), cell(t("stats.toolCalls"), fmt(props.toolCalls ?? 0)), cell(t("stats.images"), fmt(props.images ?? 0)), cell(t("stats.cacheHit"), hit === null ? "—" : hit + "%"), cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip)));
5161
+ const cell = (label, value, tip) => /* @__PURE__ */ React.createElement("div", { className: "lc-stat" + (tip === void 0 ? "" : " lc-stat-tipped") }, /* @__PURE__ */ React.createElement("span", { className: "lc-stat-label" }, label, tip !== void 0 && /* @__PURE__ */ React.createElement("i", {
5162
+ className: "lc-stat-q",
5163
+ "aria-hidden": "true"
5164
+ }, "?")), /* @__PURE__ */ React.createElement("b", { className: "lc-stat-value" }, typeof value === "number" ? fmt(value) : value), tip !== void 0 && /* @__PURE__ */ React.createElement("span", {
5165
+ className: "lc-stat-tip",
5166
+ role: "tooltip"
5167
+ }, tip));
5168
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col-stats" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("stats.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("stats.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-stats" }, cell(t("stats.turns"), turns.size), cell(t("stats.steps"), steps), cell(t("stats.toolCalls"), props.toolCalls ?? 0), cell(t("stats.images"), props.images ?? 0), cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip), cell(t("stats.injects"), injects), cell(t("stats.compactions"), compactions), cell(t("stats.prunes"), prunes)));
5169
+ };
5170
+ }
5171
+ //#endregion
5172
+ //#region src/client/components/sliceList.tsx
5173
+ function makeSliceList(kit) {
5174
+ return function SliceList(props) {
5175
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-sl" }, props.rows.map((r) => /* @__PURE__ */ React.createElement("div", {
5176
+ key: r.key,
5177
+ className: "lc-sl-row"
5178
+ }, /* @__PURE__ */ React.createElement("i", {
5179
+ className: "lc-sl-dot",
5180
+ style: { background: r.color }
5181
+ }), /* @__PURE__ */ React.createElement("span", { className: "lc-sl-label" }, r.label), r.count !== "" ? /* @__PURE__ */ React.createElement("span", { className: "lc-sl-count" }, r.count) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-sl-pct" }, r.pct))));
5182
+ };
5183
+ }
5184
+ //#endregion
5185
+ //#region src/client/components/statsTiming.tsx
5186
+ function makeStatsTiming(kit, Donut) {
5187
+ const { t, fmt, fmtDuration, fmtShare } = kit;
5188
+ const SliceList = makeSliceList(kit);
5189
+ return function StatsTiming(props) {
5190
+ const lang = props.locale === "zh" ? "zh" : "en";
5191
+ const timing = props.timing;
5192
+ const wall = timing !== null && Number.isFinite(timing.wallMs) && timing.wallMs > 0 ? timing.wallMs : 0;
5193
+ let segments = [];
5194
+ let rows = [];
5195
+ if (timing !== null && (wall > 0 || timing.calls > 0 || timing.toolCalls > 0)) {
5196
+ const lm = Math.min(timing.lmMs, wall);
5197
+ const toolRing = Math.max(0, Math.min(timing.toolsMs, wall - lm));
5198
+ const other = Math.max(0, wall - lm - toolRing);
5199
+ const share = (ms) => wall > 0 ? ms / wall : 0;
5200
+ segments = [
5201
+ {
5202
+ key: "lm",
5203
+ color: "#3b82f6",
5204
+ value: share(lm)
5205
+ },
5206
+ {
5207
+ key: "tools",
5208
+ color: "#14b8a6",
5209
+ value: share(toolRing)
5210
+ },
5211
+ {
5212
+ key: "other",
5213
+ color: "#94a3b8",
5214
+ value: share(other)
5215
+ }
5216
+ ];
5217
+ rows = [
5218
+ {
5219
+ key: "lm",
5220
+ color: "#3b82f6",
5221
+ label: `${t("timing.lm")} ${t("timing.times", { n: fmt(timing.calls) })}`,
5222
+ pct: fmtShare(timing.lmMs, wall),
5223
+ count: fmtDuration(timing.lmMs, lang)
5224
+ },
5225
+ {
5226
+ key: "tools",
5227
+ color: "#14b8a6",
5228
+ label: `${t("timing.tools")} ${t("timing.times", { n: fmt(timing.toolCalls) })}`,
5229
+ pct: fmtShare(timing.toolsMs, wall),
5230
+ count: fmtDuration(timing.toolsMs, lang)
5231
+ },
5232
+ {
5233
+ key: "other",
5234
+ color: "#94a3b8",
5235
+ label: t("timing.other"),
5236
+ pct: fmtShare(other, wall),
5237
+ count: fmtDuration(other, lang)
5238
+ }
5239
+ ];
5240
+ }
5241
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col-stats lc-col-donut" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("timing.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("timing.hint"))), rows.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-empty" }, t("timing.empty")) : /* @__PURE__ */ React.createElement("div", { className: "lc-donut-row" }, /* @__PURE__ */ React.createElement(Donut, {
5242
+ segments,
5243
+ size: 96,
5244
+ centerTop: wall > 0 ? fmtDuration(wall, lang) : "—",
5245
+ centerSub: t("timing.total")
5246
+ }), /* @__PURE__ */ React.createElement(SliceList, { rows })));
5247
+ };
5248
+ }
5249
+ //#endregion
5250
+ //#region src/client/components/statsTokens.tsx
5251
+ function makeStatsTokens(kit, Donut) {
5252
+ const { t, fmt, fmtShare } = kit;
5253
+ const SliceList = makeSliceList(kit);
5254
+ return function StatsTokens(props) {
5255
+ const reads = props.usage !== null ? numOf(props.usage.cacheReadTokens) : 0;
5256
+ const writes = props.usage !== null ? numOf(props.usage.cacheWriteTokens) : 0;
5257
+ const uncached = props.usage !== null ? numOf(props.usage.uncachedInputTokens) : 0;
5258
+ const output = props.usage !== null ? numOf(props.usage.outputTokens) : 0;
5259
+ const billed = reads + writes + uncached + output;
5260
+ const hit = props.usage !== null ? cacheHitPercent(reads, uncached + reads + writes) : null;
5261
+ const buckets = [
5262
+ {
5263
+ key: "read",
5264
+ color: "#22c55e",
5265
+ label: t("tokens.cacheRead"),
5266
+ value: reads
5267
+ },
5268
+ {
5269
+ key: "write",
5270
+ color: "#f59e0b",
5271
+ label: t("tokens.cacheWrite"),
5272
+ value: writes
5273
+ },
5274
+ {
5275
+ key: "uncached",
5276
+ color: "#6366f1",
5277
+ label: t("tokens.uncached"),
5278
+ value: uncached
5279
+ },
5280
+ {
5281
+ key: "output",
5282
+ color: "#3b82f6",
5283
+ label: t("tokens.output"),
5284
+ value: output
5285
+ }
5286
+ ];
5287
+ const rows = buckets.map((b) => ({
5288
+ key: b.key,
5289
+ color: b.color,
5290
+ label: b.label,
5291
+ pct: fmtShare(b.value, billed),
5292
+ count: fmt(b.value)
5293
+ }));
5294
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col-stats lc-col-donut" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("tokens.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("tokens.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-donut-row" }, /* @__PURE__ */ React.createElement(Donut, {
5295
+ segments: buckets.map((b) => ({
5296
+ key: b.key,
5297
+ color: b.color,
5298
+ value: b.value
5299
+ })),
5300
+ size: 96,
5301
+ centerTop: hit === null ? "—" : `${hit}%`,
5302
+ centerSub: t("tokens.cacheHit")
5303
+ }), /* @__PURE__ */ React.createElement(SliceList, { rows })));
4835
5304
  };
4836
5305
  }
4837
5306
  //#endregion
@@ -4876,6 +5345,15 @@ window.__ModuleLoader__.load({
4876
5345
  }
4877
5346
  return markers;
4878
5347
  }
5348
+ /**
5349
+ * The chat→Context jump's target: the turn bar whose closing reply the user clicked — the relayed seq is a turn's LAST step, exactly the
5350
+ * aggregate's record — or, when that turn has aged out of the host's retained window, the oldest retained bar. Resolved against turn
5351
+ * aggregates, since the jump pins in turn granularity. Null only on an empty history.
5352
+ */
5353
+ function jumpTargetOf(requests, seq) {
5354
+ for (const req of requests) if (req.seq === seq) return req;
5355
+ return requests.length > 0 ? requests[0] : null;
5356
+ }
4879
5357
  function makeTrendChart(kit) {
4880
5358
  const { t, fmt, fmtTime, eventLabel, eventAt } = kit;
4881
5359
  const CHART_H = 112;
@@ -4929,6 +5407,8 @@ window.__ModuleLoader__.load({
4929
5407
  if (d <= 0) return null;
4930
5408
  return /* @__PURE__ */ React.createElement("div", {
4931
5409
  key: c.key,
5410
+ "data-cat": c.key,
5411
+ className: "lc-cat-seg",
4932
5412
  style: {
4933
5413
  height: `${Math.max(1, Math.round(d * props.deltaScale))}px`,
4934
5414
  background: c.color
@@ -4942,6 +5422,8 @@ window.__ModuleLoader__.load({
4942
5422
  if (d >= 0) return null;
4943
5423
  return /* @__PURE__ */ React.createElement("div", {
4944
5424
  key: c.key,
5425
+ "data-cat": c.key,
5426
+ className: "lc-cat-seg",
4945
5427
  style: {
4946
5428
  height: `${Math.max(1, Math.round(-d * props.deltaScale))}px`,
4947
5429
  background: c.color
@@ -4952,6 +5434,8 @@ window.__ModuleLoader__.load({
4952
5434
  if (!v) return null;
4953
5435
  return /* @__PURE__ */ React.createElement("div", {
4954
5436
  key: c.key,
5437
+ "data-cat": c.key,
5438
+ className: "lc-cat-seg",
4955
5439
  style: {
4956
5440
  height: `${Math.max(1, Math.round(v / props.maxTotal * CHART_H))}px`,
4957
5441
  background: c.color
@@ -5135,6 +5619,7 @@ window.__ModuleLoader__.load({
5135
5619
  }
5136
5620
  }, /* @__PURE__ */ React.createElement("div", {
5137
5621
  className: "lc-chart",
5622
+ "data-catdim": props.hoverCat ?? void 0,
5138
5623
  onMouseLeave: () => {
5139
5624
  props.onHover(null);
5140
5625
  }
@@ -5180,6 +5665,43 @@ window.__ModuleLoader__.load({
5180
5665
  };
5181
5666
  }
5182
5667
  //#endregion
5668
+ //#region src/client/viewFocus.ts
5669
+ /**
5670
+ * Chat → Context jump relay. The assistant-message action records the clicked
5671
+ * reply's request seq here and activates the Context tab; the Context view
5672
+ * consumes the one-shot focus once its projection data is in. Module-level
5673
+ * per-session map — the same life pattern as the modal open-state stores.
5674
+ */
5675
+ const pendingFocus = /* @__PURE__ */ new Map();
5676
+ /** Record the Context step (request seq) to reveal for `sessionId` — replaces any unconsumed request. */
5677
+ function requestContextFocus(sessionId, seq) {
5678
+ pendingFocus.set(sessionId, seq);
5679
+ }
5680
+ /** Take the pending focus request, if any — one-shot, the map entry is consumed. */
5681
+ function takeContextFocus(sessionId) {
5682
+ const seq = pendingFocus.get(sessionId);
5683
+ if (seq === void 0) return null;
5684
+ pendingFocus.delete(sessionId);
5685
+ return seq;
5686
+ }
5687
+ /**
5688
+ * Activate the Context tab by clicking its own tab-bar button (the semantic
5689
+ * `button[role="tab"]` chrome the conversation shell renders for every view).
5690
+ * The harness hands `openView` only to the ACTIVE view entry, so a nested
5691
+ * chat action cannot call it — this rides the same button a user click would.
5692
+ * Already-active is a no-op that still reports success; no matching tab (any
5693
+ * dsh layout without the tab bar) reports failure and nothing happens.
5694
+ */
5695
+ function activateContextTab(label) {
5696
+ const tabs = document.querySelectorAll("button[role=\"tab\"]");
5697
+ for (const tab of tabs) {
5698
+ if (tab.textContent.trim() !== label) continue;
5699
+ if (tab.getAttribute("aria-selected") !== "true") tab.click();
5700
+ return true;
5701
+ }
5702
+ return false;
5703
+ }
5704
+ //#endregion
5183
5705
  //#region src/client/components/contextView.tsx
5184
5706
  const viewScroll = /* @__PURE__ */ new Map();
5185
5707
  const EVENT_KINDS = [
@@ -5197,7 +5719,10 @@ window.__ModuleLoader__.load({
5197
5719
  const RequestDetail = makeRequestDetail(kit, StackedBar);
5198
5720
  const EventList = makeEventList(kit);
5199
5721
  const FileCard = makeFileCard(kit, settings);
5200
- const StatsBoard = makeStatsBoard(kit);
5722
+ const Donut = makeDonut(kit);
5723
+ const StatsContext = makeStatsContext(kit);
5724
+ const StatsTiming = makeStatsTiming(kit, Donut);
5725
+ const StatsTokens = makeStatsTokens(kit, Donut);
5201
5726
  const PluginInfo = makePluginInfo(kit);
5202
5727
  const ContextBrowser = makeContextBrowser(kit, StackedBar);
5203
5728
  const AgentGraph = makeAgentGraph(ctx, kit);
@@ -5215,6 +5740,7 @@ window.__ModuleLoader__.load({
5215
5740
  const [granularity, setGranularity] = React.useState(() => settings.defaultGranularity());
5216
5741
  const [trendMode, setTrendMode] = React.useState(() => settings.defaultTrendMode());
5217
5742
  const [focusTurn, setFocusTurn] = React.useState(null);
5743
+ const [jumpSeq, setJumpSeq] = React.useState(null);
5218
5744
  const [hoverCat, setHoverCat] = React.useState(null);
5219
5745
  const [pickedKinds, setPickedKinds] = React.useState([...EVENT_KINDS]);
5220
5746
  const toggleKind = (k) => {
@@ -5228,12 +5754,7 @@ window.__ModuleLoader__.load({
5228
5754
  const clearNodeFocus = React.useCallback(() => {
5229
5755
  setNodeFocus(null);
5230
5756
  }, []);
5231
- const loadImage = React.useMemo(() => {
5232
- if (typeof sessionId !== "string" || sessionId === "") return void 0;
5233
- const conversation = ctx.get("conversation");
5234
- if (conversation === void 0 || typeof conversation.resolveImage !== "function") return void 0;
5235
- return (attachment) => conversation.resolveImage(sessionId, attachment);
5236
- }, [sessionId]);
5757
+ const loadImage = React.useMemo(() => imageLoaderOf(ctx, typeof sessionId === "string" ? sessionId : void 0), [ctx, sessionId]);
5237
5758
  const fetchContent = React.useMemo(() => typeof sessionId === "string" && sessionId !== "" ? makeContentFetcher(ctx, sessionId) : void 0, [ctx, sessionId]);
5238
5759
  const rootRef = React.useRef(null);
5239
5760
  const scrollerRef = React.useRef(null);
@@ -5262,9 +5783,28 @@ window.__ModuleLoader__.load({
5262
5783
  const shownEvents = pickedKinds.length === EVENT_KINDS.length ? events : events.filter((e) => pickedKinds.includes(e.kind));
5263
5784
  const displayRequests = React.useMemo(() => granularity === "turn" ? aggregateByTurn(requests) : requests, [requests, granularity]);
5264
5785
  const markers = React.useMemo(() => attachMarkers(displayRequests, events), [displayRequests, events]);
5786
+ React.useEffect(() => {
5787
+ if (typeof sessionId !== "string" || sessionId === "") return;
5788
+ const seq = takeContextFocus(sessionId);
5789
+ if (seq !== null) setJumpSeq(seq);
5790
+ }, [sessionId]);
5791
+ React.useEffect(() => {
5792
+ if (jumpSeq === null || data === null) return;
5793
+ setJumpSeq(null);
5794
+ const target = jumpTargetOf(aggregateByTurn(requests), jumpSeq);
5795
+ if (target === null) return;
5796
+ setGranularity("turn");
5797
+ setSelectedSeq(target.seq);
5798
+ setFocusTurn(target.turn ?? 0);
5799
+ if (scrollerRef.current !== null) scrollerRef.current.scrollTop = 0;
5800
+ }, [
5801
+ jumpSeq,
5802
+ data,
5803
+ requests
5804
+ ]);
5265
5805
  const briefList = React.useMemo(() => data ? briefNodes(data) : [], [data]);
5266
5806
  const replyTips = React.useMemo(() => replyTipsOf(briefList), [briefList]);
5267
- const convNodes = typeof props.useSession === "function" ? props.useSession((s) => s.nodes) : void 0;
5807
+ const convNodes = conversationNodesOf(props);
5268
5808
  const bySeq = React.useMemo(() => {
5269
5809
  const m = /* @__PURE__ */ new Map();
5270
5810
  for (const n of convNodes ?? []) m.set(n.seq, n);
@@ -5354,20 +5894,23 @@ window.__ModuleLoader__.load({
5354
5894
  break;
5355
5895
  }
5356
5896
  }
5897
+ const trendHoverCat = hoverCat !== null && hoverCat !== "free" ? hoverCat : null;
5357
5898
  const localeSvc = ctx.get("locale");
5358
5899
  const activeLocale = localeSvc !== void 0 && typeof localeSvc.getLocale === "function" ? localeSvc.getLocale().active : "en";
5359
5900
  const subtitle = (data.model ?? "") + (data.provider ? " · " + data.provider : "");
5360
5901
  return /* @__PURE__ */ React.createElement("div", {
5361
5902
  className: "lc-root",
5362
5903
  ref: rootRef
5363
- }, /* @__PURE__ */ React.createElement("div", { className: "lc-cols lc-head" }, /* @__PURE__ */ React.createElement(StatsBoard, {
5904
+ }, /* @__PURE__ */ React.createElement("div", { className: "lc-cols lc-head" }, /* @__PURE__ */ React.createElement(StatsContext, {
5364
5905
  requests,
5365
5906
  events,
5366
- usage,
5367
5907
  toolCalls: data.toolCalls,
5368
5908
  images: data.images,
5369
5909
  cost: data.cost,
5370
5910
  locale: activeLocale
5911
+ }), /* @__PURE__ */ React.createElement(StatsTokens, { usage }), /* @__PURE__ */ React.createElement(StatsTiming, {
5912
+ timing: data.timing ?? null,
5913
+ locale: activeLocale
5371
5914
  }), /* @__PURE__ */ React.createElement(PluginInfo, null)), /* @__PURE__ */ React.createElement("div", { className: "lc-cols" }, /* @__PURE__ */ React.createElement("div", { className: "lc-col" }, /* @__PURE__ */ React.createElement(CurrentComposition, {
5372
5915
  head,
5373
5916
  subtitle,
@@ -5406,6 +5949,7 @@ window.__ModuleLoader__.load({
5406
5949
  granularity,
5407
5950
  mode: trendMode,
5408
5951
  focusTurn,
5952
+ hoverCat: trendHoverCat,
5409
5953
  onSelect: setSelectedSeq,
5410
5954
  onHover: setHoveredSeq,
5411
5955
  onHoverTurn: setHoverTurn,
@@ -5426,11 +5970,12 @@ window.__ModuleLoader__.load({
5426
5970
  marker: activeReq !== null ? markerOf(activeReq) : void 0,
5427
5971
  brief,
5428
5972
  convOf,
5429
- onLocate: locateNode
5973
+ onLocate: locateNode,
5974
+ hoverKey: trendHoverCat
5430
5975
  })))), /* @__PURE__ */ React.createElement("div", { className: "lc-col lc-col-browser" }, /* @__PURE__ */ React.createElement(ContextBrowser, {
5431
5976
  data,
5432
5977
  headers,
5433
- useSession: props.useSession,
5978
+ convNodes,
5434
5979
  fetchContent,
5435
5980
  previewSeq: hoveredSeq,
5436
5981
  pinSeq: pinnedReq !== null ? pinnedReq.seq : null,
@@ -5465,6 +6010,85 @@ window.__ModuleLoader__.load({
5465
6010
  };
5466
6011
  }
5467
6012
  //#endregion
6013
+ //#region src/client/components/contextJump.tsx
6014
+ /**
6015
+ * The assistant-message action that jumps to the Context tab at this reply's
6016
+ * turn. Registered on the harness `conversation.chat.assistant-actions` seat
6017
+ * (the icon row beside copy/branch), it receives the finalized reply's durable
6018
+ * message id, resolves the matching assistant node's seq off whichever node
6019
+ * seat the running harness serves (`useChat` on 0.1.2+, the session snapshot
6020
+ * before it), records it in the viewFocus relay, and activates the Context
6021
+ * tab — where the jump pins the reply's TURN (see contextView's leg 2). An
6022
+ * unresolvable seq still switches tabs, just without a pin; a message id that
6023
+ * is not a plain string renders nothing at all.
6024
+ */
6025
+ /**
6026
+ * The reply's request seq by its durable message id, or null when no served node proves the pair. Join/log nodes are untrusted input: each
6027
+ * element is isolated, so one hostile object that throws on property access is skipped — the jump keeps its pin, never its click.
6028
+ */
6029
+ function seqOfMessageId(nodes, messageId) {
6030
+ for (const node of nodes ?? []) try {
6031
+ if (node.kind !== "assistant" || node.messageId !== messageId) continue;
6032
+ return typeof node.seq === "number" && Number.isFinite(node.seq) ? node.seq : null;
6033
+ } catch {
6034
+ continue;
6035
+ }
6036
+ return null;
6037
+ }
6038
+ /** The jump glyph: the plugin's mini stacked composition bars, same 16px outline family as the shipped row icons. */
6039
+ function JumpIcon() {
6040
+ return /* @__PURE__ */ React.createElement("svg", {
6041
+ width: "16",
6042
+ height: "16",
6043
+ viewBox: "0 0 16 16",
6044
+ fill: "none",
6045
+ "aria-hidden": "true"
6046
+ }, /* @__PURE__ */ React.createElement("rect", {
6047
+ x: "2",
6048
+ y: "3",
6049
+ width: "12",
6050
+ height: "2",
6051
+ rx: "1",
6052
+ fill: "currentColor"
6053
+ }), /* @__PURE__ */ React.createElement("rect", {
6054
+ x: "2",
6055
+ y: "7",
6056
+ width: "8.5",
6057
+ height: "2",
6058
+ rx: "1",
6059
+ fill: "currentColor"
6060
+ }), /* @__PURE__ */ React.createElement("rect", {
6061
+ x: "2",
6062
+ y: "11",
6063
+ width: "5.5",
6064
+ height: "2",
6065
+ rx: "1",
6066
+ fill: "currentColor"
6067
+ }));
6068
+ }
6069
+ function makeContextJumpButton(kit) {
6070
+ const { t } = kit;
6071
+ return function ContextJump(props) {
6072
+ const messageId = props.messageId;
6073
+ if (typeof messageId !== "string" || messageId === "") return null;
6074
+ const jump = () => {
6075
+ const seq = seqOfMessageId(conversationNodesOf(props), messageId);
6076
+ const sessionId = props.sessionId;
6077
+ if (seq !== null && typeof sessionId === "string" && sessionId !== "") requestContextFocus(sessionId, seq);
6078
+ activateContextTab(t("tab"));
6079
+ };
6080
+ return /* @__PURE__ */ React.createElement(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
6081
+ label: t("jump.title"),
6082
+ side: "bottom"
6083
+ }, /* @__PURE__ */ React.createElement("button", {
6084
+ type: "button",
6085
+ className: "lc-jump",
6086
+ "aria-label": t("jump.title"),
6087
+ onClick: jump
6088
+ }, /* @__PURE__ */ React.createElement(JumpIcon, null)));
6089
+ };
6090
+ }
6091
+ //#endregion
5468
6092
  //#region src/client/viewkit.ts
5469
6093
  function makeViewKit(t) {
5470
6094
  const { eventLabel, eventAt } = makeEventText(t);
@@ -5472,6 +6096,8 @@ window.__ModuleLoader__.load({
5472
6096
  t,
5473
6097
  fmt,
5474
6098
  fmtTime,
6099
+ fmtDuration: fmtDuration$1,
6100
+ fmtShare,
5475
6101
  catLabel: (key) => t("cat." + key),
5476
6102
  eventLabel,
5477
6103
  eventAt
@@ -5479,7 +6105,7 @@ window.__ModuleLoader__.load({
5479
6105
  }
5480
6106
  //#endregion
5481
6107
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles.css.mjs
5482
- const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(auto-fit,minmax(62px,1fr));gap:6px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-settings-card{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;transition:border-color .16s,background .16s}.lc-settings-card:hover{border-color:var(--dsw-alias-label-dimmed)}.lc-settings-open,.lc-settings-open:hover{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.lc-settings-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.lc-settings-headtext{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.lc-settings-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.lc-settings-desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.lc-settings-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.lc-settings-open .lc-settings-chevron{transform:rotate(180deg)}.lc-settings-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 12px}.lc-settings-row{align-items:center;gap:8px;padding:8px 0;display:flex}.lc-settings-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:14px}.lc-settings-select{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.lc-settings-select:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.lc-settings-select:disabled{opacity:.5;cursor:default}.lc-settings-note{color:var(--dsw-alias-label-tertiary);margin:12px 0 4px;font-size:12px;line-height:1.5}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-grid-zero{border-top-style:solid;border-top-color:#80808080}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;left:0;box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{text-overflow:ellipsis;max-width:100%;display:inline-block;overflow:hidden}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px 8px;margin-bottom:10px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary);font-size:13px}.lc-detail-time{font-variant-numeric:tabular-nums;white-space:nowrap;margin-left:auto;font-size:12px}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-metric{font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);border-radius:6px;padding:2px 8px;font-size:12px;font-weight:600}.lc-detail-metric-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-detail-metric-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-detail-rows{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:4px 24px;margin-top:10px;display:grid}.lc-brief{flex-direction:column;gap:2px;min-height:76px;margin:-4px 0 10px;display:flex}.lc-brief-row{min-width:0;color:var(--dsw-alias-label-primary);text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;margin-left:-6px;margin-right:-6px;padding:3px 6px;font-family:inherit;font-size:12px;line-height:1.5;transition:background-color .12s;display:flex}.lc-brief-row-link:hover{background:var(--dsw-alias-interactive-bg-hover)}button.lc-brief-row-link{cursor:pointer}.lc-brief-tag{box-sizing:border-box;text-align:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);min-width:56px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;position:relative}.lc-brief-tip{z-index:6;white-space:normal;text-align:left;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:240px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-brief-tag:hover .lc-brief-tip{opacity:1}.lc-brief-text{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-brief-empty{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-tertiary);flex:1;overflow:hidden}.lc-brief-fact{box-sizing:border-box;text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:160px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;overflow:hidden}.lc-brief-chip{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);min-width:0;max-width:260px;color:var(--dsw-alias-label-primary);border-radius:5px;align-items:center;gap:5px;padding:0 7px;font-size:12px;transition:background-color .12s;display:inline-flex;overflow:hidden}.lc-brief-chip-grow{flex:1;max-width:none}.lc-brief-chip-tag{text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);max-width:120px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;overflow:hidden}.lc-brief-chip-text{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-brief-chip-link{cursor:pointer}.lc-brief-chip-link:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-brief-more{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-detail-row{align-items:center;gap:8px;display:flex}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;position:relative;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-bar-zero{border-left:1px solid #80808073;position:absolute;top:0;bottom:0;left:50%}.lc-bar-fill-up,.lc-bar-fill-down{height:100%;display:block;position:absolute;top:0}.lc-bar-fill-up{border-radius:0 3px 3px 0;left:50%}.lc-bar-fill-down{border-radius:3px 0 0 3px;right:50%}.lc-detail-num{text-align:right;font-variant-numeric:tabular-nums;width:52px}.lc-detail-num-up{color:var(--dsw-alias-state-success-primary)}.lc-detail-num-down{color:var(--dsw-alias-state-error-primary)}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-col-browser{flex-direction:column;display:flex}.lc-col-browser>.lc-card{flex:1}.lc-head>.lc-card:first-child{flex:7 1 0;min-width:360px}.lc-head>.lc-card:last-child{flex:3 1 0;min-width:220px}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-hint{text-decoration:none}.lc-pi-hint:hover{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-event-icon.lc-event-mode{color:var(--dsw-alias-label-secondary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-kind-mode{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 15%, transparent);color:var(--dsw-alias-label-secondary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-fa-ctl,.lc-br-toolctl{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.lc-fa-ctl .lc-gran{margin-left:0}.lc-fa-n{opacity:.75;margin-left:4px;font-weight:700}.lc-fa-search,.lc-br-tool-search{min-width:80px;font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;outline:none;flex:1;padding:3px 8px;font-size:12px}.lc-fa-search:focus,.lc-br-tool-search:focus{border-color:var(--dsw-alias-label-dimmed)}.lc-fa-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:6px;font-size:12px;display:flex}.lc-fa-meta .lc-fa-sort{flex:none}.lc-fa-meta-delta{position:relative}.lc-fa-meta-tip{z-index:6;white-space:normal;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:260px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-fa-meta-delta:hover .lc-fa-meta-tip{opacity:1}.lc-fa-item{border:1px solid #0000;border-radius:8px;transition:background-color .12s,border-color .12s}.lc-fa-item-on{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l1)}.lc-fa-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:7px;align-items:center;gap:7px;padding:6px 8px;font-size:12px;transition:background-color .12s;display:flex}.lc-fa-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-fa-form{opacity:.85;flex:none;justify-content:center;align-items:center;width:20px;height:14px;font-size:11px;display:flex}.lc-fa-lang{border-radius:4px;justify-content:center;align-items:center;min-width:16px;height:13px;padding:0 2px;font-size:8px;font-weight:700;line-height:1;display:inline-flex}.lc-fa-row .lc-br-chev{margin-right:-2px}.lc-fa-path{word-break:break-all;flex:1;min-width:0}.lc-fa-file{cursor:pointer}.lc-fa-file:hover{text-decoration:underline}.lc-fa-path em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-fa-badge{font-variant-numeric:tabular-nums;white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:1px 7px;font-size:11px;font-weight:600;display:inline-flex}.lc-fa-badge i{background:currentColor;border-radius:50%;width:5px;height:5px;display:inline-block}.lc-fa-b-read{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent)}.lc-fa-b-write{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent)}.lc-fa-b-search{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent)}.lc-fa-chip-read,.lc-fa-chip-read:hover{color:var(--dsw-alias-brand-primary)}.lc-fa-chip-write,.lc-fa-chip-write:hover{color:var(--dsw-alias-state-success-primary)}.lc-fa-chip-search,.lc-fa-chip-search:hover{color:var(--dsw-alias-state-warn-primary)}.lc-fa-chip-read.lc-gran-on,.lc-fa-chip-read.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);color:var(--dsw-alias-brand-primary)}.lc-fa-chip-write.lc-gran-on,.lc-fa-chip-write.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-fa-chip-search.lc-gran-on,.lc-fa-chip-search.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);color:var(--dsw-alias-state-warn-primary)}.lc-fa-delta{font-variant-numeric:tabular-nums;white-space:nowrap;flex:none;gap:5px;font-size:11px;font-weight:600;display:inline-flex}.lc-fa-up{color:var(--dsw-alias-state-success-primary)}.lc-fa-down{color:var(--dsw-alias-state-error-primary)}.lc-fa-time{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.lc-fa-ops{border-left:2px solid var(--dsw-alias-border-l1);flex-direction:column;gap:1px;margin:0 8px 8px 15px;padding:2px 0 2px 10px;display:flex}.lc-fa-op{min-width:0;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;background:0 0;border:0;border-radius:5px;align-items:center;gap:8px;padding:3px 6px;font-size:11px;transition:background-color .12s;display:flex}.lc-fa-op-link{cursor:pointer}.lc-fa-op-link:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-fa-op-time{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto}.lc-fa-op-tool{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:0 6px;font-size:11px}.lc-fa-op-detail{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;overflow:hidden}.lc-fa-read{color:var(--dsw-alias-brand-primary);font-variant-numeric:tabular-nums;white-space:nowrap;flex:none;font-size:11px;font-weight:600}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-retry{color:var(--dsw-alias-brand-primary);font:inherit;cursor:pointer;text-underline-offset:2px;background:0 0;border:0;padding:0;font-size:12px;text-decoration:underline}.lc-br-retry:hover{filter:brightness(1.15)}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:flex}.lc-br-chev:before{content:\"\";border-bottom:1px solid;border-right:1px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)}.lc-br-chev-on:before{transform:rotate(45deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-err-dot{background:var(--dsw-alias-state-error-primary);width:6px;height:6px;box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-radius:50%;flex:none}.lc-br-tag{min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-tool-plugin{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);border-color:#0000;border-radius:6px;font-size:12px}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;min-width:0;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.lc-ts-card-count{margin-left:auto}.lc-ts-card-right{align-items:center;gap:8px;margin-left:auto;display:inline-flex}.lc-ts-card-meta{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:11px;font-weight:400}.lc-ts-call-state{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:2px 7px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;font-weight:600;line-height:1;display:inline-flex}.lc-ts-call-state i{background:currentColor;border-radius:50%;flex:none;width:6px;height:6px}.lc-ts-call-ok{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.lc-ts-call-err{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,140px) minmax(0,90px) 56px minmax(0,1fr);align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;overflow-wrap:anywhere;white-space:pre-line;scrollbar-width:thin;min-width:0;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow:hidden auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p{margin:6px 0}.lc-ts-desc-md div pre{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}.lc-att-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:8px 10px;display:grid}.lc-att-item{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);width:100%;min-width:0;font:inherit;text-align:left;cursor:pointer;background:0 0;border-radius:8px;align-items:center;gap:8px;padding:6px;display:flex}.lc-att-item:hover{border-color:var(--dsw-alias-border-l2,var(--dsw-alias-border-l1));background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;flex:none;justify-content:center;align-items:center;width:64px;height:64px;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;word-break:break-word;font-size:12px;line-height:1.3}.lc-att-row{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:11px}.lc-att-row-label{min-width:3.2em;font-weight:400;display:inline-block}.lc-att-lightbox{z-index:1000;place-items:center;padding:40px;display:grid;position:fixed;inset:0}.lc-att-lightbox-mask{background:var(--dsw-alias-bg-mask-1,#00000073);backdrop-filter:var(--dsw-mask-blur,blur(2px));position:absolute;inset:0}.lc-att-lightbox-img{object-fit:contain;background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));max-width:min(100%,1600px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);border-radius:12px;position:relative}.lc-att-lightbox-close{z-index:1;border:1px solid var(--dsw-alias-border-l2-darkmode-thin,var(--dsw-alias-border-l1));background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));width:36px;height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:999px;place-items:center;padding:0;display:grid;position:fixed;top:20px;right:20px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}.lc-agents-chips{flex-wrap:wrap;gap:6px;margin-bottom:10px;display:flex}.lc-agents-chip{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;border-radius:999px;padding:2px 8px;font-size:11px}.lc-agents-chip-on{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent)}.lc-agents-stage{margin:0 -4px;padding:0 4px;overflow-x:auto}.lc-agents-svg{max-width:none;margin:0 auto;display:block}.lc-agents-link{stroke-width:1.5px;stroke-opacity:.45}.lc-agents-link-live{stroke-opacity:.85}.lc-agents-flow{stroke-width:2px;stroke-linecap:round;stroke-dasharray:2 7;animation:.9s linear infinite lc-agent-flow}@keyframes lc-agent-flow{to{stroke-dashoffset:-9px}}.lc-agent-node{outline:none}.lc-agent-clickable{cursor:pointer}.lc-agent-halo{fill:#0000;transition:fill .12s}.lc-agent-hover .lc-agent-halo,.lc-agent-node:focus-visible .lc-agent-halo{fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.lc-agent-self .lc-agent-halo{fill:var(--dsw-alias-bg-layer-2)}.lc-agent-running .lc-agent-halo{fill:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent);animation:1.8s ease-in-out infinite lc-agent-glow}.lc-agent-done .lc-agent-halo{fill:color-mix(in srgb, var(--dsw-alias-state-success-primary) 7%, transparent)}@keyframes lc-agent-glow{0%,to{opacity:1}50%{opacity:.4}}.lc-agent-track{fill:var(--dsw-alias-bg-layer-1);stroke:var(--dsw-alias-border-l1);stroke-width:1.5px}.lc-agent-seg{fill:none;stroke-width:9px;transition:stroke-dasharray .3s,stroke-dashoffset .3s}.lc-agent-free{stroke:color-mix(in srgb, var(--dsw-alias-label-secondary) 18%, transparent)}.lc-agent-pct{fill:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;pointer-events:none;font-size:11px;font-weight:600}.lc-agent-caption{text-align:center;pointer-events:none;width:100%;line-height:1.25}.lc-agent-label{color:var(--dsw-alias-label-primary);overflow-wrap:break-word;-webkit-line-clamp:3;-webkit-box-orient:vertical;font-size:11px;display:-webkit-box;overflow:hidden}.lc-agent-tokens{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:10px}.lc-agents-solo{padding:4px 0 10px}.lc-agents-inspector{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;flex-wrap:wrap;align-items:baseline;gap:4px 8px;min-width:0;margin-top:10px;padding:7px 10px;font-size:12px;display:flex}.lc-agents-inspector-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}.lc-agents-badge{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 6px;font-size:10px}.lc-agent-self-badge{vertical-align:1px;margin-left:5px}.lc-agents-badge-on{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent)}.lc-agents-inspector-stats{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.lc-agents-inspector-open{color:var(--dsw-alias-brand-primary,#3b82f6);flex:none;margin-left:auto}.lc-agents-legend{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:11px;display:flex}.lc-agents-legend-item{align-items:center;gap:5px;display:inline-flex}.lc-agents-legend-item i{border-radius:2px;width:8px;height:8px}.lc-agents-legend-free{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 18%, transparent)}.lc-agents-legend-edge{border-top:2px dashed var(--dsw-alias-label-secondary);border-radius:0!important;width:14px!important;height:0!important}";
6108
+ const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}.lc-stats .lc-stat{padding:6px 3px}.lc-stats .lc-stat-q{margin:0;position:absolute;top:3px;right:4px}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-jump{width:calc(28px + var(--dsh-content-font-delta,0px));height:calc(28px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:28px;justify-content:center;align-items:center;padding:6px;display:inline-flex}.lc-jump svg{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px))}.lc-jump:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.lc-settings-card{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;transition:border-color .16s,background .16s}.lc-settings-card:hover{border-color:var(--dsw-alias-label-dimmed)}.lc-settings-open,.lc-settings-open:hover{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.lc-settings-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.lc-settings-headtext{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.lc-settings-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.lc-settings-desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.lc-settings-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.lc-settings-open .lc-settings-chevron{transform:rotate(180deg)}.lc-settings-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 12px}.lc-settings-row{align-items:center;gap:8px;padding:8px 0;display:flex}.lc-settings-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:14px}.lc-settings-select{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.lc-settings-select:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.lc-settings-select:disabled{opacity:.5;cursor:default}.lc-settings-note{color:var(--dsw-alias-label-tertiary);margin:12px 0 4px;font-size:12px;line-height:1.5}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-grid-zero{border-top-style:solid;border-top-color:#80808080}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;left:0;box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-cat-seg{transition:filter .12s,opacity .12s}.lc-chart[data-catdim] .lc-cat-seg{opacity:.35}.lc-chart[data-catdim=system] .lc-cat-seg[data-cat=system],.lc-chart[data-catdim=tools] .lc-cat-seg[data-cat=tools],.lc-chart[data-catdim=user] .lc-cat-seg[data-cat=user],.lc-chart[data-catdim=inject] .lc-cat-seg[data-cat=inject],.lc-chart[data-catdim=assistant] .lc-cat-seg[data-cat=assistant],.lc-chart[data-catdim=tool] .lc-cat-seg[data-cat=tool]{opacity:1;filter:brightness(1.18)}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{text-overflow:ellipsis;max-width:100%;display:inline-block;overflow:hidden}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px 8px;margin-bottom:10px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary);font-size:13px}.lc-detail-time{font-variant-numeric:tabular-nums;white-space:nowrap;margin-left:auto;font-size:12px}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-metric{font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);border-radius:6px;padding:2px 8px;font-size:12px;font-weight:600}.lc-detail-metric-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-detail-metric-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-detail-rows{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:4px 24px;margin-top:10px;display:grid}.lc-brief{flex-direction:column;gap:2px;min-height:76px;margin:-4px 0 10px;display:flex}.lc-brief-row{min-width:0;color:var(--dsw-alias-label-primary);text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;margin-left:-6px;margin-right:-6px;padding:3px 6px;font-family:inherit;font-size:12px;line-height:1.5;transition:background-color .12s;display:flex}.lc-brief-row-link:hover{background:var(--dsw-alias-interactive-bg-hover)}button.lc-brief-row-link{cursor:pointer}.lc-brief-tag{box-sizing:border-box;text-align:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);min-width:56px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;position:relative}.lc-brief-tip{z-index:6;white-space:normal;text-align:left;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:240px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-brief-tag:hover .lc-brief-tip{opacity:1}.lc-brief-text{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-brief-empty{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-tertiary);flex:1;overflow:hidden}.lc-brief-fact{box-sizing:border-box;text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:160px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;overflow:hidden}.lc-brief-chip{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);min-width:0;max-width:260px;color:var(--dsw-alias-label-primary);border-radius:5px;align-items:center;gap:5px;padding:0 7px;font-size:12px;transition:background-color .12s;display:inline-flex;overflow:hidden}.lc-brief-chip-grow{flex:1;max-width:none}.lc-brief-chip-tag{text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);max-width:120px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 6px;font-size:11px;overflow:hidden}.lc-brief-chip-text{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-brief-chip-link{cursor:pointer}.lc-brief-chip-link:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-brief-more{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-detail-row{border-radius:4px;align-items:center;gap:8px;margin:-1px -4px;padding:1px 4px;transition:background-color .12s;display:flex}.lc-detail-row i{transition:box-shadow .12s}.lc-detail-row-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-detail-row-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-detail-row-on .lc-detail-label{font-weight:600}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;position:relative;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-bar-zero{border-left:1px solid #80808073;position:absolute;top:0;bottom:0;left:50%}.lc-bar-fill-up,.lc-bar-fill-down{height:100%;display:block;position:absolute;top:0}.lc-bar-fill-up{border-radius:0 3px 3px 0;left:50%}.lc-bar-fill-down{border-radius:3px 0 0 3px;right:50%}.lc-detail-num{text-align:right;font-variant-numeric:tabular-nums;width:52px}.lc-detail-num-up{color:var(--dsw-alias-state-success-primary)}.lc-detail-num-down{color:var(--dsw-alias-state-error-primary)}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-col-browser{flex-direction:column;display:flex}.lc-col-browser>.lc-card{flex:1}.lc-head>.lc-card{flex:1 1 0;min-width:0}.lc-head>.lc-card:first-child{flex-direction:column;display:flex}.lc-head>.lc-card:first-child .lc-stats{flex:1;align-content:stretch}.lc-head>.lc-card:first-child .lc-stat{justify-content:center}.lc-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-donut-row{justify-content:flex-start;align-items:center;gap:12px;min-width:0;display:flex}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut-row .lc-sl{flex:auto}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:#8080802e}.lc-donut-center{pointer-events:none;text-align:center;box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:0 7px;display:flex;position:absolute;inset:0}.lc-donut-center b{white-space:nowrap;text-overflow:ellipsis;max-width:100%;line-height:1.15;overflow:hidden}.lc-donut-center span{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-sl{flex-direction:column;gap:5px;min-width:0;display:flex}.lc-sl-row{align-items:baseline;gap:6px;min-width:0;font-size:12px;display:flex}.lc-sl-dot{border-radius:2px;flex:none;align-self:flex-start;width:8px;height:8px;margin-top:2px}.lc-sl-label{flex:0 auto;min-width:80px;line-height:1.25;overflow:hidden}.lc-sl-count{text-align:right;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;flex:auto;overflow:hidden}.lc-sl-pct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:30px;font-weight:700}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row-btn{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;width:100%;padding:0}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-hint{text-decoration:none}.lc-pi-hint:hover{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-pi-row-btn .lc-pi-value{font-weight:400}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-event-icon.lc-event-mode{color:var(--dsw-alias-label-secondary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-kind-mode{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 15%, transparent);color:var(--dsw-alias-label-secondary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-fa-ctl,.lc-br-toolctl{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.lc-fa-ctl .lc-gran{margin-left:0}.lc-fa-n{opacity:.75;margin-left:4px;font-weight:700}.lc-fa-search,.lc-br-tool-search{min-width:80px;font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;outline:none;flex:1;padding:3px 8px;font-size:12px}.lc-fa-search:focus,.lc-br-tool-search:focus{border-color:var(--dsw-alias-label-dimmed)}.lc-fa-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:6px;font-size:12px;display:flex}.lc-fa-meta .lc-fa-sort{flex:none}.lc-fa-meta-delta{position:relative}.lc-fa-meta-tip{z-index:6;white-space:normal;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:260px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-fa-meta-delta:hover .lc-fa-meta-tip{opacity:1}.lc-fa-item{border:1px solid #0000;border-radius:8px;transition:background-color .12s,border-color .12s}.lc-fa-item-on{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l2)}.lc-fa-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:7px;align-items:center;gap:7px;padding:6px 8px;font-size:12px;transition:background-color .12s;display:flex}.lc-fa-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-fa-form{opacity:.85;flex:none;justify-content:center;align-items:center;width:20px;height:14px;font-size:11px;display:flex}.lc-fa-lang{border-radius:4px;justify-content:center;align-items:center;min-width:16px;height:13px;padding:0 2px;font-size:8px;font-weight:700;line-height:1;display:inline-flex}.lc-fa-row .lc-br-chev{margin-right:-2px}.lc-fa-path{word-break:break-all;flex:1;min-width:0}.lc-fa-file{cursor:pointer}.lc-fa-file:hover{text-decoration:underline}.lc-fa-path em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-fa-badge{font-variant-numeric:tabular-nums;white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:1px 7px;font-size:11px;font-weight:600;display:inline-flex}.lc-fa-badge i{background:currentColor;border-radius:50%;width:5px;height:5px;display:inline-block}.lc-fa-b-read{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent)}.lc-fa-b-write{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent)}.lc-fa-b-search{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent)}.lc-fa-chip-read,.lc-fa-chip-read:hover{color:var(--dsw-alias-brand-primary)}.lc-fa-chip-write,.lc-fa-chip-write:hover{color:var(--dsw-alias-state-success-primary)}.lc-fa-chip-search,.lc-fa-chip-search:hover{color:var(--dsw-alias-state-warn-primary)}.lc-fa-chip-read.lc-gran-on,.lc-fa-chip-read.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);color:var(--dsw-alias-brand-primary)}.lc-fa-chip-write.lc-gran-on,.lc-fa-chip-write.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-fa-chip-search.lc-gran-on,.lc-fa-chip-search.lc-gran-on:hover{background:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);color:var(--dsw-alias-state-warn-primary)}.lc-fa-delta{font-variant-numeric:tabular-nums;white-space:nowrap;flex:none;gap:5px;font-size:11px;font-weight:600;display:inline-flex}.lc-fa-up{color:var(--dsw-alias-state-success-primary)}.lc-fa-down{color:var(--dsw-alias-state-error-primary)}.lc-fa-time{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.lc-fa-ops{border-left:2px solid var(--dsw-alias-border-l1);flex-direction:column;gap:1px;margin:0 8px 8px 15px;padding:2px 0 2px 10px;display:flex}.lc-fa-op{min-width:0;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;background:0 0;border:0;border-radius:5px;align-items:center;gap:8px;padding:3px 6px;font-size:11px;transition:background-color .12s;display:flex}.lc-fa-op-link{cursor:pointer}.lc-fa-op-link:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-fa-op-time{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto}.lc-fa-op-tool{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:0 6px;font-size:11px}.lc-fa-op-detail{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;overflow:hidden}.lc-fa-read{color:var(--dsw-alias-brand-primary);font-variant-numeric:tabular-nums;white-space:nowrap;flex:none;font-size:11px;font-weight:600}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-retry{color:var(--dsw-alias-brand-primary);font:inherit;cursor:pointer;text-underline-offset:2px;background:0 0;border:0;padding:0;font-size:12px;text-decoration:underline}.lc-br-retry:hover{filter:brightness(1.15)}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:flex}.lc-br-chev:before{content:\"\";border-bottom:1px solid;border-right:1px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)}.lc-br-chev-on:before{transform:rotate(45deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-err-dot{background:var(--dsw-alias-state-error-primary);width:6px;height:6px;box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-radius:50%;flex:none}.lc-br-tag{min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-tool-plugin{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);border-color:#0000;border-radius:6px;font-size:12px}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;min-width:0;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.lc-ts-card-count{margin-left:auto}.lc-ts-card-right{align-items:center;gap:8px;margin-left:auto;display:inline-flex}.lc-ts-card-meta{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:11px;font-weight:400}.lc-ts-call-state{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:2px 7px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;font-weight:600;line-height:1;display:inline-flex}.lc-ts-call-state i{background:currentColor;border-radius:50%;flex:none;width:6px;height:6px}.lc-ts-call-ok{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.lc-ts-call-err{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-lines{counter-reset:lc-line}.lc-ts-line{padding-left:26px;display:block;position:relative}.lc-ts-line:before{content:counter(lc-line);counter-increment:lc-line;text-align:right;width:20px;color:var(--dsw-alias-label-tertiary);user-select:none;padding-right:6px;font-size:11px;position:absolute;left:0}.lc-ts-line:empty:after{content:\"​\"}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,140px) minmax(0,90px) 56px minmax(0,1fr);align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;overflow-wrap:anywhere;scrollbar-width:thin;min-width:0;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow:hidden auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p{white-space:pre-line;margin:6px 0}.lc-ts-desc-md div p br{display:none}.lc-ts-desc-md div pre{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}.lc-att-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:8px 10px;display:grid}.lc-att-item{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;min-width:0;font:inherit;text-align:left;cursor:pointer;background:0 0;border-radius:8px;align-items:center;gap:8px;padding:6px;display:flex}.lc-att-item:hover{border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;flex:none;justify-content:center;align-items:center;width:64px;height:64px;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;word-break:break-word;font-size:12px;line-height:1.3}.lc-att-row{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:11px}.lc-att-row-label{min-width:3.2em;font-weight:400;display:inline-block}.lc-att-lightbox{z-index:1000;place-items:center;padding:40px;display:grid;position:fixed;inset:0}.lc-att-lightbox-mask{background:var(--dsw-alias-bg-mask-1,#00000073);backdrop-filter:var(--dsw-mask-blur,blur(2px));position:absolute;inset:0}.lc-att-lightbox-img{object-fit:contain;background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));max-width:min(100%,1600px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);border-radius:12px;position:relative}.lc-att-lightbox-close{z-index:1;border:1px solid var(--dsw-alias-border-l2-darkmode-thin,var(--dsw-alias-border-l1));background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));width:36px;height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:999px;place-items:center;padding:0;display:grid;position:fixed;top:20px;right:20px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}.lc-agents-chips{flex-wrap:wrap;gap:6px;margin-bottom:10px;display:flex}.lc-agents-chip{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;border-radius:999px;padding:2px 8px;font-size:11px}.lc-agents-chip-on{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent)}.lc-agents-stage{margin:0 -4px;padding:0 4px;overflow-x:auto}.lc-agents-svg{max-width:none;margin:0 auto;display:block}.lc-agents-link{stroke-width:1.5px;stroke-opacity:.45}.lc-agents-link-live{stroke-opacity:.85}.lc-agents-flow{stroke-width:2px;stroke-linecap:round;stroke-dasharray:2 7;animation:.9s linear infinite lc-agent-flow}@keyframes lc-agent-flow{to{stroke-dashoffset:-9px}}.lc-agent-node{outline:none}.lc-agent-clickable{cursor:pointer}.lc-agent-halo{fill:#0000;transition:fill .12s}.lc-agent-hover .lc-agent-halo,.lc-agent-node:focus-visible .lc-agent-halo{fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.lc-agent-self .lc-agent-halo{fill:var(--dsw-alias-bg-layer-2)}.lc-agent-running .lc-agent-halo{fill:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent);animation:1.8s ease-in-out infinite lc-agent-glow}.lc-agent-done .lc-agent-halo{fill:color-mix(in srgb, var(--dsw-alias-state-success-primary) 7%, transparent)}@keyframes lc-agent-glow{0%,to{opacity:1}50%{opacity:.4}}.lc-agent-track{fill:var(--dsw-alias-bg-layer-1);stroke:var(--dsw-alias-border-l1);stroke-width:1.5px}.lc-agent-seg{fill:none;stroke-width:9px;transition:stroke-dasharray .3s,stroke-dashoffset .3s}.lc-agent-free{stroke:color-mix(in srgb, var(--dsw-alias-label-secondary) 18%, transparent)}.lc-agent-pct{fill:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;pointer-events:none;font-size:11px;font-weight:600}.lc-agent-caption{text-align:center;pointer-events:none;width:100%;line-height:1.25}.lc-agent-label{color:var(--dsw-alias-label-primary);overflow-wrap:break-word;-webkit-line-clamp:3;-webkit-box-orient:vertical;font-size:11px;display:-webkit-box;overflow:hidden}.lc-agent-tokens{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:10px}.lc-agents-solo{padding:4px 0 10px}.lc-agents-inspector{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;flex-wrap:wrap;align-items:baseline;gap:4px 8px;min-width:0;margin-top:10px;padding:7px 10px;font-size:12px;display:flex}.lc-agents-inspector-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}.lc-agents-badge{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 6px;font-size:10px}.lc-agent-self-badge{vertical-align:1px;margin-left:5px}.lc-agents-badge-on{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent)}.lc-agents-inspector-stats{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.lc-agents-inspector-open{color:var(--dsw-alias-brand-primary,#3b82f6);flex:none;margin-left:auto}.lc-agents-legend{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:11px;display:flex}.lc-agents-legend-item{align-items:center;gap:5px;display:inline-flex}.lc-agents-legend-item i{border-radius:2px;width:8px;height:8px}.lc-agents-legend-free{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 18%, transparent)}.lc-agents-legend-edge{border-top:2px dashed var(--dsw-alias-label-secondary);border-radius:0!important;width:14px!important;height:0!important}";
5483
6109
  const tagId = "dsh-context/styles.css";
5484
6110
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
5485
6111
  const tag = document.createElement("style");
@@ -5533,6 +6159,15 @@ window.__ModuleLoader__.load({
5533
6159
  label: () => t("tab")
5534
6160
  }, (props) => h(ContextView, props));
5535
6161
  });
6162
+ const ContextJump = makeContextJumpButton(kit);
6163
+ ctx.slots.inject("conversation.chat.assistant-actions", () => {
6164
+ return ctx.slots.register({
6165
+ name: "conversation.chat.assistant-actions",
6166
+ id: "context-jump",
6167
+ order: 20,
6168
+ locale: NS
6169
+ }, (props) => h(ContextJump, props));
6170
+ });
5536
6171
  registerContextCommand(ctx, kit);
5537
6172
  const ContextModal = makeContextModal(ctx, kit);
5538
6173
  ctx.slots.inject("conversation.input.overlay", () => {