dsh-context 0.38.2 → 0.38.4

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
@@ -189,8 +189,8 @@ window.__ModuleLoader__.load({
189
189
  "footer": "估算口径:与 dsh 内置 tokenMeter 相同的固定密度启发式(约 4 字符 ≈ 1 token);「实际」为供应商上报用量。",
190
190
  "tip.step": "第 {t} 轮 · 第{s}步",
191
191
  "tip.turn": "第 {t} 轮 · 共 {n} 步",
192
+ "tip.turn1": "第 {t} 轮 · 共 1 步",
192
193
  "tip.total": "合计 ≈ {n}",
193
- "tip.actual": "(实际 {n})",
194
194
  "tip.delta": "Δ {n}",
195
195
  "ev.compaction": "压缩上下文(摘要替换 {n} 条消息)",
196
196
  "ev.prune": "剪枝工具输出",
@@ -249,6 +249,9 @@ window.__ModuleLoader__.load({
249
249
  "rich.md": "Markdown",
250
250
  "rich.toMd": "按 Markdown 渲染查看",
251
251
  "rich.toRaw": "查看原始文本",
252
+ "rich.md.copy": "复制",
253
+ "rich.md.copied": "已复制",
254
+ "rich.md.footnotes": "脚注",
252
255
  "block.thinking": "思考",
253
256
  "block.answer": "回答",
254
257
  "block.content": "内容",
@@ -457,8 +460,8 @@ window.__ModuleLoader__.load({
457
460
  "footer": "Estimate: same fixed-density heuristic as dsh’s built-in tokenMeter (~4 chars ≈ 1 token); “actual” is provider-reported usage.",
458
461
  "tip.step": "Turn {t} · Step {s}",
459
462
  "tip.turn": "Turn {t} · {n} steps",
463
+ "tip.turn1": "Turn {t} · 1 step",
460
464
  "tip.total": "Total ≈ {n}",
461
- "tip.actual": " (actual {n})",
462
465
  "tip.delta": "Δ {n}",
463
466
  "ev.compaction": "Context compacted (summary replaced {n} messages)",
464
467
  "ev.prune": "Tool output pruned",
@@ -517,6 +520,9 @@ window.__ModuleLoader__.load({
517
520
  "rich.md": "Markdown",
518
521
  "rich.toMd": "View as Markdown",
519
522
  "rich.toRaw": "View Raw Text",
523
+ "rich.md.copy": "Copy",
524
+ "rich.md.copied": "Copied",
525
+ "rich.md.footnotes": "Footnotes",
520
526
  "block.thinking": "Reasoning",
521
527
  "block.answer": "Response",
522
528
  "block.content": "Content",
@@ -1706,6 +1712,7 @@ window.__ModuleLoader__.load({
1706
1712
  }
1707
1713
  //#endregion
1708
1714
  //#region src/client/components/richText.tsx
1715
+ const Markdown = _deepseek_ai_dsh_client_ui_primitives.MarkdownText;
1709
1716
  function makeRichText(kit) {
1710
1717
  const { t } = kit;
1711
1718
  function useRichMode() {
@@ -1734,7 +1741,17 @@ window.__ModuleLoader__.load({
1734
1741
  }, line)));
1735
1742
  }
1736
1743
  function RichText(props) {
1737
- if (props.mode === "md") return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-desc-md" }, /* @__PURE__ */ React.createElement(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: props.text }));
1744
+ const mdLabels = React.useMemo(() => ({
1745
+ code: {
1746
+ copyLabel: t("rich.md.copy"),
1747
+ copiedLabel: t("rich.md.copied")
1748
+ },
1749
+ footnotes: t("rich.md.footnotes")
1750
+ }), [t]);
1751
+ if (props.mode === "md") return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-desc-md" }, /* @__PURE__ */ React.createElement(Markdown, {
1752
+ text: props.text,
1753
+ labels: mdLabels
1754
+ }));
1738
1755
  return /* @__PURE__ */ React.createElement(RawText, { text: props.text });
1739
1756
  }
1740
1757
  return {
@@ -2977,20 +2994,6 @@ window.__ModuleLoader__.load({
2977
2994
  response
2978
2995
  };
2979
2996
  }
2980
- /**
2981
- * seq → one-line reply preview for the chart tooltip: the response node's
2982
- * text, else its tool-call breadcrumb. Absent for usage-only replies and
2983
- * steps outside retention.
2984
- */
2985
- function replyTipsOf(nodes) {
2986
- const m = /* @__PURE__ */ new Map();
2987
- for (const n of nodes) {
2988
- if (n.cat !== "assistant") continue;
2989
- const s = n.text ?? (n.calls !== void 0 ? n.calls.join(" › ") : "");
2990
- if (s !== "") m.set(n.seq, s);
2991
- }
2992
- return m;
2993
- }
2994
2997
  //#endregion
2995
2998
  //#region src/client/fileActivity.ts
2996
2999
  const KIND_BY_TOOL = {
@@ -4830,7 +4833,7 @@ window.__ModuleLoader__.load({
4830
4833
  return function PluginInfo() {
4831
4834
  const [latest, setLatest] = React.useState(null);
4832
4835
  React.useEffect(() => {
4833
- if ("0.38.2".includes("-dev")) return;
4836
+ if ("0.38.4".includes("-dev")) return;
4834
4837
  let on = true;
4835
4838
  fetchLatestVersion().then((v) => {
4836
4839
  if (on && v) setLatest(v);
@@ -4839,8 +4842,8 @@ window.__ModuleLoader__.load({
4839
4842
  on = false;
4840
4843
  };
4841
4844
  }, []);
4842
- const update = latest !== null && isNewerVersion(latest, "0.38.2") ? latest : null;
4843
- const nameText = "dsh-context (v0.38.2)";
4845
+ const update = latest !== null && isNewerVersion(latest, "0.38.4") ? latest : null;
4846
+ const nameText = "dsh-context (v0.38.4)";
4844
4847
  const nameValue = [nameText];
4845
4848
  if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", {
4846
4849
  key: "update",
@@ -5399,11 +5402,14 @@ window.__ModuleLoader__.load({
5399
5402
  return requests.length > 0 ? requests[0] : null;
5400
5403
  }
5401
5404
  function makeTrendChart(kit) {
5402
- const { t, fmt, fmtTime, eventLabel, eventAt } = kit;
5405
+ const { t, fmt, eventLabel, eventAt } = kit;
5403
5406
  const CHART_H = 112;
5407
+ const fmtSigned = (v) => (v > 0 ? "+" : "") + fmt(v);
5404
5408
  const BAR_W = 14;
5405
5409
  const BAR_GAP = 2;
5406
5410
  const TURN_FILLS = ["rgba(128,128,128,0.12)", "rgba(128,128,128,0.26)"];
5411
+ const LABEL_OVERHANG = 48;
5412
+ const LABEL_GAP = 4;
5407
5413
  const anchorOf = (req) => typeof req.prompt === "number" && req.prompt > 0 && req.total > 0 ? req.prompt / req.total : 1;
5408
5414
  const barTotalOf = (req) => typeof req.prompt === "number" && req.prompt > 0 ? req.prompt : req.total;
5409
5415
  /**
@@ -5513,6 +5519,8 @@ window.__ModuleLoader__.load({
5513
5519
  const deltaScale = CHART_H / span;
5514
5520
  const upPx = Math.round(maxUp * deltaScale);
5515
5521
  const downPx = CHART_H - upPx;
5522
+ const q3Clear = Math.abs(28 - upPx) >= 11;
5523
+ const q1Clear = Math.abs(84 - upPx) >= 11;
5516
5524
  const groups = [];
5517
5525
  for (const req of requests) {
5518
5526
  let grp = groups.length > 0 ? groups[groups.length - 1] : null;
@@ -5545,9 +5553,12 @@ window.__ModuleLoader__.load({
5545
5553
  const lastSeqRef = React.useRef(0);
5546
5554
  const prevScrollWidthRef = React.useRef(0);
5547
5555
  /**
5548
- * Keep each turn label centered within its block's VISIBLE slice so it never scrolls out while any part of the block is on screen
5549
- * (narrower-than-label blocks stay put); reads (offsetWidth) batch before writes (transform) to avoid layout thrash out-of-view
5550
- * blocks need no measurement.
5556
+ * Keep each turn label centered within its block's VISIBLE slice, then thin colliding labels: a label wider
5557
+ * than its block overflows it, so consecutive narrow turns (14px bars, 2-digit "T12"s) would smear into each
5558
+ * other walking left→right in content coordinates, a label whose box reaches the previous KEPT one drops to
5559
+ * visibility:hidden. Blocks that cannot reach the viewport even overhung by a label skip their reads/writes
5560
+ * entirely (their transform/visibility just reset); reads (offsetWidth) batch before the writes to avoid layout
5561
+ * thrash, and unchanged styles write nothing.
5551
5562
  */
5552
5563
  const updateTurnLabels = (el) => {
5553
5564
  const labels = el.querySelectorAll(".lc-turn-label");
@@ -5555,23 +5566,35 @@ window.__ModuleLoader__.load({
5555
5566
  const sl = el.scrollLeft;
5556
5567
  const vr = sl + el.clientWidth;
5557
5568
  const writes = [];
5569
+ let chainR = -Infinity;
5558
5570
  for (let i = 0; i < n; i++) {
5559
5571
  const off = turnOffsets[i];
5560
5572
  const w = turnWidths[i];
5561
- const visL = Math.max(off, sl);
5562
- const visR = Math.min(off + w, vr);
5563
5573
  let dx = 0;
5564
- if (visR > visL) {
5574
+ let vis = "";
5575
+ if (off + w + LABEL_OVERHANG > sl && off - LABEL_OVERHANG < vr) {
5565
5576
  const lw = labels[i].offsetWidth;
5566
- if (lw < w) {
5577
+ const visL = Math.max(off, sl);
5578
+ const visR = Math.min(off + w, vr);
5579
+ if (visR > visL && lw < w) {
5567
5580
  const center = (visL + visR) / 2 - off;
5568
5581
  dx = Math.min(Math.max(center, lw / 2), w - lw / 2) - w / 2;
5569
5582
  }
5583
+ const left = off + w / 2 + dx - lw / 2;
5584
+ if (left < chainR) vis = "hidden";
5585
+ else chainR = left + lw + LABEL_GAP;
5570
5586
  }
5571
5587
  const next = dx !== 0 ? `translateX(${dx}px)` : "";
5572
- if (labels[i].style.transform !== next) writes.push([labels[i], next]);
5588
+ if (labels[i].style.transform !== next || labels[i].style.visibility !== vis) writes.push([
5589
+ labels[i],
5590
+ next,
5591
+ vis
5592
+ ]);
5593
+ }
5594
+ for (const [label, next, vis] of writes) {
5595
+ label.style.transform = next;
5596
+ label.style.visibility = vis;
5573
5597
  }
5574
- for (const [label, next] of writes) label.style.transform = next;
5575
5598
  };
5576
5599
  React.useLayoutEffect(() => {
5577
5600
  const el = scrollRef.current;
@@ -5605,23 +5628,22 @@ window.__ModuleLoader__.load({
5605
5628
  props.focusTurn,
5606
5629
  requests
5607
5630
  ]);
5608
- const tipOf = (req) => {
5609
- const head = req.stepCount !== void 0 && req.stepCount > 1 ? t("tip.turn", {
5631
+ const tipRowsOf = (req) => {
5632
+ const n = req.stepCount ?? 1;
5633
+ const head = props.granularity === "turn" ? n > 1 ? t("tip.turn", {
5610
5634
  t: req.turn ?? 0,
5611
- n: req.stepCount
5612
- }) : t("tip.step", {
5635
+ n
5636
+ }) : t("tip.turn1", { t: req.turn ?? 0 }) : t("tip.step", {
5613
5637
  t: req.turn ?? 0,
5614
5638
  s: req.step ?? 0
5615
5639
  });
5616
- const reply = props.replyTips?.get(req.seq);
5617
- const tail = reply !== void 0 ? " · “" + (reply.length > 48 ? reply.slice(0, 48) + "…" : reply) + "”" : "";
5618
5640
  if (delta) {
5619
5641
  /* v8 ignore next 1 -- delta mode only receives records from
5620
5642
  deltaOf, which always assigns net; the fallback is defensive. */
5621
5643
  const n = req.net ?? 0;
5622
- return head + " · " + fmtTime(req.time) + " · " + t("tip.delta", { n: (n > 0 ? "+" : "") + fmt(n) }) + tail;
5644
+ return [head, t("tip.delta", { n: (n > 0 ? "+" : "") + fmt(n) })];
5623
5645
  }
5624
- return head + " · " + fmtTime(req.time) + " · " + t("tip.total", { n: fmt(req.total) }) + (req.prompt !== void 0 ? " · " + t("tip.actual", { n: fmt(req.prompt) }) : "") + tail;
5646
+ return [head, t("tip.total", { n: fmt(barTotalOf(req)) })];
5625
5647
  };
5626
5648
  const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
5627
5649
  const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
@@ -5651,10 +5673,10 @@ window.__ModuleLoader__.load({
5651
5673
  tipColRef.current = hoveredIdx >= 0 ? hoveredIdx * 16 + BAR_W / 2 : 0;
5652
5674
  syncTip(scrollRef.current);
5653
5675
  });
5654
- return /* @__PURE__ */ React.createElement("div", { className: "lc-chartrow" }, /* @__PURE__ */ React.createElement("div", { className: "lc-axis" }, delta ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "lc-axis-top" }, (maxUp > 0 ? "+" : "") + fmt(maxUp)), /* @__PURE__ */ React.createElement("span", {
5676
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-chartrow" }, /* @__PURE__ */ React.createElement("div", { className: "lc-axis" }, delta ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "lc-axis-top" }, fmtSigned(maxUp)), q3Clear ? /* @__PURE__ */ React.createElement("span", { className: "lc-axis-q3" }, fmtSigned(Math.round(maxUp - span / 4))) : null, /* @__PURE__ */ React.createElement("span", {
5655
5677
  className: "lc-axis-mid",
5656
5678
  style: { top: `${13 + upPx}px` }
5657
- }, "0"), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-bot" }, (maxDown > 0 ? "-" : "") + fmt(maxDown))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "lc-axis-top" }, fmt(maxTotal)), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-mid" }, fmt(Math.round(maxTotal / 2))), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-bot" }, "0"))), /* @__PURE__ */ React.createElement("div", { className: "lc-chart-wrap" }, /* @__PURE__ */ React.createElement("div", {
5679
+ }, "0"), q1Clear ? /* @__PURE__ */ React.createElement("span", { className: "lc-axis-q1" }, fmtSigned(Math.round(maxUp - 3 * span / 4))) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-axis-bot" }, fmtSigned(-maxDown))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "lc-axis-top" }, fmt(maxTotal)), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-q3" }, fmt(Math.round(maxTotal * 3 / 4))), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-mid" }, fmt(Math.round(maxTotal / 2))), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-q1" }, fmt(Math.round(maxTotal / 4))), /* @__PURE__ */ React.createElement("span", { className: "lc-axis-bot" }, "0"))), /* @__PURE__ */ React.createElement("div", { className: "lc-chart-wrap" }, /* @__PURE__ */ React.createElement("div", {
5658
5680
  className: "lc-chart-scroll" + (props.activeTurn !== null ? " lc-chart-dim" : ""),
5659
5681
  ref: scrollRef,
5660
5682
  onScroll: (e) => {
@@ -5667,10 +5689,10 @@ window.__ModuleLoader__.load({
5667
5689
  onMouseLeave: () => {
5668
5690
  props.onHover(null);
5669
5691
  }
5670
- }, /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-top" }), delta ? /* @__PURE__ */ React.createElement("div", {
5692
+ }, /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-top" }), !delta || q3Clear ? /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-q3" }) : null, !delta || q1Clear ? /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-q1" }) : null, !delta ? /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-mid" }) : null, /* @__PURE__ */ React.createElement("div", {
5671
5693
  className: "lc-grid lc-grid-zero",
5672
- style: { top: `${18 + upPx}px` }
5673
- }) : /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-mid" }), requests.map((req, i) => /* @__PURE__ */ React.createElement(ChartBar, {
5694
+ style: delta ? { top: `${18 + upPx}px` } : void 0
5695
+ }), requests.map((req, i) => /* @__PURE__ */ React.createElement(ChartBar, {
5674
5696
  key: req.seq,
5675
5697
  req,
5676
5698
  marker: markers[i],
@@ -5705,7 +5727,7 @@ window.__ModuleLoader__.load({
5705
5727
  props.onPickTurn(grp.turn);
5706
5728
  }
5707
5729
  }, /* @__PURE__ */ React.createElement("span", { className: "lc-turn-label" }, `T${grp.turn}`));
5708
- }))), hoveredReq !== null ? /* @__PURE__ */ React.createElement("div", { className: "lc-chart-tip" }, tipOf(hoveredReq)) : null));
5730
+ }))), hoveredReq !== null ? /* @__PURE__ */ React.createElement("div", { className: "lc-chart-tip" }, tipRowsOf(hoveredReq).map((row, i) => /* @__PURE__ */ React.createElement("span", { key: i }, row))) : null));
5709
5731
  };
5710
5732
  }
5711
5733
  //#endregion
@@ -5847,7 +5869,6 @@ window.__ModuleLoader__.load({
5847
5869
  requests
5848
5870
  ]);
5849
5871
  const briefList = React.useMemo(() => data ? briefNodes(data) : [], [data]);
5850
- const replyTips = React.useMemo(() => replyTipsOf(briefList), [briefList]);
5851
5872
  const convNodes = conversationNodesOf(props);
5852
5873
  const bySeq = React.useMemo(() => {
5853
5874
  const m = /* @__PURE__ */ new Map();
@@ -6003,8 +6024,7 @@ window.__ModuleLoader__.load({
6003
6024
  },
6004
6025
  onFocusTurnHandled: () => {
6005
6026
  setFocusTurn(null);
6006
- },
6007
- replyTips
6027
+ }
6008
6028
  }), /* @__PURE__ */ React.createElement(RequestDetail, {
6009
6029
  request: activeReq,
6010
6030
  prev: trendMode === "delta" && activeIdx >= 0 ? activeIdx > 0 ? displayRequests[activeIdx - 1] : null : void 0,
@@ -6204,7 +6224,7 @@ window.__ModuleLoader__.load({
6204
6224
  }
6205
6225
  //#endregion
6206
6226
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/trendChart.css.mjs
6207
- const css$8 = ".lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-grid-zero{border-top-style:solid;border-top-color:#80808080}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;left:0;box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-cat-seg{transition:filter .12s,opacity .12s}.lc-chart[data-catdim] .lc-cat-seg{opacity:.35}.lc-chart[data-catdim=system] .lc-cat-seg[data-cat=system],.lc-chart[data-catdim=tools] .lc-cat-seg[data-cat=tools],.lc-chart[data-catdim=user] .lc-cat-seg[data-cat=user],.lc-chart[data-catdim=inject] .lc-cat-seg[data-cat=inject],.lc-chart[data-catdim=assistant] .lc-cat-seg[data-cat=assistant],.lc-chart[data-catdim=tool] .lc-cat-seg[data-cat=tool]{opacity:1;filter:brightness(1.18)}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;margin-top:4px;display:flex;overflow:hidden}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{text-overflow:ellipsis;max-width:100%;display:inline-block;overflow:hidden}";
6227
+ const css$8 = ".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{scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-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:#80808080;top:130px}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;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-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-cat-seg{transition:filter .12s,opacity .12s}.lc-chart[data-catdim] .lc-cat-seg{opacity:.35}.lc-chart[data-catdim=system] .lc-cat-seg[data-cat=system],.lc-chart[data-catdim=tools] .lc-cat-seg[data-cat=tools],.lc-chart[data-catdim=user] .lc-cat-seg[data-cat=user],.lc-chart[data-catdim=inject] .lc-cat-seg[data-cat=inject],.lc-chart[data-catdim=assistant] .lc-cat-seg[data-cat=assistant],.lc-chart[data-catdim=tool] .lc-cat-seg[data-cat=tool]{opacity:1;filter:brightness(1.18)}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;margin-top:4px;display:flex;overflow:hidden}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{display:inline-block}";
6208
6228
  const tagId$8 = "dsh-context/trendChart.css";
6209
6229
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$8) + "]") === null) {
6210
6230
  const tag = document.createElement("style");
package/lib/index.js CHANGED
@@ -2,7 +2,6 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import { dirname, join, normalize } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { z } from "zod";
5
- import { settingsNamespace } from "@deepseek-ai/dsh-settings";
6
5
  import z$1 from "@deepseek-ai/schemastery";
7
6
  import { deriveEventMessage } from "@deepseek-ai/dsh-session";
8
7
  /**
@@ -657,7 +656,7 @@ const SettingsSchema = z$1.object({
657
656
  /** Serve the namespace while a settings provider is composed; inert otherwise. */
658
657
  function installSettings(ctx) {
659
658
  ctx.inject(["settings"], (sctx) => {
660
- sctx.settings.register(settingsNamespace(SETTINGS_NAMESPACE), SettingsSchema);
659
+ sctx.settings.register(SETTINGS_NAMESPACE, SettingsSchema);
661
660
  });
662
661
  }
663
662
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-context",
3
- "version": "0.38.2",
3
+ "version": "0.38.4",
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
  "author": "bowenliang123",
6
6
  "repository": {
@@ -68,14 +68,16 @@
68
68
  "ui"
69
69
  ],
70
70
  "license": "Apache-2.0",
71
+ "dependencies": {
72
+ "zod": "^4.4.3"
73
+ },
71
74
  "peerDependencies": {
72
75
  "@deepseek-ai/cordis": "^4.0.1",
73
76
  "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.7",
74
77
  "@deepseek-ai/dsh-session": ">=0.1.0-rc.7",
75
78
  "@deepseek-ai/dsh-settings": ">=0.1.0-rc.7",
76
79
  "@deepseek-ai/schemastery": "^3.18.1",
77
- "react": "^18.3.1",
78
- "zod": "^4.4.3"
80
+ "react": "^18.3.1"
79
81
  },
80
82
  "peerDependenciesMeta": {
81
83
  "@deepseek-ai/dsh-client-ui-primitives": {
@@ -92,6 +94,7 @@
92
94
  "@deepseek-ai/dsh-session-projection": "^0.1.1-rc.2",
93
95
  "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
94
96
  "@deepseek-ai/schemastery": "^3.18.1",
97
+ "zod": "^4.4.3",
95
98
  "@stylistic/eslint-plugin": "^5.10.0",
96
99
  "@types/node": "^26.2.0",
97
100
  "@types/react": "^18.3.31",