dsh-context 0.60.0 → 0.62.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
@@ -83,6 +83,7 @@ window.__ModuleLoader__.load({
83
83
  "timing.empty": "暂无耗时数据 · 对话开始后这里会显示时长分布",
84
84
  "timing.tps": "{tps} tok/s",
85
85
  "timing.tpsTip": "输出速度(TPS):累计解码输出 tokens ÷ 累计解码时长,与 DeepSeek Harness 会话统计同口径。",
86
+ "timing.strip": "耗时时间轴:各段按发生次序紧凑铺排,宽度为耗时占比,刻度为零、四分位与全程",
86
87
  "tokens.title": "Token 统计",
87
88
  "tokens.total": "总用量",
88
89
  "tokens.output": "输出",
@@ -119,6 +120,9 @@ window.__ModuleLoader__.load({
119
120
  "trend.focus": "仅展示 {cat}",
120
121
  "trend.adaptive": "自适应",
121
122
  "trend.adaptiveHint": "按当前可视范围内的柱子重新缩放高度,滚动时随之变化",
123
+ "trend.dna": "DNA 模式",
124
+ "trend.dnaTip": "把每根柱子画成该次请求的上下文指纹:按模型读取顺序逐条铺色,配合增量模式逐条展示每次请求的增减;悬停查看条目,点击让上下文浏览器定位到该条目,同一条目在所有柱子中亮出其存续变化",
125
+ "trend.dnaItem": "{label}:{n}",
122
126
  "trend.empty": "发起一轮对话后,这里会展示每次模型请求的上下文构成",
123
127
  "detail.step": "第 {t} 轮 · 第 {s} 步 (共 {n} 步)",
124
128
  "detail.turn": "第 {t} 轮 · 共 {n} 步",
@@ -477,6 +481,7 @@ window.__ModuleLoader__.load({
477
481
  "timing.empty": "No timing data yet — durations appear as the conversation runs",
478
482
  "timing.tps": "{tps} tok/s",
479
483
  "timing.tpsTip": "Output speed (TPS): summed decoded output tokens over summed decode time — the same pairing as the harness session stats.",
484
+ "timing.strip": "Session-time strip: slices packed in occurrence order, width as share of the active time; ticks at zero, the quartiles, and the full span",
480
485
  "tokens.title": "Token Stats",
481
486
  "tokens.total": "Total",
482
487
  "tokens.output": "Output",
@@ -513,6 +518,9 @@ window.__ModuleLoader__.load({
513
518
  "trend.focus": "Showing {cat} only",
514
519
  "trend.adaptive": "Adaptive",
515
520
  "trend.adaptiveHint": "Rescale bar heights to the visible range, following the scroll",
521
+ "trend.dna": "DNA Mode",
522
+ "trend.dnaTip": "Draw each bar as that request’s context fingerprint — one band per item in the order the model reads it; with Delta, each band shows that item’s change against the previous bar. Hover for the item, click to reveal it in the Context browser, and every bar lights the same item’s lifetime",
523
+ "trend.dnaItem": "{label}: {n}",
516
524
  "trend.empty": "Send a message and each model request’s context makeup shows up here",
517
525
  "detail.step": "Turn {t} · Step {s} of {n}",
518
526
  "detail.turn": "Turn {t} · {n} steps",
@@ -832,13 +840,19 @@ window.__ModuleLoader__.load({
832
840
  * package.json `icon` hands to the Host's package-meta reader, which serves
833
841
  * it to the Plugins page's package cards. The client bundle inlines the
834
842
  * file's markup at build time (the `?raw` channel in tsdown.config.ts) and
835
- * re-renders it at every requested size. Fixed fills, never `currentColor` —
836
- * the sheet is deliberately polychrome on both light and dark chrome.
843
+ * re-renders it at every requested size. The identity seats (tab chip,
844
+ * command, sidebar registration, panel head) keep the sheet's fixed fills —
845
+ * deliberately polychrome on both light and dark chrome — while the
846
+ * sidebar-foot entry seat (overviewButton.tsx) opts into `mono`, trading
847
+ * every fill for `currentColor` so the glyph sits quietly beside the
848
+ * harness's own footer rows (Settings and friends).
837
849
  */
838
850
  /** Everything between the file's `<svg>` tags: the sheet's strokes in paint order, whitespace-folded. */
839
851
  const SHEET_MARKUP = icon_default.slice(icon_default.indexOf(">") + 1, icon_default.lastIndexOf("</svg>")).trim().replace(/>\s+</g, "><");
840
- /** The colourful document sheet at the requested square edge. */
841
- function ContextIcon({ size = 20, className }) {
852
+ /** The mono seat's strokes: same geometry, every palette fill traded for the surrounding text colour. */
853
+ const SHEET_MARKUP_MONO = SHEET_MARKUP.replace(/fill="#[0-9A-Fa-f]{6}"/g, "fill=\"currentColor\"");
854
+ /** The document sheet at the requested square edge — polychrome by default, text-coloured in `mono`. */
855
+ function ContextIcon({ size = 20, className, mono = false }) {
842
856
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
843
857
  width: size,
844
858
  height: size,
@@ -846,7 +860,7 @@ window.__ModuleLoader__.load({
846
860
  className,
847
861
  "aria-hidden": "true",
848
862
  xmlns: "http://www.w3.org/2000/svg",
849
- dangerouslySetInnerHTML: { __html: SHEET_MARKUP }
863
+ dangerouslySetInnerHTML: { __html: mono ? SHEET_MARKUP_MONO : SHEET_MARKUP }
850
864
  });
851
865
  }
852
866
  /**
@@ -1364,7 +1378,8 @@ window.__ModuleLoader__.load({
1364
1378
  ...typeof data.surfaceFloor === "number" ? { surfaceFloor: data.surfaceFloor } : {},
1365
1379
  ...typeof data.archiveFloor === "number" ? { archiveFloor: data.archiveFloor } : {},
1366
1380
  ...data.fileOps !== void 0 ? { fileOps: objectsOf(data.fileOps) } : {},
1367
- ...typeof data.fileOpsFloor === "number" ? { fileOpsFloor: data.fileOpsFloor } : {}
1381
+ ...typeof data.fileOpsFloor === "number" ? { fileOpsFloor: data.fileOpsFloor } : {},
1382
+ ...data.spans !== void 0 ? { spans: objectsOf(data.spans) } : {}
1368
1383
  };
1369
1384
  }
1370
1385
  /**
@@ -2226,7 +2241,8 @@ window.__ModuleLoader__.load({
2226
2241
  ...typeof data.surfaceFloor === "number" ? { surfaceFloor: data.surfaceFloor } : {},
2227
2242
  ...typeof data.archiveFloor === "number" ? { archiveFloor: data.archiveFloor } : {},
2228
2243
  ...data.fileOps !== void 0 ? { fileOps: objectsOf(data.fileOps) } : {},
2229
- ...typeof data.fileOpsFloor === "number" ? { fileOpsFloor: data.fileOpsFloor } : {}
2244
+ ...typeof data.fileOpsFloor === "number" ? { fileOpsFloor: data.fileOpsFloor } : {},
2245
+ ...data.spans !== void 0 ? { spans: objectsOf(data.spans) } : {}
2230
2246
  };
2231
2247
  }
2232
2248
  /**
@@ -2434,7 +2450,8 @@ window.__ModuleLoader__.load({
2434
2450
  ...detail.surfaceFloor !== void 0 ? { surfaceFloor: detail.surfaceFloor } : {},
2435
2451
  ...detail.archiveFloor !== void 0 ? { archiveFloor: detail.archiveFloor } : {},
2436
2452
  ...detail.fileOps !== void 0 ? { fileOps: detail.fileOps } : {},
2437
- ...detail.fileOpsFloor !== void 0 ? { fileOpsFloor: detail.fileOpsFloor } : {}
2453
+ ...detail.fileOpsFloor !== void 0 ? { fileOpsFloor: detail.fileOpsFloor } : {},
2454
+ ...detail.spans !== void 0 ? { spans: detail.spans } : {}
2438
2455
  },
2439
2456
  detailState: "ready",
2440
2457
  retryDetail: retry
@@ -2530,6 +2547,102 @@ window.__ModuleLoader__.load({
2530
2547
  });
2531
2548
  return items;
2532
2549
  }
2550
+ /** The per-bar bands behind a trend chart bar: read order, category colors, cumulative offsets. */
2551
+ function trendBandsOf(view) {
2552
+ const bands = [];
2553
+ let off = 0;
2554
+ for (const it of dnaOf(view)) {
2555
+ if ("node" in it) bands.push({
2556
+ key: it.key,
2557
+ cat: it.cat,
2558
+ tokens: it.tokens,
2559
+ off,
2560
+ color: CAT_COLOR[it.cat],
2561
+ node: it.node
2562
+ });
2563
+ else bands.push({
2564
+ key: it.key,
2565
+ cat: it.cat,
2566
+ tokens: it.tokens,
2567
+ off,
2568
+ color: CAT_COLOR[it.cat]
2569
+ });
2570
+ off += it.tokens;
2571
+ }
2572
+ return bands;
2573
+ }
2574
+ function deltaBandsOf(bands, prev) {
2575
+ if (prev === null) return {
2576
+ up: [],
2577
+ down: []
2578
+ };
2579
+ const before = new Map(prev.map((b) => [b.key, b.tokens]));
2580
+ const after = new Map(bands.map((b) => [b.key, b.tokens]));
2581
+ const up = [];
2582
+ const down = [];
2583
+ for (const b of bands) {
2584
+ const d = b.tokens - (before.get(b.key) ?? 0);
2585
+ if (d <= 0) continue;
2586
+ up.push("node" in b ? {
2587
+ key: b.key,
2588
+ cat: b.cat,
2589
+ tokens: d,
2590
+ off: 0,
2591
+ color: b.color,
2592
+ node: b.node
2593
+ } : {
2594
+ key: b.key,
2595
+ cat: b.cat,
2596
+ tokens: d,
2597
+ off: 0,
2598
+ color: b.color
2599
+ });
2600
+ }
2601
+ for (const b of prev) {
2602
+ const d = (after.get(b.key) ?? 0) - b.tokens;
2603
+ if (d >= 0) continue;
2604
+ down.push("node" in b ? {
2605
+ key: b.key,
2606
+ cat: b.cat,
2607
+ tokens: d,
2608
+ off: 0,
2609
+ color: b.color,
2610
+ node: b.node
2611
+ } : {
2612
+ key: b.key,
2613
+ cat: b.cat,
2614
+ tokens: d,
2615
+ off: 0,
2616
+ color: b.color
2617
+ });
2618
+ }
2619
+ let u = 0;
2620
+ for (const x of up) {
2621
+ x.off = u;
2622
+ u += x.tokens;
2623
+ }
2624
+ let dn = 0;
2625
+ for (const x of down) {
2626
+ x.off = dn;
2627
+ dn -= x.tokens;
2628
+ }
2629
+ return {
2630
+ up,
2631
+ down
2632
+ };
2633
+ }
2634
+ /**
2635
+ * The compact item name both DNA surfaces share — the browser appends the
2636
+ * item's time on top of it for its own tooltip, the trend chart does not.
2637
+ * Header bands name the system prompt / the tool schema; message bands name
2638
+ * the item the way its browser row would (skill name, tool name, injection
2639
+ * form, else the category label).
2640
+ */
2641
+ function dnaBaseLabel(b, t, catLabel) {
2642
+ if (!("node" in b)) return b.cat === "system" ? catLabel("system") : b.key.slice(5);
2643
+ const n = b.node;
2644
+ return n.skill !== void 0 ? t("node.skillTag", { name: n.skill }) : n.cat === "tool" ? n.tool ?? "?" : n.cat === "inject" ? t("form." + (n.form || "context")) : catLabel(n.cat);
2645
+ }
2533
2646
  //#endregion
2534
2647
  //#region src/shared/fileOps.ts
2535
2648
  /** Parse a call's raw JSON arguments; non-string/malformed/non-record inputs yield null. */
@@ -2999,6 +3112,124 @@ window.__ModuleLoader__.load({
2999
3112
  out.net = net;
3000
3113
  return out;
3001
3114
  };
3115
+ const DnaBar = function DnaBar(props) {
3116
+ const visible = [];
3117
+ for (const b of props.bands) if (b.tokens > 0) visible.push(b);
3118
+ if (visible.length === 0) return null;
3119
+ const runs = [];
3120
+ for (const b of visible) {
3121
+ const from = Math.round(b.off / props.total * 1e4) / 100;
3122
+ const to = Math.round((b.off + b.tokens) / props.total * 1e4) / 100;
3123
+ const last = runs.length > 0 ? runs[runs.length - 1] : null;
3124
+ if (last !== null && last.color === b.color && last.to === from) last.to = to;
3125
+ else runs.push({
3126
+ color: b.color,
3127
+ from,
3128
+ to
3129
+ });
3130
+ }
3131
+ const hitAt = (e) => {
3132
+ const rect = e.currentTarget.getBoundingClientRect();
3133
+ const pos = (rect.height > 0 ? Math.min(1, Math.max(0, 1 - (e.clientY - rect.top) / rect.height)) : 0) * props.total;
3134
+ let hit = visible[0];
3135
+ for (const b of props.bands) {
3136
+ if (b.off > pos) break;
3137
+ if (b.tokens > 0) hit = b;
3138
+ }
3139
+ return hit;
3140
+ };
3141
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3142
+ className: "lc-bar-dna animate-lc-bar-in motion-reduce:animate-none",
3143
+ style: {
3144
+ height: `${Math.max(1, Math.round(props.total / props.maxTotal * CHART_H))}px`,
3145
+ background: "linear-gradient(to top, " + runs.map((r) => `${r.color} ${r.from}%, ${r.color} ${r.to}%`).join(", ") + ")",
3146
+ "--lc-i": Math.min(props.enterIndex, STAGGER_CAP)
3147
+ },
3148
+ onMouseMove: (e) => {
3149
+ props.onHit(hitAt(e).key);
3150
+ },
3151
+ onMouseLeave: () => {
3152
+ props.onHit(null);
3153
+ },
3154
+ onClick: (e) => {
3155
+ if (props.onPick !== void 0) props.onPick(props.seq, hitAt(e));
3156
+ }
3157
+ });
3158
+ };
3159
+ const DnaDeltaBar = function DnaDeltaBar(props) {
3160
+ let upSum = 0;
3161
+ for (const b of props.d.up) upSum += b.tokens;
3162
+ let downSum = 0;
3163
+ for (const b of props.d.down) downSum -= b.tokens;
3164
+ const gradSpan = upSum + downSum;
3165
+ if (gradSpan === 0) return null;
3166
+ const runs = [];
3167
+ const pushRun = (color, mag, at) => {
3168
+ const from = Math.round(at / gradSpan * 1e4) / 100;
3169
+ const to = Math.round((at + mag) / gradSpan * 1e4) / 100;
3170
+ const last = runs.length > 0 ? runs[runs.length - 1] : null;
3171
+ if (last !== null && last.color === color && last.to === from) last.to = to;
3172
+ else runs.push({
3173
+ color,
3174
+ from,
3175
+ to
3176
+ });
3177
+ return at + mag;
3178
+ };
3179
+ let acc = 0;
3180
+ for (let i = props.d.down.length - 1; i >= 0; i--) acc = pushRun(props.d.down[i].color, -props.d.down[i].tokens, acc);
3181
+ for (const b of props.d.up) acc = pushRun(b.color, b.tokens, acc);
3182
+ const height = Math.max(1, Math.round(gradSpan * props.scale));
3183
+ const hitAt = (e) => {
3184
+ const rect = e.currentTarget.getBoundingClientRect();
3185
+ const pos = (rect.height > 0 ? Math.min(1, Math.max(0, 1 - (e.clientY - rect.top) / rect.height)) : 0) * gradSpan - downSum;
3186
+ const useUp = pos >= 0 && props.d.up.length > 0;
3187
+ const arm = useUp ? props.d.up : props.d.down;
3188
+ const p = useUp ? pos : -pos;
3189
+ let hit = arm[0];
3190
+ for (const b of arm) {
3191
+ if (b.off > p) break;
3192
+ hit = b;
3193
+ }
3194
+ return hit;
3195
+ };
3196
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3197
+ className: "lc-bar-dna animate-lc-bar-in motion-reduce:animate-none",
3198
+ style: {
3199
+ position: "absolute",
3200
+ bottom: `${Math.round(props.zeroBottom - downSum * props.scale)}px`,
3201
+ height: `${height}px`,
3202
+ background: "linear-gradient(to top, " + runs.map((r) => `${r.color} ${r.from}%, ${r.color} ${r.to}%`).join(", ") + ")",
3203
+ transformOrigin: `50% ${Math.round(downSum / gradSpan * 1e4) / 100}%`,
3204
+ "--lc-i": Math.min(props.enterIndex, STAGGER_CAP)
3205
+ },
3206
+ onMouseMove: (e) => {
3207
+ props.onHit(hitAt(e).key);
3208
+ },
3209
+ onMouseLeave: () => {
3210
+ props.onHit(null);
3211
+ },
3212
+ onClick: (e) => {
3213
+ if (props.onPick !== void 0) props.onPick(props.seq, hitAt(e));
3214
+ }
3215
+ });
3216
+ };
3217
+ const DnaHighlights = (0, react.memo)(function DnaHighlights(props) {
3218
+ if (props.slices === null) return null;
3219
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3220
+ className: "lc-dna-hl",
3221
+ children: props.slices.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3222
+ className: "lc-dna-cell",
3223
+ children: s !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3224
+ className: "lc-dna-slice",
3225
+ style: {
3226
+ bottom: `${s.bottom}px`,
3227
+ height: `${s.height}px`
3228
+ }
3229
+ }) : null
3230
+ }, i))
3231
+ });
3232
+ });
3002
3233
  const ChartBar = (0, react.memo)(function ChartBar(props) {
3003
3234
  const { req, marker } = props;
3004
3235
  const markerAt = marker !== void 0 ? eventAt(marker) : null;
@@ -3028,7 +3259,23 @@ window.__ModuleLoader__.load({
3028
3259
  title: "✂ " + (markerAt !== null ? markerAt + " — " : "") + eventLabel(marker),
3029
3260
  children: "✂"
3030
3261
  }) : null,
3031
- diverge ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3262
+ props.dna !== null ? props.dnaDelta !== null && props.dnaScale !== void 0 && props.zeroBottom !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaDeltaBar, {
3263
+ d: props.dnaDelta,
3264
+ scale: props.dnaScale,
3265
+ zeroBottom: props.zeroBottom,
3266
+ enterIndex: props.enterIndex,
3267
+ seq: req.seq,
3268
+ onHit: props.onDnaHit,
3269
+ onPick: props.onPickBand
3270
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaBar, {
3271
+ bands: props.dna,
3272
+ total: req.total,
3273
+ maxTotal: props.maxTotal,
3274
+ enterIndex: props.enterIndex,
3275
+ seq: req.seq,
3276
+ onHit: props.onDnaHit,
3277
+ onPick: props.onPickBand
3278
+ }) : diverge ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3032
3279
  className: "lc-bar-up animate-lc-bar-in motion-reduce:animate-none",
3033
3280
  style: {
3034
3281
  bottom: `${props.downPx}px`,
@@ -3084,8 +3331,13 @@ window.__ModuleLoader__.load({
3084
3331
  });
3085
3332
  });
3086
3333
  return function TrendChart(props) {
3334
+ const dnaBands = props.dna ?? null;
3335
+ const dnaOn = dnaBands !== null;
3087
3336
  const delta = props.mode === "delta";
3088
- const focus = props.focusCat !== null && props.focusCat !== void 0 && CATS.some((c) => c.key === props.focusCat) ? props.focusCat : null;
3337
+ const dnaDeltaOn = dnaOn && delta;
3338
+ const focus = !dnaOn && props.focusCat !== null && props.focusCat !== void 0 && CATS.some((c) => c.key === props.focusCat) ? props.focusCat : null;
3339
+ const [dnaHit, setDnaHit] = (0, react.useState)(null);
3340
+ const dnaDeltas = (0, react.useMemo)(() => dnaDeltaOn ? dnaBands.map((bands, i) => deltaBandsOf(bands, i > 0 ? dnaBands[i - 1] : null)) : null, [dnaDeltaOn, dnaBands]);
3089
3341
  const requests = (0, react.useMemo)(() => {
3090
3342
  const base = focus !== null ? props.requests.map((req) => focusOf(req, focus)) : props.requests;
3091
3343
  return delta ? base.map((req, i) => deltaOf(req, i > 0 ? base[i - 1] : null)) : base;
@@ -3113,7 +3365,14 @@ window.__ModuleLoader__.load({
3113
3365
  const col = i * pitch;
3114
3366
  if (col >= vr || col + BAR_W <= sl) continue;
3115
3367
  const req = requests[i];
3116
- if (delta) {
3368
+ if (dnaDeltaOn && dnaDeltas !== null) {
3369
+ let bu = 0;
3370
+ let bd = 0;
3371
+ for (const b of dnaDeltas[i].up) bu += b.tokens;
3372
+ for (const b of dnaDeltas[i].down) bd -= b.tokens;
3373
+ if (bu > up) up = bu;
3374
+ if (bd > down) down = bd;
3375
+ } else if (delta) {
3117
3376
  let bu = 0;
3118
3377
  let bd = 0;
3119
3378
  for (const c of CATS) {
@@ -3134,7 +3393,15 @@ window.__ModuleLoader__.load({
3134
3393
  let maxTotal = 1;
3135
3394
  let maxUp = 0;
3136
3395
  let maxDown = 0;
3137
- if (delta) for (const req of requests) {
3396
+ if (dnaDeltaOn && dnaDeltas !== null) for (const d of dnaDeltas) {
3397
+ let up = 0;
3398
+ let down = 0;
3399
+ for (const b of d.up) up += b.tokens;
3400
+ for (const b of d.down) down -= b.tokens;
3401
+ if (up > maxUp) maxUp = up;
3402
+ if (down > maxDown) maxDown = down;
3403
+ }
3404
+ else if (delta) for (const req of requests) {
3138
3405
  let up = 0;
3139
3406
  let down = 0;
3140
3407
  for (const c of CATS) {
@@ -3278,7 +3545,8 @@ window.__ModuleLoader__.load({
3278
3545
  props.granularity,
3279
3546
  props.focusTurn,
3280
3547
  requests,
3281
- adaptive
3548
+ adaptive,
3549
+ dnaDeltaOn
3282
3550
  ]);
3283
3551
  const measureRef = (0, react.useRef)(measureVisible);
3284
3552
  (0, react.useLayoutEffect)(() => {
@@ -3306,6 +3574,45 @@ window.__ModuleLoader__.load({
3306
3574
  return containHorizontalOverscroll(el);
3307
3575
  }, []);
3308
3576
  const stepsOf = (0, react.useMemo)(() => turnStepsOf(props.requests), [props.requests]);
3577
+ const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
3578
+ const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
3579
+ const hoveredBands = dnaOn && !dnaDeltaOn && hoveredIdx >= 0 ? dnaBands[hoveredIdx] : null;
3580
+ const hitBand = hoveredBands !== null && dnaHit !== null ? hoveredBands.find((b) => b.key === dnaHit && b.tokens > 0) ?? null : null;
3581
+ const hoveredDelta = dnaDeltaOn && hoveredIdx >= 0 && dnaDeltas !== null ? dnaDeltas[hoveredIdx].up.find((b) => b.key === dnaHit) ?? dnaDeltas[hoveredIdx].down.find((b) => b.key === dnaHit) ?? null : null;
3582
+ const dnaSlices = (0, react.useMemo)(() => {
3583
+ if (!dnaOn || dnaHit === null) return null;
3584
+ const slices = [];
3585
+ if (dnaDeltaOn && dnaDeltas !== null) for (const d of dnaDeltas) {
3586
+ const hit = d.up.find((b) => b.key === dnaHit) ?? d.down.find((b) => b.key === dnaHit) ?? null;
3587
+ if (hit === null) {
3588
+ slices.push(null);
3589
+ continue;
3590
+ }
3591
+ const mag = Math.abs(hit.tokens);
3592
+ const edge = hit.tokens > 0 ? downPx + hit.off * deltaScale : downPx - (hit.off + mag) * deltaScale;
3593
+ slices.push({
3594
+ bottom: Math.round(edge),
3595
+ height: Math.max(1, Math.round(mag * deltaScale))
3596
+ });
3597
+ }
3598
+ else for (const bands of dnaBands) {
3599
+ const hit = bands.find((b) => b.key === dnaHit && b.tokens > 0) ?? null;
3600
+ slices.push(hit === null ? null : {
3601
+ bottom: Math.round(hit.off / maxTotal * CHART_H),
3602
+ height: Math.max(1, Math.round(hit.tokens / maxTotal * CHART_H))
3603
+ });
3604
+ }
3605
+ return slices;
3606
+ }, [
3607
+ dnaOn,
3608
+ dnaHit,
3609
+ dnaDeltaOn,
3610
+ dnaDeltas,
3611
+ dnaBands,
3612
+ downPx,
3613
+ deltaScale,
3614
+ maxTotal
3615
+ ]);
3309
3616
  const tipRowsOf = (req) => {
3310
3617
  const n = req.stepCount ?? 1;
3311
3618
  const head = props.granularity === "turn" ? n > 1 ? t("tip.turn", {
@@ -3316,19 +3623,20 @@ window.__ModuleLoader__.load({
3316
3623
  s: req.step ?? 0,
3317
3624
  n: stepsOf(req.turn)
3318
3625
  });
3319
- if (delta) {
3320
- /* v8 ignore next 1 -- delta mode only receives records from
3321
- deltaOf, which always assigns net; the fallback is defensive. */
3322
- const n = req.net ?? 0;
3323
- return [head, t("tip.delta", { n: (n > 0 ? "+" : "") + fmt(n) })];
3324
- }
3626
+ const band = hitBand ?? hoveredDelta;
3627
+ if (band !== null) return [head, t("trend.dnaItem", {
3628
+ label: dnaBaseLabel(band, t, catLabel),
3629
+ n: dnaDeltaOn ? fmtSigned(band.tokens) : fmt(band.tokens)
3630
+ })];
3631
+ if (delta)
3632
+ /* v8 ignore next 1 -- delta mode only receives records from
3633
+ deltaOf, which always assigns net; the fallback is defensive. */
3634
+ return [head, t("tip.delta", { n: fmtSigned(req.net ?? 0) })];
3325
3635
  return [head, focus !== null ? t("tip.cat", {
3326
3636
  cat: catLabel(focus),
3327
3637
  n: fmt(req.total)
3328
3638
  }) : t("tip.total", { n: fmt(req.total) })];
3329
3639
  };
3330
- const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
3331
- const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
3332
3640
  const tipColRef = (0, react.useRef)(0);
3333
3641
  /**
3334
3642
  * Glue the hover tip to its bar's VISIBLE slice. The tip deliberately does NOT live inside the scrolling
@@ -3418,6 +3726,7 @@ window.__ModuleLoader__.load({
3418
3726
  "data-catdim": props.hoverCat ?? void 0,
3419
3727
  onMouseLeave: () => {
3420
3728
  props.onHover(null);
3729
+ setDnaHit(null);
3421
3730
  },
3422
3731
  children: [
3423
3732
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "lc-grid lc-grid-top" }),
@@ -3440,9 +3749,16 @@ window.__ModuleLoader__.load({
3440
3749
  downPx: delta ? downPx : void 0,
3441
3750
  deltaScale: delta ? deltaScale : void 0,
3442
3751
  enterIndex: i,
3752
+ dna: dnaOn ? dnaBands[i] : null,
3753
+ dnaDelta: dnaDeltaOn && dnaDeltas !== null ? dnaDeltas[i] : null,
3754
+ dnaScale: dnaDeltaOn ? deltaScale : void 0,
3755
+ zeroBottom: dnaDeltaOn ? downPx : void 0,
3756
+ onDnaHit: setDnaHit,
3757
+ onPickBand: props.onPickBand,
3443
3758
  onSelect: props.onSelect,
3444
3759
  onHover: props.onHover
3445
- }, `${req.seq}:${props.granularity}`))
3760
+ }, `${req.seq}:${props.granularity}`)),
3761
+ dnaOn ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaHighlights, { slices: dnaSlices }) : null
3446
3762
  ]
3447
3763
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3448
3764
  className: "lc-turns",
@@ -4609,7 +4925,15 @@ window.__ModuleLoader__.load({
4609
4925
  const [rowQuery, setRowQuery] = (0, react.useState)("");
4610
4926
  const [rowKind, setRowKind] = (0, react.useState)(null);
4611
4927
  const [toolSort, setToolSort] = (0, react.useState)(() => settings.defaultToolSort());
4612
- const [dna, setDna] = (0, react.useState)(false);
4928
+ const [dnaLocal, setDnaLocal] = (0, react.useState)(false);
4929
+ const dnaLinked = props.dna !== void 0 && props.onDnaChange !== void 0;
4930
+ const dna = dnaLinked ? props.dna === true : dnaLocal;
4931
+ const setDna = (on) => {
4932
+ if (dnaLinked)
4933
+ /* v8 ignore next 1 -- `dnaLinked` requires both props, so the handler is always present. */
4934
+ props.onDnaChange?.(on);
4935
+ else setDnaLocal(on);
4936
+ };
4613
4937
  const [dnaKey, setDnaKey] = (0, react.useState)(null);
4614
4938
  const [deltaBase, setDeltaBase] = (0, react.useState)(() => settings.defaultDeltaBase());
4615
4939
  const onOpenCat = props.onOpenCat;
@@ -4645,7 +4969,9 @@ window.__ModuleLoader__.load({
4645
4969
  if (nodeFocus === null || nodeFocus === void 0) return;
4646
4970
  setSel(nodeFocus.step);
4647
4971
  setCat(nodeFocus.cat);
4648
- setOpenElem("n" + String(nodeFocus.seq));
4972
+ setOpenElem(nodeFocus.key);
4973
+ setRowQuery("");
4974
+ setRowKind(null);
4649
4975
  focusScrollRef.current = true;
4650
4976
  if (props.onNodeFocusHandled !== void 0) props.onNodeFocusHandled();
4651
4977
  }, [
@@ -4697,12 +5023,7 @@ window.__ModuleLoader__.load({
4697
5023
  for (const n of view.nodes) if ((n.cat === "tool" || n.cat === "skill") && n.tool !== void 0) toolHits.set(n.tool, (toolHits.get(n.tool) ?? 0) + 1);
4698
5024
  const toolHitsOf = (tool) => toolHits.get(tool.name) ?? 0;
4699
5025
  const dnaLabel = (it) => {
4700
- let base;
4701
- if (!("node" in it)) base = it.cat === "system" ? catLabel("system") : it.key.slice(5);
4702
- else {
4703
- const n = it.node;
4704
- base = n.skill !== void 0 ? t("node.skillTag", { name: n.skill }) : n.cat === "tool" ? n.tool ?? "?" : n.cat === "inject" ? t("form." + (n.form || "context")) : catLabel(n.cat);
4705
- }
5026
+ const base = dnaBaseLabel(it, t, catLabel);
4706
5027
  return it.time !== void 0 ? base + " · " + fmtTime(it.time) : base;
4707
5028
  };
4708
5029
  const dnaItems = dna ? dnaOf(view) : null;
@@ -5022,7 +5343,7 @@ window.__ModuleLoader__.load({
5022
5343
  type: "button",
5023
5344
  className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
5024
5345
  onClick: () => {
5025
- setDna((on) => !on);
5346
+ setDna(!dna);
5026
5347
  },
5027
5348
  children: t("browser.dna")
5028
5349
  })
@@ -5202,7 +5523,7 @@ window.__ModuleLoader__.load({
5202
5523
  * widening after this many slots and late bands simply join within the cap (stackedBar.css delays by
5203
5524
  * `--lc-i`); the composition bar's few category segments never reach it.
5204
5525
  */
5205
- const STAGGER_CAP = 8;
5526
+ const STAGGER_CAP$1 = 8;
5206
5527
  function makeStackedBar(kit) {
5207
5528
  const { t, fmt, catLabel } = kit;
5208
5529
  return function StackedBar(props) {
@@ -5285,7 +5606,7 @@ window.__ModuleLoader__.load({
5285
5606
  style: {
5286
5607
  width: `${widths[i]}%`,
5287
5608
  backgroundColor: p.color,
5288
- "--lc-i": Math.min(i, STAGGER_CAP)
5609
+ "--lc-i": Math.min(i, STAGGER_CAP$1)
5289
5610
  },
5290
5611
  onMouseEnter: () => {
5291
5612
  if (props.onHoverKey !== void 0) props.onHoverKey(p.key);
@@ -5635,9 +5956,10 @@ window.__ModuleLoader__.load({
5635
5956
  * The Context Dashboard's sidebar entry: a footer action stacked directly
5636
5957
  * above Settings (the harness's own foot layout: footer actions, then the
5637
5958
  * settings row), mirroring the Settings trigger's geometry in both column
5638
- * widths. The button carries the plugin emblem and, on the wide
5639
- * column, its label. Clicking opens the overview overlay through the shared
5640
- * module store (overviewStore.ts).
5959
+ * widths. The button carries the plugin emblem — in the mono seat, so the
5960
+ * glyph matches the harness's own footer rows rather than shouting over
5961
+ * them — and, on the wide column, its label. Clicking opens the overview
5962
+ * overlay through the shared module store (overviewStore.ts).
5641
5963
  *
5642
5964
  * The per-user `insightsEntry` preference takes the entry down (renders
5643
5965
  * null) without unregistering the seat. The subscription fails open: an
@@ -5663,7 +5985,8 @@ window.__ModuleLoader__.load({
5663
5985
  },
5664
5986
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextIcon, {
5665
5987
  size: props.wide === true ? 16 : 18,
5666
- className: "lc-ov-entry-icon"
5988
+ className: "lc-ov-entry-icon",
5989
+ mono: true
5667
5990
  }), props.wide === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5668
5991
  className: "lc-ov-entry-label",
5669
5992
  children: t("ov.entry")
@@ -7670,6 +7993,126 @@ window.__ModuleLoader__.load({
7670
7993
  };
7671
7994
  }
7672
7995
  //#endregion
7996
+ //#region src/client/components/timingStrip.tsx
7997
+ /**
7998
+ * The timing card's session-time strip: the fold's painted spans (every
7999
+ * completed step's TTFT wait, decode blocks in stream order, tool-run
8000
+ * windows, and in-step residue) packed shoulder-to-shoulder in occurrence
8001
+ * order — the strip reads as WHERE THE TIME WENT, not when: each band's
8002
+ * width is its share of the session's cumulative active time (the donut's
8003
+ * Active Time), and idle time between steps takes no track at all. The DNA
8004
+ * idiom applied to time consumed. The axis runs 0 → the total active time
8005
+ * with quartile ticks between (0, ¼, ½, ¾, full). Hover relays the span's
8006
+ * KIND through the card's shared hover key, so every span of a category
8007
+ * lights together with its donut arc and legend row (the DNA
8008
+ * lifetime-highlight idiom); the floating tip answers only the strip's OWN
8009
+ * pointer — a mirrored legend/donut hover lights the matching bands without
8010
+ * floating a second tip over a surface the pointer is not on (the stacked
8011
+ * bar's mirror rule).
8012
+ */
8013
+ /** The strip's palette: the timing card's own slice colors, keyed by span kind (statsTiming.tsx shares it). */
8014
+ const TIMING_COLOR = {
8015
+ ttft: "var(--color-blue-500)",
8016
+ reasoning: "var(--color-violet-500)",
8017
+ text: "var(--color-pink-500)",
8018
+ toolarg: "var(--color-amber-500)",
8019
+ tools: "var(--color-teal-500)",
8020
+ other: "var(--color-slate-400)"
8021
+ };
8022
+ /** The legend-label key of each span kind (the timing card's own vocabulary). */
8023
+ const KIND_LABEL = {
8024
+ ttft: "timing.ttft",
8025
+ reasoning: "timing.reasoning",
8026
+ text: "timing.text",
8027
+ toolarg: "timing.toolArgs",
8028
+ tools: "timing.tools",
8029
+ other: "timing.other"
8030
+ };
8031
+ /** Entrance stagger cap (the stacked bar's own rule): late bands join within the cap so a long span list settles fast. */
8032
+ const STAGGER_CAP = 8;
8033
+ /** The axis's fixed tick fractions: zero, the three quartiles, and the full span. */
8034
+ const TICK_FRACS = [
8035
+ 0,
8036
+ .25,
8037
+ .5,
8038
+ .75,
8039
+ 1
8040
+ ];
8041
+ function makeTimingStrip(kit) {
8042
+ const { t, fmtDuration, fmtTime } = kit;
8043
+ return function TimingStrip(props) {
8044
+ const [tipKey, setTipKey] = (0, react.useState)(null);
8045
+ const valid = props.spans.filter((s) => Object.hasOwn(TIMING_COLOR, s.kind) && Number.isFinite(s.start) && Number.isFinite(s.end) && s.end > s.start);
8046
+ if (valid.length === 0) return null;
8047
+ let total = 0;
8048
+ for (const s of valid) total += s.end - s.start;
8049
+ let cursor = 0;
8050
+ const bands = valid.map((s, i) => {
8051
+ const leftPct = cursor / total * 100;
8052
+ cursor += s.end - s.start;
8053
+ return {
8054
+ key: i,
8055
+ kind: s.kind,
8056
+ leftPct,
8057
+ widthPct: (s.end - s.start) / total * 100,
8058
+ tip: `${t(KIND_LABEL[s.kind])} ${fmtDuration(s.end - s.start)} · ${fmtTime(s.start)}`
8059
+ };
8060
+ });
8061
+ const hoverKey = props.hoverKey;
8062
+ const hovering = hoverKey !== null && hoverKey !== void 0 && bands.some((b) => b.kind === hoverKey);
8063
+ let tip = null;
8064
+ for (const b of bands) if (b.key === tipKey) {
8065
+ tip = {
8066
+ text: b.tip,
8067
+ leftPct: Math.max(10, Math.min(b.leftPct + b.widthPct / 2, 90))
8068
+ };
8069
+ break;
8070
+ }
8071
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8072
+ className: "lc-tstrip",
8073
+ role: "img",
8074
+ "aria-label": t("timing.strip"),
8075
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8076
+ className: "lc-tstrip-wrap",
8077
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8078
+ className: "lc-tstrip-bar" + (hovering ? " lc-tstrip-dim" : ""),
8079
+ onMouseLeave: () => {
8080
+ setTipKey(null);
8081
+ props.onHoverKey?.(null);
8082
+ },
8083
+ children: bands.map((b, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8084
+ className: "lc-tstrip-seg animate-lc-stacked-in motion-reduce:animate-none" + (hoverKey === b.kind ? " lc-tstrip-seg-on" : ""),
8085
+ style: {
8086
+ left: `${b.leftPct}%`,
8087
+ width: `${b.widthPct}%`,
8088
+ background: TIMING_COLOR[b.kind],
8089
+ "--lc-i": Math.min(i, STAGGER_CAP)
8090
+ },
8091
+ onMouseEnter: () => {
8092
+ setTipKey(b.key);
8093
+ props.onHoverKey?.(b.kind);
8094
+ }
8095
+ }, b.key))
8096
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8097
+ className: "lc-tip lc-bar-tip" + (tip !== null ? " lc-bar-tip-on" : ""),
8098
+ style: { left: `${tip !== null ? tip.leftPct : 50}%` },
8099
+ children: tip !== null ? tip.text : ""
8100
+ })]
8101
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8102
+ className: "lc-tstrip-axis",
8103
+ children: TICK_FRACS.map((frac, i) => {
8104
+ const ms = total * frac;
8105
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8106
+ className: "lc-tstrip-tick" + (i === 0 ? " lc-tstrip-tick-first" : i === TICK_FRACS.length - 1 ? " lc-tstrip-tick-last" : ""),
8107
+ style: { left: `${frac * 100}%` },
8108
+ children: ms === 0 ? "0" : fmtDuration(ms)
8109
+ }, frac);
8110
+ })
8111
+ })]
8112
+ });
8113
+ };
8114
+ }
8115
+ //#endregion
7673
8116
  //#region src/client/components/statsTiming.tsx
7674
8117
  /**
7675
8118
  * The Timing card: where the session's ACTIVE time went. The donut splits
@@ -7688,16 +8131,13 @@ window.__ModuleLoader__.load({
7688
8131
  * read as "no time, many calls". The donut and the rows sit side by side so
7689
8132
  * the head row stays half-height. Parallel tool calls each count, so the tools
7690
8133
  * figure can overlap — the ring clamps it into the post-model window while the
7691
- * row numbers stay true.
8134
+ * row numbers stay true. Below them the session-time strip packs every
8135
+ * completed step's slices gapless in occurrence order (the DNA idiom applied
8136
+ * to time consumed — each band's width is its share of the cumulative active
8137
+ * time, idle time takes no track), joining the same hover link by KIND.
7692
8138
  */
7693
- const COLOR = {
7694
- ttft: "var(--color-blue-500)",
7695
- reasoning: "var(--color-violet-500)",
7696
- text: "var(--color-pink-500)",
7697
- toolarg: "var(--color-amber-500)",
7698
- tools: "var(--color-teal-500)",
7699
- other: "var(--color-slate-400)"
7700
- };
8139
+ /** The card's slice palette (timingStrip.tsx owns it — the strip paints the same kinds). */
8140
+ const COLOR = TIMING_COLOR;
7701
8141
  /**
7702
8142
  * The decode-throughput figure, formatted exactly as the harness's own
7703
8143
  * session-stats seat formats it: whole tokens from ten up, one decimal below.
@@ -7709,6 +8149,7 @@ window.__ModuleLoader__.load({
7709
8149
  function makeStatsTiming(kit, Donut) {
7710
8150
  const { t, fmt, fmtDuration, fmtShare } = kit;
7711
8151
  const SliceList = makeSliceList(kit);
8152
+ const TimingStrip = makeTimingStrip(kit);
7712
8153
  return function StatsTiming(props) {
7713
8154
  const [hoverKey, setHoverKey] = (0, react.useState)(null);
7714
8155
  const timing = props.timing;
@@ -7840,7 +8281,7 @@ window.__ModuleLoader__.load({
7840
8281
  }), rows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7841
8282
  className: "lc-empty",
7842
8283
  children: t("timing.empty")
7843
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8284
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7844
8285
  className: "lc-donut-row flex items-center justify-start gap-3 min-w-0 @max-[320px]/lc-card:gap-2 @max-[240px]/lc-card:flex-wrap",
7845
8286
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Donut, {
7846
8287
  segments,
@@ -7854,7 +8295,11 @@ window.__ModuleLoader__.load({
7854
8295
  hoverKey,
7855
8296
  onHoverKey: setHoverKey
7856
8297
  })]
7857
- })]
8298
+ }), props.spans !== void 0 && props.spans.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TimingStrip, {
8299
+ spans: props.spans,
8300
+ hoverKey,
8301
+ onHoverKey: setHoverKey
8302
+ }) : null] })]
7858
8303
  });
7859
8304
  };
7860
8305
  }
@@ -10959,7 +11404,7 @@ window.__ModuleLoader__.load({
10959
11404
  return function PluginInfo() {
10960
11405
  const [latest, setLatest] = (0, react.useState)(null);
10961
11406
  (0, react.useEffect)(() => {
10962
- if ("0.60.0".includes("-dev")) return;
11407
+ if ("0.62.0".includes("-dev")) return;
10963
11408
  let on = true;
10964
11409
  fetchLatestVersion().then((v) => {
10965
11410
  if (on && v) setLatest(v);
@@ -10968,8 +11413,8 @@ window.__ModuleLoader__.load({
10968
11413
  on = false;
10969
11414
  };
10970
11415
  }, []);
10971
- const update = latest !== null && isNewerVersion(latest, "0.60.0") ? latest : null;
10972
- const nameText = "dsh-context (v0.60.0)";
11416
+ const update = latest !== null && isNewerVersion(latest, "0.62.0") ? latest : null;
11417
+ const nameText = "dsh-context (v0.62.0)";
10973
11418
  const nameValue = [nameText];
10974
11419
  if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10975
11420
  className: "lc-pi-update",
@@ -11932,6 +12377,7 @@ window.__ModuleLoader__.load({
11932
12377
  const [hoverTurn, setHoverTurn] = (0, react.useState)(null);
11933
12378
  const [granularity, setGranularity] = (0, react.useState)(() => settings.defaultGranularity());
11934
12379
  const [trendMode, setTrendMode] = (0, react.useState)(() => settings.defaultTrendMode());
12380
+ const [dna, setDna] = (0, react.useState)(false);
11935
12381
  const [adaptive, setAdaptive] = (0, react.useState)(false);
11936
12382
  const [focusTurn, setFocusTurn] = (0, react.useState)(null);
11937
12383
  const [jumpSeq, setJumpSeq] = (0, react.useState)(null);
@@ -11987,6 +12433,21 @@ window.__ModuleLoader__.load({
11987
12433
  const displayRequests = (0, react.useMemo)(() => granularity === "turn" ? aggregateByTurn(requests) : requests, [requests, granularity]);
11988
12434
  const stepsOf = (0, react.useMemo)(() => turnStepsOf(requests), [requests]);
11989
12435
  const markers = (0, react.useMemo)(() => attachMarkers(displayRequests, events), [displayRequests, events]);
12436
+ /* v8 ignore next 1 -- a missing projection returns the loading screen before the trend card
12437
+ (and its DNA toggle) renders, so `dna && data === null` cannot occur. */
12438
+ const dnaBands = (0, react.useMemo)(() => dna && data !== null ? displayRequests.map((req) => trendBandsOf(assemble(data, headers, req.seq))) : null, [
12439
+ dna,
12440
+ data,
12441
+ headers,
12442
+ displayRequests
12443
+ ]);
12444
+ const revealBand = (0, react.useCallback)((seq, band) => {
12445
+ setNodeFocus({
12446
+ step: seq,
12447
+ key: band.key,
12448
+ cat: band.cat
12449
+ });
12450
+ }, []);
11990
12451
  (0, react.useEffect)(() => {
11991
12452
  if (typeof sessionId !== "string" || sessionId === "") return;
11992
12453
  const take = () => {
@@ -12084,7 +12545,7 @@ window.__ModuleLoader__.load({
12084
12545
  if (step === null) return;
12085
12546
  setNodeFocus({
12086
12547
  step,
12087
- seq,
12548
+ key: "n" + String(seq),
12088
12549
  cat: "tool"
12089
12550
  });
12090
12551
  }, [requests]);
@@ -12096,7 +12557,7 @@ window.__ModuleLoader__.load({
12096
12557
  const step = isResponse ? next !== null ? next.seq : "live" : activeReq.seq;
12097
12558
  setNodeFocus({
12098
12559
  step,
12099
- seq: node.seq,
12560
+ key: "n" + String(node.seq),
12100
12561
  cat: node.cat
12101
12562
  });
12102
12563
  }, [
@@ -12158,6 +12619,19 @@ window.__ModuleLoader__.load({
12158
12619
  className: "lc-card-title-text",
12159
12620
  children: t("trend.title")
12160
12621
  }),
12622
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
12623
+ className: "lc-gran lc-trend-dna",
12624
+ role: "group",
12625
+ title: t("trend.dnaTip"),
12626
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
12627
+ type: "button",
12628
+ className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
12629
+ onClick: () => {
12630
+ setDna((v) => !v);
12631
+ },
12632
+ children: t("trend.dna")
12633
+ })
12634
+ }),
12161
12635
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
12162
12636
  className: "lc-gran lc-trend-adaptive",
12163
12637
  role: "group",
@@ -12229,6 +12703,8 @@ window.__ModuleLoader__.load({
12229
12703
  hoverCat: trendHoverCat,
12230
12704
  focusCat,
12231
12705
  adaptive,
12706
+ dna: dnaBands,
12707
+ onPickBand: revealBand,
12232
12708
  onSelect: setSelectedSeq,
12233
12709
  onHover: setHoveredSeq,
12234
12710
  onHoverTurn: setHoverTurn,
@@ -12268,7 +12744,9 @@ window.__ModuleLoader__.load({
12268
12744
  onNodeFocusHandled: clearNodeFocus,
12269
12745
  loadImage,
12270
12746
  detailState: source.detailState,
12271
- onDetailRetry: source.retryDetail
12747
+ onDetailRetry: source.retryDetail,
12748
+ dna,
12749
+ onDnaChange: setDna
12272
12750
  });
12273
12751
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12274
12752
  className: "lc-root",
@@ -12292,7 +12770,10 @@ window.__ModuleLoader__.load({
12292
12770
  usage,
12293
12771
  current: data.current,
12294
12772
  breakdown
12295
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatsTiming, { timing: data.timing ?? null })]
12773
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatsTiming, {
12774
+ timing: data.timing ?? null,
12775
+ spans: data.spans
12776
+ })]
12296
12777
  }),
12297
12778
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12298
12779
  className: "lc-cols lc-cols-main",
@@ -12513,7 +12994,7 @@ window.__ModuleLoader__.load({
12513
12994
  }
12514
12995
  //#endregion
12515
12996
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/tailwind.css.mjs
12516
- const css$15 = "/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root,:host{--spacing:4px;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-amber-500:oklch(76.9% .188 70.08);--color-green-500:oklch(72.3% .219 149.579);--color-teal-500:oklch(70.4% .14 182.503);--color-blue-500:oklch(62.3% .214 259.815);--color-indigo-500:oklch(58.5% .233 277.117);--color-violet-500:oklch(60.6% .25 292.717);--color-purple-500:oklch(62.7% .265 303.9);--color-pink-500:oklch(65.6% .241 354.308);--color-slate-400:oklch(70.4% .04 256.788);--color-neutral-500:oklch(55.6% 0 none);--animate-lc-donut-in:lc-donut-in .45s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 50ms) backwards;--animate-lc-stacked-in:lc-stacked-in .4s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 40ms) backwards;--animate-lc-bar-in:lc-bar-in .35s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 15ms) backwards;--animate-lc-agent-flow:lc-agent-flow .9s linear infinite;--animate-lc-agent-glow:lc-agent-glow 1.8s ease-in-out infinite}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.table{display:table}.min-w-0{min-width:0}.min-w-\\[min\\(240px\\,100\\%\\)\\]{min-width:min(240px,100%)}.min-w-\\[min\\(360px\\,100\\%\\)\\]{min-width:min(360px,100%)}.flex-1{flex:1}.flex-\\[3\\]{flex:3}.flex-auto{flex:auto}.shrink{flex-shrink:1}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-lc-agent-flow{animation:var(--animate-lc-agent-flow)}.animate-lc-agent-glow{animation:var(--animate-lc-agent-glow)}.animate-lc-bar-in{animation:var(--animate-lc-bar-in)}.animate-lc-donut-in{animation:var(--animate-lc-donut-in)}.animate-lc-stacked-in{animation:var(--animate-lc-stacked-in)}.resize{resize:both}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(108px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(108px,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-3{gap:calc(var(--spacing) * 3)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border{border-style:var(--tw-border-style);border-width:1px}.fill-\\(--dsw-alias-bg-layer-1\\){fill:var(--dsw-alias-bg-layer-1)}.fill-\\(--dsw-alias-label-primary\\){fill:var(--dsw-alias-label-primary)}.fill-current{fill:currentColor}.fill-none{fill:none}.fill-transparent{fill:#0000}.stroke-\\(--dsw-alias-border-l1\\){stroke:var(--dsw-alias-border-l1)}.stroke-2{stroke-width:2px}.stroke-4{stroke-width:4px}.stroke-9{stroke-width:9px}.stroke-\\[1\\.5px\\]{stroke-width:1.5px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}@media (hover:hover){.group-hover\\/agent\\:fill-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:is(:where(.group\\/agent):hover *){fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.group-hover\\/pi\\:underline:is(:where(.group\\/pi):hover *){text-decoration-line:underline}.group-hover\\/tip\\:border-\\(--dsw-alias-label-primary\\):is(:where(.group\\/tip):hover *){border-color:var(--dsw-alias-label-primary)}.group-hover\\/tip\\:text-\\(--dsw-alias-label-primary\\):is(:where(.group\\/tip):hover *){color:var(--dsw-alias-label-primary)}.group-hover\\/tip\\:opacity-100:is(:where(.group\\/tip):hover *){opacity:1}}.group-focus-visible\\/agent\\:fill-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:is(:where(.group\\/agent):focus-visible *){fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}@media (hover:hover){.hover\\:border-\\(--dsw-alias-label-dimmed\\):hover{border-color:var(--dsw-alias-label-dimmed)}.hover\\:border-\\(--dsw-alias-label-primary\\):hover{border-color:var(--dsw-alias-label-primary)}.hover\\:bg-\\(--dsw-alias-bg-layer-2\\):hover{background-color:var(--dsw-alias-bg-layer-2)}.hover\\:bg-\\(--dsw-alias-interactive-bg-hover\\):hover{background-color:var(--dsw-alias-interactive-bg-hover)}.hover\\:bg-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:hover{background-color:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.hover\\:text-\\(--dsw-alias-label-primary\\):hover{color:var(--dsw-alias-label-primary)}.hover\\:text-\\(--dsw-alias-label-secondary\\):hover{color:var(--dsw-alias-label-secondary)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.hover\\:brightness-\\[1\\.15\\]:hover{--tw-brightness:brightness(1.15);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\\:border-\\(--dsw-alias-label-dimmed\\):focus{border-color:var(--dsw-alias-label-dimmed)}@media (hover:hover){.hover\\:enabled\\:bg-\\(--dsw-alias-interactive-bg-hover\\):hover:enabled{background-color:var(--dsw-alias-interactive-bg-hover)}}.disabled\\:cursor-default:disabled{cursor:default}.disabled\\:opacity-50:disabled{opacity:.5}@media (prefers-reduced-motion:reduce){.motion-reduce\\:animate-none{animation:none}}@container lc-card (width<380px){.\\@max-\\[380px\\]\\/lc-card\\:basis-\\[calc\\(100\\%-46px\\)\\]{flex-basis:calc(100% - 46px)}.\\@max-\\[380px\\]\\/lc-card\\:basis-\\[calc\\(100\\%-92px\\)\\]{flex-basis:calc(100% - 92px)}.\\@max-\\[380px\\]\\/lc-card\\:flex-wrap{flex-wrap:wrap}}@container lc-card (width<320px){.\\@max-\\[320px\\]\\/lc-card\\:gap-2{gap:calc(var(--spacing) * 2)}}@container lc-card (width<240px){.\\@max-\\[240px\\]\\/lc-card\\:mx-auto{margin-inline:auto}.\\@max-\\[240px\\]\\/lc-card\\:basis-full{flex-basis:100%}.\\@max-\\[240px\\]\\/lc-card\\:flex-wrap{flex-wrap:wrap}}@property --tw-rotate-x{syntax:\"*\";inherits:false}@property --tw-rotate-y{syntax:\"*\";inherits:false}@property --tw-rotate-z{syntax:\"*\";inherits:false}@property --tw-skew-x{syntax:\"*\";inherits:false}@property --tw-skew-y{syntax:\"*\";inherits:false}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-blur{syntax:\"*\";inherits:false}@property --tw-brightness{syntax:\"*\";inherits:false}@property --tw-contrast{syntax:\"*\";inherits:false}@property --tw-grayscale{syntax:\"*\";inherits:false}@property --tw-hue-rotate{syntax:\"*\";inherits:false}@property --tw-invert{syntax:\"*\";inherits:false}@property --tw-opacity{syntax:\"*\";inherits:false}@property --tw-saturate{syntax:\"*\";inherits:false}@property --tw-sepia{syntax:\"*\";inherits:false}@property --tw-drop-shadow{syntax:\"*\";inherits:false}@property --tw-drop-shadow-color{syntax:\"*\";inherits:false}@property --tw-drop-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:\"*\";inherits:false}@keyframes lc-donut-in{0%{stroke-dasharray:0 100}}@keyframes lc-stacked-in{0%{transform:scaleX(0)}}@keyframes lc-bar-in{0%{transform:scaleY(0)}}@keyframes lc-agent-flow{to{stroke-dashoffset:-9px}}@keyframes lc-agent-glow{0%,to{opacity:1}50%{opacity:.4}}";
12997
+ const css$15 = "/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root,:host{--spacing:4px;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-amber-500:oklch(76.9% .188 70.08);--color-green-500:oklch(72.3% .219 149.579);--color-teal-500:oklch(70.4% .14 182.503);--color-blue-500:oklch(62.3% .214 259.815);--color-indigo-500:oklch(58.5% .233 277.117);--color-violet-500:oklch(60.6% .25 292.717);--color-purple-500:oklch(62.7% .265 303.9);--color-pink-500:oklch(65.6% .241 354.308);--color-slate-400:oklch(70.4% .04 256.788);--color-neutral-500:oklch(55.6% 0 none);--animate-lc-donut-in:lc-donut-in .45s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 50ms) backwards;--animate-lc-stacked-in:lc-stacked-in .4s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 40ms) backwards;--animate-lc-bar-in:lc-bar-in .35s cubic-bezier(.4, 0, .2, 1) calc(var(--lc-i,0) * 15ms) backwards;--animate-lc-agent-flow:lc-agent-flow .9s linear infinite;--animate-lc-agent-glow:lc-agent-glow 1.8s ease-in-out infinite}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.table{display:table}.min-w-0{min-width:0}.min-w-\\[min\\(240px\\,100\\%\\)\\]{min-width:min(240px,100%)}.min-w-\\[min\\(360px\\,100\\%\\)\\]{min-width:min(360px,100%)}.flex-1{flex:1}.flex-\\[3\\]{flex:3}.flex-auto{flex:auto}.shrink{flex-shrink:1}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-lc-agent-flow{animation:var(--animate-lc-agent-flow)}.animate-lc-agent-glow{animation:var(--animate-lc-agent-glow)}.animate-lc-bar-in{animation:var(--animate-lc-bar-in)}.animate-lc-donut-in{animation:var(--animate-lc-donut-in)}.animate-lc-stacked-in{animation:var(--animate-lc-stacked-in)}.resize{resize:both}.grid-cols-\\[repeat\\(auto-fit\\,minmax\\(108px\\,1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(108px,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-3{gap:calc(var(--spacing) * 3)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border{border-style:var(--tw-border-style);border-width:1px}.fill-\\(--dsw-alias-bg-layer-1\\){fill:var(--dsw-alias-bg-layer-1)}.fill-\\(--dsw-alias-label-primary\\){fill:var(--dsw-alias-label-primary)}.fill-current{fill:currentColor}.fill-none{fill:none}.fill-transparent{fill:#0000}.stroke-\\(--dsw-alias-border-l1\\){stroke:var(--dsw-alias-border-l1)}.stroke-2{stroke-width:2px}.stroke-4{stroke-width:4px}.stroke-9{stroke-width:9px}.stroke-\\[1\\.5px\\]{stroke-width:1.5px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}@media (hover:hover){.group-hover\\/agent\\:fill-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:is(:where(.group\\/agent):hover *){fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.group-hover\\/pi\\:underline:is(:where(.group\\/pi):hover *){text-decoration-line:underline}.group-hover\\/tip\\:border-\\(--dsw-alias-label-primary\\):is(:where(.group\\/tip):hover *){border-color:var(--dsw-alias-label-primary)}.group-hover\\/tip\\:text-\\(--dsw-alias-label-primary\\):is(:where(.group\\/tip):hover *){color:var(--dsw-alias-label-primary)}.group-hover\\/tip\\:opacity-100:is(:where(.group\\/tip):hover *){opacity:1}}.group-focus-visible\\/agent\\:fill-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:is(:where(.group\\/agent):focus-visible *){fill:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}@media (hover:hover){.hover\\:border-\\(--dsw-alias-label-dimmed\\):hover{border-color:var(--dsw-alias-label-dimmed)}.hover\\:border-\\(--dsw-alias-label-primary\\):hover{border-color:var(--dsw-alias-label-primary)}.hover\\:bg-\\(--dsw-alias-bg-layer-2\\):hover{background-color:var(--dsw-alias-bg-layer-2)}.hover\\:bg-\\(--dsw-alias-interactive-bg-hover\\):hover{background-color:var(--dsw-alias-interactive-bg-hover)}.hover\\:bg-\\[var\\(--dsw-alias-interactive-bg-hover\\,var\\(--dsw-alias-bg-layer-2\\)\\)\\]:hover{background-color:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.hover\\:text-\\(--dsw-alias-label-primary\\):hover{color:var(--dsw-alias-label-primary)}.hover\\:text-\\(--dsw-alias-label-secondary\\):hover{color:var(--dsw-alias-label-secondary)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.hover\\:brightness-\\[1\\.15\\]:hover{--tw-brightness:brightness(1.15);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\\:border-\\(--dsw-alias-label-dimmed\\):focus{border-color:var(--dsw-alias-label-dimmed)}@media (hover:hover){.hover\\:enabled\\:bg-\\(--dsw-alias-interactive-bg-hover\\):hover:enabled{background-color:var(--dsw-alias-interactive-bg-hover)}}.disabled\\:cursor-default:disabled{cursor:default}.disabled\\:opacity-50:disabled{opacity:.5}@media (prefers-reduced-motion:reduce){.motion-reduce\\:animate-none{animation:none}}@container lc-card (width<380px){.\\@max-\\[380px\\]\\/lc-card\\:basis-\\[calc\\(100\\%-46px\\)\\]{flex-basis:calc(100% - 46px)}.\\@max-\\[380px\\]\\/lc-card\\:basis-\\[calc\\(100\\%-92px\\)\\]{flex-basis:calc(100% - 92px)}.\\@max-\\[380px\\]\\/lc-card\\:flex-wrap{flex-wrap:wrap}}@container lc-card (width<320px){.\\@max-\\[320px\\]\\/lc-card\\:gap-2{gap:calc(var(--spacing) * 2)}}@container lc-card (width<240px){.\\@max-\\[240px\\]\\/lc-card\\:mx-auto{margin-inline:auto}.\\@max-\\[240px\\]\\/lc-card\\:basis-full{flex-basis:100%}.\\@max-\\[240px\\]\\/lc-card\\:flex-wrap{flex-wrap:wrap}}@property --tw-rotate-x{syntax:\"*\";inherits:false}@property --tw-rotate-y{syntax:\"*\";inherits:false}@property --tw-rotate-z{syntax:\"*\";inherits:false}@property --tw-skew-x{syntax:\"*\";inherits:false}@property --tw-skew-y{syntax:\"*\";inherits:false}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-blur{syntax:\"*\";inherits:false}@property --tw-brightness{syntax:\"*\";inherits:false}@property --tw-contrast{syntax:\"*\";inherits:false}@property --tw-grayscale{syntax:\"*\";inherits:false}@property --tw-hue-rotate{syntax:\"*\";inherits:false}@property --tw-invert{syntax:\"*\";inherits:false}@property --tw-opacity{syntax:\"*\";inherits:false}@property --tw-saturate{syntax:\"*\";inherits:false}@property --tw-sepia{syntax:\"*\";inherits:false}@property --tw-drop-shadow{syntax:\"*\";inherits:false}@property --tw-drop-shadow-color{syntax:\"*\";inherits:false}@property --tw-drop-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:\"*\";inherits:false}@keyframes lc-donut-in{0%{stroke-dasharray:0 100}}@keyframes lc-stacked-in{0%{transform:scaleX(0)}}@keyframes lc-bar-in{0%{transform:scaleY(0)}}@keyframes lc-agent-flow{to{stroke-dashoffset:-9px}}@keyframes lc-agent-glow{0%,to{opacity:1}50%{opacity:.4}}";
12517
12998
  const tagId$15 = "dsh-context/tailwind.css";
12518
12999
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$15) + "]") === null) {
12519
13000
  const tag = document.createElement("style");
@@ -12524,7 +13005,7 @@ window.__ModuleLoader__.load({
12524
13005
  }
12525
13006
  //#endregion
12526
13007
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/base.css.mjs
12527
- const css$14 = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}[data-sidebar-right-open] .lc-root,[data-sidebar-right-float-host] .lc-root{padding:12px}.lc-title-icon{flex:none}.lc-title-label{padding-right:30px}.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-root .lc-card{box-sizing:border-box;margin-bottom:7px;padding:7px 8px;container:lc-card/inline-size}.lc-root .lc-cols{gap:7px;margin-bottom:7px}.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-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,.lc-heat-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran,.lc-heat-ctl .lc-gran,.lc-heat-ctl .lc-card-sub{margin-left:0}.lc-trend-adaptive{flex:none;margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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-kind-n{font-variant-numeric:tabular-nums;opacity:.65;margin-left:4px}.lc-gran-on .lc-kind-n{opacity:.85}.lc-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 2px 8px #0000002e);pointer-events:none;opacity:0;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:6px 10px;font-size:12px;position:absolute}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.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:has(.lc-stats){flex-direction:column;display:flex}.lc-head .lc-stats{flex:1;align-content:stretch}.lc-head .lc-stat{justify-content:center}.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{font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);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-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;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:4px 14px;font-size:12px}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])),[data-conversation-scroll]:has(.lc-root,.lc-modal-backdrop)~[data-width-handle]{display:none}";
13008
+ const css$14 = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}[data-sidebar-right-open] .lc-root,[data-sidebar-right-float-host] .lc-root{padding:12px}.lc-title-icon{flex:none}.lc-title-label{padding-right:30px}.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-root .lc-card{box-sizing:border-box;margin-bottom:7px;padding:7px 8px;container:lc-card/inline-size}.lc-root .lc-cols{gap:7px;margin-bottom:7px}.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-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,.lc-heat-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran,.lc-heat-ctl .lc-gran,.lc-heat-ctl .lc-card-sub{margin-left:0}.lc-trend-dna,.lc-trend-adaptive{flex:none;margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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-btn:disabled{opacity:.4;cursor:not-allowed}.lc-gran-btn:disabled:hover{color:var(--dsw-alias-label-secondary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-kind-n{font-variant-numeric:tabular-nums;opacity:.65;margin-left:4px}.lc-gran-on .lc-kind-n{opacity:.85}.lc-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 2px 8px #0000002e);pointer-events:none;opacity:0;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:6px 10px;font-size:12px;position:absolute}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.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:has(.lc-stats){flex-direction:column;display:flex}.lc-head .lc-stats{flex:1;align-content:stretch}.lc-head .lc-stat{justify-content:center}.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{font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);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-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;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:4px 14px;font-size:12px}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])),[data-conversation-scroll]:has(.lc-root,.lc-modal-backdrop)~[data-width-handle]{display:none}";
12528
13009
  const tagId$14 = "dsh-context/base.css";
12529
13010
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$14) + "]") === null) {
12530
13011
  const tag = document.createElement("style");
@@ -12535,7 +13016,7 @@ window.__ModuleLoader__.load({
12535
13016
  }
12536
13017
  //#endregion
12537
13018
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/stats.css.mjs
12538
- const css$13 = ".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}a.lc-stat{color:inherit;cursor:pointer;text-decoration:none}a.lc-stat:hover{border-color:var(--dsw-alias-label-secondary)}.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;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.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-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-band{justify-content:space-between;gap:2rem;display:flex}.lc-stat-tip-band i{font-style:normal}.lc-stat-tip-by{color:var(--dsw-alias-label-secondary);margin-top:3px;display:block}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.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-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:color-mix(in srgb, var(--color-neutral-500) 18%, transparent)}.lc-donut-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-donut-dim .lc-donut-seg{opacity:.35}.lc-donut-dim .lc-donut-seg-on{opacity:1}.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{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:4px 20px;min-width:0;display:grid;overflow:hidden}.lc-sl-row{min-width:0;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;flex-direction:column;gap:1px;margin:0 -6px;padding:1px 6px;font-size:12px;display:flex}.lc-sl-row-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-sl-row-dim{opacity:.55}.lc-sl-main{align-items:center;gap:6px;min-width:0;display:flex}.lc-sl-dot{border-radius:2px;flex:none;width:8px;height:8px}.lc-sl-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;font-weight:600;line-height:1.25;overflow:hidden}.lc-sl-pct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:34px;font-weight:700}.lc-sl-sub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;margin-left:14px;font-size:11px;line-height:1.3;overflow:hidden}.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-hint{text-decoration:none}.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-labelicon{vertical-align:-2px;margin-right:4px;display:inline-block}.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}";
13019
+ const css$13 = ".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}a.lc-stat{color:inherit;cursor:pointer;text-decoration:none}a.lc-stat:hover{border-color:var(--dsw-alias-label-secondary)}.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;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.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-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-band{justify-content:space-between;gap:2rem;display:flex}.lc-stat-tip-band i{font-style:normal}.lc-stat-tip-by{color:var(--dsw-alias-label-secondary);margin-top:3px;display:block}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.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-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:color-mix(in srgb, var(--color-neutral-500) 18%, transparent)}.lc-donut-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-donut-dim .lc-donut-seg{opacity:.35}.lc-donut-dim .lc-donut-seg-on{opacity:1}.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{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:4px 20px;min-width:0;display:grid;overflow:hidden}.lc-sl-row{min-width:0;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;flex-direction:column;gap:1px;margin:0 -6px;padding:1px 6px;font-size:12px;display:flex}.lc-sl-row-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-sl-row-dim{opacity:.55}.lc-sl-main{align-items:center;gap:6px;min-width:0;display:flex}.lc-sl-dot{border-radius:2px;flex:none;width:8px;height:8px}.lc-sl-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;font-weight:600;line-height:1.25;overflow:hidden}.lc-sl-pct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:34px;font-weight:700}.lc-sl-sub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;margin-left:14px;font-size:11px;line-height:1.3;overflow:hidden}.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-hint{text-decoration:none}.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-labelicon{vertical-align:-2px;margin-right:4px;display:inline-block}.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-tstrip{margin-top:10px}.lc-tstrip-wrap{position:relative}.lc-tstrip-bar{background:color-mix(in srgb, var(--color-neutral-500) 18%, transparent);border-radius:4px;width:100%;height:12px;position:relative;overflow:hidden}.lc-tstrip-seg{transform-origin:0;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);position:absolute;top:0}.lc-tstrip-seg-on{filter:brightness(1.18)}.lc-tstrip-dim .lc-tstrip-seg{opacity:.35}.lc-tstrip-dim .lc-tstrip-seg-on{opacity:1}.lc-tstrip-axis{height:13px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;margin-top:5px;font-size:10px;line-height:13px;position:relative}.lc-tstrip-tick{white-space:nowrap;position:absolute;transform:translate(-50%)}.lc-tstrip-tick:before{content:\"\";background:var(--dsw-alias-border-l1);width:1px;height:3px;position:absolute;top:-4px;left:50%}.lc-tstrip-tick-first{transform:none}.lc-tstrip-tick-first:before{left:0}.lc-tstrip-tick-last{transform:translate(-100%)}.lc-tstrip-tick-last:before{left:auto;right:0}";
12539
13020
  const tagId$13 = "dsh-context/stats.css";
12540
13021
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
12541
13022
  const tag = document.createElement("style");
@@ -12579,7 +13060,7 @@ window.__ModuleLoader__.load({
12579
13060
  }
12580
13061
  //#endregion
12581
13062
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/trendChart.css.mjs
12582
- const css$9 = ".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-q3{top:41px}.lc-axis-mid{top:69px}.lc-axis-q1{top:97px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{overscroll-behavior-x:contain;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:18px 2px 0;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l2);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-q3{top:46px}.lc-grid-mid{top:74px}.lc-grid-q1{top:102px}.lc-grid-zero{border-top-style:solid;border-top-color:color-mix(in srgb, var(--color-neutral-500) 50%, transparent);top:130px}.lc-bar{cursor:pointer;outline-offset:1px;width:14px;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), outline-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;outline:1px dashed #0000;flex:none;align-items:flex-end;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;box-sizing:border-box;overflow-wrap:break-word;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:100%;color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;flex-direction:column;gap:2px;padding:3px 8px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);left:0;box-shadow:0 2px 8px #0000002e}.lc-chart-tip span+span{color:var(--dsw-alias-label-secondary)}.lc-bar-hovered{outline-color:var(--dsw-alias-brand-primary)}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:color-mix(in srgb, var(--color-neutral-500) 14%, transparent)}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-stack,.lc-bar-up,.lc-bar-down{transform-origin:50% 100%}.lc-bar-down{transform-origin:50% 0}.lc-bar-stack>div:first-child{border-radius:0 0 2px 2px}.lc-bar-stack>div:last-child{border-radius:2px 2px 0 0}.lc-bar-stack>div:only-child{border-radius:2px}.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-up>div:last-child{border-radius:2px 2px 0 0}.lc-bar-down>div:last-child{border-radius:0 0 2px 2px}.lc-cat-seg{transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.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=skill] .lc-cat-seg[data-cat=skill],.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-step-flag{background:color-mix(in srgb, var(--color-neutral-500) 45%, transparent);pointer-events:none;width:1px;position:absolute;top:-17px;bottom:0;right:-1px}.lc-step-flag-label{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--color-neutral-500) 45%, transparent);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);white-space:nowrap;border-radius:3px;padding:1px 3px;font-size:9px;font-weight:600;line-height:1;position:absolute;top:0;right:0}.lc-turns{box-sizing:border-box;gap:2px;width:max-content;min-width:100%;margin-top:4px;padding:0 2px;display:flex;overflow:hidden}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;height:14px;transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:3px;flex:none;font-size:10px;font-weight:600;line-height:14px}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{display:inline-block}";
13063
+ const css$9 = ".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-q3{top:41px}.lc-axis-mid{top:69px}.lc-axis-q1{top:97px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{overscroll-behavior-x:contain;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:18px 2px 0;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l2);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-q3{top:46px}.lc-grid-mid{top:74px}.lc-grid-q1{top:102px}.lc-grid-zero{border-top-style:solid;border-top-color:color-mix(in srgb, var(--color-neutral-500) 50%, transparent);top:130px}.lc-bar{cursor:pointer;outline-offset:1px;width:14px;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), outline-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;outline:1px dashed #0000;flex:none;align-items:flex-end;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;box-sizing:border-box;overflow-wrap:break-word;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:100%;color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;flex-direction:column;gap:2px;padding:3px 8px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);left:0;box-shadow:0 2px 8px #0000002e}.lc-chart-tip span+span{color:var(--dsw-alias-label-secondary)}.lc-bar-hovered{outline-color:var(--dsw-alias-brand-primary)}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:color-mix(in srgb, var(--color-neutral-500) 14%, transparent)}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-dna{border-radius:2px;width:100%}.lc-bar-stack,.lc-bar-up,.lc-bar-down,.lc-bar-dna{transform-origin:50% 100%}.lc-bar-down{transform-origin:50% 0}.lc-bar-stack>div:first-child{border-radius:0 0 2px 2px}.lc-bar-stack>div:last-child{border-radius:2px 2px 0 0}.lc-bar-stack>div:only-child{border-radius:2px}.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-up>div:last-child{border-radius:2px 2px 0 0}.lc-bar-down>div:last-child{border-radius:0 0 2px 2px}.lc-cat-seg{transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.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=skill] .lc-cat-seg[data-cat=skill],.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-dna-hl{z-index:1;pointer-events:none;align-items:stretch;gap:2px;display:flex;position:absolute;inset:18px 2px 0}.lc-dna-cell{flex:none;width:14px;position:relative}.lc-dna-slice{box-sizing:border-box;border:1px solid var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 26%, transparent);border-radius:1px;width:100%;position:absolute;left:0}.lc-bar-marker{z-index:2;color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-step-flag{z-index:2;background:color-mix(in srgb, var(--color-neutral-500) 45%, transparent);pointer-events:none;width:1px;position:absolute;top:-17px;bottom:0;right:-1px}.lc-step-flag-label{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--color-neutral-500) 45%, transparent);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);white-space:nowrap;border-radius:3px;padding:1px 3px;font-size:9px;font-weight:600;line-height:1;position:absolute;top:0;right:0}.lc-turns{box-sizing:border-box;gap:2px;width:max-content;min-width:100%;margin-top:4px;padding:0 2px;display:flex;overflow:hidden}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;height:14px;transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:3px;flex:none;font-size:10px;font-weight:600;line-height:14px}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{display:inline-block}";
12583
13064
  const tagId$9 = "dsh-context/trendChart.css";
12584
13065
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
12585
13066
  const tag = document.createElement("style");