dsh-context 0.54.3 → 0.55.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 +8 -3
- package/icon.svg +12 -0
- package/lib/client.js +386 -194
- package/lib/index.d.ts +83 -36
- package/lib/index.js +252 -92
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +9 -4
package/lib/client.js
CHANGED
|
@@ -3,10 +3,33 @@ window.__ModuleLoader__.load({
|
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
module.exports;
|
|
6
|
+
//#region \0rolldown/runtime.js
|
|
7
|
+
var __create = Object.create;
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
12
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
15
|
+
key = keys[i];
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
17
|
+
get: ((k) => from[k]).bind(null, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
//#endregion
|
|
6
28
|
let react = require("react");
|
|
7
29
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
30
|
let react_dom = require("react-dom");
|
|
9
31
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
32
|
+
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
10
33
|
//#region src/client/i18n.ts
|
|
11
34
|
const DICT_ZH = {
|
|
12
35
|
"tab": "上下文",
|
|
@@ -55,6 +78,7 @@ window.__ModuleLoader__.load({
|
|
|
55
78
|
"timing.other": "其他开销",
|
|
56
79
|
"timing.callTimes": "{n}次",
|
|
57
80
|
"timing.toolTimes": "{n}次",
|
|
81
|
+
"timing.blockTimes": "{n}次",
|
|
58
82
|
"timing.empty": "暂无耗时数据 · 对话开始后这里会显示时长分布",
|
|
59
83
|
"timing.tps": "{tps} tok/s",
|
|
60
84
|
"timing.tpsTip": "输出速度(TPS):累计解码输出 tokens ÷ 累计解码时长,与 DeepSeek Harness 会话统计同口径。",
|
|
@@ -67,7 +91,7 @@ window.__ModuleLoader__.load({
|
|
|
67
91
|
"plugin.name": "插件",
|
|
68
92
|
"plugin.github": "GitHub",
|
|
69
93
|
"plugin.settings": "设置",
|
|
70
|
-
"plugin.settingsOpen": "
|
|
94
|
+
"plugin.settingsOpen": "打开偏好设置",
|
|
71
95
|
"trend.title": "上下文趋势",
|
|
72
96
|
"gran.step": "步骤",
|
|
73
97
|
"gran.turn": "轮次",
|
|
@@ -427,6 +451,7 @@ window.__ModuleLoader__.load({
|
|
|
427
451
|
"timing.other": "Overhead",
|
|
428
452
|
"timing.callTimes": "{n} calls",
|
|
429
453
|
"timing.toolTimes": "{n} runs",
|
|
454
|
+
"timing.blockTimes": "{n} blocks",
|
|
430
455
|
"timing.empty": "No timing data yet — durations appear as the conversation runs",
|
|
431
456
|
"timing.tps": "{tps} tok/s",
|
|
432
457
|
"timing.tpsTip": "Output speed (TPS): summed decoded output tokens over summed decode time — the same pairing as the harness session stats.",
|
|
@@ -439,7 +464,7 @@ window.__ModuleLoader__.load({
|
|
|
439
464
|
"plugin.name": "Plugin",
|
|
440
465
|
"plugin.github": "GitHub",
|
|
441
466
|
"plugin.settings": "Settings",
|
|
442
|
-
"plugin.settingsOpen": "Open
|
|
467
|
+
"plugin.settingsOpen": "Open preferences",
|
|
443
468
|
"trend.title": "Context Trend",
|
|
444
469
|
"gran.step": "Step",
|
|
445
470
|
"gran.turn": "Turn",
|
|
@@ -753,20 +778,23 @@ window.__ModuleLoader__.load({
|
|
|
753
778
|
"ov.time.d": "{n}d ago"
|
|
754
779
|
};
|
|
755
780
|
//#endregion
|
|
781
|
+
//#region icon.svg?raw
|
|
782
|
+
var icon_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\">\n <path d=\"M899.984 19.873h-3.452c-26.123 0-47.296 21.172-47.296 47.296v888.508c0 26.127 21.173 47.298 47.296 47.298h3.452c26.119 0 47.297-21.171 47.297-47.298V67.169c0-26.124-21.177-47.296-47.297-47.296z\" fill=\"#4A5699\"/>\n <path d=\"M132.643 19.873h-3.449c-26.12 0-47.296 21.172-47.296 47.296v888.508c0 26.127 21.177 47.298 47.296 47.298h3.449c26.123 0 47.299-21.171 47.299-47.298V67.169c0-26.124-21.176-47.296-47.299-47.296z\" fill=\"#C45FA0\"/>\n <path d=\"M899.463 19.873H129.194c-26.12 0-47.296 21.172-47.296 47.296v3.377c0 26.12 21.177 47.299 47.296 47.299h770.269c26.123 0 47.296-21.179 47.296-47.299v-3.377c0-26.124-21.173-47.296-47.296-47.296z\" fill=\"#6277BA\"/>\n <path d=\"M899.463 905.006H129.194c-26.12 0-47.296 21.17-47.296 47.29v3.381c0 26.127 21.177 47.298 47.296 47.298h770.269c26.123 0 47.296-21.171 47.296-47.298v-3.381c0-26.12-21.173-47.29-47.296-47.29z\" fill=\"#C45FA0\"/>\n <path d=\"M717.962 543.153H542.047c-26.121 0-47.298 21.175-47.298 47.297v3.724c0 26.123 21.177 47.293 47.298 47.293h175.915c26.121 0 47.297-21.17 47.297-47.293v-3.724c0-26.122-21.176-47.297-47.297-47.297z\" fill=\"#E5594F\"/>\n <path d=\"M689.268 198.849H513.355c-26.122 0-47.298 21.175-47.298 47.297v3.722c0 26.12 21.176 47.297 47.298 47.297h175.912c26.122 0 47.298-21.177 47.298-47.297v-3.722c0-26.122-21.175-47.297-47.297-47.297z\" fill=\"#F0D043\"/>\n <path d=\"M757.789 353.081H261.17c-26.121 0-47.297 21.172-47.297 47.296v3.377c0 26.121 21.177 47.299 47.297 47.299h496.619c26.121 0 47.296-21.178 47.296-47.299v-3.377c0-26.125-21.175-47.296-47.296-47.296z\" fill=\"#E5594F\"/>\n <path d=\"M762.638 726.225h-496.62c-26.12 0-47.294 21.18-47.294 47.301v3.377c0 26.12 21.174 47.3 47.294 47.3h496.62c26.122 0 47.296-21.18 47.296-47.3v-3.377c0-26.122-21.174-47.301-47.296-47.301z\" fill=\"#6277BA\"/>\n <path d=\"M355.734 543.328H281.41c-26.122 0-47.297 21.17-47.297 47.293v3.378c0 26.118 21.175 47.297 47.297 47.297h74.324c26.123 0 47.296-21.179 47.296-47.297v-3.378c0-26.123-21.174-47.293-47.296-47.293z\" fill=\"#F39A2B\"/>\n <path d=\"M334.85 248.006m-48.986 0a48.986 48.986 0 1 0 97.972 0 48.986 48.986 0 1 0-97.972 0Z\" fill=\"#F39A2B\"/>\n</svg>\n";
|
|
783
|
+
//#endregion
|
|
756
784
|
//#region src/client/icon.tsx
|
|
757
|
-
/**
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
785
|
+
/**
|
|
786
|
+
* The Context emblem: the colourful document sheet, bundled rather than read
|
|
787
|
+
* off the harness primitives so the plugin's identity is self-contained.
|
|
788
|
+
*
|
|
789
|
+
* The single graphic source is the package-root `icon.svg` — the same file
|
|
790
|
+
* package.json `icon` hands to the Host's package-meta reader, which serves
|
|
791
|
+
* it to the Plugins page's package cards. The client bundle inlines the
|
|
792
|
+
* file's markup at build time (the `?raw` channel in tsdown.config.ts) and
|
|
793
|
+
* re-renders it at every requested size. Fixed fills, never `currentColor` —
|
|
794
|
+
* the sheet is deliberately polychrome on both light and dark chrome.
|
|
795
|
+
*/
|
|
796
|
+
/** Everything between the file's `<svg>` tags: the sheet's strokes in paint order, whitespace-folded. */
|
|
797
|
+
const SHEET_MARKUP = icon_default.slice(icon_default.indexOf(">") + 1, icon_default.lastIndexOf("</svg>")).trim().replace(/>\s+</g, "><");
|
|
770
798
|
/** The colourful document sheet at the requested square edge. */
|
|
771
799
|
function ContextIcon({ size = 20, className }) {
|
|
772
800
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
@@ -776,10 +804,7 @@ window.__ModuleLoader__.load({
|
|
|
776
804
|
className,
|
|
777
805
|
"aria-hidden": "true",
|
|
778
806
|
xmlns: "http://www.w3.org/2000/svg",
|
|
779
|
-
|
|
780
|
-
d,
|
|
781
|
-
fill
|
|
782
|
-
}, d))
|
|
807
|
+
dangerouslySetInnerHTML: { __html: SHEET_MARKUP }
|
|
783
808
|
});
|
|
784
809
|
}
|
|
785
810
|
/**
|
|
@@ -1439,11 +1464,12 @@ window.__ModuleLoader__.load({
|
|
|
1439
1464
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
1440
1465
|
}
|
|
1441
1466
|
/**
|
|
1442
|
-
* The OPTIONAL timing scalars (the generation split
|
|
1443
|
-
* number passes, anything else — including absence — reads
|
|
1444
|
-
* field stays absent on the narrowed value (see
|
|
1467
|
+
* The OPTIONAL timing scalars (the generation split's spans and block counts):
|
|
1468
|
+
* a real non-negative number passes, anything else — including absence — reads
|
|
1469
|
+
* as undefined so the field stays absent on the narrowed value (see
|
|
1470
|
+
* `timingOf`).
|
|
1445
1471
|
*/
|
|
1446
|
-
function
|
|
1472
|
+
function optNumOf(value) {
|
|
1447
1473
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
1448
1474
|
}
|
|
1449
1475
|
/**
|
|
@@ -1467,7 +1493,10 @@ window.__ModuleLoader__.load({
|
|
|
1467
1493
|
for (const k of [
|
|
1468
1494
|
"reasoningMs",
|
|
1469
1495
|
"textMs",
|
|
1470
|
-
"toolArgMs"
|
|
1496
|
+
"toolArgMs",
|
|
1497
|
+
"reasoningBlocks",
|
|
1498
|
+
"textBlocks",
|
|
1499
|
+
"toolArgBlocks"
|
|
1471
1500
|
]) {
|
|
1472
1501
|
const v = t[k];
|
|
1473
1502
|
if (v !== void 0 && (typeof v !== "number" || !Number.isFinite(v) || v < 0)) return false;
|
|
@@ -1515,12 +1544,18 @@ window.__ModuleLoader__.load({
|
|
|
1515
1544
|
toolCalls: msNumOf(data.toolCalls),
|
|
1516
1545
|
tools
|
|
1517
1546
|
};
|
|
1518
|
-
const reasoning =
|
|
1547
|
+
const reasoning = optNumOf(data.reasoningMs);
|
|
1519
1548
|
if (reasoning !== void 0) totals.reasoningMs = reasoning;
|
|
1520
|
-
const
|
|
1549
|
+
const reasoningBlocks = optNumOf(data.reasoningBlocks);
|
|
1550
|
+
if (reasoningBlocks !== void 0) totals.reasoningBlocks = reasoningBlocks;
|
|
1551
|
+
const textMs = optNumOf(data.textMs);
|
|
1521
1552
|
if (textMs !== void 0) totals.textMs = textMs;
|
|
1522
|
-
const
|
|
1553
|
+
const textBlocks = optNumOf(data.textBlocks);
|
|
1554
|
+
if (textBlocks !== void 0) totals.textBlocks = textBlocks;
|
|
1555
|
+
const toolArgMs = optNumOf(data.toolArgMs);
|
|
1523
1556
|
if (toolArgMs !== void 0) totals.toolArgMs = toolArgMs;
|
|
1557
|
+
const toolArgBlocks = optNumOf(data.toolArgBlocks);
|
|
1558
|
+
if (toolArgBlocks !== void 0) totals.toolArgBlocks = toolArgBlocks;
|
|
1524
1559
|
return totals;
|
|
1525
1560
|
}
|
|
1526
1561
|
/**
|
|
@@ -2445,6 +2480,16 @@ window.__ModuleLoader__.load({
|
|
|
2445
2480
|
return kindOfTool(tool);
|
|
2446
2481
|
}
|
|
2447
2482
|
/**
|
|
2483
|
+
* Whether a settled call's arguments can yield an op at all: the file tools
|
|
2484
|
+
* plus `str_replace_editor`, whose purpose follows its `command`. The public
|
|
2485
|
+
* face of the gate {@link opsOfCall} short-circuits on — callers that decide
|
|
2486
|
+
* whether to parse or to KEEP a call's raw arguments ask here instead of
|
|
2487
|
+
* restating the tool list.
|
|
2488
|
+
*/
|
|
2489
|
+
function opBearingTool(tool) {
|
|
2490
|
+
return tool === "str_replace_editor" || kindOfTool(tool) !== null;
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2448
2493
|
* The operation's target path: the path-ish argument of read/write tools;
|
|
2449
2494
|
* for searches the narrowing `path`, else the pattern itself (a pathless
|
|
2450
2495
|
* grep/glob's target IS the pattern — the workspace-wide search text).
|
|
@@ -2583,7 +2628,7 @@ window.__ModuleLoader__.load({
|
|
|
2583
2628
|
* resolve no target) rows nothing.
|
|
2584
2629
|
*/
|
|
2585
2630
|
function opsOfCall(input) {
|
|
2586
|
-
const args = parseCallArgs(input.argsRaw);
|
|
2631
|
+
const args = opBearingTool(input.tool) ? parseCallArgs(input.argsRaw) : null;
|
|
2587
2632
|
const kind = kindOfCall(input.tool, args);
|
|
2588
2633
|
if (kind === null) return [];
|
|
2589
2634
|
const stamp = {
|
|
@@ -3411,6 +3456,39 @@ window.__ModuleLoader__.load({
|
|
|
3411
3456
|
return t("browser.loading");
|
|
3412
3457
|
}
|
|
3413
3458
|
//#endregion
|
|
3459
|
+
//#region src/client/primitives.ts
|
|
3460
|
+
/** The platform module's export surface, read by name (the two vocabularies meet here). */
|
|
3461
|
+
const ns = _deepseek_ai_dsh_client_ui_primitives;
|
|
3462
|
+
/**
|
|
3463
|
+
* Read one export through a bounded catch: partial module mocks (and any
|
|
3464
|
+
* hostile namespace) may throw on the property access itself, which must
|
|
3465
|
+
* degrade to "not this spelling", never crash the importer.
|
|
3466
|
+
*/
|
|
3467
|
+
function read(source, key) {
|
|
3468
|
+
try {
|
|
3469
|
+
return source[key];
|
|
3470
|
+
} catch {
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
/**
|
|
3475
|
+
* Resolve one icon across the range's two spellings: the modern
|
|
3476
|
+
* `…OutlineRegular`/`…OutlineMedium` name first, then the legacy
|
|
3477
|
+
* `…Outline16`/`…Outline14` one; neither present (or not a component)
|
|
3478
|
+
* renders nothing. `source` overrides the platform namespace for tests.
|
|
3479
|
+
*/
|
|
3480
|
+
function resolveIcon(modern, legacy, source = ns) {
|
|
3481
|
+
const found = read(source, modern) ?? read(source, legacy);
|
|
3482
|
+
return typeof found === "function" ? found : () => null;
|
|
3483
|
+
}
|
|
3484
|
+
const IconBranch = resolveIcon("IconBranchOutlineRegular", "IconBranchOutline16");
|
|
3485
|
+
const IconPlus = resolveIcon("IconPlusOutlineRegular", "IconPlusOutline16");
|
|
3486
|
+
const IconCheck = resolveIcon("IconCheckOutlineRegular", "IconCheckOutline16");
|
|
3487
|
+
const IconCopy = resolveIcon("IconCopyOutlineRegular", "IconCopyOutline16");
|
|
3488
|
+
const IconClose = resolveIcon("IconCloseOutlineRegular", "IconCloseOutline16");
|
|
3489
|
+
const IconSettings = resolveIcon("IconSettingsOutlineMedium", "IconSettingsOutline14");
|
|
3490
|
+
const IconChevronDown = resolveIcon("IconChevronDownOutlineMedium", "IconChevronDownOutline14");
|
|
3491
|
+
//#endregion
|
|
3414
3492
|
//#region src/client/format.ts
|
|
3415
3493
|
/** `fmt`: the k/M/B suffix style shared by bars/details/stats; `fmtTime`: local HH:MM:SS. */
|
|
3416
3494
|
function fmt(n) {
|
|
@@ -3686,7 +3764,7 @@ window.__ModuleLoader__.load({
|
|
|
3686
3764
|
className: "lc-att-lightbox-close",
|
|
3687
3765
|
"aria-label": labels.close,
|
|
3688
3766
|
onClick: onClose,
|
|
3689
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3767
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconClose, { size: 16 })
|
|
3690
3768
|
})
|
|
3691
3769
|
]
|
|
3692
3770
|
}), document.body);
|
|
@@ -3852,7 +3930,7 @@ window.__ModuleLoader__.load({
|
|
|
3852
3930
|
title: label,
|
|
3853
3931
|
"aria-label": label,
|
|
3854
3932
|
onClick: onCopy,
|
|
3855
|
-
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3933
|
+
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheck, { size: 13 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopy, { size: 13 })
|
|
3856
3934
|
});
|
|
3857
3935
|
}
|
|
3858
3936
|
function RichText(props) {
|
|
@@ -7241,18 +7319,28 @@ window.__ModuleLoader__.load({
|
|
|
7241
7319
|
//#endregion
|
|
7242
7320
|
//#region src/client/settingsJump.ts
|
|
7243
7321
|
/**
|
|
7244
|
-
* Best-effort jump to this plugin's
|
|
7245
|
-
*
|
|
7246
|
-
*
|
|
7247
|
-
*
|
|
7248
|
-
* the
|
|
7249
|
-
*
|
|
7250
|
-
*
|
|
7251
|
-
*
|
|
7252
|
-
*
|
|
7322
|
+
* Best-effort jump to this plugin's preferences. Two generations of chrome:
|
|
7323
|
+
* - dsh 0.1.7+ (Config-form generation): the preferences live on the
|
|
7324
|
+
* bundle's page of the Plugins main panel — the jump clicks the panel's
|
|
7325
|
+
* sidebar entry (its shipped aria-label), then follows the page with a
|
|
7326
|
+
* bounded poll for the bundle card's open control, found by the shipped,
|
|
7327
|
+
* locale-independent `data-plugin-package` list identity: the card lists
|
|
7328
|
+
* once the page's package load settles, and inside it the one button
|
|
7329
|
+
* that is not the enable switch is the title that opens the page. A
|
|
7330
|
+
* poll that never finds the card (still loading, plugin absent, or the
|
|
7331
|
+
* page already open on the detail view — the list unmounts there)
|
|
7332
|
+
* degrades to the card list, and every step stays silent.
|
|
7333
|
+
* - older lines: Settings → Plugins → Plugin configuration — the settings
|
|
7334
|
+
* panel keeps its open state inside the shell component (no plugin-facing
|
|
7335
|
+
* open face exists), so the jump drives the real chrome: click the
|
|
7336
|
+
* sidebar's settings trigger, then the Plugins section nav row, both
|
|
7337
|
+
* found by their shipped attributes and labels.
|
|
7253
7338
|
* The last leg — the card itself — is ours: the module also carries a
|
|
7254
|
-
* short-lived in-bundle expand request that the
|
|
7255
|
-
* consumes on mount, so
|
|
7339
|
+
* short-lived in-bundle expand request that the settings-section card
|
|
7340
|
+
* consumes on mount, so that jump lands on the configuration already open.
|
|
7341
|
+
* EVERY step is individually guarded: a shell that doesn't match (different
|
|
7342
|
+
* layout, missing sidebar) degrades the whole jump to a silent no-op — this
|
|
7343
|
+
* path must never throw into the caller's render.
|
|
7256
7344
|
*/
|
|
7257
7345
|
let requestedAt = 0;
|
|
7258
7346
|
/** Raise a short-lived request for the plugin's settings card to mount expanded. */
|
|
@@ -7265,24 +7353,66 @@ window.__ModuleLoader__.load({
|
|
|
7265
7353
|
requestedAt = 0;
|
|
7266
7354
|
return fresh;
|
|
7267
7355
|
}
|
|
7268
|
-
/**
|
|
7269
|
-
|
|
7356
|
+
/**
|
|
7357
|
+
* The shipped Plugins label in both locales — the main-panel entry's
|
|
7358
|
+
* aria-label and the settings section's nav row text are the same word.
|
|
7359
|
+
*/
|
|
7360
|
+
const PLUGIN_LABELS = /* @__PURE__ */ new Set(["Plugins", "插件"]);
|
|
7361
|
+
/** The bundle card's shipped list identity (locale-independent). */
|
|
7362
|
+
const PACKAGE_KEY = "dsh-context";
|
|
7363
|
+
/** How long the card poll follows the panel: 40 ticks at the 100ms tick, enough for the page's package load. */
|
|
7364
|
+
const POLL_TICKS = 40;
|
|
7270
7365
|
/** Buttons the jump may operate on, in document order. */
|
|
7271
7366
|
function buttonsOf(doc) {
|
|
7272
7367
|
return [...doc.querySelectorAll("button")];
|
|
7273
7368
|
}
|
|
7369
|
+
/** The Plugins main-panel entry, matched by its shipped aria-label. */
|
|
7370
|
+
function findPanelEntry(doc) {
|
|
7371
|
+
return buttonsOf(doc).find((b) => PLUGIN_LABELS.has(b.getAttribute("aria-label") ?? ""));
|
|
7372
|
+
}
|
|
7373
|
+
/**
|
|
7374
|
+
* The bundle card's open control: the one button inside the card that is not
|
|
7375
|
+
* the enable switch (the primitives switch carries `role="switch"`); the
|
|
7376
|
+
* title button's own aria-label is localized.
|
|
7377
|
+
*/
|
|
7378
|
+
function findCardOpenControl(doc) {
|
|
7379
|
+
const card = doc.querySelector(`[data-plugin-package="${PACKAGE_KEY}"]`);
|
|
7380
|
+
if (card === null) return void 0;
|
|
7381
|
+
const open = [...card.querySelectorAll("button")].filter((b) => b.getAttribute("role") !== "switch");
|
|
7382
|
+
return open.length === 1 ? open[0] : void 0;
|
|
7383
|
+
}
|
|
7274
7384
|
/** The sidebar's settings triggers: dialog semantics plus an expanded flag. */
|
|
7275
7385
|
function findTriggers(doc) {
|
|
7276
7386
|
return buttonsOf(doc).filter((b) => b.getAttribute("aria-haspopup") === "dialog" && b.hasAttribute("aria-expanded"));
|
|
7277
7387
|
}
|
|
7278
|
-
/** The Plugins section's nav row, matched by its shipped label. */
|
|
7388
|
+
/** The Plugins section's nav row, matched by its shipped label text. */
|
|
7279
7389
|
function findSectionRow(doc) {
|
|
7280
|
-
return buttonsOf(doc).find((b) =>
|
|
7390
|
+
return buttonsOf(doc).find((b) => PLUGIN_LABELS.has(b.textContent.trim()));
|
|
7281
7391
|
}
|
|
7282
7392
|
function openPluginSettings(doc = document, schedule = (run, ms) => {
|
|
7283
7393
|
window.setTimeout(run, ms);
|
|
7284
7394
|
}) {
|
|
7285
7395
|
try {
|
|
7396
|
+
const panel = findPanelEntry(doc);
|
|
7397
|
+
if (panel !== void 0) {
|
|
7398
|
+
panel.click();
|
|
7399
|
+
const poll = (left) => {
|
|
7400
|
+
try {
|
|
7401
|
+
const open = findCardOpenControl(doc);
|
|
7402
|
+
if (open !== void 0) {
|
|
7403
|
+
open.click();
|
|
7404
|
+
return;
|
|
7405
|
+
}
|
|
7406
|
+
} catch {}
|
|
7407
|
+
if (left > 0) schedule(() => {
|
|
7408
|
+
poll(left - 1);
|
|
7409
|
+
}, 100);
|
|
7410
|
+
};
|
|
7411
|
+
schedule(() => {
|
|
7412
|
+
poll(POLL_TICKS);
|
|
7413
|
+
}, 200);
|
|
7414
|
+
return;
|
|
7415
|
+
}
|
|
7286
7416
|
const triggers = findTriggers(doc);
|
|
7287
7417
|
if (triggers.find((b) => b.getAttribute("aria-expanded") === "true") === void 0 && triggers.length === 0) return;
|
|
7288
7418
|
triggers.find((b) => b.getAttribute("aria-expanded") !== "true")?.click();
|
|
@@ -7297,13 +7427,17 @@ window.__ModuleLoader__.load({
|
|
|
7297
7427
|
//#endregion
|
|
7298
7428
|
//#region src/client/components/settingsCard.tsx
|
|
7299
7429
|
/**
|
|
7300
|
-
* The dsh-context
|
|
7301
|
-
* the
|
|
7302
|
-
*
|
|
7303
|
-
*
|
|
7304
|
-
*
|
|
7305
|
-
*
|
|
7306
|
-
*
|
|
7430
|
+
* The dsh-context preference cards — two seats over the same six rows. The
|
|
7431
|
+
* settings-section card (`settings.plugin.item`, the older harness lines)
|
|
7432
|
+
* renders a collapsible list item in Settings → Plugins → Plugin
|
|
7433
|
+
* configuration; the Plugins-page card (`plugins.bundle.config`, the
|
|
7434
|
+
* Config-form generation) renders the rows flat inside the section chrome the
|
|
7435
|
+
* Plugins page draws for the bundle. Both are keyed on the Host-served
|
|
7436
|
+
* `dsh-context` namespace and render nothing while it is unavailable (a
|
|
7437
|
+
* deployment without the Host half, or a remote browser, shows no trace).
|
|
7438
|
+
* The settings-section card mounts expanded when the Plugin Info card's
|
|
7439
|
+
* "Open preferences" jump left a fresh expand request (settingsJump.ts),
|
|
7440
|
+
* scrolling itself into view.
|
|
7307
7441
|
*/
|
|
7308
7442
|
function PrefRow(props) {
|
|
7309
7443
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -7335,11 +7469,129 @@ window.__ModuleLoader__.load({
|
|
|
7335
7469
|
onClick: () => {
|
|
7336
7470
|
setOpen((v) => !v);
|
|
7337
7471
|
},
|
|
7338
|
-
children: [active, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7472
|
+
children: [active, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDown, {})]
|
|
7339
7473
|
})
|
|
7340
7474
|
})]
|
|
7341
7475
|
});
|
|
7342
7476
|
}
|
|
7477
|
+
/** The six preference rows shared by both seats. */
|
|
7478
|
+
function PreferenceRows(props) {
|
|
7479
|
+
const { t, state, set } = props;
|
|
7480
|
+
const disabled = state.status !== "ready" || !state.writable;
|
|
7481
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7482
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7483
|
+
label: t("settings.placement"),
|
|
7484
|
+
value: state.placement,
|
|
7485
|
+
disabled,
|
|
7486
|
+
options: [
|
|
7487
|
+
{
|
|
7488
|
+
id: "all",
|
|
7489
|
+
label: t("placement.all")
|
|
7490
|
+
},
|
|
7491
|
+
{
|
|
7492
|
+
id: "tab",
|
|
7493
|
+
label: t("placement.tab")
|
|
7494
|
+
},
|
|
7495
|
+
{
|
|
7496
|
+
id: "sidebar",
|
|
7497
|
+
label: t("placement.sidebar")
|
|
7498
|
+
}
|
|
7499
|
+
],
|
|
7500
|
+
onPick: (id) => {
|
|
7501
|
+
set?.("defaultPlacement", id);
|
|
7502
|
+
}
|
|
7503
|
+
}),
|
|
7504
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7505
|
+
label: t("settings.insightsEntry"),
|
|
7506
|
+
value: state.insightsEntry,
|
|
7507
|
+
disabled,
|
|
7508
|
+
options: [{
|
|
7509
|
+
id: "show",
|
|
7510
|
+
label: t("insightsEntry.show")
|
|
7511
|
+
}, {
|
|
7512
|
+
id: "hide",
|
|
7513
|
+
label: t("insightsEntry.hide")
|
|
7514
|
+
}],
|
|
7515
|
+
onPick: (id) => {
|
|
7516
|
+
set?.("insightsEntry", id);
|
|
7517
|
+
}
|
|
7518
|
+
}),
|
|
7519
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7520
|
+
label: t("settings.gran"),
|
|
7521
|
+
value: state.granularity,
|
|
7522
|
+
disabled,
|
|
7523
|
+
options: [{
|
|
7524
|
+
id: "step",
|
|
7525
|
+
label: t("gran.step")
|
|
7526
|
+
}, {
|
|
7527
|
+
id: "turn",
|
|
7528
|
+
label: t("gran.turn")
|
|
7529
|
+
}],
|
|
7530
|
+
onPick: (id) => {
|
|
7531
|
+
set?.("defaultGranularity", id);
|
|
7532
|
+
}
|
|
7533
|
+
}),
|
|
7534
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7535
|
+
label: t("settings.mode"),
|
|
7536
|
+
value: state.mode,
|
|
7537
|
+
disabled,
|
|
7538
|
+
options: [{
|
|
7539
|
+
id: "total",
|
|
7540
|
+
label: t("gran.total")
|
|
7541
|
+
}, {
|
|
7542
|
+
id: "delta",
|
|
7543
|
+
label: t("gran.delta")
|
|
7544
|
+
}],
|
|
7545
|
+
onPick: (id) => {
|
|
7546
|
+
set?.("defaultTrendMode", id);
|
|
7547
|
+
}
|
|
7548
|
+
}),
|
|
7549
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7550
|
+
label: t("settings.toolSort"),
|
|
7551
|
+
value: state.toolSort,
|
|
7552
|
+
disabled,
|
|
7553
|
+
options: [
|
|
7554
|
+
{
|
|
7555
|
+
id: "size",
|
|
7556
|
+
label: t("tool.sort.size")
|
|
7557
|
+
},
|
|
7558
|
+
{
|
|
7559
|
+
id: "count",
|
|
7560
|
+
label: t("tool.sort.count")
|
|
7561
|
+
},
|
|
7562
|
+
{
|
|
7563
|
+
id: "name",
|
|
7564
|
+
label: t("tool.sort.name")
|
|
7565
|
+
}
|
|
7566
|
+
],
|
|
7567
|
+
onPick: (id) => {
|
|
7568
|
+
set?.("defaultToolSort", id);
|
|
7569
|
+
}
|
|
7570
|
+
}),
|
|
7571
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7572
|
+
label: t("settings.fileSort"),
|
|
7573
|
+
value: state.fileSort,
|
|
7574
|
+
disabled,
|
|
7575
|
+
options: [
|
|
7576
|
+
{
|
|
7577
|
+
id: "count",
|
|
7578
|
+
label: t("files.sort.count")
|
|
7579
|
+
},
|
|
7580
|
+
{
|
|
7581
|
+
id: "latest",
|
|
7582
|
+
label: t("files.sort.latest")
|
|
7583
|
+
},
|
|
7584
|
+
{
|
|
7585
|
+
id: "path",
|
|
7586
|
+
label: t("files.sort.path")
|
|
7587
|
+
}
|
|
7588
|
+
],
|
|
7589
|
+
onPick: (id) => {
|
|
7590
|
+
set?.("defaultFileSort", id);
|
|
7591
|
+
}
|
|
7592
|
+
})
|
|
7593
|
+
] });
|
|
7594
|
+
}
|
|
7343
7595
|
function makeSettingsCard(kit) {
|
|
7344
7596
|
const { t } = kit;
|
|
7345
7597
|
return function SettingsCard(props) {
|
|
@@ -7354,7 +7606,6 @@ window.__ModuleLoader__.load({
|
|
|
7354
7606
|
}, []);
|
|
7355
7607
|
const state = typeof props.useContextSettings === "function" ? props.useContextSettings((s) => s) : void 0;
|
|
7356
7608
|
if (state === void 0 || state.status === "unavailable") return null;
|
|
7357
|
-
const disabled = state.status !== "ready" || !state.writable;
|
|
7358
7609
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
7359
7610
|
ref: itemRef,
|
|
7360
7611
|
className: "lc-settings-card" + (open ? " lc-settings-open" : ""),
|
|
@@ -7375,131 +7626,47 @@ window.__ModuleLoader__.load({
|
|
|
7375
7626
|
className: "lc-settings-desc",
|
|
7376
7627
|
children: t("settings.desc")
|
|
7377
7628
|
})]
|
|
7378
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7629
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDown, { className: "lc-settings-chevron" })]
|
|
7379
7630
|
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7380
7631
|
className: "lc-settings-body",
|
|
7381
|
-
children: [
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
disabled,
|
|
7391
|
-
options: [
|
|
7392
|
-
{
|
|
7393
|
-
id: "all",
|
|
7394
|
-
label: t("placement.all")
|
|
7395
|
-
},
|
|
7396
|
-
{
|
|
7397
|
-
id: "tab",
|
|
7398
|
-
label: t("placement.tab")
|
|
7399
|
-
},
|
|
7400
|
-
{
|
|
7401
|
-
id: "sidebar",
|
|
7402
|
-
label: t("placement.sidebar")
|
|
7403
|
-
}
|
|
7404
|
-
],
|
|
7405
|
-
onPick: (id) => {
|
|
7406
|
-
props.set?.("defaultPlacement", id);
|
|
7407
|
-
}
|
|
7408
|
-
}),
|
|
7409
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7410
|
-
label: t("settings.insightsEntry"),
|
|
7411
|
-
value: state.insightsEntry,
|
|
7412
|
-
disabled,
|
|
7413
|
-
options: [{
|
|
7414
|
-
id: "show",
|
|
7415
|
-
label: t("insightsEntry.show")
|
|
7416
|
-
}, {
|
|
7417
|
-
id: "hide",
|
|
7418
|
-
label: t("insightsEntry.hide")
|
|
7419
|
-
}],
|
|
7420
|
-
onPick: (id) => {
|
|
7421
|
-
props.set?.("insightsEntry", id);
|
|
7422
|
-
}
|
|
7423
|
-
}),
|
|
7424
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7425
|
-
label: t("settings.gran"),
|
|
7426
|
-
value: state.granularity,
|
|
7427
|
-
disabled,
|
|
7428
|
-
options: [{
|
|
7429
|
-
id: "step",
|
|
7430
|
-
label: t("gran.step")
|
|
7431
|
-
}, {
|
|
7432
|
-
id: "turn",
|
|
7433
|
-
label: t("gran.turn")
|
|
7434
|
-
}],
|
|
7435
|
-
onPick: (id) => {
|
|
7436
|
-
props.set?.("defaultGranularity", id);
|
|
7437
|
-
}
|
|
7438
|
-
}),
|
|
7439
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7440
|
-
label: t("settings.mode"),
|
|
7441
|
-
value: state.mode,
|
|
7442
|
-
disabled,
|
|
7443
|
-
options: [{
|
|
7444
|
-
id: "total",
|
|
7445
|
-
label: t("gran.total")
|
|
7446
|
-
}, {
|
|
7447
|
-
id: "delta",
|
|
7448
|
-
label: t("gran.delta")
|
|
7449
|
-
}],
|
|
7450
|
-
onPick: (id) => {
|
|
7451
|
-
props.set?.("defaultTrendMode", id);
|
|
7452
|
-
}
|
|
7453
|
-
}),
|
|
7454
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7455
|
-
label: t("settings.toolSort"),
|
|
7456
|
-
value: state.toolSort,
|
|
7457
|
-
disabled,
|
|
7458
|
-
options: [
|
|
7459
|
-
{
|
|
7460
|
-
id: "size",
|
|
7461
|
-
label: t("tool.sort.size")
|
|
7462
|
-
},
|
|
7463
|
-
{
|
|
7464
|
-
id: "count",
|
|
7465
|
-
label: t("tool.sort.count")
|
|
7466
|
-
},
|
|
7467
|
-
{
|
|
7468
|
-
id: "name",
|
|
7469
|
-
label: t("tool.sort.name")
|
|
7470
|
-
}
|
|
7471
|
-
],
|
|
7472
|
-
onPick: (id) => {
|
|
7473
|
-
props.set?.("defaultToolSort", id);
|
|
7474
|
-
}
|
|
7475
|
-
}),
|
|
7476
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
7477
|
-
label: t("settings.fileSort"),
|
|
7478
|
-
value: state.fileSort,
|
|
7479
|
-
disabled,
|
|
7480
|
-
options: [
|
|
7481
|
-
{
|
|
7482
|
-
id: "count",
|
|
7483
|
-
label: t("files.sort.count")
|
|
7484
|
-
},
|
|
7485
|
-
{
|
|
7486
|
-
id: "latest",
|
|
7487
|
-
label: t("files.sort.latest")
|
|
7488
|
-
},
|
|
7489
|
-
{
|
|
7490
|
-
id: "path",
|
|
7491
|
-
label: t("files.sort.path")
|
|
7492
|
-
}
|
|
7493
|
-
],
|
|
7494
|
-
onPick: (id) => {
|
|
7495
|
-
props.set?.("defaultFileSort", id);
|
|
7496
|
-
}
|
|
7497
|
-
})
|
|
7498
|
-
]
|
|
7632
|
+
children: [!state.writable && state.status === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7633
|
+
className: "lc-settings-note",
|
|
7634
|
+
role: "status",
|
|
7635
|
+
children: t("settings.readOnly")
|
|
7636
|
+
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PreferenceRows, {
|
|
7637
|
+
t,
|
|
7638
|
+
state,
|
|
7639
|
+
set: props.set
|
|
7640
|
+
})]
|
|
7499
7641
|
}) : null]
|
|
7500
7642
|
});
|
|
7501
7643
|
};
|
|
7502
7644
|
}
|
|
7645
|
+
/**
|
|
7646
|
+
* The Plugins-page card (the Config-form generation's `plugins.bundle.config`
|
|
7647
|
+
* seat, `view: 'page'`): the page owns the bundle's page and section chrome,
|
|
7648
|
+
* so the rows render flat. Same unserved/absent degradation as the
|
|
7649
|
+
* settings-section card.
|
|
7650
|
+
*/
|
|
7651
|
+
function makePluginConfigCard(kit) {
|
|
7652
|
+
const { t } = kit;
|
|
7653
|
+
return function PluginConfigCard(props) {
|
|
7654
|
+
const state = typeof props.useContextSettings === "function" ? props.useContextSettings((s) => s) : void 0;
|
|
7655
|
+
if (state === void 0 || state.status === "unavailable") return null;
|
|
7656
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7657
|
+
className: "lc-settings-prefs",
|
|
7658
|
+
children: [!state.writable && state.status === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7659
|
+
className: "lc-settings-note",
|
|
7660
|
+
role: "status",
|
|
7661
|
+
children: t("settings.readOnly")
|
|
7662
|
+
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PreferenceRows, {
|
|
7663
|
+
t,
|
|
7664
|
+
state,
|
|
7665
|
+
set: props.set
|
|
7666
|
+
})]
|
|
7667
|
+
});
|
|
7668
|
+
};
|
|
7669
|
+
}
|
|
7503
7670
|
//#endregion
|
|
7504
7671
|
//#region src/client/settings.ts
|
|
7505
7672
|
function prefsOf(value) {
|
|
@@ -9292,7 +9459,7 @@ window.__ModuleLoader__.load({
|
|
|
9292
9459
|
children: sorted.map((ev) => {
|
|
9293
9460
|
const label = eventLabel(ev);
|
|
9294
9461
|
const at = eventAt(ev);
|
|
9295
|
-
const glyph = ev.kind === "inject" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
9462
|
+
const glyph = ev.kind === "inject" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconPlus, {}) : ev.kind === "model" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconBranch, {}) : EVENT_ICONS[ev.kind] || "•";
|
|
9296
9463
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9297
9464
|
className: "lc-event @max-[380px]/lc-card:flex-wrap",
|
|
9298
9465
|
children: [
|
|
@@ -9737,7 +9904,7 @@ window.__ModuleLoader__.load({
|
|
|
9737
9904
|
return function PluginInfo() {
|
|
9738
9905
|
const [latest, setLatest] = (0, react.useState)(null);
|
|
9739
9906
|
(0, react.useEffect)(() => {
|
|
9740
|
-
if ("0.
|
|
9907
|
+
if ("0.55.0".includes("-dev")) return;
|
|
9741
9908
|
let on = true;
|
|
9742
9909
|
fetchLatestVersion().then((v) => {
|
|
9743
9910
|
if (on && v) setLatest(v);
|
|
@@ -9746,8 +9913,8 @@ window.__ModuleLoader__.load({
|
|
|
9746
9913
|
on = false;
|
|
9747
9914
|
};
|
|
9748
9915
|
}, []);
|
|
9749
|
-
const update = latest !== null && isNewerVersion(latest, "0.
|
|
9750
|
-
const nameText = "dsh-context (v0.
|
|
9916
|
+
const update = latest !== null && isNewerVersion(latest, "0.55.0") ? latest : null;
|
|
9917
|
+
const nameText = "dsh-context (v0.55.0)";
|
|
9751
9918
|
const nameValue = [nameText];
|
|
9752
9919
|
if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9753
9920
|
className: "lc-pi-update",
|
|
@@ -9780,7 +9947,7 @@ window.__ModuleLoader__.load({
|
|
|
9780
9947
|
},
|
|
9781
9948
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9782
9949
|
className: "lc-pi-label",
|
|
9783
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
9950
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconSettings, {
|
|
9784
9951
|
size: 12,
|
|
9785
9952
|
className: "lc-pi-labelicon"
|
|
9786
9953
|
}), t("plugin.settings")]
|
|
@@ -10463,10 +10630,10 @@ window.__ModuleLoader__.load({
|
|
|
10463
10630
|
* lands in the residue. When the host folded the generation split (see
|
|
10464
10631
|
* TimingTotals), the generation slice expands into what was being decoded:
|
|
10465
10632
|
* thinking, answer text, and tool-call arguments. The slice rows lead with
|
|
10466
|
-
* the true duration and qualify it with
|
|
10467
|
-
*
|
|
10468
|
-
* call count would be a false tally)
|
|
10469
|
-
* that never happened (zero time) is omitted entirely — the ring already skips
|
|
10633
|
+
* the true duration and qualify it with a tally on the secondary line — the
|
|
10634
|
+
* model calls (TTFT), the tool runs, and the decode slices' own BLOCK counts
|
|
10635
|
+
* (zero to many per call, so a call count would be a false tally there). A
|
|
10636
|
+
* slice that never happened (zero time) is omitted entirely — the ring already skips
|
|
10470
10637
|
* its arc, and a zero row would otherwise borrow the session's call count and
|
|
10471
10638
|
* read as "no time, many calls". The donut and the rows sit side by side so
|
|
10472
10639
|
* the head row stays half-height. Parallel tool calls each count, so the tools
|
|
@@ -10508,31 +10675,36 @@ window.__ModuleLoader__.load({
|
|
|
10508
10675
|
ms: timing.ttftMs,
|
|
10509
10676
|
times: callTimes
|
|
10510
10677
|
}];
|
|
10678
|
+
const blockTimes = (blocks) => blocks !== void 0 && blocks > 0 ? t("timing.blockTimes", { n: fmt(blocks) }) : void 0;
|
|
10511
10679
|
const buckets = [
|
|
10512
10680
|
[
|
|
10513
10681
|
"reasoning",
|
|
10514
10682
|
COLOR.reasoning,
|
|
10515
10683
|
t("timing.reasoning"),
|
|
10516
|
-
timing.reasoningMs ?? 0
|
|
10684
|
+
timing.reasoningMs ?? 0,
|
|
10685
|
+
blockTimes(timing.reasoningBlocks)
|
|
10517
10686
|
],
|
|
10518
10687
|
[
|
|
10519
10688
|
"text",
|
|
10520
10689
|
COLOR.text,
|
|
10521
10690
|
t("timing.text"),
|
|
10522
|
-
timing.textMs ?? 0
|
|
10691
|
+
timing.textMs ?? 0,
|
|
10692
|
+
blockTimes(timing.textBlocks)
|
|
10523
10693
|
],
|
|
10524
10694
|
[
|
|
10525
10695
|
"toolarg",
|
|
10526
10696
|
COLOR.toolarg,
|
|
10527
10697
|
t("timing.toolArgs"),
|
|
10528
|
-
timing.toolArgMs ?? 0
|
|
10698
|
+
timing.toolArgMs ?? 0,
|
|
10699
|
+
blockTimes(timing.toolArgBlocks)
|
|
10529
10700
|
]
|
|
10530
10701
|
];
|
|
10531
|
-
if (buckets.some(([, , , ms]) => ms > 0)) for (const [key, color, label, ms] of buckets) modelSlices.push({
|
|
10702
|
+
if (buckets.some(([, , , ms]) => ms > 0)) for (const [key, color, label, ms, times] of buckets) modelSlices.push({
|
|
10532
10703
|
key,
|
|
10533
10704
|
color,
|
|
10534
10705
|
label,
|
|
10535
|
-
ms
|
|
10706
|
+
ms,
|
|
10707
|
+
...times !== void 0 ? { times } : {}
|
|
10536
10708
|
});
|
|
10537
10709
|
else modelSlices.push({
|
|
10538
10710
|
key: "gen",
|
|
@@ -11565,7 +11737,7 @@ window.__ModuleLoader__.load({
|
|
|
11565
11737
|
}
|
|
11566
11738
|
//#endregion
|
|
11567
11739
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/settings.css.mjs
|
|
11568
|
-
const css$11 = ".lc-settings-card{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);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:12px}.lc-settings-card:hover{border-color:var(--dsw-alias-label-dimmed)}.lc-settings-open,.lc-settings-open:hover{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.lc-settings-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.lc-settings-headtext{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.lc-settings-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.lc-settings-desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.lc-settings-chevron{color:var(--dsw-alias-label-tertiary);transition:transform var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);flex:none}.lc-settings-open .lc-settings-chevron{transform:rotate(180deg)}.lc-settings-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 12px}.lc-settings-row{align-items:center;gap:8px;padding:8px 0;display:flex}.lc-settings-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:14px}.lc-settings-select{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.lc-settings-note{color:var(--dsw-alias-label-tertiary);margin:12px 0 4px;font-size:12px;line-height:1.5}";
|
|
11740
|
+
const css$11 = ".lc-settings-card{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);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:12px}.lc-settings-card:hover{border-color:var(--dsw-alias-label-dimmed)}.lc-settings-open,.lc-settings-open:hover{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.lc-settings-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.lc-settings-headtext{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.lc-settings-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.lc-settings-desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.lc-settings-chevron{color:var(--dsw-alias-label-tertiary);transition:transform var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);flex:none}.lc-settings-open .lc-settings-chevron{transform:rotate(180deg)}.lc-settings-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 12px}.lc-settings-prefs{padding:4px 0}.lc-settings-row{align-items:center;gap:8px;padding:8px 0;display:flex}.lc-settings-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:14px}.lc-settings-select{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.lc-settings-note{color:var(--dsw-alias-label-tertiary);margin:12px 0 4px;font-size:12px;line-height:1.5}";
|
|
11569
11741
|
const tagId$11 = "dsh-context/settings.css";
|
|
11570
11742
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$11) + "]") === null) {
|
|
11571
11743
|
const tag = document.createElement("style");
|
|
@@ -11783,6 +11955,14 @@ window.__ModuleLoader__.load({
|
|
|
11783
11955
|
locale: NS
|
|
11784
11956
|
}, (props) => (0, react.createElement)(OverviewPanel, props));
|
|
11785
11957
|
});
|
|
11958
|
+
/** The injected face both preference cards ride: the settings store as the
|
|
11959
|
+
* framework's hooks-compartment `useContextSettings` seat, plus the set verb. */
|
|
11960
|
+
const cardFace = () => ({
|
|
11961
|
+
hooks: { contextSettings: settings.store },
|
|
11962
|
+
set: (field, value) => {
|
|
11963
|
+
settings.set(field, value);
|
|
11964
|
+
}
|
|
11965
|
+
});
|
|
11786
11966
|
ctx.inject(["settingsScope"], (raw) => {
|
|
11787
11967
|
const c = raw;
|
|
11788
11968
|
const binder = c.settingsScope;
|
|
@@ -11794,15 +11974,27 @@ window.__ModuleLoader__.load({
|
|
|
11794
11974
|
name: "settings.plugin.item",
|
|
11795
11975
|
key: NS,
|
|
11796
11976
|
locale: NS,
|
|
11797
|
-
inject:
|
|
11798
|
-
hooks: { contextSettings: settings.store },
|
|
11799
|
-
set: (field, value) => {
|
|
11800
|
-
settings.set(field, value);
|
|
11801
|
-
}
|
|
11802
|
-
})
|
|
11977
|
+
inject: cardFace
|
|
11803
11978
|
}, (props) => (0, react.createElement)(SettingsCard, props));
|
|
11804
11979
|
});
|
|
11805
11980
|
});
|
|
11981
|
+
ctx.inject(["configForms"], (raw) => {
|
|
11982
|
+
const c = raw;
|
|
11983
|
+
const forms = c.configForms;
|
|
11984
|
+
if (forms === void 0 || typeof forms.get !== "function" || typeof forms.whileServed !== "function") return;
|
|
11985
|
+
c.effect(() => settings.attach(forms.get(NS)), "dsh-context: config forms");
|
|
11986
|
+
const PluginConfigCard = makePluginConfigCard(kit);
|
|
11987
|
+
c.effect(() => forms.whileServed([NS], () => {
|
|
11988
|
+
return c.slots.inject("plugins.bundle.config", () => {
|
|
11989
|
+
return c.slots.register({
|
|
11990
|
+
name: "plugins.bundle.config",
|
|
11991
|
+
key: NS,
|
|
11992
|
+
locale: NS,
|
|
11993
|
+
inject: cardFace
|
|
11994
|
+
}, (props) => (0, react.createElement)(PluginConfigCard, props));
|
|
11995
|
+
});
|
|
11996
|
+
}), "dsh-context: plugins-page card");
|
|
11997
|
+
});
|
|
11806
11998
|
}
|
|
11807
11999
|
module.exports = {
|
|
11808
12000
|
name: "dsh-context",
|