dsh-context 0.60.0 → 0.61.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/lib/client.js +392 -41
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -186,7 +186,7 @@ In-chart and in-card toggles stay per-view and never overwrite the stored prefer
186
186
  ## Good to know
187
187
 
188
188
  - **Estimates vs actuals** — category figures use dsh's own fixed-density heuristic (the same one as its built-in token meter); the pinned trend details show provider-reported actuals next to them, and the Token card pairs its ≈-estimated composition shares with the provider-exact billed total.
189
- - **Compatibility** — works on `@deepseek-ai/dsh` **0.1.5-rc.1+** (the `0.1.5` line from rc.1, the `0.1.7` line from rc.2), across the V3 (`0.1.5-alpha.x+`) and V4 (`0.1.6/0.1.7+`) session-log generations, from one shape-driven code path. The per-release matrix and how it is verified: [docs/compatibility.md](docs/compatibility.md).
189
+ - **Compatibility** — works on `@deepseek-ai/dsh` **0.1.5-rc.1+** (the `0.1.5` line from rc.1, the `0.1.7` line from rc.2, the `0.2.0` line from rc.2), across the V3 (`0.1.5-alpha.x+`) and V4 (`0.1.6/0.1.7/0.2.0+`) session-log generations, from one shape-driven code path. The per-release matrix and how it is verified: [docs/compatibility.md](docs/compatibility.md).
190
190
  - **I18n** — UI in English and 简体中文.
191
191
 
192
192
  ## Like it?
package/lib/client.js CHANGED
@@ -119,6 +119,9 @@ window.__ModuleLoader__.load({
119
119
  "trend.focus": "仅展示 {cat}",
120
120
  "trend.adaptive": "自适应",
121
121
  "trend.adaptiveHint": "按当前可视范围内的柱子重新缩放高度,滚动时随之变化",
122
+ "trend.dna": "DNA 模式",
123
+ "trend.dnaTip": "把每根柱子画成该次请求的上下文指纹:按模型读取顺序逐条铺色,配合增量模式逐条展示每次请求的增减;悬停查看条目,点击让上下文浏览器定位到该条目,同一条目在所有柱子中亮出其存续变化",
124
+ "trend.dnaItem": "{label}:{n}",
122
125
  "trend.empty": "发起一轮对话后,这里会展示每次模型请求的上下文构成",
123
126
  "detail.step": "第 {t} 轮 · 第 {s} 步 (共 {n} 步)",
124
127
  "detail.turn": "第 {t} 轮 · 共 {n} 步",
@@ -513,6 +516,9 @@ window.__ModuleLoader__.load({
513
516
  "trend.focus": "Showing {cat} only",
514
517
  "trend.adaptive": "Adaptive",
515
518
  "trend.adaptiveHint": "Rescale bar heights to the visible range, following the scroll",
519
+ "trend.dna": "DNA Mode",
520
+ "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",
521
+ "trend.dnaItem": "{label}: {n}",
516
522
  "trend.empty": "Send a message and each model request’s context makeup shows up here",
517
523
  "detail.step": "Turn {t} · Step {s} of {n}",
518
524
  "detail.turn": "Turn {t} · {n} steps",
@@ -832,13 +838,19 @@ window.__ModuleLoader__.load({
832
838
  * package.json `icon` hands to the Host's package-meta reader, which serves
833
839
  * it to the Plugins page's package cards. The client bundle inlines the
834
840
  * 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.
841
+ * re-renders it at every requested size. The identity seats (tab chip,
842
+ * command, sidebar registration, panel head) keep the sheet's fixed fills —
843
+ * deliberately polychrome on both light and dark chrome — while the
844
+ * sidebar-foot entry seat (overviewButton.tsx) opts into `mono`, trading
845
+ * every fill for `currentColor` so the glyph sits quietly beside the
846
+ * harness's own footer rows (Settings and friends).
837
847
  */
838
848
  /** Everything between the file's `<svg>` tags: the sheet's strokes in paint order, whitespace-folded. */
839
849
  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 }) {
850
+ /** The mono seat's strokes: same geometry, every palette fill traded for the surrounding text colour. */
851
+ const SHEET_MARKUP_MONO = SHEET_MARKUP.replace(/fill="#[0-9A-Fa-f]{6}"/g, "fill=\"currentColor\"");
852
+ /** The document sheet at the requested square edge — polychrome by default, text-coloured in `mono`. */
853
+ function ContextIcon({ size = 20, className, mono = false }) {
842
854
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
843
855
  width: size,
844
856
  height: size,
@@ -846,7 +858,7 @@ window.__ModuleLoader__.load({
846
858
  className,
847
859
  "aria-hidden": "true",
848
860
  xmlns: "http://www.w3.org/2000/svg",
849
- dangerouslySetInnerHTML: { __html: SHEET_MARKUP }
861
+ dangerouslySetInnerHTML: { __html: mono ? SHEET_MARKUP_MONO : SHEET_MARKUP }
850
862
  });
851
863
  }
852
864
  /**
@@ -2530,6 +2542,102 @@ window.__ModuleLoader__.load({
2530
2542
  });
2531
2543
  return items;
2532
2544
  }
2545
+ /** The per-bar bands behind a trend chart bar: read order, category colors, cumulative offsets. */
2546
+ function trendBandsOf(view) {
2547
+ const bands = [];
2548
+ let off = 0;
2549
+ for (const it of dnaOf(view)) {
2550
+ if ("node" in it) bands.push({
2551
+ key: it.key,
2552
+ cat: it.cat,
2553
+ tokens: it.tokens,
2554
+ off,
2555
+ color: CAT_COLOR[it.cat],
2556
+ node: it.node
2557
+ });
2558
+ else bands.push({
2559
+ key: it.key,
2560
+ cat: it.cat,
2561
+ tokens: it.tokens,
2562
+ off,
2563
+ color: CAT_COLOR[it.cat]
2564
+ });
2565
+ off += it.tokens;
2566
+ }
2567
+ return bands;
2568
+ }
2569
+ function deltaBandsOf(bands, prev) {
2570
+ if (prev === null) return {
2571
+ up: [],
2572
+ down: []
2573
+ };
2574
+ const before = new Map(prev.map((b) => [b.key, b.tokens]));
2575
+ const after = new Map(bands.map((b) => [b.key, b.tokens]));
2576
+ const up = [];
2577
+ const down = [];
2578
+ for (const b of bands) {
2579
+ const d = b.tokens - (before.get(b.key) ?? 0);
2580
+ if (d <= 0) continue;
2581
+ up.push("node" in b ? {
2582
+ key: b.key,
2583
+ cat: b.cat,
2584
+ tokens: d,
2585
+ off: 0,
2586
+ color: b.color,
2587
+ node: b.node
2588
+ } : {
2589
+ key: b.key,
2590
+ cat: b.cat,
2591
+ tokens: d,
2592
+ off: 0,
2593
+ color: b.color
2594
+ });
2595
+ }
2596
+ for (const b of prev) {
2597
+ const d = (after.get(b.key) ?? 0) - b.tokens;
2598
+ if (d >= 0) continue;
2599
+ down.push("node" in b ? {
2600
+ key: b.key,
2601
+ cat: b.cat,
2602
+ tokens: d,
2603
+ off: 0,
2604
+ color: b.color,
2605
+ node: b.node
2606
+ } : {
2607
+ key: b.key,
2608
+ cat: b.cat,
2609
+ tokens: d,
2610
+ off: 0,
2611
+ color: b.color
2612
+ });
2613
+ }
2614
+ let u = 0;
2615
+ for (const x of up) {
2616
+ x.off = u;
2617
+ u += x.tokens;
2618
+ }
2619
+ let dn = 0;
2620
+ for (const x of down) {
2621
+ x.off = dn;
2622
+ dn -= x.tokens;
2623
+ }
2624
+ return {
2625
+ up,
2626
+ down
2627
+ };
2628
+ }
2629
+ /**
2630
+ * The compact item name both DNA surfaces share — the browser appends the
2631
+ * item's time on top of it for its own tooltip, the trend chart does not.
2632
+ * Header bands name the system prompt / the tool schema; message bands name
2633
+ * the item the way its browser row would (skill name, tool name, injection
2634
+ * form, else the category label).
2635
+ */
2636
+ function dnaBaseLabel(b, t, catLabel) {
2637
+ if (!("node" in b)) return b.cat === "system" ? catLabel("system") : b.key.slice(5);
2638
+ const n = b.node;
2639
+ 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);
2640
+ }
2533
2641
  //#endregion
2534
2642
  //#region src/shared/fileOps.ts
2535
2643
  /** Parse a call's raw JSON arguments; non-string/malformed/non-record inputs yield null. */
@@ -2999,6 +3107,124 @@ window.__ModuleLoader__.load({
2999
3107
  out.net = net;
3000
3108
  return out;
3001
3109
  };
3110
+ const DnaBar = function DnaBar(props) {
3111
+ const visible = [];
3112
+ for (const b of props.bands) if (b.tokens > 0) visible.push(b);
3113
+ if (visible.length === 0) return null;
3114
+ const runs = [];
3115
+ for (const b of visible) {
3116
+ const from = Math.round(b.off / props.total * 1e4) / 100;
3117
+ const to = Math.round((b.off + b.tokens) / props.total * 1e4) / 100;
3118
+ const last = runs.length > 0 ? runs[runs.length - 1] : null;
3119
+ if (last !== null && last.color === b.color && last.to === from) last.to = to;
3120
+ else runs.push({
3121
+ color: b.color,
3122
+ from,
3123
+ to
3124
+ });
3125
+ }
3126
+ const hitAt = (e) => {
3127
+ const rect = e.currentTarget.getBoundingClientRect();
3128
+ const pos = (rect.height > 0 ? Math.min(1, Math.max(0, 1 - (e.clientY - rect.top) / rect.height)) : 0) * props.total;
3129
+ let hit = visible[0];
3130
+ for (const b of props.bands) {
3131
+ if (b.off > pos) break;
3132
+ if (b.tokens > 0) hit = b;
3133
+ }
3134
+ return hit;
3135
+ };
3136
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3137
+ className: "lc-bar-dna animate-lc-bar-in motion-reduce:animate-none",
3138
+ style: {
3139
+ height: `${Math.max(1, Math.round(props.total / props.maxTotal * CHART_H))}px`,
3140
+ background: "linear-gradient(to top, " + runs.map((r) => `${r.color} ${r.from}%, ${r.color} ${r.to}%`).join(", ") + ")",
3141
+ "--lc-i": Math.min(props.enterIndex, STAGGER_CAP)
3142
+ },
3143
+ onMouseMove: (e) => {
3144
+ props.onHit(hitAt(e).key);
3145
+ },
3146
+ onMouseLeave: () => {
3147
+ props.onHit(null);
3148
+ },
3149
+ onClick: (e) => {
3150
+ if (props.onPick !== void 0) props.onPick(props.seq, hitAt(e));
3151
+ }
3152
+ });
3153
+ };
3154
+ const DnaDeltaBar = function DnaDeltaBar(props) {
3155
+ let upSum = 0;
3156
+ for (const b of props.d.up) upSum += b.tokens;
3157
+ let downSum = 0;
3158
+ for (const b of props.d.down) downSum -= b.tokens;
3159
+ const gradSpan = upSum + downSum;
3160
+ if (gradSpan === 0) return null;
3161
+ const runs = [];
3162
+ const pushRun = (color, mag, at) => {
3163
+ const from = Math.round(at / gradSpan * 1e4) / 100;
3164
+ const to = Math.round((at + mag) / gradSpan * 1e4) / 100;
3165
+ const last = runs.length > 0 ? runs[runs.length - 1] : null;
3166
+ if (last !== null && last.color === color && last.to === from) last.to = to;
3167
+ else runs.push({
3168
+ color,
3169
+ from,
3170
+ to
3171
+ });
3172
+ return at + mag;
3173
+ };
3174
+ let acc = 0;
3175
+ for (let i = props.d.down.length - 1; i >= 0; i--) acc = pushRun(props.d.down[i].color, -props.d.down[i].tokens, acc);
3176
+ for (const b of props.d.up) acc = pushRun(b.color, b.tokens, acc);
3177
+ const height = Math.max(1, Math.round(gradSpan * props.scale));
3178
+ const hitAt = (e) => {
3179
+ const rect = e.currentTarget.getBoundingClientRect();
3180
+ const pos = (rect.height > 0 ? Math.min(1, Math.max(0, 1 - (e.clientY - rect.top) / rect.height)) : 0) * gradSpan - downSum;
3181
+ const useUp = pos >= 0 && props.d.up.length > 0;
3182
+ const arm = useUp ? props.d.up : props.d.down;
3183
+ const p = useUp ? pos : -pos;
3184
+ let hit = arm[0];
3185
+ for (const b of arm) {
3186
+ if (b.off > p) break;
3187
+ hit = b;
3188
+ }
3189
+ return hit;
3190
+ };
3191
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3192
+ className: "lc-bar-dna animate-lc-bar-in motion-reduce:animate-none",
3193
+ style: {
3194
+ position: "absolute",
3195
+ bottom: `${Math.round(props.zeroBottom - downSum * props.scale)}px`,
3196
+ height: `${height}px`,
3197
+ background: "linear-gradient(to top, " + runs.map((r) => `${r.color} ${r.from}%, ${r.color} ${r.to}%`).join(", ") + ")",
3198
+ transformOrigin: `50% ${Math.round(downSum / gradSpan * 1e4) / 100}%`,
3199
+ "--lc-i": Math.min(props.enterIndex, STAGGER_CAP)
3200
+ },
3201
+ onMouseMove: (e) => {
3202
+ props.onHit(hitAt(e).key);
3203
+ },
3204
+ onMouseLeave: () => {
3205
+ props.onHit(null);
3206
+ },
3207
+ onClick: (e) => {
3208
+ if (props.onPick !== void 0) props.onPick(props.seq, hitAt(e));
3209
+ }
3210
+ });
3211
+ };
3212
+ const DnaHighlights = (0, react.memo)(function DnaHighlights(props) {
3213
+ if (props.slices === null) return null;
3214
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3215
+ className: "lc-dna-hl",
3216
+ children: props.slices.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3217
+ className: "lc-dna-cell",
3218
+ children: s !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3219
+ className: "lc-dna-slice",
3220
+ style: {
3221
+ bottom: `${s.bottom}px`,
3222
+ height: `${s.height}px`
3223
+ }
3224
+ }) : null
3225
+ }, i))
3226
+ });
3227
+ });
3002
3228
  const ChartBar = (0, react.memo)(function ChartBar(props) {
3003
3229
  const { req, marker } = props;
3004
3230
  const markerAt = marker !== void 0 ? eventAt(marker) : null;
@@ -3028,7 +3254,23 @@ window.__ModuleLoader__.load({
3028
3254
  title: "✂ " + (markerAt !== null ? markerAt + " — " : "") + eventLabel(marker),
3029
3255
  children: "✂"
3030
3256
  }) : null,
3031
- diverge ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3257
+ props.dna !== null ? props.dnaDelta !== null && props.dnaScale !== void 0 && props.zeroBottom !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaDeltaBar, {
3258
+ d: props.dnaDelta,
3259
+ scale: props.dnaScale,
3260
+ zeroBottom: props.zeroBottom,
3261
+ enterIndex: props.enterIndex,
3262
+ seq: req.seq,
3263
+ onHit: props.onDnaHit,
3264
+ onPick: props.onPickBand
3265
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaBar, {
3266
+ bands: props.dna,
3267
+ total: req.total,
3268
+ maxTotal: props.maxTotal,
3269
+ enterIndex: props.enterIndex,
3270
+ seq: req.seq,
3271
+ onHit: props.onDnaHit,
3272
+ onPick: props.onPickBand
3273
+ }) : diverge ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3032
3274
  className: "lc-bar-up animate-lc-bar-in motion-reduce:animate-none",
3033
3275
  style: {
3034
3276
  bottom: `${props.downPx}px`,
@@ -3084,8 +3326,13 @@ window.__ModuleLoader__.load({
3084
3326
  });
3085
3327
  });
3086
3328
  return function TrendChart(props) {
3329
+ const dnaBands = props.dna ?? null;
3330
+ const dnaOn = dnaBands !== null;
3087
3331
  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;
3332
+ const dnaDeltaOn = dnaOn && delta;
3333
+ const focus = !dnaOn && props.focusCat !== null && props.focusCat !== void 0 && CATS.some((c) => c.key === props.focusCat) ? props.focusCat : null;
3334
+ const [dnaHit, setDnaHit] = (0, react.useState)(null);
3335
+ const dnaDeltas = (0, react.useMemo)(() => dnaDeltaOn ? dnaBands.map((bands, i) => deltaBandsOf(bands, i > 0 ? dnaBands[i - 1] : null)) : null, [dnaDeltaOn, dnaBands]);
3089
3336
  const requests = (0, react.useMemo)(() => {
3090
3337
  const base = focus !== null ? props.requests.map((req) => focusOf(req, focus)) : props.requests;
3091
3338
  return delta ? base.map((req, i) => deltaOf(req, i > 0 ? base[i - 1] : null)) : base;
@@ -3113,7 +3360,14 @@ window.__ModuleLoader__.load({
3113
3360
  const col = i * pitch;
3114
3361
  if (col >= vr || col + BAR_W <= sl) continue;
3115
3362
  const req = requests[i];
3116
- if (delta) {
3363
+ if (dnaDeltaOn && dnaDeltas !== null) {
3364
+ let bu = 0;
3365
+ let bd = 0;
3366
+ for (const b of dnaDeltas[i].up) bu += b.tokens;
3367
+ for (const b of dnaDeltas[i].down) bd -= b.tokens;
3368
+ if (bu > up) up = bu;
3369
+ if (bd > down) down = bd;
3370
+ } else if (delta) {
3117
3371
  let bu = 0;
3118
3372
  let bd = 0;
3119
3373
  for (const c of CATS) {
@@ -3134,7 +3388,15 @@ window.__ModuleLoader__.load({
3134
3388
  let maxTotal = 1;
3135
3389
  let maxUp = 0;
3136
3390
  let maxDown = 0;
3137
- if (delta) for (const req of requests) {
3391
+ if (dnaDeltaOn && dnaDeltas !== null) for (const d of dnaDeltas) {
3392
+ let up = 0;
3393
+ let down = 0;
3394
+ for (const b of d.up) up += b.tokens;
3395
+ for (const b of d.down) down -= b.tokens;
3396
+ if (up > maxUp) maxUp = up;
3397
+ if (down > maxDown) maxDown = down;
3398
+ }
3399
+ else if (delta) for (const req of requests) {
3138
3400
  let up = 0;
3139
3401
  let down = 0;
3140
3402
  for (const c of CATS) {
@@ -3278,7 +3540,8 @@ window.__ModuleLoader__.load({
3278
3540
  props.granularity,
3279
3541
  props.focusTurn,
3280
3542
  requests,
3281
- adaptive
3543
+ adaptive,
3544
+ dnaDeltaOn
3282
3545
  ]);
3283
3546
  const measureRef = (0, react.useRef)(measureVisible);
3284
3547
  (0, react.useLayoutEffect)(() => {
@@ -3306,6 +3569,45 @@ window.__ModuleLoader__.load({
3306
3569
  return containHorizontalOverscroll(el);
3307
3570
  }, []);
3308
3571
  const stepsOf = (0, react.useMemo)(() => turnStepsOf(props.requests), [props.requests]);
3572
+ const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
3573
+ const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
3574
+ const hoveredBands = dnaOn && !dnaDeltaOn && hoveredIdx >= 0 ? dnaBands[hoveredIdx] : null;
3575
+ const hitBand = hoveredBands !== null && dnaHit !== null ? hoveredBands.find((b) => b.key === dnaHit && b.tokens > 0) ?? null : null;
3576
+ 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;
3577
+ const dnaSlices = (0, react.useMemo)(() => {
3578
+ if (!dnaOn || dnaHit === null) return null;
3579
+ const slices = [];
3580
+ if (dnaDeltaOn && dnaDeltas !== null) for (const d of dnaDeltas) {
3581
+ const hit = d.up.find((b) => b.key === dnaHit) ?? d.down.find((b) => b.key === dnaHit) ?? null;
3582
+ if (hit === null) {
3583
+ slices.push(null);
3584
+ continue;
3585
+ }
3586
+ const mag = Math.abs(hit.tokens);
3587
+ const edge = hit.tokens > 0 ? downPx + hit.off * deltaScale : downPx - (hit.off + mag) * deltaScale;
3588
+ slices.push({
3589
+ bottom: Math.round(edge),
3590
+ height: Math.max(1, Math.round(mag * deltaScale))
3591
+ });
3592
+ }
3593
+ else for (const bands of dnaBands) {
3594
+ const hit = bands.find((b) => b.key === dnaHit && b.tokens > 0) ?? null;
3595
+ slices.push(hit === null ? null : {
3596
+ bottom: Math.round(hit.off / maxTotal * CHART_H),
3597
+ height: Math.max(1, Math.round(hit.tokens / maxTotal * CHART_H))
3598
+ });
3599
+ }
3600
+ return slices;
3601
+ }, [
3602
+ dnaOn,
3603
+ dnaHit,
3604
+ dnaDeltaOn,
3605
+ dnaDeltas,
3606
+ dnaBands,
3607
+ downPx,
3608
+ deltaScale,
3609
+ maxTotal
3610
+ ]);
3309
3611
  const tipRowsOf = (req) => {
3310
3612
  const n = req.stepCount ?? 1;
3311
3613
  const head = props.granularity === "turn" ? n > 1 ? t("tip.turn", {
@@ -3316,19 +3618,20 @@ window.__ModuleLoader__.load({
3316
3618
  s: req.step ?? 0,
3317
3619
  n: stepsOf(req.turn)
3318
3620
  });
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
- }
3621
+ const band = hitBand ?? hoveredDelta;
3622
+ if (band !== null) return [head, t("trend.dnaItem", {
3623
+ label: dnaBaseLabel(band, t, catLabel),
3624
+ n: dnaDeltaOn ? fmtSigned(band.tokens) : fmt(band.tokens)
3625
+ })];
3626
+ if (delta)
3627
+ /* v8 ignore next 1 -- delta mode only receives records from
3628
+ deltaOf, which always assigns net; the fallback is defensive. */
3629
+ return [head, t("tip.delta", { n: fmtSigned(req.net ?? 0) })];
3325
3630
  return [head, focus !== null ? t("tip.cat", {
3326
3631
  cat: catLabel(focus),
3327
3632
  n: fmt(req.total)
3328
3633
  }) : t("tip.total", { n: fmt(req.total) })];
3329
3634
  };
3330
- const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
3331
- const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
3332
3635
  const tipColRef = (0, react.useRef)(0);
3333
3636
  /**
3334
3637
  * Glue the hover tip to its bar's VISIBLE slice. The tip deliberately does NOT live inside the scrolling
@@ -3418,6 +3721,7 @@ window.__ModuleLoader__.load({
3418
3721
  "data-catdim": props.hoverCat ?? void 0,
3419
3722
  onMouseLeave: () => {
3420
3723
  props.onHover(null);
3724
+ setDnaHit(null);
3421
3725
  },
3422
3726
  children: [
3423
3727
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "lc-grid lc-grid-top" }),
@@ -3440,9 +3744,16 @@ window.__ModuleLoader__.load({
3440
3744
  downPx: delta ? downPx : void 0,
3441
3745
  deltaScale: delta ? deltaScale : void 0,
3442
3746
  enterIndex: i,
3747
+ dna: dnaOn ? dnaBands[i] : null,
3748
+ dnaDelta: dnaDeltaOn && dnaDeltas !== null ? dnaDeltas[i] : null,
3749
+ dnaScale: dnaDeltaOn ? deltaScale : void 0,
3750
+ zeroBottom: dnaDeltaOn ? downPx : void 0,
3751
+ onDnaHit: setDnaHit,
3752
+ onPickBand: props.onPickBand,
3443
3753
  onSelect: props.onSelect,
3444
3754
  onHover: props.onHover
3445
- }, `${req.seq}:${props.granularity}`))
3755
+ }, `${req.seq}:${props.granularity}`)),
3756
+ dnaOn ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DnaHighlights, { slices: dnaSlices }) : null
3446
3757
  ]
3447
3758
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3448
3759
  className: "lc-turns",
@@ -4609,7 +4920,15 @@ window.__ModuleLoader__.load({
4609
4920
  const [rowQuery, setRowQuery] = (0, react.useState)("");
4610
4921
  const [rowKind, setRowKind] = (0, react.useState)(null);
4611
4922
  const [toolSort, setToolSort] = (0, react.useState)(() => settings.defaultToolSort());
4612
- const [dna, setDna] = (0, react.useState)(false);
4923
+ const [dnaLocal, setDnaLocal] = (0, react.useState)(false);
4924
+ const dnaLinked = props.dna !== void 0 && props.onDnaChange !== void 0;
4925
+ const dna = dnaLinked ? props.dna === true : dnaLocal;
4926
+ const setDna = (on) => {
4927
+ if (dnaLinked)
4928
+ /* v8 ignore next 1 -- `dnaLinked` requires both props, so the handler is always present. */
4929
+ props.onDnaChange?.(on);
4930
+ else setDnaLocal(on);
4931
+ };
4613
4932
  const [dnaKey, setDnaKey] = (0, react.useState)(null);
4614
4933
  const [deltaBase, setDeltaBase] = (0, react.useState)(() => settings.defaultDeltaBase());
4615
4934
  const onOpenCat = props.onOpenCat;
@@ -4645,7 +4964,9 @@ window.__ModuleLoader__.load({
4645
4964
  if (nodeFocus === null || nodeFocus === void 0) return;
4646
4965
  setSel(nodeFocus.step);
4647
4966
  setCat(nodeFocus.cat);
4648
- setOpenElem("n" + String(nodeFocus.seq));
4967
+ setOpenElem(nodeFocus.key);
4968
+ setRowQuery("");
4969
+ setRowKind(null);
4649
4970
  focusScrollRef.current = true;
4650
4971
  if (props.onNodeFocusHandled !== void 0) props.onNodeFocusHandled();
4651
4972
  }, [
@@ -4697,12 +5018,7 @@ window.__ModuleLoader__.load({
4697
5018
  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
5019
  const toolHitsOf = (tool) => toolHits.get(tool.name) ?? 0;
4699
5020
  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
- }
5021
+ const base = dnaBaseLabel(it, t, catLabel);
4706
5022
  return it.time !== void 0 ? base + " · " + fmtTime(it.time) : base;
4707
5023
  };
4708
5024
  const dnaItems = dna ? dnaOf(view) : null;
@@ -5022,7 +5338,7 @@ window.__ModuleLoader__.load({
5022
5338
  type: "button",
5023
5339
  className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
5024
5340
  onClick: () => {
5025
- setDna((on) => !on);
5341
+ setDna(!dna);
5026
5342
  },
5027
5343
  children: t("browser.dna")
5028
5344
  })
@@ -5635,9 +5951,10 @@ window.__ModuleLoader__.load({
5635
5951
  * The Context Dashboard's sidebar entry: a footer action stacked directly
5636
5952
  * above Settings (the harness's own foot layout: footer actions, then the
5637
5953
  * 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).
5954
+ * widths. The button carries the plugin emblem — in the mono seat, so the
5955
+ * glyph matches the harness's own footer rows rather than shouting over
5956
+ * them — and, on the wide column, its label. Clicking opens the overview
5957
+ * overlay through the shared module store (overviewStore.ts).
5641
5958
  *
5642
5959
  * The per-user `insightsEntry` preference takes the entry down (renders
5643
5960
  * null) without unregistering the seat. The subscription fails open: an
@@ -5663,7 +5980,8 @@ window.__ModuleLoader__.load({
5663
5980
  },
5664
5981
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextIcon, {
5665
5982
  size: props.wide === true ? 16 : 18,
5666
- className: "lc-ov-entry-icon"
5983
+ className: "lc-ov-entry-icon",
5984
+ mono: true
5667
5985
  }), props.wide === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5668
5986
  className: "lc-ov-entry-label",
5669
5987
  children: t("ov.entry")
@@ -10959,7 +11277,7 @@ window.__ModuleLoader__.load({
10959
11277
  return function PluginInfo() {
10960
11278
  const [latest, setLatest] = (0, react.useState)(null);
10961
11279
  (0, react.useEffect)(() => {
10962
- if ("0.60.0".includes("-dev")) return;
11280
+ if ("0.61.0".includes("-dev")) return;
10963
11281
  let on = true;
10964
11282
  fetchLatestVersion().then((v) => {
10965
11283
  if (on && v) setLatest(v);
@@ -10968,8 +11286,8 @@ window.__ModuleLoader__.load({
10968
11286
  on = false;
10969
11287
  };
10970
11288
  }, []);
10971
- const update = latest !== null && isNewerVersion(latest, "0.60.0") ? latest : null;
10972
- const nameText = "dsh-context (v0.60.0)";
11289
+ const update = latest !== null && isNewerVersion(latest, "0.61.0") ? latest : null;
11290
+ const nameText = "dsh-context (v0.61.0)";
10973
11291
  const nameValue = [nameText];
10974
11292
  if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10975
11293
  className: "lc-pi-update",
@@ -11932,6 +12250,7 @@ window.__ModuleLoader__.load({
11932
12250
  const [hoverTurn, setHoverTurn] = (0, react.useState)(null);
11933
12251
  const [granularity, setGranularity] = (0, react.useState)(() => settings.defaultGranularity());
11934
12252
  const [trendMode, setTrendMode] = (0, react.useState)(() => settings.defaultTrendMode());
12253
+ const [dna, setDna] = (0, react.useState)(false);
11935
12254
  const [adaptive, setAdaptive] = (0, react.useState)(false);
11936
12255
  const [focusTurn, setFocusTurn] = (0, react.useState)(null);
11937
12256
  const [jumpSeq, setJumpSeq] = (0, react.useState)(null);
@@ -11987,6 +12306,21 @@ window.__ModuleLoader__.load({
11987
12306
  const displayRequests = (0, react.useMemo)(() => granularity === "turn" ? aggregateByTurn(requests) : requests, [requests, granularity]);
11988
12307
  const stepsOf = (0, react.useMemo)(() => turnStepsOf(requests), [requests]);
11989
12308
  const markers = (0, react.useMemo)(() => attachMarkers(displayRequests, events), [displayRequests, events]);
12309
+ /* v8 ignore next 1 -- a missing projection returns the loading screen before the trend card
12310
+ (and its DNA toggle) renders, so `dna && data === null` cannot occur. */
12311
+ const dnaBands = (0, react.useMemo)(() => dna && data !== null ? displayRequests.map((req) => trendBandsOf(assemble(data, headers, req.seq))) : null, [
12312
+ dna,
12313
+ data,
12314
+ headers,
12315
+ displayRequests
12316
+ ]);
12317
+ const revealBand = (0, react.useCallback)((seq, band) => {
12318
+ setNodeFocus({
12319
+ step: seq,
12320
+ key: band.key,
12321
+ cat: band.cat
12322
+ });
12323
+ }, []);
11990
12324
  (0, react.useEffect)(() => {
11991
12325
  if (typeof sessionId !== "string" || sessionId === "") return;
11992
12326
  const take = () => {
@@ -12084,7 +12418,7 @@ window.__ModuleLoader__.load({
12084
12418
  if (step === null) return;
12085
12419
  setNodeFocus({
12086
12420
  step,
12087
- seq,
12421
+ key: "n" + String(seq),
12088
12422
  cat: "tool"
12089
12423
  });
12090
12424
  }, [requests]);
@@ -12096,7 +12430,7 @@ window.__ModuleLoader__.load({
12096
12430
  const step = isResponse ? next !== null ? next.seq : "live" : activeReq.seq;
12097
12431
  setNodeFocus({
12098
12432
  step,
12099
- seq: node.seq,
12433
+ key: "n" + String(node.seq),
12100
12434
  cat: node.cat
12101
12435
  });
12102
12436
  }, [
@@ -12158,6 +12492,19 @@ window.__ModuleLoader__.load({
12158
12492
  className: "lc-card-title-text",
12159
12493
  children: t("trend.title")
12160
12494
  }),
12495
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
12496
+ className: "lc-gran lc-trend-dna",
12497
+ role: "group",
12498
+ title: t("trend.dnaTip"),
12499
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
12500
+ type: "button",
12501
+ className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
12502
+ onClick: () => {
12503
+ setDna((v) => !v);
12504
+ },
12505
+ children: t("trend.dna")
12506
+ })
12507
+ }),
12161
12508
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
12162
12509
  className: "lc-gran lc-trend-adaptive",
12163
12510
  role: "group",
@@ -12229,6 +12576,8 @@ window.__ModuleLoader__.load({
12229
12576
  hoverCat: trendHoverCat,
12230
12577
  focusCat,
12231
12578
  adaptive,
12579
+ dna: dnaBands,
12580
+ onPickBand: revealBand,
12232
12581
  onSelect: setSelectedSeq,
12233
12582
  onHover: setHoveredSeq,
12234
12583
  onHoverTurn: setHoverTurn,
@@ -12268,7 +12617,9 @@ window.__ModuleLoader__.load({
12268
12617
  onNodeFocusHandled: clearNodeFocus,
12269
12618
  loadImage,
12270
12619
  detailState: source.detailState,
12271
- onDetailRetry: source.retryDetail
12620
+ onDetailRetry: source.retryDetail,
12621
+ dna,
12622
+ onDnaChange: setDna
12272
12623
  });
12273
12624
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12274
12625
  className: "lc-root",
@@ -12513,7 +12864,7 @@ window.__ModuleLoader__.load({
12513
12864
  }
12514
12865
  //#endregion
12515
12866
  //#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}}";
12867
+ 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
12868
  const tagId$15 = "dsh-context/tailwind.css";
12518
12869
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$15) + "]") === null) {
12519
12870
  const tag = document.createElement("style");
@@ -12524,7 +12875,7 @@ window.__ModuleLoader__.load({
12524
12875
  }
12525
12876
  //#endregion
12526
12877
  //#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}";
12878
+ 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
12879
  const tagId$14 = "dsh-context/base.css";
12529
12880
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$14) + "]") === null) {
12530
12881
  const tag = document.createElement("style");
@@ -12579,7 +12930,7 @@ window.__ModuleLoader__.load({
12579
12930
  }
12580
12931
  //#endregion
12581
12932
  //#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}";
12933
+ 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
12934
  const tagId$9 = "dsh-context/trendChart.css";
12584
12935
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
12585
12936
  const tag = document.createElement("style");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-context",
3
- "version": "0.60.0",
3
+ "version": "0.61.0",
4
4
  "description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
5
5
  "icon": "icon.svg",
6
6
  "author": "bowenliang123",
@@ -69,7 +69,8 @@
69
69
  "compatibility": {
70
70
  "dshReleases": {
71
71
  "0.1.5-rc.1": "compatible",
72
- "0.1.7-rc.2": "compatible"
72
+ "0.1.7-rc.2": "compatible",
73
+ "0.2.0-rc.2": "compatible"
73
74
  }
74
75
  }
75
76
  },