dsh-context 0.63.0 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/lib/client.js +420 -303
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
**The best [DeepSeek Harness plugin](https://www.deepseek.com/harness/) for Agent's context insights and management.**
|
|
10
10
|
|
|
11
11
|
[`dsh-context`](https://www.npmjs.com/package/dsh-context) provides full context lifecycle management features.
|
|
12
|
-
- **Context
|
|
12
|
+
- **Context Insights page** — the cross-session overview as a first-level sidebar panel (beside Plugins and Automation tasks): KPI band with a 7-day token/cost usage chart, activity heatmap, aggregate composition ring, and filterable session cards that jump straight into any session.
|
|
13
13
|
- **Context tab** — an UI context dashboard for DeepSeek Harness's context stats, composition, trend, events, and messages.
|
|
14
14
|
- **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.
|
|
15
15
|
- **`/context` command** — the slash command shows the context model for current context composition and recent context evolution.
|
|
@@ -44,16 +44,16 @@ Four surfaces, one story — what your agent is carrying, how it got there, and
|
|
|
44
44
|
|
|
45
45
|
| Where | What you get |
|
|
46
46
|
| --- | --- |
|
|
47
|
-
| **Context
|
|
47
|
+
| **Context Insights page** | Every session at a glance: usage, cost, cache hit, daily activity, and per-session context profiles — filtered by range, day, group, or search, one click to jump in. |
|
|
48
48
|
| **Context tab** | The full dashboard: stats, composition, per-request trend, events, file activity, and the agent network — in every session. |
|
|
49
49
|
| **`/context` command** | A centered modal with the same composition and context browser, without leaving the chat. |
|
|
50
50
|
| **Preferences card** | Per-user defaults: view placement, trend granularity & mode, File Activity sort, and more. |
|
|
51
51
|
|
|
52
|
-
## 🗂️ The Context
|
|
52
|
+
## 🗂️ The Context Insights page
|
|
53
53
|
|
|
54
|
-
Click **Context
|
|
54
|
+
Click **Context Insights / 上下文洞察** in the sidebar's panel list — the same row level as **Plugins** and **Automation tasks** — and the page opens as a full center-column panel:
|
|
55
55
|
|
|
56
|
-

|
|
57
57
|
|
|
58
58
|
| Section | The question it answers |
|
|
59
59
|
| --- | --- |
|
package/lib/client.js
CHANGED
|
@@ -118,7 +118,6 @@ window.__ModuleLoader__.load({
|
|
|
118
118
|
"gran.total": "全量",
|
|
119
119
|
"gran.delta": "增量",
|
|
120
120
|
"gran.modeHint": "全量:累计构成;增量:相对上一条请求的变化量",
|
|
121
|
-
"trend.focus": "仅展示 {cat}",
|
|
122
121
|
"trend.adaptive": "自适应",
|
|
123
122
|
"trend.adaptiveHint": "按当前可视范围内的柱子重新缩放高度,滚动时随之变化",
|
|
124
123
|
"trend.duration": "耗时",
|
|
@@ -358,7 +357,6 @@ window.__ModuleLoader__.load({
|
|
|
358
357
|
"attach.sent": "发送",
|
|
359
358
|
"attach.token": "Token",
|
|
360
359
|
"attach.tokensTip": "按 DeepSeek 官方图片尺寸换算(单图上限 384 tokens)估算的 token 消耗",
|
|
361
|
-
"ov.entry": "上下文洞察",
|
|
362
360
|
"ov.title": "上下文洞察",
|
|
363
361
|
"ov.unavailable": "会话列表暂不可用",
|
|
364
362
|
"ov.range.label": "统计范围",
|
|
@@ -520,7 +518,6 @@ window.__ModuleLoader__.load({
|
|
|
520
518
|
"gran.total": "Total",
|
|
521
519
|
"gran.delta": "Delta",
|
|
522
520
|
"gran.modeHint": "Total: cumulative makeup; Delta: change vs the previous request",
|
|
523
|
-
"trend.focus": "Showing {cat} only",
|
|
524
521
|
"trend.adaptive": "Adaptive",
|
|
525
522
|
"trend.adaptiveHint": "Rescale bar heights to the visible range, following the scroll",
|
|
526
523
|
"trend.duration": "Duration",
|
|
@@ -760,7 +757,6 @@ window.__ModuleLoader__.load({
|
|
|
760
757
|
"attach.sent": "Sent",
|
|
761
758
|
"attach.token": "Token",
|
|
762
759
|
"attach.tokensTip": "Estimated token cost via DeepSeek's official image-size conversion (384-token cap per image)",
|
|
763
|
-
"ov.entry": "Context Insights",
|
|
764
760
|
"ov.title": "Context Insights",
|
|
765
761
|
"ov.unavailable": "The session list is unavailable",
|
|
766
762
|
"ov.range.label": "Range",
|
|
@@ -849,11 +845,11 @@ window.__ModuleLoader__.load({
|
|
|
849
845
|
* it to the Plugins page's package cards. The client bundle inlines the
|
|
850
846
|
* file's markup at build time (the `?raw` channel in tsdown.config.ts) and
|
|
851
847
|
* re-renders it at every requested size. The identity seats (tab chip,
|
|
852
|
-
* command, sidebar registration
|
|
848
|
+
* command, sidebar registration) keep the sheet's fixed fills —
|
|
853
849
|
* deliberately polychrome on both light and dark chrome — while the
|
|
854
|
-
* sidebar-
|
|
855
|
-
* every fill for `currentColor` so the glyph
|
|
856
|
-
*
|
|
850
|
+
* sidebar's panel-list seat (insightPage.ts) opts into `mono`, trading
|
|
851
|
+
* every fill for `currentColor` so the glyph follows the shell-owned row's
|
|
852
|
+
* own state colors, exactly as the shipped panel glyphs do.
|
|
857
853
|
*/
|
|
858
854
|
/** Everything between the file's `<svg>` tags: the sheet's strokes in paint order, whitespace-folded. */
|
|
859
855
|
const SHEET_MARKUP = icon_default.slice(icon_default.indexOf(">") + 1, icon_default.lastIndexOf("</svg>")).trim().replace(/>\s+</g, "><");
|
|
@@ -872,6 +868,19 @@ window.__ModuleLoader__.load({
|
|
|
872
868
|
});
|
|
873
869
|
}
|
|
874
870
|
/**
|
|
871
|
+
* The sidebar panel-list glyph (`sidebar.panellist`): the emblem in `mono` at
|
|
872
|
+
* the size the shell asks for, so the shell-owned row's hover/active colors
|
|
873
|
+
* paint it like the shipped panel glyphs. The shell owns the row's label,
|
|
874
|
+
* and the row's selected state its own styling, so — as on the shipped
|
|
875
|
+
* glyphs — the owner props' `active` goes unread.
|
|
876
|
+
*/
|
|
877
|
+
function InsightPanelIcon({ size = 18 }) {
|
|
878
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextIcon, {
|
|
879
|
+
size,
|
|
880
|
+
mono: true
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
875
884
|
* The tab chip's title seat (`sidebar.right.pane.tab.title`): the emblem before
|
|
876
885
|
* the label, so the chip reads as the files chip does. The label comes from the
|
|
877
886
|
* plugin's own bound translate — read at render, so the chip follows the active
|
|
@@ -3526,6 +3535,8 @@ window.__ModuleLoader__.load({
|
|
|
3526
3535
|
const lastGranRef = (0, react.useRef)(props.granularity);
|
|
3527
3536
|
const lastSeqRef = (0, react.useRef)(0);
|
|
3528
3537
|
const prevScrollWidthRef = (0, react.useRef)(0);
|
|
3538
|
+
const cwRef = (0, react.useRef)(0);
|
|
3539
|
+
const slRef = (0, react.useRef)(0);
|
|
3529
3540
|
/**
|
|
3530
3541
|
* Keep each turn label centered within its block's VISIBLE slice, then thin colliding labels: a label wider
|
|
3531
3542
|
* than its block overflows it, so consecutive narrow turns would smear into each other — walking left→right
|
|
@@ -3596,6 +3607,8 @@ window.__ModuleLoader__.load({
|
|
|
3596
3607
|
} else if (grew && el.scrollLeft + el.clientWidth >= widthBeforeAppend - 24) el.scrollLeft = el.scrollWidth;
|
|
3597
3608
|
lastSeqRef.current = newestSeq;
|
|
3598
3609
|
prevScrollWidthRef.current = el.scrollWidth;
|
|
3610
|
+
slRef.current = el.scrollLeft;
|
|
3611
|
+
cwRef.current = el.clientWidth;
|
|
3599
3612
|
updateTurnLabels(el);
|
|
3600
3613
|
syncTip(el);
|
|
3601
3614
|
measureVisible(el);
|
|
@@ -3617,6 +3630,7 @@ window.__ModuleLoader__.load({
|
|
|
3617
3630
|
if (el === null) return;
|
|
3618
3631
|
if (typeof ResizeObserver !== "function") return;
|
|
3619
3632
|
const observer = new ResizeObserver(() => {
|
|
3633
|
+
cwRef.current = el.clientWidth;
|
|
3620
3634
|
measureRef.current(el);
|
|
3621
3635
|
});
|
|
3622
3636
|
observer.observe(el);
|
|
@@ -3704,17 +3718,18 @@ window.__ModuleLoader__.load({
|
|
|
3704
3718
|
* Glue the hover tip to its bar's VISIBLE slice. The tip deliberately does NOT live inside the scrolling
|
|
3705
3719
|
* content: an absolutely-positioned child of a scroller contributes to its scrollable overflow, so a wide
|
|
3706
3720
|
* reply preview on a right-edge bar used to inflate scrollWidth on every hover and flap the horizontal
|
|
3707
|
-
* scrollbar open/closed — jumping the whole card.
|
|
3708
|
-
*
|
|
3721
|
+
* scrollbar open/closed — jumping the whole card. The only layout read left is the tip's own width (its
|
|
3722
|
+
* subtree is the thing that just changed); the scroller's width/offset ride the cached refs, so this never
|
|
3723
|
+
* forces a document-scope layout flush on the hover path. Unchanged transforms write nothing.
|
|
3709
3724
|
*/
|
|
3710
3725
|
const syncTip = (el) => {
|
|
3711
3726
|
/* v8 ignore next 1 -- the scroll div renders unconditionally while mounted, so its parent exists. */
|
|
3712
3727
|
const tip = (el.parentElement ?? document.body).querySelector(".lc-chart-tip");
|
|
3713
3728
|
if (tip === null) return;
|
|
3714
3729
|
const lw = tip.offsetWidth;
|
|
3715
|
-
const cw =
|
|
3730
|
+
const cw = cwRef.current;
|
|
3716
3731
|
const half = Math.min(lw / 2, cw / 2);
|
|
3717
|
-
const cx = Math.min(Math.max(tipColRef.current -
|
|
3732
|
+
const cx = Math.min(Math.max(tipColRef.current - slRef.current, half), cw - half);
|
|
3718
3733
|
const next = `translate(${Math.round(cx - lw / 2)}px, 0)`;
|
|
3719
3734
|
if (tip.style.transform !== next) tip.style.transform = next;
|
|
3720
3735
|
};
|
|
@@ -3781,6 +3796,8 @@ window.__ModuleLoader__.load({
|
|
|
3781
3796
|
className: "lc-chart-scroll" + (props.activeTurn !== null ? " lc-chart-dim" : ""),
|
|
3782
3797
|
ref: scrollRef,
|
|
3783
3798
|
onScroll: (e) => {
|
|
3799
|
+
slRef.current = e.currentTarget.scrollLeft;
|
|
3800
|
+
cwRef.current = e.currentTarget.clientWidth;
|
|
3784
3801
|
updateTurnLabels(e.currentTarget);
|
|
3785
3802
|
syncTip(e.currentTarget);
|
|
3786
3803
|
measureVisible(e.currentTarget);
|
|
@@ -4038,10 +4055,17 @@ window.__ModuleLoader__.load({
|
|
|
4038
4055
|
const scaled = Math.trunc(reads / billed * 100 * factor + 1e-9);
|
|
4039
4056
|
return `${Math.floor(scaled / factor)}.${String(scaled % factor).padStart(decimals, "0")}`;
|
|
4040
4057
|
}
|
|
4058
|
+
/** One shared formatter: building an Intl formatter per call costs ~50x the format itself (issue #116). */
|
|
4059
|
+
const TIME_FMT = new Intl.DateTimeFormat("en-GB", {
|
|
4060
|
+
hour12: false,
|
|
4061
|
+
hour: "2-digit",
|
|
4062
|
+
minute: "2-digit",
|
|
4063
|
+
second: "2-digit"
|
|
4064
|
+
});
|
|
4041
4065
|
function fmtTime(t) {
|
|
4042
4066
|
const d = new Date(t);
|
|
4043
4067
|
if (isNaN(d.getTime())) return "—";
|
|
4044
|
-
return
|
|
4068
|
+
return TIME_FMT.format(d);
|
|
4045
4069
|
}
|
|
4046
4070
|
/**
|
|
4047
4071
|
* Share of a whole as a compact leading percentage for the slice rows:
|
|
@@ -6031,71 +6055,6 @@ window.__ModuleLoader__.load({
|
|
|
6031
6055
|
};
|
|
6032
6056
|
}
|
|
6033
6057
|
//#endregion
|
|
6034
|
-
//#region src/client/overviewStore.ts
|
|
6035
|
-
function createStore() {
|
|
6036
|
-
let open = false;
|
|
6037
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
6038
|
-
return {
|
|
6039
|
-
subscribe: (listener) => {
|
|
6040
|
-
listeners.add(listener);
|
|
6041
|
-
return () => {
|
|
6042
|
-
listeners.delete(listener);
|
|
6043
|
-
};
|
|
6044
|
-
},
|
|
6045
|
-
getSnapshot: () => open,
|
|
6046
|
-
set: (next) => {
|
|
6047
|
-
if (next === open) return;
|
|
6048
|
-
open = next;
|
|
6049
|
-
for (const listener of listeners) listener();
|
|
6050
|
-
}
|
|
6051
|
-
};
|
|
6052
|
-
}
|
|
6053
|
-
const overviewStore = createStore();
|
|
6054
|
-
//#endregion
|
|
6055
|
-
//#region src/client/components/overviewButton.tsx
|
|
6056
|
-
/**
|
|
6057
|
-
* The Context Dashboard's sidebar entry: a footer action stacked directly
|
|
6058
|
-
* above Settings (the harness's own foot layout: footer actions, then the
|
|
6059
|
-
* settings row), mirroring the Settings trigger's geometry in both column
|
|
6060
|
-
* widths. The button carries the plugin emblem — in the mono seat, so the
|
|
6061
|
-
* glyph matches the harness's own footer rows rather than shouting over
|
|
6062
|
-
* them — and, on the wide column, its label. Clicking opens the overview
|
|
6063
|
-
* overlay through the shared module store (overviewStore.ts).
|
|
6064
|
-
*
|
|
6065
|
-
* The per-user `insightsEntry` preference takes the entry down (renders
|
|
6066
|
-
* null) without unregistering the seat. The subscription fails open: an
|
|
6067
|
-
* absent settings store, an unserved namespace, or a value the plugin
|
|
6068
|
-
* cannot understand all leave the entry visible.
|
|
6069
|
-
*/
|
|
6070
|
-
/** Stable subscription faces for the settings-less degrade (no re-subscribes). */
|
|
6071
|
-
const subscribeNever = () => () => {};
|
|
6072
|
-
const entryShown = () => "show";
|
|
6073
|
-
function makeOverviewButton(kit, settings) {
|
|
6074
|
-
const { t } = kit;
|
|
6075
|
-
const subscribeEntry = settings === void 0 ? subscribeNever : (listener) => settings.store.subscribe(listener);
|
|
6076
|
-
const getEntry = settings === void 0 ? entryShown : () => settings.insightsEntry();
|
|
6077
|
-
return function OverviewButton(props) {
|
|
6078
|
-
if ((0, react.useSyncExternalStore)(subscribeEntry, getEntry) === "hide") return null;
|
|
6079
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6080
|
-
type: "button",
|
|
6081
|
-
className: props.wide === true ? "lc-ov-entry" : "lc-ov-entry lc-ov-entry-rail",
|
|
6082
|
-
title: t("ov.entry"),
|
|
6083
|
-
"aria-label": t("ov.entry"),
|
|
6084
|
-
onClick: () => {
|
|
6085
|
-
overviewStore.set(true);
|
|
6086
|
-
},
|
|
6087
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextIcon, {
|
|
6088
|
-
size: props.wide === true ? 16 : 18,
|
|
6089
|
-
className: "lc-ov-entry-icon",
|
|
6090
|
-
mono: true
|
|
6091
|
-
}), props.wide === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6092
|
-
className: "lc-ov-entry-label",
|
|
6093
|
-
children: t("ov.entry")
|
|
6094
|
-
})]
|
|
6095
|
-
});
|
|
6096
|
-
};
|
|
6097
|
-
}
|
|
6098
|
-
//#endregion
|
|
6099
6058
|
//#region src/shared/providers.ts
|
|
6100
6059
|
/**
|
|
6101
6060
|
* The provider-id seam between dsh request envelopes and the models.dev
|
|
@@ -7441,14 +7400,15 @@ window.__ModuleLoader__.load({
|
|
|
7441
7400
|
//#region src/client/components/balanceCapsule.tsx
|
|
7442
7401
|
/**
|
|
7443
7402
|
* BalanceCapsule — the DeepSeek open-platform balance pill in the Context
|
|
7444
|
-
*
|
|
7403
|
+
* Insights page's heading (the plugin's one account-level figure, beside the
|
|
7445
7404
|
* session-level ones). Clicking it opens the platform's usage console in a
|
|
7446
|
-
* new tab. Mounted only by the
|
|
7405
|
+
* new tab. Mounted only by the page heading; it paints the figure the
|
|
7447
7406
|
* previous open remembered while client/balance.ts revalidates it in the
|
|
7448
7407
|
* background, and renders NOTHING when nothing is remembered and the route
|
|
7449
7408
|
* answers nothing — the pill exists only when there is a figure to show. The
|
|
7450
|
-
* non-zero parts of the breakdown (topped-up / granted) ride the
|
|
7451
|
-
*
|
|
7409
|
+
* non-zero parts of the breakdown (topped-up / granted) ride the page's
|
|
7410
|
+
* portaled hover tip (hoverTip.tsx, off the pill's `data-lc-tip`) —
|
|
7411
|
+
* immediate on hover, where a native `title` lags — in
|
|
7452
7412
|
* the entry's own currency (the pill itself carries the total); the entry
|
|
7453
7413
|
* follows the active locale (zh → CNY) with the account's first currency as
|
|
7454
7414
|
* the fallback.
|
|
@@ -7472,9 +7432,13 @@ window.__ModuleLoader__.load({
|
|
|
7472
7432
|
if (entry === null) return null;
|
|
7473
7433
|
const money = (amount) => symbolOf(entry.currency) + amount.toFixed(2);
|
|
7474
7434
|
const tipLines = [...entry.toppedUp > 0 ? [t("balance.tip.toppedUp") + ": " + money(entry.toppedUp)] : [], ...entry.granted > 0 ? [t("balance.tip.granted") + ": " + money(entry.granted)] : []];
|
|
7475
|
-
|
|
7435
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
7476
7436
|
className: "lc-ov-balance",
|
|
7477
7437
|
"aria-label": tipLines.length > 0 ? tipLines.join("\n") : void 0,
|
|
7438
|
+
...tipLines.length > 0 ? {
|
|
7439
|
+
"data-lc-tip": tipLines.join("\n"),
|
|
7440
|
+
"data-lc-tip-side": "bottom"
|
|
7441
|
+
} : {},
|
|
7478
7442
|
href: USAGE_URL,
|
|
7479
7443
|
target: "_blank",
|
|
7480
7444
|
rel: "noreferrer",
|
|
@@ -7486,11 +7450,6 @@ window.__ModuleLoader__.load({
|
|
|
7486
7450
|
children: money(entry.total)
|
|
7487
7451
|
})]
|
|
7488
7452
|
});
|
|
7489
|
-
return tipLines.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
7490
|
-
label: tipLines.join("\n"),
|
|
7491
|
-
side: "bottom",
|
|
7492
|
-
children: pill
|
|
7493
|
-
}) : pill;
|
|
7494
7453
|
};
|
|
7495
7454
|
}
|
|
7496
7455
|
//#endregion
|
|
@@ -7551,24 +7510,6 @@ window.__ModuleLoader__.load({
|
|
|
7551
7510
|
//#endregion
|
|
7552
7511
|
//#region src/client/components/heatmap.tsx
|
|
7553
7512
|
/**
|
|
7554
|
-
* The Context Dashboard's activity heatmap: a GitHub-style contribution grid
|
|
7555
|
-
* (weeks as columns, Sunday-first weekdays as rows, a month label over each
|
|
7556
|
-
* column where a month begins — the window's opening column always labeled —
|
|
7557
|
-
* and a Less→More key for the depth steps) over the merged daily
|
|
7558
|
-
* ledger (overview.ts). Cell depth is the selected metric's share of the
|
|
7559
|
-
* window's maximum — distinct active sessions or settlement steps; a session
|
|
7560
|
-
* can spread its steps thinly across many days while another day stacks a
|
|
7561
|
-
* run, so each metric scales on its OWN maximum — in four steps; a day with
|
|
7562
|
-
* data is a button whose click
|
|
7563
|
-
* pins the session list to that day (click again to release). Cells tip
|
|
7564
|
-
* through the harness's own Tooltip primitive (instant on hover; native
|
|
7565
|
-
* `title` lags a second behind), the bubble carrying the date, the day's
|
|
7566
|
-
* active sessions, and its steps. The grid is computed from the injected
|
|
7567
|
-
* `today` key, so
|
|
7568
|
-
* the layout is deterministic in tests and follows the browser's local
|
|
7569
|
-
* calendar at runtime.
|
|
7570
|
-
*/
|
|
7571
|
-
/**
|
|
7572
7513
|
* Lay out the grid: `weeks` columns ending at today's week, each seven
|
|
7573
7514
|
* Sunday-first cells (row 0 = Sunday). Returns null when `today` (or its
|
|
7574
7515
|
* week math) fails — a corrupt injected key degrades the card to its empty
|
|
@@ -7679,25 +7620,21 @@ window.__ModuleLoader__.load({
|
|
|
7679
7620
|
"aria-hidden": "true"
|
|
7680
7621
|
}, cell.key);
|
|
7681
7622
|
const level = cell.entry === void 0 ? 0 : levelOf(metricValueOf(cell.entry), max);
|
|
7682
|
-
if (cell.entry === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "lc-heat-cell lc-heat-0" })
|
|
7623
|
+
if (cell.entry === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7624
|
+
className: "lc-heat-cell lc-heat-0",
|
|
7625
|
+
"data-lc-tip": cell.key
|
|
7686
7626
|
}, cell.key);
|
|
7687
7627
|
const picked = props.selected === cell.key;
|
|
7688
7628
|
const label = `${cell.key}\n${t("ov.heat.sessions", { n: cell.entry.sessions })}\n${t("ov.heat.steps", { n: cell.entry.requests })}`;
|
|
7689
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
if (props.onSelect !== void 0) props.onSelect(picked ? null : cell.key);
|
|
7699
|
-
}
|
|
7700
|
-
})
|
|
7629
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7630
|
+
type: "button",
|
|
7631
|
+
className: `lc-heat-cell lc-heat-${String(level)}${picked ? " lc-heat-on" : ""}`,
|
|
7632
|
+
"data-lc-tip": label,
|
|
7633
|
+
"aria-label": label,
|
|
7634
|
+
"aria-pressed": picked,
|
|
7635
|
+
onClick: () => {
|
|
7636
|
+
if (props.onSelect !== void 0) props.onSelect(picked ? null : cell.key);
|
|
7637
|
+
}
|
|
7701
7638
|
}, cell.key);
|
|
7702
7639
|
})]
|
|
7703
7640
|
}, wi);
|
|
@@ -7825,6 +7762,156 @@ window.__ModuleLoader__.load({
|
|
|
7825
7762
|
};
|
|
7826
7763
|
}
|
|
7827
7764
|
//#endregion
|
|
7765
|
+
//#region src/client/components/hoverTip.tsx
|
|
7766
|
+
/**
|
|
7767
|
+
* The dashboard's hover tips — one fixed bubble, portaled to <body>, driven
|
|
7768
|
+
* by event delegation off the page root.
|
|
7769
|
+
*
|
|
7770
|
+
* Why not the harness Tooltip: the Insights page is the `lc-ov` query
|
|
7771
|
+
* container, and inline-size containment makes the page the containing block
|
|
7772
|
+
* for FIXED descendants — an in-tree fixed bubble (the harness Tooltip's
|
|
7773
|
+
* unportaled spelling) would paint sidebar-width away from its anchor, while
|
|
7774
|
+
* the primitive's `portal` prop exists only on 0.1.7+. The plugin already
|
|
7775
|
+
* portals its own fixed overlays for exactly this trap (the image lightbox,
|
|
7776
|
+
* base.css), so the page's tips follow that precedent and stay correct on
|
|
7777
|
+
* every supported line.
|
|
7778
|
+
*
|
|
7779
|
+
* Anchors carry `data-lc-tip` (the label) and optional `data-lc-tip-side`
|
|
7780
|
+
* ('top' default, 'bottom'); the zone delegates `mouseover`/`mouseout` and
|
|
7781
|
+
* focus/blur capture, so anchors stay plain elements — no per-cell wrapper
|
|
7782
|
+
* components. One bubble at a time: it re-anchors on anchor switch, hides on
|
|
7783
|
+
* anchor leave, on any zone scroll, on a viewport resize (every anchor just
|
|
7784
|
+
* moved), and on unmount; while shown it sets the anchor's
|
|
7785
|
+
* `aria-describedby`.
|
|
7786
|
+
*
|
|
7787
|
+
* @module dsh-context/client/components/hoverTip
|
|
7788
|
+
*/
|
|
7789
|
+
/** The bubble's identity for the anchor's `aria-describedby` (one live bubble at a time). */
|
|
7790
|
+
const TIP_ID = "lc-hovertip-bubble";
|
|
7791
|
+
/** Anchor-to-bubble distance and the viewport margin the bubble clamps inside, in px. */
|
|
7792
|
+
const GAP = 6;
|
|
7793
|
+
const VIEWPORT_MARGIN = 8;
|
|
7794
|
+
/** The nearest tip anchor of an event target, if any. */
|
|
7795
|
+
function anchorOf(target) {
|
|
7796
|
+
return target instanceof Element ? target.closest("[data-lc-tip]") : null;
|
|
7797
|
+
}
|
|
7798
|
+
function tipOf(anchor) {
|
|
7799
|
+
const label = anchor.getAttribute("data-lc-tip");
|
|
7800
|
+
if (label === null || label === "") return null;
|
|
7801
|
+
const r = anchor.getBoundingClientRect();
|
|
7802
|
+
return {
|
|
7803
|
+
anchor,
|
|
7804
|
+
label,
|
|
7805
|
+
side: anchor.getAttribute("data-lc-tip-side") === "bottom" ? "bottom" : "top",
|
|
7806
|
+
rect: {
|
|
7807
|
+
left: r.left,
|
|
7808
|
+
top: r.top,
|
|
7809
|
+
width: r.width,
|
|
7810
|
+
height: r.height,
|
|
7811
|
+
bottom: r.bottom
|
|
7812
|
+
}
|
|
7813
|
+
};
|
|
7814
|
+
}
|
|
7815
|
+
/**
|
|
7816
|
+
* The zone hook: stable delegated handlers plus the portaled bubble. The
|
|
7817
|
+
* bubble renders hidden until the layout effect measures it, so it never
|
|
7818
|
+
* flashes at an unmeasured spot.
|
|
7819
|
+
*/
|
|
7820
|
+
function useHoverTip() {
|
|
7821
|
+
const [tip, setTip] = (0, react.useState)(null);
|
|
7822
|
+
const [measured, setMeasured] = (0, react.useState)(null);
|
|
7823
|
+
const bubbleRef = (0, react.useRef)(null);
|
|
7824
|
+
const show = (0, react.useCallback)((anchor) => {
|
|
7825
|
+
setTip((current) => {
|
|
7826
|
+
if (current?.anchor === anchor) return current;
|
|
7827
|
+
current?.anchor.removeAttribute("aria-describedby");
|
|
7828
|
+
const next = tipOf(anchor);
|
|
7829
|
+
if (next === null) return null;
|
|
7830
|
+
anchor.setAttribute("aria-describedby", TIP_ID);
|
|
7831
|
+
return next;
|
|
7832
|
+
});
|
|
7833
|
+
}, []);
|
|
7834
|
+
const hide = (0, react.useCallback)(() => {
|
|
7835
|
+
setTip((current) => {
|
|
7836
|
+
current?.anchor.removeAttribute("aria-describedby");
|
|
7837
|
+
return null;
|
|
7838
|
+
});
|
|
7839
|
+
}, []);
|
|
7840
|
+
const onMouseOver = (0, react.useCallback)((ev) => {
|
|
7841
|
+
const anchor = anchorOf(ev.target);
|
|
7842
|
+
if (anchor !== null) show(anchor);
|
|
7843
|
+
}, [show]);
|
|
7844
|
+
const onMouseOut = (0, react.useCallback)((ev) => {
|
|
7845
|
+
if (anchorOf(ev.target) !== null && anchorOf(ev.relatedTarget) === null) hide();
|
|
7846
|
+
}, [hide]);
|
|
7847
|
+
const onFocusCapture = (0, react.useCallback)((ev) => {
|
|
7848
|
+
const anchor = anchorOf(ev.target);
|
|
7849
|
+
if (anchor !== null) show(anchor);
|
|
7850
|
+
}, [show]);
|
|
7851
|
+
const onBlurCapture = (0, react.useCallback)((ev) => {
|
|
7852
|
+
if (anchorOf(ev.target) !== null && anchorOf(ev.relatedTarget) === null) hide();
|
|
7853
|
+
}, [hide]);
|
|
7854
|
+
const onScrollCapture = (0, react.useCallback)(() => {
|
|
7855
|
+
hide();
|
|
7856
|
+
}, [hide]);
|
|
7857
|
+
(0, react.useEffect)(() => {
|
|
7858
|
+
if (tip === null) return void 0;
|
|
7859
|
+
const retract = () => {
|
|
7860
|
+
hide();
|
|
7861
|
+
};
|
|
7862
|
+
window.addEventListener("resize", retract);
|
|
7863
|
+
return () => {
|
|
7864
|
+
window.removeEventListener("resize", retract);
|
|
7865
|
+
};
|
|
7866
|
+
}, [tip, hide]);
|
|
7867
|
+
(0, react.useLayoutEffect)(() => {
|
|
7868
|
+
if (tip === null || measured?.tip === tip) return;
|
|
7869
|
+
const el = bubbleRef.current;
|
|
7870
|
+
/* v8 ignore next -- the portal commits its ref before layout effects run,
|
|
7871
|
+
* so a null ref here is unreachable; kept as a guard so a future portal
|
|
7872
|
+
* change cannot crash the page. */
|
|
7873
|
+
if (el === null) return;
|
|
7874
|
+
const w = el.offsetWidth;
|
|
7875
|
+
const h = el.offsetHeight;
|
|
7876
|
+
const { rect } = tip;
|
|
7877
|
+
const left = Math.max(VIEWPORT_MARGIN, Math.min(rect.left + rect.width / 2 - w / 2, window.innerWidth - w - VIEWPORT_MARGIN));
|
|
7878
|
+
let top = tip.side === "top" ? rect.top - h - GAP : rect.bottom + GAP;
|
|
7879
|
+
if (tip.side === "top" && top < VIEWPORT_MARGIN) top = rect.bottom + GAP;
|
|
7880
|
+
else if (tip.side === "bottom" && top + h > window.innerHeight - VIEWPORT_MARGIN) top = rect.top - h - GAP;
|
|
7881
|
+
setMeasured({
|
|
7882
|
+
tip,
|
|
7883
|
+
left,
|
|
7884
|
+
top: Math.max(VIEWPORT_MARGIN, top)
|
|
7885
|
+
});
|
|
7886
|
+
}, [tip, measured]);
|
|
7887
|
+
const shown = measured !== null && measured.tip === tip ? measured : null;
|
|
7888
|
+
return {
|
|
7889
|
+
zoneProps: {
|
|
7890
|
+
onMouseOver,
|
|
7891
|
+
onMouseOut,
|
|
7892
|
+
onFocusCapture,
|
|
7893
|
+
onBlurCapture,
|
|
7894
|
+
onScrollCapture
|
|
7895
|
+
},
|
|
7896
|
+
bubble: tip === null ? null : (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7897
|
+
ref: bubbleRef,
|
|
7898
|
+
id: TIP_ID,
|
|
7899
|
+
role: "tooltip",
|
|
7900
|
+
className: "lc-tip lc-hovertip",
|
|
7901
|
+
style: shown === null ? {
|
|
7902
|
+
left: 0,
|
|
7903
|
+
top: 0,
|
|
7904
|
+
visibility: "hidden"
|
|
7905
|
+
} : {
|
|
7906
|
+
left: shown.left,
|
|
7907
|
+
top: shown.top,
|
|
7908
|
+
opacity: 1
|
|
7909
|
+
},
|
|
7910
|
+
children: tip.label
|
|
7911
|
+
}), document.body)
|
|
7912
|
+
};
|
|
7913
|
+
}
|
|
7914
|
+
//#endregion
|
|
7828
7915
|
//#region src/client/components/sliceList.tsx
|
|
7829
7916
|
/**
|
|
7830
7917
|
* The stats cards' slice rows: the donut's legend with numbers, two tiers
|
|
@@ -7935,26 +8022,6 @@ window.__ModuleLoader__.load({
|
|
|
7935
8022
|
}
|
|
7936
8023
|
//#endregion
|
|
7937
8024
|
//#region src/client/components/overviewUsage.tsx
|
|
7938
|
-
/**
|
|
7939
|
-
* The Context Insights panel's first-row usage chart — the RIGHT half of the
|
|
7940
|
-
* KPI row. Seven day columns ending today, each pairing two bars priced off
|
|
7941
|
-
* the merged daily ledger (overview.ts aggregateDays): billed TOKENS (the
|
|
7942
|
-
* heatmap's own blue) and the day's estimated COST (green). The fee rides
|
|
7943
|
-
* the same per-day pricing records the host fold books at each turn's
|
|
7944
|
-
* initiation, priced by the same book and estimator as the KPI band's cost
|
|
7945
|
-
* cell — never a whole session's spend dumped on the day it was last
|
|
7946
|
-
* active. The two series scale on their OWN window maxima (a $2 week must
|
|
7947
|
-
* not flatten under a 169M-token week), so each bar reads as a share of its
|
|
7948
|
-
* series' peak; the tooltip carries the exact figures. The window is fixed
|
|
7949
|
-
* to the last 7 days — the range selector above scopes the KPI figures, not
|
|
7950
|
-
* this calendar.
|
|
7951
|
-
*
|
|
7952
|
-
* The plot is framed like a chart: hairline gridlines at 0/25/50/75/100% of
|
|
7953
|
-
* each series' own peak, a solid baseline at 0, and a tick rail on each
|
|
7954
|
-
* side — TOKENS on the left, COST on the right, computed from the same
|
|
7955
|
-
* maxima the bars scale to. The cost rail reads '—' until some day actually
|
|
7956
|
-
* prices.
|
|
7957
|
-
*/
|
|
7958
8025
|
/** The chart's window: today and the six days before it, oldest first. */
|
|
7959
8026
|
function usageWindowOf(today) {
|
|
7960
8027
|
const columns = [];
|
|
@@ -8035,21 +8102,18 @@ window.__ModuleLoader__.load({
|
|
|
8035
8102
|
const tokens = c.entry?.tokens ?? 0;
|
|
8036
8103
|
const cost = c.entry?.cost ?? null;
|
|
8037
8104
|
const label = `${c.key}\n${t("ov.usage.tokens")} ${fmt(tokens)}\n${t("ov.usage.costTip")} ${cost === null ? "—" : formatCost(cost, props.currency)}`;
|
|
8038
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8042
|
-
className: "lc-ov-usage-
|
|
8043
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8044
|
-
className: "lc-ov-usage-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
style: { height: cost === null ? "0%" : heightOf(cost, maxCost) }
|
|
8051
|
-
})]
|
|
8052
|
-
})
|
|
8105
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8106
|
+
className: "lc-ov-usage-col",
|
|
8107
|
+
"data-lc-tip": label,
|
|
8108
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8109
|
+
className: "lc-ov-usage-bars",
|
|
8110
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8111
|
+
className: "lc-ov-usage-bar lc-ov-usage-tokens",
|
|
8112
|
+
style: { height: heightOf(tokens, maxTokens) }
|
|
8113
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8114
|
+
className: "lc-ov-usage-bar lc-ov-usage-cost",
|
|
8115
|
+
style: { height: cost === null ? "0%" : heightOf(cost, maxCost) }
|
|
8116
|
+
})]
|
|
8053
8117
|
})
|
|
8054
8118
|
}, c.key);
|
|
8055
8119
|
})
|
|
@@ -8541,27 +8605,37 @@ window.__ModuleLoader__.load({
|
|
|
8541
8605
|
//#endregion
|
|
8542
8606
|
//#region src/client/components/overviewPanel.tsx
|
|
8543
8607
|
/**
|
|
8544
|
-
* The Context
|
|
8545
|
-
*
|
|
8546
|
-
*
|
|
8547
|
-
*
|
|
8548
|
-
*
|
|
8549
|
-
*
|
|
8608
|
+
* The Context Insights page — the plugin's first-level panel, opened from
|
|
8609
|
+
* the sidebar's panel list (insightPage.ts), a sibling of the shipped
|
|
8610
|
+
* Plugins and Automation tasks pages. Registered on the layout's keyed
|
|
8611
|
+
* `main` slot, so the shell's center column mounts it when the panel is
|
|
8612
|
+
* selected and unmounts it on leave — the page's mount IS its open, and its
|
|
8613
|
+
* data rides the root-scope `useSessions`/`useWorkspaces` standard kit
|
|
8614
|
+
* (every list row's host-cached projection values), so the page draws every
|
|
8615
|
+
* session's insight without opening one log.
|
|
8616
|
+
*
|
|
8617
|
+
* The chrome mirrors the shipped first-level pages: one scroll region whose
|
|
8618
|
+
* centered content column (the Plugins page's 960px frame) opens with the
|
|
8619
|
+
* page heading — the title beside the range group (and the DeepSeek balance
|
|
8620
|
+
* capsule when it serves) — and the page element is the `lc-ov` query
|
|
8621
|
+
* container, so every fold keys off the pane's own width. Hover tips portal
|
|
8622
|
+
* to <body> (hoverTip.tsx) because the container would otherwise capture
|
|
8623
|
+
* their fixed positioning.
|
|
8550
8624
|
*
|
|
8551
|
-
* The
|
|
8625
|
+
* The body's first row is a 1:1 column pair: the KPI metrics band (the
|
|
8552
8626
|
* range's six figures — sessions, billed tokens, cost, cache hit, tool
|
|
8553
8627
|
* calls, active time — three per row) beside the last-7-days usage chart
|
|
8554
|
-
* (each day's billed tokens and estimated cost as a bar pair, folded off
|
|
8555
|
-
*
|
|
8556
|
-
*
|
|
8557
|
-
*
|
|
8558
|
-
*
|
|
8559
|
-
*
|
|
8560
|
-
*
|
|
8561
|
-
*
|
|
8562
|
-
*
|
|
8563
|
-
*
|
|
8564
|
-
*
|
|
8628
|
+
* (each day's billed tokens and estimated cost as a bar pair, folded off the
|
|
8629
|
+
* merged daily ledger). Below it, the aggregate stats row folds the same
|
|
8630
|
+
* range's sessions into the two donut cards the per-session Context tab
|
|
8631
|
+
* opens with — Token Stats (the composition-split billed volume) and Timing
|
|
8632
|
+
* Stats (the summed totals). The body is then a 3:7 column pair: the
|
|
8633
|
+
* insight column (the activity heatmap, then the preferences entry row)
|
|
8634
|
+
* beside the session column (search, group chips, and the card grid); the
|
|
8635
|
+
* heatmap keeps its own fixed 8-week window and PINs the list to a picked
|
|
8636
|
+
* day (the page's drill-down gesture). A session card click jumps to that
|
|
8637
|
+
* session through the harness's own selection verb (openSessionVia), whose
|
|
8638
|
+
* navigation returns the center column to the conversation.
|
|
8565
8639
|
*/
|
|
8566
8640
|
const RANGES = [
|
|
8567
8641
|
"24h",
|
|
@@ -8592,7 +8666,6 @@ window.__ModuleLoader__.load({
|
|
|
8592
8666
|
return (typeof locale.getLocale === "function" ? locale.getLocale().active : "en") === "zh" ? "cny" : "usd";
|
|
8593
8667
|
}
|
|
8594
8668
|
function OverviewBody(props) {
|
|
8595
|
-
const open = (0, react.useSyncExternalStore)(overviewStore.subscribe, overviewStore.getSnapshot);
|
|
8596
8669
|
const { book } = useModelPrices();
|
|
8597
8670
|
const snapshot = sessionsSnapshotOf(props);
|
|
8598
8671
|
const wsSnapshot = workspacesSnapshotOf(props);
|
|
@@ -8603,18 +8676,13 @@ window.__ModuleLoader__.load({
|
|
|
8603
8676
|
const [sort, setSort] = (0, react.useState)("recent");
|
|
8604
8677
|
const [metric, setMetric] = (0, react.useState)("steps");
|
|
8605
8678
|
const [page, setPage] = (0, react.useState)(0);
|
|
8606
|
-
const
|
|
8607
|
-
overviewStore.set(false);
|
|
8608
|
-
};
|
|
8609
|
-
useEscapeClose(open, close);
|
|
8679
|
+
const { zoneProps, bubble } = useHoverTip();
|
|
8610
8680
|
const rows = (0, react.useMemo)(() => rowsOfSnapshot(snapshot, wsSnapshot), [snapshot, wsSnapshot]);
|
|
8611
8681
|
const groups = (0, react.useMemo)(() => sessionGroupsOf(wsSnapshot), [wsSnapshot]);
|
|
8612
8682
|
(0, react.useEffect)(() => {
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
}
|
|
8617
|
-
}, [open]);
|
|
8683
|
+
requestActivityBackfill();
|
|
8684
|
+
refreshSessions(ctx);
|
|
8685
|
+
}, []);
|
|
8618
8686
|
(0, react.useEffect)(() => {
|
|
8619
8687
|
setPage(0);
|
|
8620
8688
|
}, [
|
|
@@ -8624,7 +8692,6 @@ window.__ModuleLoader__.load({
|
|
|
8624
8692
|
group,
|
|
8625
8693
|
sort
|
|
8626
8694
|
]);
|
|
8627
|
-
if (!open) return null;
|
|
8628
8695
|
const currency = activeCurrency();
|
|
8629
8696
|
const now = Date.now();
|
|
8630
8697
|
const allRows = rows ?? [];
|
|
@@ -8649,55 +8716,41 @@ window.__ModuleLoader__.load({
|
|
|
8649
8716
|
const days = aggregateDays(allRows, book, currency);
|
|
8650
8717
|
const openOne = (id) => {
|
|
8651
8718
|
openSessionVia(ctx, id);
|
|
8652
|
-
overviewStore.set(false);
|
|
8653
8719
|
};
|
|
8654
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8655
|
-
className: "lc-ov-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
type: "button",
|
|
8689
|
-
className: "lc-modal-close hover:text-(--dsw-alias-label-primary) hover:bg-(--dsw-alias-bg-layer-2)",
|
|
8690
|
-
"aria-label": t("cmd.close"),
|
|
8691
|
-
onClick: close,
|
|
8692
|
-
children: "×"
|
|
8693
|
-
})
|
|
8694
|
-
]
|
|
8695
|
-
}), rows === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8696
|
-
className: "lc-empty",
|
|
8697
|
-
children: t("ov.unavailable")
|
|
8698
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8699
|
-
className: "lc-ov-scroll",
|
|
8700
|
-
children: [
|
|
8720
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8721
|
+
className: "lc-ov-page",
|
|
8722
|
+
"aria-label": t("ov.title"),
|
|
8723
|
+
...zoneProps,
|
|
8724
|
+
children: [bubble, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8725
|
+
className: "lc-ov-pagescroll",
|
|
8726
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8727
|
+
className: "lc-ov-pagecontent",
|
|
8728
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8729
|
+
className: "lc-ov-pagehead",
|
|
8730
|
+
children: [
|
|
8731
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
|
|
8732
|
+
className: "lc-ov-pagetitle",
|
|
8733
|
+
children: t("ov.title")
|
|
8734
|
+
}),
|
|
8735
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(BalanceCapsule, {}),
|
|
8736
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8737
|
+
className: "lc-gran lc-ov-range",
|
|
8738
|
+
role: "group",
|
|
8739
|
+
"aria-label": t("ov.range.label"),
|
|
8740
|
+
children: RANGES.map((r) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8741
|
+
type: "button",
|
|
8742
|
+
className: "lc-gran-btn" + (range === r ? " lc-gran-on" : ""),
|
|
8743
|
+
onClick: () => {
|
|
8744
|
+
setRange(r);
|
|
8745
|
+
},
|
|
8746
|
+
children: t("ov.range." + r)
|
|
8747
|
+
}, r))
|
|
8748
|
+
})
|
|
8749
|
+
]
|
|
8750
|
+
}), rows === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8751
|
+
className: "lc-empty",
|
|
8752
|
+
children: t("ov.unavailable")
|
|
8753
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
8701
8754
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8702
8755
|
className: "lc-ov-first",
|
|
8703
8756
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -8865,7 +8918,6 @@ window.__ModuleLoader__.load({
|
|
|
8865
8918
|
className: "lc-ov-settings",
|
|
8866
8919
|
onClick: () => {
|
|
8867
8920
|
openPluginSettings();
|
|
8868
|
-
close();
|
|
8869
8921
|
},
|
|
8870
8922
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8871
8923
|
className: "lc-ov-settings-label",
|
|
@@ -8998,9 +9050,9 @@ window.__ModuleLoader__.load({
|
|
|
8998
9050
|
]
|
|
8999
9051
|
})]
|
|
9000
9052
|
})
|
|
9001
|
-
]
|
|
9002
|
-
})
|
|
9003
|
-
})
|
|
9053
|
+
] })]
|
|
9054
|
+
})
|
|
9055
|
+
})]
|
|
9004
9056
|
});
|
|
9005
9057
|
}
|
|
9006
9058
|
return function OverviewPanel(props) {
|
|
@@ -9287,6 +9339,97 @@ window.__ModuleLoader__.load({
|
|
|
9287
9339
|
};
|
|
9288
9340
|
}
|
|
9289
9341
|
//#endregion
|
|
9342
|
+
//#region src/client/insightPage.ts
|
|
9343
|
+
/**
|
|
9344
|
+
* The Context Insights page — the plugin's first-level panel, a sibling of
|
|
9345
|
+
* the shipped Plugins and Automation tasks pages.
|
|
9346
|
+
*
|
|
9347
|
+
* Two registrations, one identity:
|
|
9348
|
+
* - the full page itself on the layout's root keyed `main` slot, under the
|
|
9349
|
+
* panel key — the shell's center column renders it whenever the panel is
|
|
9350
|
+
* selected (keyed entryKey switching mounts it on entry and unmounts it
|
|
9351
|
+
* on leave, so the page's mount IS its open);
|
|
9352
|
+
* - the sidebar entry on the root list `sidebar.panellist` under the same
|
|
9353
|
+
* id — the shell owns the row (button, label, active state, and the
|
|
9354
|
+
* click that selects the panel), the plugin contributes only the glyph
|
|
9355
|
+
* and the localized label thunk.
|
|
9356
|
+
*
|
|
9357
|
+
* Both seats ship on every supported line (the `main` conversation panel and
|
|
9358
|
+
* the panellist contract are present since 0.1.5-rc.1 — the compat matrix
|
|
9359
|
+
* pins both spellings per baseline), so the registrations ride plain
|
|
9360
|
+
* `slots.inject` declaration injects, like the conversation tab's.
|
|
9361
|
+
*
|
|
9362
|
+
* The per-user `insightsEntry` preference gates the pair: 'show' mounts both
|
|
9363
|
+
* registrations, 'hide' unwinds them (a hidden entry leaves the page no
|
|
9364
|
+
* opener). The watcher mirrors placement.ts's preference-glued mounting;
|
|
9365
|
+
* each mount owns its disposers so a preference flip takes down exactly what
|
|
9366
|
+
* it drops.
|
|
9367
|
+
*
|
|
9368
|
+
* @module dsh-context/client/insightPage
|
|
9369
|
+
*/
|
|
9370
|
+
/**
|
|
9371
|
+
* The id shared by the sidebar entry and the `main` panel it opens (the
|
|
9372
|
+
* layout's MainPanelId domain) — namespaced, like the right-Sidebar kind, so
|
|
9373
|
+
* no shipped or foreign panel collides with it.
|
|
9374
|
+
*/
|
|
9375
|
+
const INSIGHT_PANEL_ID = "dsh-context";
|
|
9376
|
+
/**
|
|
9377
|
+
* Mount the page and its sidebar entry while the preference shows them.
|
|
9378
|
+
* @param ctx - client root context carrying `slots` and the locale service.
|
|
9379
|
+
* @param settings - the preferences store; the gate re-reads on every publish.
|
|
9380
|
+
* @param page - the Insights page component (the root-scope standard kit
|
|
9381
|
+
* arrives on its props, as on every root seat).
|
|
9382
|
+
* @param t - the plugin-namespace translate; the label thunk reads it at call
|
|
9383
|
+
* time, so a language switch relabels the sidebar row.
|
|
9384
|
+
* @param ns - the plugin's locale namespace, put on both registrations so the
|
|
9385
|
+
* framework synthesizes the `t` seat for the page too.
|
|
9386
|
+
* @returns the watcher's disposer (unsubscribes and unwinds any live mount).
|
|
9387
|
+
*/
|
|
9388
|
+
function watchInsightPage(ctx, settings, page, t, ns) {
|
|
9389
|
+
let mounted = false;
|
|
9390
|
+
const disposers = [];
|
|
9391
|
+
const own = (result) => {
|
|
9392
|
+
if (typeof result === "function") disposers.push(result);
|
|
9393
|
+
};
|
|
9394
|
+
const mount = () => {
|
|
9395
|
+
own(ctx.slots.inject("main", () => ctx.slots.register({
|
|
9396
|
+
name: "main",
|
|
9397
|
+
key: INSIGHT_PANEL_ID,
|
|
9398
|
+
locale: ns
|
|
9399
|
+
}, page)));
|
|
9400
|
+
own(ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({
|
|
9401
|
+
name: "sidebar.panellist",
|
|
9402
|
+
id: INSIGHT_PANEL_ID,
|
|
9403
|
+
order: 20,
|
|
9404
|
+
label: () => t("ov.title"),
|
|
9405
|
+
locale: ns
|
|
9406
|
+
}, (props) => (0, react.createElement)(InsightPanelIcon, { size: typeof props.size === "number" ? props.size : void 0 }))));
|
|
9407
|
+
};
|
|
9408
|
+
const unmount = () => {
|
|
9409
|
+
while (disposers.length > 0) disposers.pop()?.();
|
|
9410
|
+
};
|
|
9411
|
+
const applyEntry = (entry) => {
|
|
9412
|
+
if (entry === "show" && !mounted) {
|
|
9413
|
+
mounted = true;
|
|
9414
|
+
mount();
|
|
9415
|
+
} else if (entry === "hide" && mounted) {
|
|
9416
|
+
mounted = false;
|
|
9417
|
+
unmount();
|
|
9418
|
+
}
|
|
9419
|
+
};
|
|
9420
|
+
applyEntry(settings.insightsEntry());
|
|
9421
|
+
const unsubscribe = settings.store.subscribe(() => {
|
|
9422
|
+
applyEntry(settings.insightsEntry());
|
|
9423
|
+
});
|
|
9424
|
+
return () => {
|
|
9425
|
+
unsubscribe();
|
|
9426
|
+
if (mounted) {
|
|
9427
|
+
mounted = false;
|
|
9428
|
+
unmount();
|
|
9429
|
+
}
|
|
9430
|
+
};
|
|
9431
|
+
}
|
|
9432
|
+
//#endregion
|
|
9290
9433
|
//#region src/client/settings.ts
|
|
9291
9434
|
function prefsOf(value) {
|
|
9292
9435
|
if (value === null || typeof value !== "object") return {};
|
|
@@ -11524,7 +11667,7 @@ window.__ModuleLoader__.load({
|
|
|
11524
11667
|
return function PluginInfo() {
|
|
11525
11668
|
const [latest, setLatest] = (0, react.useState)(null);
|
|
11526
11669
|
(0, react.useEffect)(() => {
|
|
11527
|
-
if ("0.
|
|
11670
|
+
if ("0.64.0".includes("-dev")) return;
|
|
11528
11671
|
let on = true;
|
|
11529
11672
|
fetchLatestVersion().then((v) => {
|
|
11530
11673
|
if (on && v) setLatest(v);
|
|
@@ -11533,8 +11676,8 @@ window.__ModuleLoader__.load({
|
|
|
11533
11676
|
on = false;
|
|
11534
11677
|
};
|
|
11535
11678
|
}, []);
|
|
11536
|
-
const update = latest !== null && isNewerVersion(latest, "0.
|
|
11537
|
-
const nameText = "dsh-context (v0.
|
|
11679
|
+
const update = latest !== null && isNewerVersion(latest, "0.64.0") ? latest : null;
|
|
11680
|
+
const nameText = "dsh-context (v0.64.0)";
|
|
11538
11681
|
const nameValue = [nameText];
|
|
11539
11682
|
if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11540
11683
|
className: "lc-pi-update",
|
|
@@ -12740,49 +12883,39 @@ window.__ModuleLoader__.load({
|
|
|
12740
12883
|
className: "lc-card-title-text",
|
|
12741
12884
|
children: t("trend.title")
|
|
12742
12885
|
}),
|
|
12743
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
12744
|
-
className: "lc-gran lc-trend-
|
|
12745
|
-
role: "group",
|
|
12746
|
-
title: t("trend.dnaTip"),
|
|
12747
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12748
|
-
type: "button",
|
|
12749
|
-
className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
|
|
12750
|
-
onClick: () => {
|
|
12751
|
-
setDna((v) => !v);
|
|
12752
|
-
},
|
|
12753
|
-
children: t("trend.dna")
|
|
12754
|
-
})
|
|
12755
|
-
}),
|
|
12756
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12757
|
-
className: "lc-gran lc-trend-adaptive",
|
|
12758
|
-
role: "group",
|
|
12759
|
-
title: t("trend.adaptiveHint"),
|
|
12760
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12761
|
-
type: "button",
|
|
12762
|
-
className: "lc-gran-btn" + (adaptive ? " lc-gran-on" : ""),
|
|
12763
|
-
onClick: () => {
|
|
12764
|
-
setAdaptive((on) => !on);
|
|
12765
|
-
},
|
|
12766
|
-
children: t("trend.adaptive")
|
|
12767
|
-
})
|
|
12768
|
-
}),
|
|
12769
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12770
|
-
className: "lc-gran lc-trend-duration",
|
|
12886
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12887
|
+
className: "lc-gran lc-trend-mods",
|
|
12771
12888
|
role: "group",
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12889
|
+
children: [
|
|
12890
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12891
|
+
type: "button",
|
|
12892
|
+
className: "lc-gran-btn" + (dna ? " lc-gran-on" : ""),
|
|
12893
|
+
title: t("trend.dnaTip"),
|
|
12894
|
+
onClick: () => {
|
|
12895
|
+
setDna((v) => !v);
|
|
12896
|
+
},
|
|
12897
|
+
children: t("trend.dna")
|
|
12898
|
+
}),
|
|
12899
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12900
|
+
type: "button",
|
|
12901
|
+
className: "lc-gran-btn" + (adaptive ? " lc-gran-on" : ""),
|
|
12902
|
+
title: t("trend.adaptiveHint"),
|
|
12903
|
+
onClick: () => {
|
|
12904
|
+
setAdaptive((on) => !on);
|
|
12905
|
+
},
|
|
12906
|
+
children: t("trend.adaptive")
|
|
12907
|
+
}),
|
|
12908
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12909
|
+
type: "button",
|
|
12910
|
+
className: "lc-gran-btn" + (durationCurve ? " lc-gran-on" : ""),
|
|
12911
|
+
title: t("trend.durationTip"),
|
|
12912
|
+
onClick: () => {
|
|
12913
|
+
setDurationCurve((on) => !on);
|
|
12914
|
+
},
|
|
12915
|
+
children: t("trend.duration")
|
|
12916
|
+
})
|
|
12917
|
+
]
|
|
12781
12918
|
}),
|
|
12782
|
-
focusCat !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12783
|
-
className: "lc-card-sub",
|
|
12784
|
-
children: t("trend.focus", { cat: kit.catLabel(focusCat) })
|
|
12785
|
-
}) : null,
|
|
12786
12919
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12787
12920
|
className: "lc-trend-ctl",
|
|
12788
12921
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -13140,7 +13273,7 @@ window.__ModuleLoader__.load({
|
|
|
13140
13273
|
}
|
|
13141
13274
|
//#endregion
|
|
13142
13275
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/base.css.mjs
|
|
13143
|
-
const css$14 = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}[data-sidebar-right-open] .lc-root,[data-sidebar-right-float-host] .lc-root{padding:12px}.lc-title-icon{flex:none}.lc-title-label{padding-right:30px}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-root .lc-card{box-sizing:border-box;margin-bottom:7px;padding:7px 8px;container:lc-card/inline-size}.lc-root .lc-cols{gap:7px;margin-bottom:7px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl,.lc-heat-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran,.lc-heat-ctl .lc-gran,.lc-heat-ctl .lc-card-sub{margin-left:0}.lc-trend-
|
|
13276
|
+
const css$14 = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}[data-sidebar-right-open] .lc-root,[data-sidebar-right-float-host] .lc-root{padding:12px}.lc-title-icon{flex:none}.lc-title-label{padding-right:30px}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-root .lc-card{box-sizing:border-box;margin-bottom:7px;padding:7px 8px;container:lc-card/inline-size}.lc-root .lc-cols{gap:7px;margin-bottom:7px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl,.lc-heat-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran,.lc-heat-ctl .lc-gran,.lc-heat-ctl .lc-card-sub{margin-left:0}.lc-trend-mods{flex:none;margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-btn:disabled{opacity:.4;cursor:not-allowed}.lc-gran-btn:disabled:hover{color:var(--dsw-alias-label-secondary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-kind-n{font-variant-numeric:tabular-nums;opacity:.65;margin-left:4px}.lc-gran-on .lc-kind-n{opacity:.85}.lc-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 2px 8px #0000002e);pointer-events:none;opacity:0;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:6px 10px;font-size:12px;position:absolute}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-col-browser{flex-direction:column;display:flex}.lc-col-browser>.lc-card{flex:1}.lc-head>.lc-card:has(.lc-stats){flex-direction:column;display:flex}.lc-head .lc-stats{flex:1;align-content:stretch}.lc-head .lc-stat{justify-content:center}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:4px 14px;font-size:12px}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])),[data-conversation-scroll]:has(.lc-root,.lc-modal-backdrop)~[data-width-handle]{display:none}";
|
|
13144
13277
|
const tagId$14 = "dsh-context/base.css";
|
|
13145
13278
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$14) + "]") === null) {
|
|
13146
13279
|
const tag = document.createElement("style");
|
|
@@ -13151,7 +13284,7 @@ window.__ModuleLoader__.load({
|
|
|
13151
13284
|
}
|
|
13152
13285
|
//#endregion
|
|
13153
13286
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/stats.css.mjs
|
|
13154
|
-
const css$13 = ".lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}a.lc-stat{color:inherit;cursor:pointer;text-decoration:none}a.lc-stat:hover{border-color:var(--dsw-alias-label-secondary)}.lc-stats .lc-stat{padding:6px 3px}.lc-stats .lc-stat-q{margin:0;position:absolute;top:3px;right:4px}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:help;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-band{justify-content:space-between;gap:2rem;display:flex}.lc-stat-tip-band i{font-style:normal}.lc-stat-tip-by{color:var(--dsw-alias-label-secondary);margin-top:3px;display:block}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:color-mix(in srgb, var(--color-neutral-500) 18%, transparent)}.lc-donut-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-donut-dim .lc-donut-seg{opacity:.35}.lc-donut-dim .lc-donut-seg-on{opacity:1}.lc-donut-center{pointer-events:none;text-align:center;box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:0 7px;display:flex;position:absolute;inset:0}.lc-donut-center b{white-space:nowrap;text-overflow:ellipsis;max-width:100%;line-height:1.15;overflow:hidden}.lc-donut-center span{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-sl{grid-template-columns:repeat(auto-fill,minmax(
|
|
13287
|
+
const css$13 = ".lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}a.lc-stat{color:inherit;cursor:pointer;text-decoration:none}a.lc-stat:hover{border-color:var(--dsw-alias-label-secondary)}.lc-stats .lc-stat{padding:6px 3px}.lc-stats .lc-stat-q{margin:0;position:absolute;top:3px;right:4px}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:help;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-band{justify-content:space-between;gap:2rem;display:flex}.lc-stat-tip-band i{font-style:normal}.lc-stat-tip-by{color:var(--dsw-alias-label-secondary);margin-top:3px;display:block}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:color-mix(in srgb, var(--color-neutral-500) 18%, transparent)}.lc-donut-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-donut-dim .lc-donut-seg{opacity:.35}.lc-donut-dim .lc-donut-seg-on{opacity:1}.lc-donut-center{pointer-events:none;text-align:center;box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:0 7px;display:flex;position:absolute;inset:0}.lc-donut-center b{white-space:nowrap;text-overflow:ellipsis;max-width:100%;line-height:1.15;overflow:hidden}.lc-donut-center span{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-sl{grid-template-columns:repeat(auto-fill,minmax(min(150px,100%),1fr));gap:4px 8px;min-width:0;display:grid;overflow:hidden}.lc-sl-row{min-width:0;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;flex-direction:column;gap:1px;margin:0 -6px;padding:1px 6px;font-size:12px;display:flex}.lc-sl-row-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-sl-row-dim{opacity:.55}.lc-sl-main{align-items:center;gap:6px;min-width:0;display:flex}.lc-sl-dot{border-radius:2px;flex:none;width:8px;height:8px}.lc-sl-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;font-weight:600;line-height:1.25;overflow:hidden}.lc-sl-pct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:30px;font-weight:700}.lc-sl-sub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;margin-left:14px;font-size:11px;line-height:1.3;overflow:hidden}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row-btn{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;width:100%;padding:0}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-hint{text-decoration:none}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-labelicon{vertical-align:-2px;margin-right:4px;display:inline-block}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-tstrip{margin-top:10px}.lc-tstrip-wrap{position:relative}.lc-tstrip-bar{background:color-mix(in srgb, var(--color-neutral-500) 18%, transparent);border-radius:4px;width:100%;height:12px;position:relative;overflow:hidden}.lc-tstrip-seg{transform-origin:0;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);position:absolute;top:0}.lc-tstrip-seg-on{filter:brightness(1.18)}.lc-tstrip-dim .lc-tstrip-seg{opacity:.35}.lc-tstrip-dim .lc-tstrip-seg-on{opacity:1}.lc-tstrip-axis{height:13px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;margin-top:5px;font-size:10px;line-height:13px;position:relative}.lc-tstrip-tick{white-space:nowrap;position:absolute;transform:translate(-50%)}.lc-tstrip-tick:before{content:\"\";background:var(--dsw-alias-border-l1);width:1px;height:3px;position:absolute;top:-4px;left:50%}.lc-tstrip-tick-first{transform:none}.lc-tstrip-tick-first:before{left:0}.lc-tstrip-tick-last{transform:translate(-100%)}.lc-tstrip-tick-last:before{left:auto;right:0}";
|
|
13155
13288
|
const tagId$13 = "dsh-context/stats.css";
|
|
13156
13289
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
|
|
13157
13290
|
const tag = document.createElement("style");
|
|
@@ -13195,7 +13328,7 @@ window.__ModuleLoader__.load({
|
|
|
13195
13328
|
}
|
|
13196
13329
|
//#endregion
|
|
13197
13330
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/trendChart.css.mjs
|
|
13198
|
-
const css$9 = ".lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-r{flex:none;width:34px}.lc-axis-r span{left:0;right:auto}.lc-axis-top{top:13px}.lc-axis-q3{top:41px}.lc-axis-mid{top:69px}.lc-axis-q1{top:97px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{overscroll-behavior-x:contain;scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding:18px 2px 0;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l2);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-q3{top:46px}.lc-grid-mid{top:74px}.lc-grid-q1{top:102px}.lc-grid-zero{border-top-style:solid;border-top-color:color-mix(in srgb, var(--color-neutral-500) 50%, transparent);top:130px}.lc-bar{cursor:pointer;outline-offset:1px;width:14px;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), outline-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;outline:1px dashed #0000;flex:none;align-items:flex-end;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;box-sizing:border-box;overflow-wrap:break-word;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:100%;color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;flex-direction:column;gap:2px;padding:3px 8px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);left:0;box-shadow:0 2px 8px #0000002e}.lc-chart-tip span+span{color:var(--dsw-alias-label-secondary)}.lc-bar-hovered{outline-color:var(--dsw-alias-brand-primary)}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:color-mix(in srgb, var(--color-neutral-500) 14%, transparent)}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-dna{border-radius:2px;width:100%}.lc-bar-stack,.lc-bar-up,.lc-bar-down,.lc-bar-dna{transform-origin:50% 100%}.lc-bar-down{transform-origin:50% 0}.lc-bar-stack>div:first-child{border-radius:0 0 2px 2px}.lc-bar-stack>div:last-child{border-radius:2px 2px 0 0}.lc-bar-stack>div:only-child{border-radius:2px}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-bar-up>div:last-child{border-radius:2px 2px 0 0}.lc-bar-down>div:last-child{border-radius:0 0 2px 2px}.lc-cat-seg{transition:
|
|
13331
|
+
const css$9 = ".lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-r{flex:none;width:34px}.lc-axis-r span{left:0;right:auto}.lc-axis-top{top:13px}.lc-axis-q3{top:41px}.lc-axis-mid{top:69px}.lc-axis-q1{top:97px}.lc-axis-bot{top:125px}.lc-chart-wrap{flex:1;min-width:0;position:relative}.lc-chart-scroll{overscroll-behavior-x:contain;scrollbar-gutter:stable;padding-bottom:var(--dsh-scrollbar-width,8px);overflow:auto hidden}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding:18px 2px 0;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l2);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-q3{top:46px}.lc-grid-mid{top:74px}.lc-grid-q1{top:102px}.lc-grid-zero{border-top-style:solid;border-top-color:color-mix(in srgb, var(--color-neutral-500) 50%, transparent);top:130px}.lc-bar{cursor:pointer;outline-offset:1px;width:14px;height:100%;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), outline-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:2px;outline:1px dashed #0000;flex:none;align-items:flex-end;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;box-sizing:border-box;overflow-wrap:break-word;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:100%;color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;flex-direction:column;gap:2px;padding:3px 8px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);left:0;box-shadow:0 2px 8px #0000002e}.lc-chart-tip span+span{color:var(--dsw-alias-label-secondary)}.lc-bar-hovered{outline-color:var(--dsw-alias-brand-primary)}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:color-mix(in srgb, var(--color-neutral-500) 14%, transparent)}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-dna{border-radius:2px;width:100%}.lc-bar-stack,.lc-bar-up,.lc-bar-down,.lc-bar-dna{transform-origin:50% 100%}.lc-bar-down{transform-origin:50% 0}.lc-bar-stack>div:first-child{border-radius:0 0 2px 2px}.lc-bar-stack>div:last-child{border-radius:2px 2px 0 0}.lc-bar-stack>div:only-child{border-radius:2px}.lc-bar-up,.lc-bar-down{width:100%;display:flex;position:absolute;left:0}.lc-bar-up{flex-direction:column-reverse}.lc-bar-down{flex-direction:column}.lc-bar-up>div,.lc-bar-down>div{width:100%}.lc-bar-up>div:last-child{border-radius:2px 2px 0 0}.lc-bar-down>div:last-child{border-radius:0 0 2px 2px}.lc-cat-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-chart[data-catdim] .lc-cat-seg{opacity:.35}.lc-chart[data-catdim=system] .lc-cat-seg[data-cat=system],.lc-chart[data-catdim=tools] .lc-cat-seg[data-cat=tools],.lc-chart[data-catdim=user] .lc-cat-seg[data-cat=user],.lc-chart[data-catdim=inject] .lc-cat-seg[data-cat=inject],.lc-chart[data-catdim=skill] .lc-cat-seg[data-cat=skill],.lc-chart[data-catdim=assistant] .lc-cat-seg[data-cat=assistant],.lc-chart[data-catdim=tool] .lc-cat-seg[data-cat=tool]{opacity:1}.lc-dna-hl{z-index:1;pointer-events:none;align-items:stretch;gap:2px;display:flex;position:absolute;inset:18px 2px 0}.lc-dna-cell{flex:none;width:14px;position:relative}.lc-dna-slice{box-sizing:border-box;border:1px solid var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 26%, transparent);border-radius:1px;width:100%;position:absolute;left:0}.lc-duration{z-index:1;pointer-events:none;position:absolute;top:18px;left:2px;overflow:visible}.lc-duration polyline,.lc-duration circle{fill:none;stroke:var(--dsw-alias-brand-primary);stroke-width:1.5px;stroke-linejoin:round;stroke-linecap:round}.lc-duration circle{fill:var(--dsw-alias-brand-primary)}.lc-chart-dim .lc-duration{opacity:.35}.lc-bar-marker{z-index:2;color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-step-flag{z-index:2;background:color-mix(in srgb, var(--color-neutral-500) 45%, transparent);pointer-events:none;width:1px;position:absolute;top:-17px;bottom:0;right:-1px}.lc-step-flag-label{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--color-neutral-500) 45%, transparent);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);white-space:nowrap;border-radius:3px;padding:1px 3px;font-size:9px;font-weight:600;line-height:1;position:absolute;top:0;right:0}.lc-turns{box-sizing:border-box;gap:2px;width:max-content;min-width:100%;margin-top:4px;padding:0 2px;display:flex;overflow:hidden}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;height:14px;transition:filter var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:3px;flex:none;font-size:10px;font-weight:600;line-height:14px}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-turn-label{display:inline-block}";
|
|
13199
13332
|
const tagId$9 = "dsh-context/trendChart.css";
|
|
13200
13333
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
|
|
13201
13334
|
const tag = document.createElement("style");
|
|
@@ -13294,7 +13427,7 @@ window.__ModuleLoader__.load({
|
|
|
13294
13427
|
}
|
|
13295
13428
|
//#endregion
|
|
13296
13429
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/overview.css.mjs
|
|
13297
|
-
const css = ".lc-ov-entry{box-sizing:border-box;width:calc(100% + 4px);height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:8px;margin:0 -2px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.lc-ov-entry:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-ov-entry-rail{border-radius:50%;flex:none;justify-content:center;gap:0;width:36px;height:36px;margin:0;padding:0}.lc-ov-entry-icon{flex:none}.lc-ov-entry-label{text-align:left;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-ov-backdrop{z-index:200;background:var(--dsw-alias-bg-mask-1,#00000073);justify-content:center;align-items:center;display:flex;position:fixed;inset:0;container:lc-ov/inline-size}.lc-ov-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);width:min(1120px,100vw - 32px);height:calc(100% - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;flex-direction:column;padding:16px 18px 18px;font-size:13px;display:flex;overflow:hidden}.lc-ov-head{flex-wrap:wrap;flex:none;align-items:center;gap:10px;margin-bottom:14px;display:flex}.lc-ov-head-icon{flex:none}.lc-ov-title{white-space:nowrap;font-size:15px;font-weight:600}.lc-ov-balance{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:inherit;border-radius:999px;flex:none;align-items:center;gap:6px;padding:2px 10px;font-size:12px;line-height:18px;text-decoration:none;display:inline-flex}.lc-ov-balance:hover .lc-ov-balance-value{text-decoration:underline}.lc-ov-balance-label{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-ov-balance-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-head .lc-modal-close{flex:none;margin-left:0}.lc-ov-scroll{scrollbar-gutter:stable;flex:auto;min-height:0;padding-right:8px;overflow-y:auto}.lc-ov-first{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-kpis{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;display:grid}.lc-ov-kpi{align-items:center;padding:8px}.lc-ov-kpi .lc-stat-value{font-size:20px}@container lc-ov (width<=932px){.lc-ov-first{grid-template-columns:minmax(0,1fr)}}@container lc-ov (width<=640px){.lc-ov-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}.lc-ov-usage{box-sizing:border-box;flex-direction:column;flex:auto;min-width:0;margin-bottom:0;display:flex}.lc-ov-usage .lc-card-title{margin-bottom:4px}.lc-ov-usage-plot{flex:auto;align-items:stretch;gap:6px;min-height:0;display:flex}.lc-ov-usage-rail{width:42px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:9px;line-height:1.2;position:relative}.lc-ov-usage-rail-l .lc-ov-usage-tick{right:0}.lc-ov-usage-rail-r .lc-ov-usage-tick{left:0}.lc-ov-usage-tick{white-space:nowrap;position:absolute;transform:translateY(-50%)}.lc-ov-usage-grid{flex:auto;min-width:0;min-height:56px;display:flex;position:relative}.lc-ov-usage-line{background:color-mix(in srgb, var(--dsw-alias-border-l2) 70%, transparent);height:1px;position:absolute;left:0;right:0}.lc-ov-usage-line-0{background:var(--dsw-alias-border-l2)}.lc-ov-usage-cols{flex:auto;align-items:stretch;gap:6px;min-width:0;display:flex;position:relative}.lc-ov-usage-col{flex-direction:column;flex:1 1 0;min-width:0;display:flex}.lc-ov-usage-bars{flex:auto;justify-content:center;align-items:flex-end;gap:3px;width:100%;display:flex}.lc-ov-usage-bar{border-radius:3px 3px 0 0;flex:none;width:10px}.lc-ov-usage-tokens{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-ov-usage-cost{background:color-mix(in srgb, var(--color-green-500) 72%, transparent)}.lc-ov-usage-days{flex:none;gap:6px;padding-top:3px;display:flex}.lc-ov-usage-day{text-align:center;min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;flex:1 1 0;font-size:9px;line-height:1.2}.lc-ov-usage-key{flex:none;justify-content:flex-end;align-items:center;gap:5px;padding-top:5px;display:flex}.lc-ov-usage-swatch{border-radius:2px;flex:none;width:10px;height:8px}.lc-ov-usage-key-label{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-stats>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}@container lc-ov (width<=700px){.lc-ov-stats{grid-template-columns:minmax(0,1fr)}}.lc-ov-body{grid-template-columns:minmax(0,3fr) minmax(0,7fr);align-items:start;gap:10px;display:grid}.lc-ov-left{flex-direction:column;gap:10px;min-width:0;display:flex}.lc-ov-right{min-width:0}@container lc-ov (width<=932px){.lc-ov-body{display:block}.lc-ov-left{margin-bottom:12px}}.lc-ov-left>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}.lc-ov-heat-card{flex-direction:column;display:flex}.lc-ov-settings{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex:none;align-items:center;gap:8px;padding:9px 12px;font-size:12px;display:flex}.lc-ov-settings:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary)}.lc-ov-settings-label{white-space:nowrap;flex:none;align-items:center;gap:6px;display:inline-flex}.lc-ov-settings-hint{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-heat-wrap{flex-direction:column;flex:1;display:flex}.lc-heat{flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.lc-heat-wds,.lc-heat-col{padding-top:18px}.lc-heat-wds{flex-direction:column;gap:3px;display:flex}.lc-heat-wd{height:20px;color:var(--dsw-alias-label-secondary);text-align:center;white-space:nowrap;flex:none;justify-content:center;align-items:center;font-size:9px;display:flex}.lc-heat-cols{gap:3px;display:flex}.lc-heat-col{flex-direction:column;gap:3px;display:flex;position:relative}.lc-heat-mon{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:9px;line-height:18px;position:absolute;top:0;left:0}.lc-heat-cell{box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);cursor:default;border:0;border-radius:20%;width:20px;height:20px;padding:0}button.lc-heat-cell{cursor:pointer}button.lc-heat-cell:hover{box-shadow:0 0 0 1.5px color-mix(in srgb, var(--color-blue-500) 70%, transparent)}.lc-heat-future{background:0 0}.lc-heat-0{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent)}.lc-heat-1{background:color-mix(in srgb, var(--color-blue-500) 28%, transparent)}.lc-heat-2{background:color-mix(in srgb, var(--color-blue-500) 50%, transparent)}.lc-heat-3{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-heat-4{background:color-mix(in srgb, var(--color-blue-500) 92%, transparent)}.lc-heat-on{box-shadow:0 0 0 1.5px var(--color-blue-500)}.lc-heat-legend{justify-content:flex-end;align-items:center;gap:3px;padding-top:6px;display:flex}.lc-heat-key{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-list-head{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:10px;display:flex}.lc-ov-list-title{white-space:nowrap;font-weight:600}.lc-ov-list-count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;background:var(--dsw-alias-bg-layer-2);border-radius:8px;padding:1px 7px;font-size:11px}.lc-ov-day-chip{border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);color:var(--color-blue-500);background:color-mix(in srgb, var(--color-blue-500) 10%, transparent);cursor:pointer;white-space:nowrap;border-radius:999px;padding:1px 10px;font-family:inherit;font-size:11px;line-height:1.4}.lc-ov-search{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:110px;font:inherit;color:var(--dsw-alias-label-primary);transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;outline:none;flex:150px;padding:4px 10px;font-size:12px}.lc-ov-search:focus{border-color:var(--dsw-alias-label-secondary)}.lc-ov-search::placeholder{color:var(--dsw-alias-label-secondary)}.lc-ov-groups{flex-wrap:wrap;gap:6px;margin:-2px 0 10px;display:flex}.lc-ov-chip{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;text-overflow:ellipsis;max-width:220px;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:999px;align-items:baseline;gap:5px;padding:2px 10px;font-size:11px;line-height:1.5;display:inline-flex;overflow:hidden}.lc-ov-chip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary)}.lc-ov-chip-on,.lc-ov-chip-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:#0000}.lc-ov-chip-n{font-variant-numeric:tabular-nums;opacity:.65;font-size:10px}.lc-ov-chip-on .lc-ov-chip-n{opacity:.85}.lc-ov-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px;display:grid}.lc-ov-session{text-align:left;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;font:inherit;color:inherit;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.lc-ov-session:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.lc-ov-session-current{border-color:color-mix(in srgb, var(--color-blue-500) 65%, transparent)}.lc-ov-session-head{align-items:flex-start;gap:6px;min-width:0;display:flex}.lc-ov-running{background:var(--color-green-500);border-radius:50%;flex:none;width:7px;height:7px}.lc-ov-session-title{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;flex:auto;min-width:0;font-weight:600;display:-webkit-box;overflow:hidden}.lc-ov-current{color:var(--color-blue-500);border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);border-radius:4px;flex:none;padding:0 4px;font-size:10px;line-height:1.5}.lc-ov-session-times{flex-direction:column;flex:none;align-items:flex-end;gap:1px;display:flex}.lc-ov-session-time{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:11px}.lc-ov-session-created{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:10px;line-height:1.4}.lc-ov-session-crumb{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;align-items:center;gap:5px;font-size:11px;display:flex;overflow:hidden}.lc-ov-crumb-group{text-overflow:ellipsis;flex:none;max-width:55%;overflow:hidden}.lc-ov-crumb-sep{opacity:.55;flex:none}.lc-ov-crumb-project{text-overflow:ellipsis;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent);border-radius:999px;flex:0 auto;padding:0 8px;font-size:10px;line-height:1.6;overflow:hidden}.lc-ov-session-body{align-items:center;gap:14px;min-width:0;display:flex}.lc-ov-mini-stats{flex-direction:column;flex:auto;gap:3px;min-width:0;display:flex}.lc-ov-mini-stat{justify-content:space-between;align-items:baseline;gap:10px;font-size:11px;display:flex}.lc-ov-mini-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none}.lc-ov-mini-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-session-empty{color:var(--dsw-alias-label-secondary);padding:6px 0;font-size:11px;line-height:1.5}.lc-ov-session-preview{border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 60%, transparent);align-items:baseline;gap:6px;min-width:0;margin-top:auto;padding-top:6px;display:flex}.lc-ov-session-preview-label{color:var(--dsw-alias-label-secondary);flex:none;font-size:10px}.lc-ov-session-preview-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);flex:0 auto;font-size:11px;line-height:1.5;overflow:hidden}.lc-ov-pager{justify-content:center;align-items:center;gap:10px;margin-top:12px;display:flex}.lc-ov-pager-btn{border:1px solid var(--dsw-alias-border-l2);width:26px;height:22px;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);background:0 0;border-radius:6px;flex:none;justify-content:center;align-items:center;line-height:1;display:flex}.lc-ov-pager-btn:hover:enabled{border-color:var(--dsw-alias-label-secondary)}.lc-ov-pager-btn:disabled{opacity:.4;cursor:default}.lc-ov-pager-n{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:11px}";
|
|
13430
|
+
const css = ".lc-ov-page{box-sizing:border-box;background:var(--dsw-alias-bg-base);width:100%;min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);flex-direction:column;font-size:13px;display:flex;overflow:hidden;container:lc-ov/inline-size}.lc-ov-pagescroll{scrollbar-gutter:stable;flex:auto;min-height:0;overflow-y:auto}.lc-ov-pagecontent{max-width:960px;margin:0 auto;padding:0 clamp(24px,4vw,48px) 48px}.lc-ov-pagehead{flex-wrap:wrap;align-items:center;gap:16px;margin-bottom:24px;padding-top:28px;display:flex}[data-platform=darwin] .lc-ov-pagehead{padding-top:calc(28px + var(--dsh-frame-top-clearance,0px))}.lc-ov-pagetitle{flex:auto;min-width:0;margin:0;font-size:20px;font-weight:500;line-height:28px}.lc-ov-balance{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:inherit;border-radius:999px;flex:none;align-items:center;gap:6px;padding:2px 10px;font-size:12px;line-height:18px;text-decoration:none;display:inline-flex}.lc-ov-balance:hover .lc-ov-balance-value{text-decoration:underline}.lc-ov-balance-label{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-ov-balance-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-hovertip{z-index:300;white-space:pre-line;max-width:min(320px,50vw);position:fixed}.lc-ov-first{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-kpis{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;display:grid}.lc-ov-kpi{align-items:center;padding:8px}.lc-ov-kpi .lc-stat-value{font-size:20px}@container lc-ov (width<=932px){.lc-ov-first{grid-template-columns:minmax(0,1fr)}}@container lc-ov (width<=640px){.lc-ov-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}.lc-ov-usage{box-sizing:border-box;flex-direction:column;flex:auto;min-width:0;margin-bottom:0;display:flex}.lc-ov-usage .lc-card-title{margin-bottom:4px}.lc-ov-usage-plot{flex:auto;align-items:stretch;gap:6px;min-height:0;display:flex}.lc-ov-usage-rail{width:42px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:9px;line-height:1.2;position:relative}.lc-ov-usage-rail-l .lc-ov-usage-tick{right:0}.lc-ov-usage-rail-r .lc-ov-usage-tick{left:0}.lc-ov-usage-tick{white-space:nowrap;position:absolute;transform:translateY(-50%)}.lc-ov-usage-grid{flex:auto;min-width:0;min-height:56px;display:flex;position:relative}.lc-ov-usage-line{background:color-mix(in srgb, var(--dsw-alias-border-l2) 70%, transparent);height:1px;position:absolute;left:0;right:0}.lc-ov-usage-line-0{background:var(--dsw-alias-border-l2)}.lc-ov-usage-cols{flex:auto;align-items:stretch;gap:6px;min-width:0;display:flex;position:relative}.lc-ov-usage-col{flex-direction:column;flex:1 1 0;min-width:0;display:flex}.lc-ov-usage-bars{flex:auto;justify-content:center;align-items:flex-end;gap:3px;width:100%;display:flex}.lc-ov-usage-bar{border-radius:3px 3px 0 0;flex:none;width:10px}.lc-ov-usage-tokens{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-ov-usage-cost{background:color-mix(in srgb, var(--color-green-500) 72%, transparent)}.lc-ov-usage-days{flex:none;gap:6px;padding-top:3px;display:flex}.lc-ov-usage-day{text-align:center;min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;flex:1 1 0;font-size:9px;line-height:1.2}.lc-ov-usage-key{flex:none;justify-content:flex-end;align-items:center;gap:5px;padding-top:5px;display:flex}.lc-ov-usage-swatch{border-radius:2px;flex:none;width:10px;height:8px}.lc-ov-usage-key-label{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-stats>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}@container lc-ov (width<=700px){.lc-ov-stats{grid-template-columns:minmax(0,1fr)}}.lc-ov-body{grid-template-columns:minmax(0,3fr) minmax(0,7fr);align-items:start;gap:10px;display:grid}.lc-ov-left{flex-direction:column;gap:10px;min-width:0;display:flex}.lc-ov-right{min-width:0}@container lc-ov (width<=932px){.lc-ov-body{display:block}.lc-ov-left{margin-bottom:12px}}.lc-ov-left>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}.lc-ov-heat-card{flex-direction:column;display:flex}.lc-ov-settings{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex:none;align-items:center;gap:8px;padding:9px 12px;font-size:12px;display:flex}.lc-ov-settings:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary)}.lc-ov-settings-label{white-space:nowrap;flex:none;align-items:center;gap:6px;display:inline-flex}.lc-ov-settings-hint{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-heat-wrap{flex-direction:column;flex:1;display:flex}.lc-heat{flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.lc-heat-wds,.lc-heat-col{padding-top:18px}.lc-heat-wds{flex-direction:column;gap:3px;display:flex}.lc-heat-wd{height:20px;color:var(--dsw-alias-label-secondary);text-align:center;white-space:nowrap;flex:none;justify-content:center;align-items:center;font-size:9px;display:flex}.lc-heat-cols{gap:3px;display:flex}.lc-heat-col{flex-direction:column;gap:3px;display:flex;position:relative}.lc-heat-mon{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:9px;line-height:18px;position:absolute;top:0;left:0}.lc-heat-cell{box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);cursor:default;border:0;border-radius:20%;width:20px;height:20px;padding:0}button.lc-heat-cell{cursor:pointer}button.lc-heat-cell:hover{box-shadow:0 0 0 1.5px color-mix(in srgb, var(--color-blue-500) 70%, transparent)}.lc-heat-future{background:0 0}.lc-heat-0{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent)}.lc-heat-1{background:color-mix(in srgb, var(--color-blue-500) 28%, transparent)}.lc-heat-2{background:color-mix(in srgb, var(--color-blue-500) 50%, transparent)}.lc-heat-3{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-heat-4{background:color-mix(in srgb, var(--color-blue-500) 92%, transparent)}.lc-heat-on{box-shadow:0 0 0 1.5px var(--color-blue-500)}.lc-heat-legend{justify-content:flex-end;align-items:center;gap:3px;padding-top:6px;display:flex}.lc-heat-key{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-list-head{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:10px;display:flex}.lc-ov-list-title{white-space:nowrap;font-weight:600}.lc-ov-list-count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;background:var(--dsw-alias-bg-layer-2);border-radius:8px;padding:1px 7px;font-size:11px}.lc-ov-day-chip{border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);color:var(--color-blue-500);background:color-mix(in srgb, var(--color-blue-500) 10%, transparent);cursor:pointer;white-space:nowrap;border-radius:999px;padding:1px 10px;font-family:inherit;font-size:11px;line-height:1.4}.lc-ov-search{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:110px;font:inherit;color:var(--dsw-alias-label-primary);transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;outline:none;flex:150px;padding:4px 10px;font-size:12px}.lc-ov-search:focus{border-color:var(--dsw-alias-label-secondary)}.lc-ov-search::placeholder{color:var(--dsw-alias-label-secondary)}.lc-ov-groups{flex-wrap:wrap;gap:6px;margin:-2px 0 10px;display:flex}.lc-ov-chip{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;text-overflow:ellipsis;max-width:220px;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:999px;align-items:baseline;gap:5px;padding:2px 10px;font-size:11px;line-height:1.5;display:inline-flex;overflow:hidden}.lc-ov-chip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary)}.lc-ov-chip-on,.lc-ov-chip-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:#0000}.lc-ov-chip-n{font-variant-numeric:tabular-nums;opacity:.65;font-size:10px}.lc-ov-chip-on .lc-ov-chip-n{opacity:.85}.lc-ov-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px;display:grid}.lc-ov-session{text-align:left;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;font:inherit;color:inherit;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.lc-ov-session:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.lc-ov-session-current{border-color:color-mix(in srgb, var(--color-blue-500) 65%, transparent)}.lc-ov-session-head{align-items:flex-start;gap:6px;min-width:0;display:flex}.lc-ov-running{background:var(--color-green-500);border-radius:50%;flex:none;width:7px;height:7px}.lc-ov-session-title{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;flex:auto;min-width:0;font-weight:600;display:-webkit-box;overflow:hidden}.lc-ov-current{color:var(--color-blue-500);border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);border-radius:4px;flex:none;padding:0 4px;font-size:10px;line-height:1.5}.lc-ov-session-times{flex-direction:column;flex:none;align-items:flex-end;gap:1px;display:flex}.lc-ov-session-time{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:11px}.lc-ov-session-created{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:10px;line-height:1.4}.lc-ov-session-crumb{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;align-items:center;gap:5px;font-size:11px;display:flex;overflow:hidden}.lc-ov-crumb-group{text-overflow:ellipsis;flex:none;max-width:55%;overflow:hidden}.lc-ov-crumb-sep{opacity:.55;flex:none}.lc-ov-crumb-project{text-overflow:ellipsis;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent);border-radius:999px;flex:0 auto;padding:0 8px;font-size:10px;line-height:1.6;overflow:hidden}.lc-ov-session-body{align-items:center;gap:14px;min-width:0;display:flex}.lc-ov-mini-stats{flex-direction:column;flex:auto;gap:3px;min-width:0;display:flex}.lc-ov-mini-stat{justify-content:space-between;align-items:baseline;gap:10px;font-size:11px;display:flex}.lc-ov-mini-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none}.lc-ov-mini-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-session-empty{color:var(--dsw-alias-label-secondary);padding:6px 0;font-size:11px;line-height:1.5}.lc-ov-session-preview{border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 60%, transparent);align-items:baseline;gap:6px;min-width:0;margin-top:auto;padding-top:6px;display:flex}.lc-ov-session-preview-label{color:var(--dsw-alias-label-secondary);flex:none;font-size:10px}.lc-ov-session-preview-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);flex:0 auto;font-size:11px;line-height:1.5;overflow:hidden}.lc-ov-pager{justify-content:center;align-items:center;gap:10px;margin-top:12px;display:flex}.lc-ov-pager-btn{border:1px solid var(--dsw-alias-border-l2);width:26px;height:22px;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);background:0 0;border-radius:6px;flex:none;justify-content:center;align-items:center;line-height:1;display:flex}.lc-ov-pager-btn:hover:enabled{border-color:var(--dsw-alias-label-secondary)}.lc-ov-pager-btn:disabled{opacity:.4;cursor:default}.lc-ov-pager-n{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:11px}";
|
|
13298
13431
|
const tagId = "dsh-context/overview.css";
|
|
13299
13432
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
13300
13433
|
const tag = document.createElement("style");
|
|
@@ -13373,24 +13506,8 @@ window.__ModuleLoader__.load({
|
|
|
13373
13506
|
inject: (sessionId = "") => ({ hooks: { contextModal: modalStoreOf(sessionId) } })
|
|
13374
13507
|
}, (props) => (0, react.createElement)(ContextModal, props));
|
|
13375
13508
|
});
|
|
13376
|
-
const OverviewButton = makeOverviewButton(kit, settings);
|
|
13377
|
-
ctx.slots.inject("sidebar.footer.action", () => {
|
|
13378
|
-
return ctx.slots.register({
|
|
13379
|
-
name: "sidebar.footer.action",
|
|
13380
|
-
id: "context-overview",
|
|
13381
|
-
order: 10,
|
|
13382
|
-
locale: NS
|
|
13383
|
-
}, (props) => (0, react.createElement)(OverviewButton, props));
|
|
13384
|
-
});
|
|
13385
13509
|
const OverviewPanel = makeOverviewPanel(ctx, kit);
|
|
13386
|
-
ctx.
|
|
13387
|
-
return ctx.slots.register({
|
|
13388
|
-
name: "shell.overlay",
|
|
13389
|
-
id: "context-overview",
|
|
13390
|
-
order: 10,
|
|
13391
|
-
locale: NS
|
|
13392
|
-
}, (props) => (0, react.createElement)(OverviewPanel, props));
|
|
13393
|
-
});
|
|
13510
|
+
ctx.effect(() => watchInsightPage(ctx, settings, (props) => (0, react.createElement)(OverviewPanel, props), t, NS), "dsh-context: insight page");
|
|
13394
13511
|
/** The injected face both preference cards ride: the settings store as the
|
|
13395
13512
|
* framework's hooks-compartment `useContextSettings` seat, plus the set verb. */
|
|
13396
13513
|
const cardFace = () => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.0",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"icon": "icon.svg",
|
|
6
6
|
"author": "bowenliang123",
|