dsh-context 0.18.0 → 0.19.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 (3) hide show
  1. package/lib/client.js +120 -19
  2. package/lib/index.js +12 -8
  3. package/package.json +2 -1
package/lib/client.js CHANGED
@@ -103,7 +103,13 @@ var DICT_ZH = {
103
103
  "tool.params": "\u53C2\u6570",
104
104
  "tool.paramsEmpty": "\uFF08\u65E0\u53C2\u6570\uFF09",
105
105
  "tool.jsonToggle": "\u67E5\u770B\u539F\u59CB JSON",
106
- "tool.jsonHide": "\u6536\u8D77"
106
+ "tool.jsonHide": "\u6536\u8D77",
107
+ // Detail-card view switch (system prompt / tool description / message and
108
+ // injection bodies): a segmented pill — segment labels + tooltips.
109
+ "rich.raw": "\u539F\u6587",
110
+ "rich.md": "Markdown",
111
+ "rich.toMd": "\u6309 Markdown \u6E32\u67D3\u67E5\u770B",
112
+ "rich.toRaw": "\u67E5\u770B\u539F\u59CB\u6587\u672C"
107
113
  };
108
114
  var DICT_EN = {
109
115
  "tab": "Context",
@@ -201,7 +207,13 @@ var DICT_EN = {
201
207
  "tool.params": "Parameters",
202
208
  "tool.paramsEmpty": "(no parameters)",
203
209
  "tool.jsonToggle": "View Raw JSON",
204
- "tool.jsonHide": "Collapse"
210
+ "tool.jsonHide": "Collapse",
211
+ // Detail-card view switch (system prompt / tool description / message and
212
+ // injection bodies): a segmented pill — segment labels + tooltips.
213
+ "rich.raw": "Raw",
214
+ "rich.md": "Markdown",
215
+ "rich.toMd": "View as Markdown",
216
+ "rich.toRaw": "View Raw Text"
205
217
  };
206
218
 
207
219
  // src/client/modalStore.ts
@@ -393,6 +405,42 @@ function makeNodeList(kit) {
393
405
  };
394
406
  }
395
407
 
408
+ // src/client/components/richText.tsx
409
+ var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
410
+ function makeRichText(kit) {
411
+ const { t } = kit;
412
+ function useRichMode() {
413
+ const [mode, setMode] = React.useState("md");
414
+ return [mode, setMode];
415
+ }
416
+ function RichSwitch(props) {
417
+ const seg = (m, label, tip) => /* @__PURE__ */ React.createElement(
418
+ "button",
419
+ {
420
+ type: "button",
421
+ className: "lc-rich-seg-btn" + (props.mode === m ? " lc-rich-seg-on" : ""),
422
+ title: tip,
423
+ onClick: () => {
424
+ props.onPick(m);
425
+ }
426
+ },
427
+ label
428
+ );
429
+ return /* @__PURE__ */ React.createElement("span", { className: "lc-rich-seg" + (props.inHead === true ? " lc-rich-seg-head" : "") }, seg("raw", t("rich.raw"), t("rich.toRaw")), seg("md", t("rich.md"), t("rich.toMd")));
430
+ }
431
+ function RichText(props) {
432
+ if (props.mode === "md") {
433
+ return /* @__PURE__ */ React.createElement("div", { className: props.mdClass ?? "lc-br-md" }, /* @__PURE__ */ React.createElement(import_dsh_client_ui_primitives.MarkdownText, { text: props.text }));
434
+ }
435
+ return /* @__PURE__ */ React.createElement("pre", { className: props.rawClass ?? "lc-br-pre" }, props.text);
436
+ }
437
+ function RichCard(props) {
438
+ const [mode, setMode] = useRichMode();
439
+ return /* @__PURE__ */ React.createElement("div", { className: props.className ?? "lc-br-content" }, /* @__PURE__ */ React.createElement(RichSwitch, { mode, onPick: setMode }), props.render(mode));
440
+ }
441
+ return { RichText, RichCard, RichSwitch, useRichMode };
442
+ }
443
+
396
444
  // src/client/components/browser.tsx
397
445
  function unionTypesOf(p) {
398
446
  const branches = [];
@@ -449,7 +497,9 @@ function ParamRow(props) {
449
497
  return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-param-row" }, /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-name" }, props.name), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-type" }, typeLabel), /* @__PURE__ */ React.createElement("span", { className: props.required ? "lc-ts-param-req" : "lc-ts-param-req-off" }, props.required ? "\u2713" : "\xB7"), typeof desc === "string" && desc !== "" ? /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-desc" }, desc) : null);
450
498
  }
451
499
  function ToolSchema(props) {
500
+ const { rich } = props;
452
501
  const [jsonOpen, setJsonOpen] = React.useState(false);
502
+ const [descMode, setDescMode] = rich.useRichMode();
453
503
  const params = React.useMemo(() => paramsOf(props.schema), [props.schema]);
454
504
  const rows = React.useMemo(() => {
455
505
  if (params === null) return [];
@@ -468,7 +518,15 @@ function ToolSchema(props) {
468
518
  () => props.schema !== void 0 ? JSON.stringify(props.schema, null, 2) : "",
469
519
  [props.schema]
470
520
  );
471
- return /* @__PURE__ */ React.createElement(React.Fragment, null, props.description !== void 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", null, props.labels.desc)), /* @__PURE__ */ React.createElement("pre", { className: "lc-ts-desc-body" }, props.description)) : null, params !== null && rows.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", null, props.labels.title), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-card-count" }, rows.length)), rows.map((r) => /* @__PURE__ */ React.createElement(ParamRow, { key: r.name, name: r.name, schema: r.schema, required: r.required }))) : params !== null ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-params-empty" }, props.labels.empty) : null, schemaJson !== "" ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-json" }, /* @__PURE__ */ React.createElement(
521
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, props.description !== void 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", null, props.labels.desc), /* @__PURE__ */ React.createElement(rich.RichSwitch, { mode: descMode, onPick: setDescMode, inHead: true })), /* @__PURE__ */ React.createElement(
522
+ rich.RichText,
523
+ {
524
+ text: props.description,
525
+ mode: descMode,
526
+ rawClass: "lc-ts-desc-body",
527
+ mdClass: "lc-ts-desc-md"
528
+ }
529
+ )) : null, params !== null && rows.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", null, props.labels.title), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-card-count" }, rows.length)), rows.map((r) => /* @__PURE__ */ React.createElement(ParamRow, { key: r.name, name: r.name, schema: r.schema, required: r.required }))) : params !== null ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-params-empty" }, props.labels.empty) : null, schemaJson !== "" ? /* @__PURE__ */ React.createElement("div", { className: "lc-ts-json" }, /* @__PURE__ */ React.createElement(
472
530
  "button",
473
531
  {
474
532
  type: "button",
@@ -481,27 +539,37 @@ function ToolSchema(props) {
481
539
  ), jsonOpen ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, schemaJson) : null) : null);
482
540
  }
483
541
  function RawBlocks(props) {
542
+ const { rich } = props;
484
543
  return /* @__PURE__ */ React.createElement(React.Fragment, null, props.blocks.map((b, i) => {
485
544
  const blk = b;
486
545
  if (blk !== null && typeof blk === "object" && (blk.type === "text" || blk.type === "reasoning") && typeof blk.text === "string") {
487
- return /* @__PURE__ */ React.createElement("pre", { key: i, className: "lc-br-pre" + (blk.type === "reasoning" ? " lc-br-dim" : "") }, blk.text);
546
+ if (blk.type === "reasoning") {
547
+ return /* @__PURE__ */ React.createElement("pre", { key: i, className: "lc-br-pre lc-br-dim" }, blk.text);
548
+ }
549
+ return /* @__PURE__ */ React.createElement(rich.RichText, { key: i, text: blk.text, mode: props.mode });
488
550
  }
489
551
  if (blk !== null && typeof blk === "object" && blk.type === "tool-result" && Array.isArray(blk.content)) {
490
- return /* @__PURE__ */ React.createElement(RawBlocks, { key: i, blocks: blk.content });
552
+ return /* @__PURE__ */ React.createElement(RawBlocks, { key: i, blocks: blk.content, mode: props.mode, rich });
491
553
  }
492
554
  return /* @__PURE__ */ React.createElement("pre", { key: i, className: "lc-br-pre lc-br-dim" }, JSON.stringify(b, null, 2));
493
555
  }));
494
556
  }
495
557
  function NodeContent(props) {
496
- const { node, conv } = props;
558
+ const { node, conv, rich } = props;
559
+ const richable = node.cat === "user" || node.cat === "assistant" || node.cat === "inject";
560
+ const wrap = (render) => richable ? /* @__PURE__ */ React.createElement(rich.RichCard, { render }) : /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, render("raw"));
497
561
  if (conv === void 0) {
498
- return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, node.text !== void 0 && node.text !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre" }, node.text) : null, /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, props.hint));
562
+ if (node.text === void 0 || node.text === "") {
563
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, props.hint));
564
+ }
565
+ return wrap((mode) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(rich.RichText, { text: node.text ?? "", mode }), /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, props.hint)));
499
566
  }
500
567
  if (conv.kind === "assistant" && Array.isArray(conv.blocks)) {
501
- return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, conv.blocks.map((b, i) => {
568
+ const blocks = conv.blocks;
569
+ return wrap((mode) => /* @__PURE__ */ React.createElement(React.Fragment, null, blocks.map((b, i) => {
502
570
  const blk = b;
503
571
  if (blk.kind === "text" && typeof blk.text === "string") {
504
- return /* @__PURE__ */ React.createElement("pre", { key: i, className: "lc-br-pre" }, blk.text);
572
+ return /* @__PURE__ */ React.createElement(rich.RichText, { key: i, text: blk.text, mode });
505
573
  }
506
574
  if (blk.kind === "reasoning" && typeof blk.text === "string") {
507
575
  return /* @__PURE__ */ React.createElement("pre", { key: i, className: "lc-br-pre lc-br-dim" }, blk.text);
@@ -510,16 +578,16 @@ function NodeContent(props) {
510
578
  return /* @__PURE__ */ React.createElement("div", { key: i, className: "lc-br-call" }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" }, "\u2192 " + String(blk.name ?? "?")), typeof blk.argsRaw === "string" && blk.argsRaw !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, blk.argsRaw) : null);
511
579
  }
512
580
  return null;
513
- }));
581
+ })));
514
582
  }
515
583
  if (conv.kind === "tool-result") {
516
- return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, conv.call != null ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-call" }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" }, "\u2190 " + conv.call.name), conv.call.argsRaw !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, conv.call.argsRaw) : null) : null, Array.isArray(conv.content) ? /* @__PURE__ */ React.createElement(RawBlocks, { blocks: conv.content }) : null);
584
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, conv.call != null ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-call" }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" }, "\u2190 " + conv.call.name), conv.call.argsRaw !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, conv.call.argsRaw) : null) : null, Array.isArray(conv.content) ? /* @__PURE__ */ React.createElement(RawBlocks, { blocks: conv.content, mode: "raw", rich }) : null);
517
585
  }
518
586
  if (conv.kind === "compaction") {
519
- return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, typeof conv.summary === "string" && conv.summary !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre" }, conv.summary) : null);
587
+ return wrap((mode) => /* @__PURE__ */ React.createElement(React.Fragment, null, typeof conv.summary === "string" && conv.summary !== "" ? /* @__PURE__ */ React.createElement(rich.RichText, { text: conv.summary, mode }) : null));
520
588
  }
521
589
  if (Array.isArray(conv.content)) {
522
- return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement(RawBlocks, { blocks: conv.content }));
590
+ return wrap((mode) => /* @__PURE__ */ React.createElement(RawBlocks, { blocks: conv.content, mode, rich }));
523
591
  }
524
592
  return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, props.hint));
525
593
  }
@@ -541,6 +609,7 @@ function lastOfTurn(requests, turn) {
541
609
  function makeContextBrowser(kit, StackedBar) {
542
610
  const { t, fmt: fmt3, fmtTime: fmtTime2, catLabel } = kit;
543
611
  const nodeText = makeNodeText(kit);
612
+ const rich = makeRichText(kit);
544
613
  const catColor = {};
545
614
  for (const c of CATS) catColor[c.key] = c.color;
546
615
  const MAX_AUTO_PAGES = 20;
@@ -637,7 +706,7 @@ function makeContextBrowser(kit, StackedBar) {
637
706
  system.replace(/\s+/g, " ").trim().slice(0, 80),
638
707
  breakdown.system,
639
708
  void 0,
640
- /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre" }, system))
709
+ /* @__PURE__ */ React.createElement(rich.RichCard, { render: (mode) => /* @__PURE__ */ React.createElement(rich.RichText, { text: system, mode }) })
641
710
  );
642
711
  }
643
712
  if (c === "tools") {
@@ -656,7 +725,7 @@ function makeContextBrowser(kit, StackedBar) {
656
725
  tool.name,
657
726
  tool.tokens,
658
727
  void 0,
659
- /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement(ToolSchema, { description: tool.description, schema: tool.schema, labels }))
728
+ /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement(ToolSchema, { description: tool.description, schema: tool.schema, rich, labels }))
660
729
  );
661
730
  });
662
731
  }
@@ -684,6 +753,7 @@ function makeContextBrowser(kit, StackedBar) {
684
753
  {
685
754
  node: n,
686
755
  conv: bySeq.get(n.seq),
756
+ rich,
687
757
  hint: bySeq.get(n.seq) === void 0 && awaiting ? t("browser.loading") : t("browser.noContent")
688
758
  }
689
759
  )
@@ -1262,11 +1332,42 @@ var STYLES = [
1262
1332
  // body compact).
1263
1333
  ".lc-ts-json { display: flex; flex-direction: column; gap: 4px; }",
1264
1334
  ".lc-ts-json-toggle { align-self: flex-start; border: 0; background: transparent; color: var(--dsw-alias-label-secondary); font: inherit; font-size: 11px; padding: 0; cursor: pointer; }",
1265
- ".lc-ts-json-toggle:hover { color: var(--dsw-alias-label-primary); text-decoration: underline; }"
1335
+ ".lc-ts-json-toggle:hover { color: var(--dsw-alias-label-primary); text-decoration: underline; }",
1336
+ // ---- Raw/markdown view switch (detail cards: system prompt, tool
1337
+ // description, user/assistant message + injection bodies). A segmented
1338
+ // pill mirroring the trend chart's 步骤/轮次 control (`lc-gran`), riding
1339
+ // the card's top-right corner as a self-end item of the content column
1340
+ // (no absolute overlay, so it never covers text); the `in-head` variant
1341
+ // sits at the right end of the tool description card's title row. The
1342
+ // markdown box reuses the raw <pre> chrome minus the pre whitespace. ----
1343
+ ".lc-rich-seg { align-self: flex-end; display: flex; gap: 2px; background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 1px; }",
1344
+ ".lc-rich-seg-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; }",
1345
+ ".lc-rich-seg-btn:hover { color: var(--dsw-alias-label-primary); }",
1346
+ ".lc-rich-seg-on, .lc-rich-seg-on:hover { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }",
1347
+ ".lc-rich-seg-head { align-self: auto; margin-left: auto; }",
1348
+ ".lc-br-md { padding: 4px 10px; background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; color: var(--dsw-alias-label-primary); font-size: 12px; line-height: 1.55; word-break: break-word; max-height: 320px; overflow-y: auto; scrollbar-width: thin; }",
1349
+ ".lc-ts-desc-md { padding: 4px 10px; color: var(--dsw-alias-label-primary); font-size: 12px; line-height: 1.55; word-break: break-word; max-height: 160px; overflow-y: auto; scrollbar-width: thin; }",
1350
+ // The shared markdown renderer sizes its root/headings for chat bubbles;
1351
+ // inside a detail card the base size sits one step ABOVE the raw text
1352
+ // (13px vs 12px — a proportional face at 13px matches the visual weight
1353
+ // of the raw view's 12px monospace) and the heading scale collapses to a
1354
+ // weight-only bump (specificity beats the renderer's one-class rules).
1355
+ // Inline code keeps the FULL size too — the renderer shrinks it to
1356
+ // 0.875em (!important) and table code to 13px, both visibly off. Its
1357
+ // `font` shorthand also drags in a ~22px line-height, TALLER than the
1358
+ // 13px/1.55 paragraph line (~20px), so a code chip wrapping onto the
1359
+ // next line sticks to the neighbor line's chip; pin the chip just under
1360
+ // the paragraph line (1.3em + 1px padding ≈ 19px) to reopen the gap.
1361
+ ".lc-br-md > div, .lc-ts-desc-md > div { font-size: 13px; line-height: 1.55; }",
1362
+ ".lc-br-md div :is(h1, h2, h3, h4, h5, h6), .lc-ts-desc-md div :is(h1, h2, h3, h4, h5, h6) { font-size: 13px; font-weight: 600; margin: 10px 0 4px; }",
1363
+ ".lc-br-md div p, .lc-ts-desc-md div p { margin: 6px 0; }",
1364
+ ".lc-br-md div pre, .lc-ts-desc-md div pre { margin: 6px 0; }",
1365
+ ".lc-br-md div :not(pre) > code, .lc-ts-desc-md div :not(pre) > code { font-size: 1em !important; line-height: 1.3; padding: 1px 5px; box-decoration-break: clone; }",
1366
+ ".lc-br-md div table code, .lc-ts-desc-md div table code { font-size: inherit; }"
1266
1367
  ].join("\n");
1267
1368
 
1268
1369
  // src/client/components/events.tsx
1269
- var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
1370
+ var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
1270
1371
 
1271
1372
  // src/client/format.ts
1272
1373
  function fmt(n) {
@@ -1334,7 +1435,7 @@ function makeEventList(kit) {
1334
1435
  return /* @__PURE__ */ React.createElement("div", { className: "lc-events", ref: rootRef }, sorted.map((ev, i) => {
1335
1436
  const label = eventLabel(ev);
1336
1437
  const at = eventAt(ev);
1337
- const glyph = ev.kind === "inject" ? /* @__PURE__ */ React.createElement(import_dsh_client_ui_primitives.IconPlusOutline16, null) : ev.kind === "model" ? /* @__PURE__ */ React.createElement(import_dsh_client_ui_primitives.IconBranchOutline16, null) : EVENT_ICONS[ev.kind] || "\u2022";
1438
+ const glyph = ev.kind === "inject" ? /* @__PURE__ */ React.createElement(import_dsh_client_ui_primitives2.IconPlusOutline16, null) : ev.kind === "model" ? /* @__PURE__ */ React.createElement(import_dsh_client_ui_primitives2.IconBranchOutline16, null) : EVENT_ICONS[ev.kind] || "\u2022";
1338
1439
  return /* @__PURE__ */ React.createElement("div", { key: ev.seq + "-" + i, className: "lc-event" }, /* @__PURE__ */ React.createElement("span", { className: "lc-event-icon lc-event-" + ev.kind }, glyph), /* @__PURE__ */ React.createElement("span", { className: "lc-kind lc-kind-" + ev.kind }, t("kind." + ev.kind)), /* @__PURE__ */ React.createElement("span", { className: "lc-event-label" }, label), at !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-event-at" }, at) : null, ev.tokens ? /* @__PURE__ */ React.createElement("span", { className: "lc-event-tokens" + (ev.kind === "inject" ? " lc-up" : " lc-down") }, (ev.kind === "inject" ? "+" : "\u2212") + fmt3(ev.tokens)) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-event-time" }, fmtTime2(ev.time)));
1339
1440
  }));
1340
1441
  };
@@ -1342,7 +1443,7 @@ function makeEventList(kit) {
1342
1443
 
1343
1444
  // src/client/meta.ts
1344
1445
  var PLUGIN_NAME = "dsh-context";
1345
- var PLUGIN_VERSION = true ? "0.18.0" : "0.0.0-dev";
1446
+ var PLUGIN_VERSION = true ? "0.19.1" : "0.0.0-dev";
1346
1447
  var PLUGIN_REPO = true ? "https://github.com/bowenliang123/dsh-context" : "https://github.com/bowenliang123/dsh-context";
1347
1448
  var PLUGIN_REPO_SHORT = PLUGIN_REPO.replace(/^https?:\/\/github\.com\//, "");
1348
1449
 
package/lib/index.js CHANGED
@@ -211,10 +211,6 @@ function createTimelineState() {
211
211
  systemTokens: 0,
212
212
  toolsTokens: 0,
213
213
  toolList: [],
214
- model: void 0,
215
- provider: void 0,
216
- lastModel: void 0,
217
- contextWindow: void 0,
218
214
  requests: [],
219
215
  events: [],
220
216
  archived: [],
@@ -274,7 +270,7 @@ function applySurface(st, ev, type, data, message) {
274
270
  if (utext !== "") node.text = utext;
275
271
  }
276
272
  const shadowedSeqs = st.pendingShadowedSeqs;
277
- st.pendingShadowedSeqs = void 0;
273
+ delete st.pendingShadowedSeqs;
278
274
  const op = ev.surfaceOp;
279
275
  if (op !== null && typeof op === "object" && op.op === "replace") {
280
276
  if (Array.isArray(shadowedSeqs) && shadowedSeqs.length > 0) {
@@ -394,8 +390,6 @@ function applyTimeline(state, event, bounds) {
394
390
  const s = ensure();
395
391
  const total = s.systemTokens + s.toolsTokens + s.sums.user + s.sums.inject + s.sums.assistant + s.sums.tool;
396
392
  const record = {
397
- turn: data && typeof data.turn === "number" ? data.turn : void 0,
398
- step: data && typeof data.step === "number" ? data.step : void 0,
399
393
  time: event.time,
400
394
  seq: event.seq,
401
395
  system: s.systemTokens,
@@ -406,6 +400,8 @@ function applyTimeline(state, event, bounds) {
406
400
  tool: s.sums.tool,
407
401
  total
408
402
  };
403
+ if (data && typeof data.turn === "number") record.turn = data.turn;
404
+ if (data && typeof data.step === "number") record.step = data.step;
409
405
  if (usage && typeof usage.inputTokens === "number") {
410
406
  record.prompt = usage.inputTokens + (usage.cacheReadTokens || 0) + (usage.cacheWriteTokens || 0);
411
407
  if (typeof usage.outputTokens === "number") record.output = usage.outputTokens;
@@ -578,7 +574,15 @@ function createContextTimelineDefinition(config) {
578
574
  // 3 since 0.12: the removed-node archive (`archived` + `archiveFloor`)
579
575
  // joined the persisted state for the Context browser's per-step
580
576
  // reconstruction — cached rows predate the shape and are refolded.
581
- stateVersion: 3
577
+ // 4 since 0.18: the persisted state no longer carries `undefined`-valued
578
+ // properties (model/provider/lastModel/contextWindow are absent until
579
+ // known; pendingShadowedSeqs is deleted when consumed). The previous
580
+ // shape violated the plain-JSON persisted-state precondition and failed
581
+ // EVERY session-projection-cache write (TypeError: projection checkpoint
582
+ // is not losslessly JSON-serializable) — which also starved the `title`
583
+ // projection row and broke the session list after a restart. The bump
584
+ // discards old cached rows and refolds them clean.
585
+ stateVersion: 4
582
586
  };
583
587
  }
584
588
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-context",
3
- "version": "0.18.0",
3
+ "version": "0.19.1",
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": {
@@ -26,6 +26,7 @@
26
26
  ],
27
27
  "scripts": {
28
28
  "build": "tsup",
29
+ "watch": "tsup --watch",
29
30
  "register": "bash scripts/register.sh",
30
31
  "typecheck": "tsc --noEmit",
31
32
  "test": "npm run typecheck && node tests/host.test.mjs && node tests/client.test.mjs",