dsh-context 0.48.0 → 0.49.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.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  [`dsh-context`](https://www.npmjs.com/package/dsh-context) provides full context lifecycle management features.
12
12
  - **Context tab** — an UI context dashboard for DeepSeek Harness's context stats, composition, trend, events, and messages.
13
- - **Context panel** — the same dashboard as a right-sidebar tab (dsh 0.1.5-alpha.2+): pick **Context** on the sidebar's guide page and the panel opens beside the chat.
13
+ - **Context panel** — the same dashboard as a right-sidebar tab (dsh 0.1.5-rc.1+): pick **Context** on the sidebar's guide page and the panel opens beside the chat.
14
14
  - **`/context` command** — the slash command shows the context model for current context composition and recent context evolution.
15
15
 
16
16
  ## Install / Update
package/lib/client.js CHANGED
@@ -10,6 +10,7 @@ window.__ModuleLoader__.load({
10
10
  //#region src/client/i18n.ts
11
11
  const DICT_ZH = {
12
12
  "tab": "上下文",
13
+ "sidebar.guideDescription": "查看上下文的构成、统计、演变。",
13
14
  "cat.system": "系统提示词",
14
15
  "cat.tools": "工具定义",
15
16
  "cat.user": "用户消息",
@@ -31,7 +32,7 @@ window.__ModuleLoader__.load({
31
32
  "stats.toolCalls": "工具调用",
32
33
  "stats.images": "图片",
33
34
  "stats.cost": "预估费用",
34
- "stats.costTip": "按 DeepSeek 官方刊例价估算整个会话的累计费用:输入区分缓存命中/未命中,输出含思考;按请求时间区分高峰(北京时间工作日 9:00–12:00、14:00–18:00)与空闲时段(半价,周末全天均为空闲时段)。适用于 deepseek-v4.1-flash / deepseek-v4-pro(不限 provider;V4.1 Pro 上线前,V4 Pro 请求将被路由并按 V4.1 Flash 单价计费),价格写死在代码中,仅供参考。",
35
+ "stats.costTip": "按 DeepSeek 官方刊例价估算整个会话的累计费用:输入区分缓存命中/未命中,输出含思考;按请求时间区分高峰(北京时间工作日 9:00–12:00、14:00–18:00)与空闲时段(半价,周末全天均为空闲时段)。适用于 deepseek-v4.1-flash / deepseek-flash / deepseek-v4-pro(不限 provider;V4.1 Pro 上线前,V4 Pro 请求将被路由并按 V4.1 Flash 单价计费),价格写死在代码中,仅供参考。",
35
36
  "stats.costPriceHead": "每百万 tokens 价格(高峰 | 空闲半价):",
36
37
  "stats.costHit": "命中",
37
38
  "stats.costMiss": "未命中",
@@ -270,6 +271,8 @@ window.__ModuleLoader__.load({
270
271
  "rich.md": "Markdown",
271
272
  "rich.toMd": "按 Markdown 渲染查看",
272
273
  "rich.toRaw": "查看原始文本",
274
+ "rich.copy": "复制原文",
275
+ "rich.copied": "已复制",
273
276
  "rich.md.copy": "复制",
274
277
  "rich.md.copied": "已复制",
275
278
  "rich.md.footnotes": "脚注",
@@ -299,6 +302,7 @@ window.__ModuleLoader__.load({
299
302
  };
300
303
  const DICT_EN = {
301
304
  "tab": "Context",
305
+ "sidebar.guideDescription": "Inspect context composition, stats, and evolution.",
302
306
  "cat.system": "System Prompt",
303
307
  "cat.tools": "Tool Schemas",
304
308
  "cat.user": "User Messages",
@@ -320,7 +324,7 @@ window.__ModuleLoader__.load({
320
324
  "stats.toolCalls": "Tool Calls",
321
325
  "stats.images": "Images",
322
326
  "stats.cost": "Cost",
323
- "stats.costTip": "Rough cumulative cost of the whole session at DeepSeek’s list prices: input split by cache hit/miss, output includes reasoning; each request is priced at the peak (Beijing Time weekdays 09:00–12:00, 14:00–18:00) or half-price off-peak rate by its time — weekends bill at off-peak all day. Applies to deepseek-v4.1-flash / deepseek-v4-pro on any provider (until V4.1 Pro ships, Pro requests are routed to and billed at V4.1 Flash rates); prices are hardcoded, for reference only.",
327
+ "stats.costTip": "Rough cumulative cost of the whole session at DeepSeek’s list prices: input split by cache hit/miss, output includes reasoning; each request is priced at the peak (Beijing Time weekdays 09:00–12:00, 14:00–18:00) or half-price off-peak rate by its time — weekends bill at off-peak all day. Applies to deepseek-v4.1-flash / deepseek-flash / deepseek-v4-pro on any provider (until V4.1 Pro ships, Pro requests are routed to and billed at V4.1 Flash rates); prices are hardcoded, for reference only.",
324
328
  "stats.costPriceHead": "Per-1M-token rates (peak | off-peak at half price):",
325
329
  "stats.costHit": "hit",
326
330
  "stats.costMiss": "miss",
@@ -559,6 +563,8 @@ window.__ModuleLoader__.load({
559
563
  "rich.md": "Markdown",
560
564
  "rich.toMd": "View as Markdown",
561
565
  "rich.toRaw": "View Raw Text",
566
+ "rich.copy": "Copy Raw Text",
567
+ "rich.copied": "Copied",
562
568
  "rich.md.copy": "Copy",
563
569
  "rich.md.copied": "Copied",
564
570
  "rich.md.footnotes": "Footnotes",
@@ -2814,7 +2820,7 @@ window.__ModuleLoader__.load({
2814
2820
  /**
2815
2821
  * RichText — the raw/markdown body for the Context browser's detail sections. Markdown renders via the harness's shared MarkdownText (GFM,
2816
2822
  * sanitized, resolved from the platform module table — zero plugin-side markdown dependency); raw is a line-numbered `<pre>`. The Raw/MD
2817
- * switch sits at a section head's right edge (RichSwitch; per-card mode via useRichMode).
2823
+ * switch sits at a section head's right edge (RichSwitch; per-card mode via useRichMode), with the copy-raw control (RichCopy) beside it.
2818
2824
  */
2819
2825
  const Markdown = _deepseek_ai_dsh_client_ui_primitives.MarkdownText;
2820
2826
  function makeRichText(kit) {
@@ -2851,6 +2857,28 @@ window.__ModuleLoader__.load({
2851
2857
  }, index))
2852
2858
  });
2853
2859
  }
2860
+ function RichCopy(props) {
2861
+ const [copied, setCopied] = (0, react.useState)(false);
2862
+ const onCopy = (0, react.useCallback)(() => {
2863
+ if (copied) return;
2864
+ (0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(props.text).then((ok) => {
2865
+ if (!ok) return;
2866
+ setCopied(true);
2867
+ window.setTimeout(() => {
2868
+ setCopied(false);
2869
+ }, 1200);
2870
+ });
2871
+ }, [copied, props.text]);
2872
+ const label = copied ? t("rich.copied") : t("rich.copy");
2873
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2874
+ type: "button",
2875
+ className: "lc-rich-copy" + (copied ? " lc-rich-copy-on" : ""),
2876
+ title: label,
2877
+ "aria-label": label,
2878
+ onClick: onCopy,
2879
+ children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 13 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, { size: 13 })
2880
+ });
2881
+ }
2854
2882
  function RichText(props) {
2855
2883
  const mdLabels = (0, react.useMemo)(() => ({
2856
2884
  code: {
@@ -2871,6 +2899,7 @@ window.__ModuleLoader__.load({
2871
2899
  return {
2872
2900
  RichText,
2873
2901
  RichSwitch,
2902
+ RichCopy,
2874
2903
  useRichMode
2875
2904
  };
2876
2905
  }
@@ -2952,7 +2981,7 @@ window.__ModuleLoader__.load({
2952
2981
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2953
2982
  className: "lc-ts-card",
2954
2983
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2955
- className: "lc-ts-card-head",
2984
+ className: "lc-ts-card-head" + (props.foldHead === true ? " lc-ts-card-head-wrap" : ""),
2956
2985
  children: [
2957
2986
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
2958
2987
  className: props.labelClass,
@@ -2980,10 +3009,11 @@ window.__ModuleLoader__.load({
2980
3009
  const lineCount = (0, react.useMemo)(() => lineCountOf(props.text), [props.text]);
2981
3010
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Section, {
2982
3011
  label: props.label,
2983
- actions: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(rich.RichSwitch, {
3012
+ foldHead: true,
3013
+ actions: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(rich.RichSwitch, {
2984
3014
  mode,
2985
3015
  onPick: setMode
2986
- }),
3016
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(rich.RichCopy, { text: props.text })] }),
2987
3017
  meta: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2988
3018
  className: "lc-ts-card-meta",
2989
3019
  children: props.lines(lineCount)
@@ -6604,7 +6634,7 @@ window.__ModuleLoader__.load({
6604
6634
  return function PluginInfo() {
6605
6635
  const [latest, setLatest] = (0, react.useState)(null);
6606
6636
  (0, react.useEffect)(() => {
6607
- if ("0.48.0".includes("-dev")) return;
6637
+ if ("0.49.1".includes("-dev")) return;
6608
6638
  let on = true;
6609
6639
  fetchLatestVersion().then((v) => {
6610
6640
  if (on && v) setLatest(v);
@@ -6613,8 +6643,8 @@ window.__ModuleLoader__.load({
6613
6643
  on = false;
6614
6644
  };
6615
6645
  }, []);
6616
- const update = latest !== null && isNewerVersion(latest, "0.48.0") ? latest : null;
6617
- const nameText = "dsh-context (v0.48.0)";
6646
+ const update = latest !== null && isNewerVersion(latest, "0.49.1") ? latest : null;
6647
+ const nameText = "dsh-context (v0.49.1)";
6618
6648
  const nameValue = [nameText];
6619
6649
  if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6620
6650
  className: "lc-pi-update",
@@ -7148,7 +7178,7 @@ window.__ModuleLoader__.load({
7148
7178
  */
7149
7179
  function sessionPrices(currency) {
7150
7180
  return ["flash", "pro"].map((id) => ({
7151
- family: id === "flash" ? "deepseek-v4.1-flash" : "deepseek-v4-pro",
7181
+ family: id === "flash" ? "deepseek-v4.1-flash / deepseek-flash" : "deepseek-v4-pro",
7152
7182
  peak: PRICES[currency][id].peak,
7153
7183
  off: PRICES[currency][id].off
7154
7184
  }));
@@ -8720,9 +8750,61 @@ window.__ModuleLoader__.load({
8720
8750
  };
8721
8751
  }
8722
8752
  //#endregion
8753
+ //#region src/client/icon.tsx
8754
+ /** The sheet's strokes, in paint order, as `[path, fill]` pairs. */
8755
+ const SHEET_PATHS = [
8756
+ ["M899.984 19.873h-3.452c-26.123 0-47.296 21.172-47.296 47.296v888.508c0 26.127 21.173 47.298 47.296 47.298h3.452c26.119 0 47.297-21.171 47.297-47.298V67.169c0-26.124-21.177-47.296-47.297-47.296z", "#4A5699"],
8757
+ ["M132.643 19.873h-3.449c-26.12 0-47.296 21.172-47.296 47.296v888.508c0 26.127 21.177 47.298 47.296 47.298h3.449c26.123 0 47.299-21.171 47.299-47.298V67.169c0-26.124-21.176-47.296-47.299-47.296z", "#C45FA0"],
8758
+ ["M899.463 19.873H129.194c-26.12 0-47.296 21.172-47.296 47.296v3.377c0 26.12 21.177 47.299 47.296 47.299h770.269c26.123 0 47.296-21.179 47.296-47.299v-3.377c0-26.124-21.173-47.296-47.296-47.296z", "#6277BA"],
8759
+ ["M899.463 905.006H129.194c-26.12 0-47.296 21.17-47.296 47.29v3.381c0 26.127 21.177 47.298 47.296 47.298h770.269c26.123 0 47.296-21.171 47.296-47.298v-3.381c0-26.12-21.173-47.29-47.296-47.29z", "#C45FA0"],
8760
+ ["M717.962 543.153H542.047c-26.121 0-47.298 21.175-47.298 47.297v3.724c0 26.123 21.177 47.293 47.298 47.293h175.915c26.121 0 47.297-21.17 47.297-47.293v-3.724c0-26.122-21.176-47.297-47.297-47.297z", "#E5594F"],
8761
+ ["M689.268 198.849H513.355c-26.122 0-47.298 21.175-47.298 47.297v3.722c0 26.12 21.176 47.297 47.298 47.297h175.912c26.122 0 47.298-21.177 47.298-47.297v-3.722c0-26.122-21.175-47.297-47.297-47.297z", "#F0D043"],
8762
+ ["M757.789 353.081H261.17c-26.121 0-47.297 21.172-47.297 47.296v3.377c0 26.121 21.177 47.299 47.297 47.299h496.619c26.121 0 47.296-21.178 47.296-47.299v-3.377c0-26.125-21.175-47.296-47.296-47.296z", "#E5594F"],
8763
+ ["M762.638 726.225h-496.62c-26.12 0-47.294 21.18-47.294 47.301v3.377c0 26.12 21.174 47.3 47.294 47.3h496.62c26.122 0 47.296-21.18 47.296-47.3v-3.377c0-26.122-21.174-47.301-47.296-47.301z", "#6277BA"],
8764
+ ["M355.734 543.328H281.41c-26.122 0-47.297 21.17-47.297 47.293v3.378c0 26.118 21.175 47.297 47.297 47.297h74.324c26.123 0 47.296-21.179 47.296-47.297v-3.378c0-26.123-21.174-47.293-47.296-47.293z", "#F39A2B"],
8765
+ ["M334.85 248.006m-48.986 0a48.986 48.986 0 1 0 97.972 0 48.986 48.986 0 1 0-97.972 0Z", "#F39A2B"]
8766
+ ];
8767
+ /** The colourful document sheet at the requested square edge. */
8768
+ function ContextIcon({ size = 20, className }) {
8769
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
8770
+ width: size,
8771
+ height: size,
8772
+ viewBox: "0 0 1024 1024",
8773
+ className,
8774
+ "aria-hidden": "true",
8775
+ xmlns: "http://www.w3.org/2000/svg",
8776
+ children: SHEET_PATHS.map(([d, fill]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
8777
+ d,
8778
+ fill
8779
+ }, d))
8780
+ });
8781
+ }
8782
+ /**
8783
+ * The tab chip's title seat (`sidebar.right.pane.tab.title`): the emblem before
8784
+ * the label, so the chip reads as the files chip does. The label comes from the
8785
+ * plugin's own bound translate — read at render, so the chip follows the active
8786
+ * locale — rather than the tab-information hook, which a foreign or
8787
+ * not-yet-committed tab record can throw on. It carries a trailing gutter
8788
+ * (`.lc-title-label`) so the active chip's fade lands past the text, never on
8789
+ * the last glyphs.
8790
+ * @param t - the plugin-namespace translate bound in `apply`.
8791
+ * @returns the title component to register under the tab type's id.
8792
+ */
8793
+ function makeContextTabTitle(t) {
8794
+ return function ContextTabTitle() {
8795
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextIcon, {
8796
+ size: 16,
8797
+ className: "lc-title-icon"
8798
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8799
+ className: "lc-title-label",
8800
+ children: t("tab")
8801
+ })] });
8802
+ };
8803
+ }
8804
+ //#endregion
8723
8805
  //#region src/client/sidebar.ts
8724
8806
  /**
8725
- * The right Sidebar's Context tab (dsh 0.1.5-alpha.2+).
8807
+ * The right Sidebar's Context tab (dsh 0.1.5-rc.1+).
8726
8808
  *
8727
8809
  * The tab reuses the Context conversation-view component VERBATIM: the
8728
8810
  * `sidebar.right.pane.tab` seat is session-scoped and delivers the same
@@ -8731,10 +8813,11 @@ window.__ModuleLoader__.load({
8731
8813
  * one component with one data path. The tab type contributes a guide entry, so
8732
8814
  * the sidebar's guide page offers "Context" and picking it opens the panel —
8733
8815
  * the product's own path, exactly as the shipped Files type does: a capsule of
8734
- * glyph + title.
8816
+ * glyph, title, and description line, plus the chip-title seat that puts the
8817
+ * same glyph beside the label once the tab is open (`icon.tsx`).
8735
8818
  *
8736
8819
  * OPTIONAL BY CONTRACT. `ctx.sidebarRightTabs` and the seat ship only on the
8737
- * 0.1.5 line (0.1.5-alpha.2+ supported); the registration therefore rides a
8820
+ * 0.1.5 line (0.1.5-rc.1+ supported); the registration therefore rides a
8738
8821
  * DEFERRED inject (the plugin's hard injects stay `slots` + `locale`), so on
8739
8822
  * every older supported line the callback never fires, the plugin fiber never
8740
8823
  * pends, and nothing is registered. The registry is re-proved structurally and
@@ -8755,22 +8838,8 @@ window.__ModuleLoader__.load({
8755
8838
  /** The guide capsule's position: after the shipped Files entry (order 10). */
8756
8839
  const GUIDE_ORDER = 20;
8757
8840
  /**
8758
- * The guide capsule's glyph, read defensively: the icon is OPTIONAL in the
8759
- * entry, and a primitives module that does not serve it or whose namespace
8760
- * THROWS on the read (an interop/mock shape does exactly that) — must cost the
8761
- * glyph, never the whole tab.
8762
- * @returns the icon component, or undefined to register the tab without one.
8763
- */
8764
- function guideIcon() {
8765
- try {
8766
- return _deepseek_ai_dsh_client_ui_primitives.IconContextInjectionOutline16;
8767
- } catch {
8768
- return;
8769
- }
8770
- }
8771
- /**
8772
- * Register the Context tab type and its body on the right Sidebar, if — and
8773
- * only if — this harness serves the sidebar tab registry.
8841
+ * Register the Context tab type, its body, and its chip title on the right
8842
+ * Sidebar, if and only if this harness serves the sidebar tab registry.
8774
8843
  * @param ctx - client root context carrying `slots` and the locale service.
8775
8844
  * @param view - the Context view component factory result (the same one the
8776
8845
  * conversation tab mounts).
@@ -8782,34 +8851,43 @@ window.__ModuleLoader__.load({
8782
8851
  function watchSidebarContextTab(ctx, view, t, ns) {
8783
8852
  ctx.inject(["sidebarRightTabs"], (raw) => {
8784
8853
  const injected = raw;
8854
+ const disposers = [];
8855
+ const own = (result) => {
8856
+ if (typeof result === "function") disposers.push(result);
8857
+ };
8785
8858
  try {
8786
8859
  const tabs = injected.sidebarRightTabs;
8787
8860
  if (tabs === void 0 || typeof tabs.register !== "function") return;
8788
- const disposeType = tabs.register({
8861
+ own(tabs.register({
8789
8862
  id: SIDEBAR_CONTEXT_ID,
8790
8863
  kind: SIDEBAR_CONTEXT_KIND,
8791
8864
  title: () => t("tab"),
8792
8865
  guide: [{
8793
8866
  order: GUIDE_ORDER,
8794
8867
  title: () => t("tab"),
8795
- icon: guideIcon()
8868
+ description: () => t("sidebar.guideDescription"),
8869
+ icon: ContextIcon
8796
8870
  }]
8797
- });
8798
- const disposeBody = injected.slots.inject("sidebar.right.pane.tab", () => injected.slots.register({
8871
+ }));
8872
+ own(injected.slots.inject("sidebar.right.pane.tab", () => injected.slots.register({
8799
8873
  name: "sidebar.right.pane.tab",
8800
8874
  key: SIDEBAR_CONTEXT_ID,
8801
8875
  locale: ns
8802
8876
  }, (props) => view({
8803
8877
  ...props,
8804
8878
  host: "sidebar"
8805
- })));
8806
- return () => {
8807
- disposeType();
8808
- if (typeof disposeBody === "function") disposeBody();
8809
- };
8879
+ }))));
8880
+ own(injected.slots.inject("sidebar.right.pane.tab.title", () => injected.slots.register({
8881
+ name: "sidebar.right.pane.tab.title",
8882
+ key: SIDEBAR_CONTEXT_ID
8883
+ }, makeContextTabTitle(t))));
8810
8884
  } catch {
8885
+ for (const dispose of disposers) dispose();
8811
8886
  return;
8812
8887
  }
8888
+ return () => {
8889
+ for (const dispose of disposers) dispose();
8890
+ };
8813
8891
  });
8814
8892
  }
8815
8893
  //#endregion
@@ -8829,7 +8907,7 @@ window.__ModuleLoader__.load({
8829
8907
  }
8830
8908
  //#endregion
8831
8909
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/base.css.mjs
8832
- const css$13 = ".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{height:auto;padding:12px;overflow:visible}.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{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{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{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-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-col{flex:1;min-width:min(360px,100%)}.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{container:lc-head-row/inline-size}.lc-head>.lc-card{flex:1 1 0;min-width:0}@container lc-head-row (width<=1045px){.lc-head>.lc-card{flex-basis:40%}}@container lc-head-row (width<=480px){.lc-head>.lc-card{flex-basis:100%}}.lc-head>.lc-card:first-child{flex-direction:column;display:flex}.lc-head>.lc-card:first-child .lc-stats{flex:1;align-content:stretch}.lc-head>.lc-card:first-child .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-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.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}";
8910
+ const css$13 = ".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{height:auto;padding:12px;overflow:visible}.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{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{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{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-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-col{flex:1;min-width:min(360px,100%)}.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{container:lc-head-row/inline-size}.lc-head>.lc-card{flex:1 1 0;min-width:0}@container lc-head-row (width<=1045px){.lc-head>.lc-card{flex-basis:40%}}@container lc-head-row (width<=480px){.lc-head>.lc-card{flex-basis:100%}}.lc-head>.lc-card:first-child{flex-direction:column;display:flex}.lc-head>.lc-card:first-child .lc-stats{flex:1;align-content:stretch}.lc-head>.lc-card:first-child .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-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.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}";
8833
8911
  const tagId$13 = "dsh-context/base.css";
8834
8912
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
8835
8913
  const tag = document.createElement("style");
@@ -8939,7 +9017,7 @@ window.__ModuleLoader__.load({
8939
9017
  }
8940
9018
  //#endregion
8941
9019
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/browser.css.mjs
8942
- const css$3 = ".lc-br-dna-ctl{flex:none;margin-left:0}.lc-br-bar-dna .lc-stacked-seg{background-image:linear-gradient(to right, transparent calc(100% - min(1px, 25%)), var(--dsw-alias-bg-layer-1) 0)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-retry{color:var(--dsw-alias-brand-primary);font:inherit;cursor:pointer;text-underline-offset:2px;transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;padding:0;font-size:12px;text-decoration:underline}.lc-br-retry:hover{filter:brightness(1.15)}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{width:8px;height:8px;transition:box-shadow var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;flex:none;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:flex}.lc-br-chev:before{content:\"\";width:5px;height:5px;transition:transform var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-bottom:1px solid;border-right:1px solid;transform:rotate(-45deg)}.lc-br-chev-on:before{transform:rotate(45deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-err-dot{background:var(--dsw-alias-state-error-primary);width:6px;height:6px;box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-radius:50%;flex:none}.lc-br-tag{min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-tool-plugin{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);border-color:#0000;border-radius:6px;font-size:12px}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}";
9020
+ const css$3 = ".lc-br-dna-ctl{flex:none;margin-left:0}.lc-br-bar-dna .lc-stacked-seg{background-image:linear-gradient(to right, transparent calc(100% - min(.5px, 12.5%)), var(--dsw-alias-bg-layer-1) 0)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-retry{color:var(--dsw-alias-brand-primary);font:inherit;cursor:pointer;text-underline-offset:2px;transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;padding:0;font-size:12px;text-decoration:underline}.lc-br-retry:hover{filter:brightness(1.15)}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{width:8px;height:8px;transition:box-shadow var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;flex:none;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:flex}.lc-br-chev:before{content:\"\";width:5px;height:5px;transition:transform var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-bottom:1px solid;border-right:1px solid;transform:rotate(-45deg)}.lc-br-chev-on:before{transform:rotate(45deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-err-dot{background:var(--dsw-alias-state-error-primary);width:6px;height:6px;box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-radius:50%;flex:none}.lc-br-tag{min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-tool-plugin{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent);border-color:#0000;border-radius:6px;font-size:12px}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}";
8943
9021
  const tagId$3 = "dsh-context/browser.css";
8944
9022
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
8945
9023
  const tag = document.createElement("style");
@@ -8950,7 +9028,7 @@ window.__ModuleLoader__.load({
8950
9028
  }
8951
9029
  //#endregion
8952
9030
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/detailSections.css.mjs
8953
- const css$2 = ".lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;min-width:0;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-size:13px;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.lc-ts-card-count{margin-left:auto}.lc-ts-card-right{align-items:center;gap:8px;margin-left:auto;display:inline-flex}.lc-ts-card-meta{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:11px;font-weight:400}.lc-ts-call-state{white-space:nowrap;font-size:11px;font-weight:600;line-height:1;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);border-radius:999px;flex:none;align-items:center;gap:4px;padding:2px 7px;display:inline-flex}.lc-ts-call-state i{background:currentColor;border-radius:50%;flex:none;width:6px;height:6px}.lc-ts-call-ok{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.lc-ts-call-err{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-lines{counter-reset:lc-line}.lc-ts-line{padding-left:26px;display:block;position:relative}.lc-ts-line:before{content:counter(lc-line);counter-increment:lc-line;text-align:right;width:20px;color:var(--dsw-alias-label-tertiary);user-select:none;padding-right:6px;font-size:11px;position:absolute;left:0}.lc-ts-line:empty:after{content:\"​\"}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,140px) minmax(0,90px) 56px minmax(0,1fr);align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{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-rich-seg-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-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;overflow-wrap:anywhere;scrollbar-width:thin;min-width:0;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow:hidden auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p{white-space:pre-line;margin:6px 0}.lc-ts-desc-md div p br{display:none}.lc-ts-desc-md div pre{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}";
9031
+ const css$2 = ".lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;min-width:0;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head-wrap{flex-wrap:wrap}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-size:13px;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.lc-ts-card-count{margin-left:auto}.lc-ts-card-right{align-items:center;gap:8px;margin-left:auto;display:inline-flex}.lc-ts-card-meta{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:11px;font-weight:400}.lc-ts-call-state{white-space:nowrap;font-size:11px;font-weight:600;line-height:1;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);border-radius:999px;flex:none;align-items:center;gap:4px;padding:2px 7px;display:inline-flex}.lc-ts-call-state i{background:currentColor;border-radius:50%;flex:none;width:6px;height:6px}.lc-ts-call-ok{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.lc-ts-call-err{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-lines{counter-reset:lc-line}.lc-ts-line{padding-left:26px;display:block;position:relative}.lc-ts-line:before{content:counter(lc-line);counter-increment:lc-line;text-align:right;width:20px;color:var(--dsw-alias-label-tertiary);user-select:none;padding-right:6px;font-size:11px;position:absolute;left:0}.lc-ts-line:empty:after{content:\"​\"}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,140px) minmax(0,90px) 56px minmax(0,1fr);align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{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-rich-seg-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-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-rich-copy{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;align-items:center;padding:2px;display:inline-flex}.lc-rich-copy:hover{color:var(--dsw-alias-label-primary)}.lc-rich-copy-on,.lc-rich-copy-on:hover{color:var(--dsw-alias-state-success-primary)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;overflow-wrap:anywhere;scrollbar-width:thin;min-width:0;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow:hidden auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p{white-space:pre-line;margin:6px 0}.lc-ts-desc-md div p br{display:none}.lc-ts-desc-md div pre{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}";
8954
9032
  const tagId$2 = "dsh-context/detailSections.css";
8955
9033
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
8956
9034
  const tag = document.createElement("style");
package/lib/index.d.ts CHANGED
@@ -129,10 +129,10 @@ interface TimelineState {
129
129
  archived: SurfaceNode[];
130
130
  /**
131
131
  * Session-cost raw material: cumulative billed-token totals per DeepSeek
132
- * V4 model family and pricing period (see SessionCostUsage). Running
132
+ * model family and pricing period (see SessionCostUsage). Running
133
133
  * totals — never trimmed, so the estimate always covers the COMPLETE
134
134
  * session log even after the request/event retention bounds cut in.
135
- * Absent until a v4-flash / v4-pro request reports usage.
135
+ * Absent until a DeepSeek flash/pro request reports usage.
136
136
  */
137
137
  cost?: SessionCostUsage;
138
138
  archiveFloor?: number;
@@ -565,10 +565,11 @@ interface CostFamilyUsage {
565
565
  }
566
566
  /**
567
567
  * The session-cost estimate's raw material: cumulative provider-reported
568
- * token totals per DeepSeek V4 model family (matched on the model NAME,
568
+ * token totals per DeepSeek model family (matched on the model NAME,
569
569
  * provider-agnostic) and pricing period. The Client prices these with its
570
570
  * hardcoded list-price table in the locale's currency. Absent until a
571
- * deepseek-v4.1-flash / deepseek-v4-pro request reports usage.
571
+ * deepseek-flash / deepseek-v4.1-flash / deepseek-v4-pro request reports
572
+ * usage.
572
573
  */
573
574
  interface SessionCostUsage {
574
575
  flash?: CostFamilyUsage;
package/lib/index.js CHANGED
@@ -1274,15 +1274,16 @@ function tokenCountOf(value) {
1274
1274
  return null;
1275
1275
  }
1276
1276
  /**
1277
- * The DeepSeek V4 model family a model name prices as — matched on the NAME
1277
+ * The DeepSeek model family a model name prices as — matched on the NAME
1278
1278
  * alone (provider-agnostic: official API, proxies, OpenRouter spellings like
1279
- * `deepseek/deepseek-v4.1-flash` all land here). Null for any other model:
1280
- * non-V4 usage is simply not priced.
1279
+ * `deepseek/deepseek-v4.1-flash` and `deepseek/deepseek-flash` all land
1280
+ * here). The name must carry a DeepSeek marker (`v4` or `deepseek`) so a
1281
+ * foreign flash/pro-named model (gemini-2.0-flash) is never priced.
1281
1282
  */
1282
1283
  function costFamilyOf(model) {
1283
1284
  if (model === void 0) return null;
1284
1285
  const m = model.toLowerCase();
1285
- if (!m.includes("v4")) return null;
1286
+ if (!m.includes("v4") && !m.includes("deepseek")) return null;
1286
1287
  if (m.includes("flash")) return "flash";
1287
1288
  if (m.includes("pro")) return "pro";
1288
1289
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-context",
3
- "version": "0.48.0",
3
+ "version": "0.49.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": {
@@ -66,7 +66,7 @@
66
66
  "dshReleases": {
67
67
  "0.1.2-rc.1": "compatible",
68
68
  "0.1.3-alpha.2": "compatible",
69
- "0.1.5-alpha.2": "compatible"
69
+ "0.1.5-rc.1": "compatible"
70
70
  }
71
71
  }
72
72
  },