dsh-context 0.6.0 → 0.6.1

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 (2) hide show
  1. package/lib/client.js +28 -26
  2. package/package.json +4 -1
package/lib/client.js CHANGED
@@ -186,23 +186,21 @@ function makeView(ctx, t) {
186
186
  let total = 0;
187
187
  for (const p of props.parts) total += p.value;
188
188
  const scale = props.max !== void 0 && props.max > total ? props.max : total;
189
- const wrapRef = React.useRef(null);
190
- const [tip, setTip] = React.useState(null);
191
- const showTip = (e, p) => {
192
- const rect = wrapRef.current?.getBoundingClientRect();
193
- const left = rect ? e.clientX - rect.left : 50;
194
- const width = rect?.width ?? 200;
195
- setTip({
196
- key: p.key,
197
- text: catLabel(p.key) + " " + fmt(p.value) + " (" + Math.round(p.value / total * 100) + "%)",
198
- left: Math.max(48, Math.min(left, width - 48))
199
- });
200
- if (props.onHoverKey !== void 0) props.onHoverKey(p.key);
201
- };
202
- const clearHover = () => {
203
- setTip(null);
204
- if (props.onHoverKey !== void 0) props.onHoverKey(null);
205
- };
189
+ let tip = null;
190
+ if (props.hoverKey !== null && props.hoverKey !== void 0) {
191
+ let acc = 0;
192
+ for (const p of props.parts) {
193
+ const pct = scale > 0 ? p.value / scale * 100 : 0;
194
+ if (p.key === props.hoverKey && p.value > 0) {
195
+ tip = {
196
+ text: catLabel(p.key) + " " + fmt(p.value) + " (" + Math.round(p.value / total * 100) + "%)",
197
+ leftPct: Math.max(12, Math.min(acc + pct / 2, 88))
198
+ };
199
+ break;
200
+ }
201
+ acc += pct;
202
+ }
203
+ }
206
204
  return h(
207
205
  "div",
208
206
  { className: "lc-stacked-wrap" },
@@ -211,8 +209,9 @@ function makeView(ctx, t) {
211
209
  {
212
210
  className: "lc-stacked",
213
211
  style: { height: (props.height || 14) + "px" },
214
- ref: wrapRef,
215
- onMouseLeave: clearHover
212
+ onMouseLeave: () => {
213
+ if (props.onHoverKey !== void 0) props.onHoverKey(null);
214
+ }
216
215
  },
217
216
  total <= 0 ? null : props.parts.map((p) => {
218
217
  if (!p.value) return null;
@@ -221,16 +220,13 @@ function makeView(ctx, t) {
221
220
  key: p.key,
222
221
  className: "lc-stacked-seg" + (on ? " lc-stacked-seg-on" : ""),
223
222
  style: { width: p.value / scale * 100 + "%", background: p.color },
224
- onMouseEnter: (e) => {
225
- showTip(e, p);
226
- },
227
- onMouseMove: (e) => {
228
- showTip(e, p);
223
+ onMouseEnter: () => {
224
+ if (props.onHoverKey !== void 0) props.onHoverKey(p.key);
229
225
  }
230
226
  });
231
227
  })
232
228
  ),
233
- tip ? h("div", { className: "lc-bar-tip", style: { left: tip.left + "px" } }, tip.text) : null
229
+ tip ? h("div", { className: "lc-bar-tip", style: { left: tip.leftPct + "%" } }, tip.text) : null
234
230
  );
235
231
  }
236
232
  function Legend(props) {
@@ -295,6 +291,7 @@ function makeView(ctx, t) {
295
291
  }
296
292
  const scrollRef = React.useRef(null);
297
293
  const scrolledOnce = React.useRef(false);
294
+ const lastGranRef = React.useRef(props.granularity);
298
295
  const [edges, setEdges] = React.useState({ left: false, right: false });
299
296
  const updateEdges = (el) => {
300
297
  const left = el.scrollLeft > 4;
@@ -304,6 +301,10 @@ function makeView(ctx, t) {
304
301
  React.useLayoutEffect(() => {
305
302
  const el = scrollRef.current;
306
303
  if (el === null) return;
304
+ if (props.granularity !== lastGranRef.current) {
305
+ lastGranRef.current = props.granularity;
306
+ scrolledOnce.current = false;
307
+ }
307
308
  if (!scrolledOnce.current) {
308
309
  scrolledOnce.current = true;
309
310
  el.scrollLeft = el.scrollWidth;
@@ -647,6 +648,7 @@ function makeView(ctx, t) {
647
648
  selectedSeq: pinnedReq ? pinnedReq.seq : null,
648
649
  hoveredSeq,
649
650
  activeTurn,
651
+ granularity,
650
652
  onSelect: setSelectedSeq,
651
653
  onHover: setHoveredSeq,
652
654
  onHoverTurn: setHoverTurn
@@ -689,7 +691,7 @@ const STYLES = [
689
691
  ".lc-gran { margin-left: auto; display: flex; gap: 2px; background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 1px; }",
690
692
  ".lc-gran-btn { border: 0; background: transparent; color: var(--dsw-alias-label-secondary); font-size: 11px; line-height: 1; padding: 3px 8px; border-radius: 5px; cursor: pointer; font-family: inherit; }",
691
693
  ".lc-gran-btn:hover { color: var(--dsw-alias-label-primary); }",
692
- ".lc-gran-on, .lc-gran-on:hover { background: var(--dsw-alias-brand-primary); color: #fff; }",
694
+ ".lc-gran-on, .lc-gran-on:hover { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }",
693
695
  ".lc-overview-num { margin-bottom: 8px; }",
694
696
  ".lc-overview-num b { font-size: 20px; }",
695
697
  ".lc-overview-num span { color: var(--dsw-alias-label-secondary); }",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-context",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Context insight panel for DeepSeek Harness: a Context tab (beside Chat/Trajectory) showing what the model's context window is made of and how it evolves — composition, per-request history, compactions, injections, and model switches.",
5
5
  "author": "bowenliang123",
6
6
  "repository": {
@@ -60,6 +60,9 @@
60
60
  "@types/react": "^18.3.31",
61
61
  "esbuild": "^0.28.2",
62
62
  "husky": "^9.1.7",
63
+ "jsdom": "^30.0.1",
64
+ "react": "^18.3.1",
65
+ "react-dom": "^18.3.1",
63
66
  "typescript": "^7.0.2"
64
67
  },
65
68
  "packageManager": "pnpm@11.9.0"