dsh-capability-panel 1.2.0 → 1.3.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.en.md +136 -0
- package/README.i18n.yaml +6 -5
- package/README.ja.md +15 -16
- package/README.ko.md +15 -16
- package/README.md +78 -79
- package/lib/client.js +288 -95
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +116 -12
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7157 -195
- package/lib/index.js.map +1 -1
- package/package.json +7 -6
- package/README.zh.md +0 -137
package/lib/client.js
CHANGED
|
@@ -32,10 +32,10 @@ let react = require("react");
|
|
|
32
32
|
react = __toESM(react);
|
|
33
33
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
34
34
|
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
35
|
-
let react_dom = require("react-dom");
|
|
36
|
-
react_dom = __toESM(react_dom);
|
|
37
35
|
let __deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
38
36
|
__deepseek_ai_dsh_client_ui_primitives = __toESM(__deepseek_ai_dsh_client_ui_primitives);
|
|
37
|
+
let react_dom = require("react-dom");
|
|
38
|
+
react_dom = __toESM(react_dom);
|
|
39
39
|
|
|
40
40
|
//#region src/wire.ts
|
|
41
41
|
const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -413,6 +413,8 @@ const zh = {
|
|
|
413
413
|
"group.skills": "技能 ({shown}/{total})",
|
|
414
414
|
"group.mcp": "MCP ({shown}/{total})",
|
|
415
415
|
"group.system": "系统工具 ({shown}/{total})",
|
|
416
|
+
"group.systemTools": "系统工具",
|
|
417
|
+
"group.count": "{shown}/{total}",
|
|
416
418
|
"tab.all": "全部",
|
|
417
419
|
"tab.skills": "技能",
|
|
418
420
|
"tab.mcp": "MCP",
|
|
@@ -427,6 +429,8 @@ const zh = {
|
|
|
427
429
|
"filter.count": "匹配 {shown} / {total} 项",
|
|
428
430
|
"footer.feedback": "反馈问题",
|
|
429
431
|
"footer.feedbackHint": "在 GitHub 上打开能力面板的 issue 页",
|
|
432
|
+
"footer.openSettings": "全局配置",
|
|
433
|
+
"footer.openSettingsHint": "打开设置并进入「能力面板」页",
|
|
430
434
|
"disclosure.expand": "展开 {subject} 的{detail}",
|
|
431
435
|
"disclosure.collapse": "收起 {subject} 的{detail}",
|
|
432
436
|
"disclosure.pinned": "{subject} 的{detail}(筛选时保持展开)",
|
|
@@ -482,6 +486,8 @@ const en = {
|
|
|
482
486
|
"group.skills": "Skills ({shown}/{total})",
|
|
483
487
|
"group.mcp": "MCP ({shown}/{total})",
|
|
484
488
|
"group.system": "System tools ({shown}/{total})",
|
|
489
|
+
"group.systemTools": "System tools",
|
|
490
|
+
"group.count": "{shown}/{total}",
|
|
485
491
|
"tab.all": "All",
|
|
486
492
|
"tab.skills": "Skills",
|
|
487
493
|
"tab.mcp": "MCP",
|
|
@@ -496,6 +502,8 @@ const en = {
|
|
|
496
502
|
"filter.count": "{shown} / {total} matched",
|
|
497
503
|
"footer.feedback": "Report an issue",
|
|
498
504
|
"footer.feedbackHint": "Open the capability panel’s issues on GitHub",
|
|
505
|
+
"footer.openSettings": "Global settings",
|
|
506
|
+
"footer.openSettingsHint": "Open Settings on the Capability Panel page",
|
|
499
507
|
"disclosure.expand": "Expand {detail} for {subject}",
|
|
500
508
|
"disclosure.collapse": "Collapse {detail} for {subject}",
|
|
501
509
|
"disclosure.pinned": "{detail} for {subject} (kept open while filtering)",
|
|
@@ -553,6 +561,7 @@ const TOK = {
|
|
|
553
561
|
menuBg: "var(--dsw-specific-menu, #ffffff)",
|
|
554
562
|
menuBorder: "var(--dsw-alias-border-inverted, rgba(0,0,0,.1))",
|
|
555
563
|
menuShadow: "var(--dsw-shadow-lv3, 0 12px 32px rgba(0,0,0,.22))",
|
|
564
|
+
menuBlur: "var(--dsw-menu-backdrop-filter, none)",
|
|
556
565
|
bgBase: "var(--dsw-alias-bg-base, #ffffff)",
|
|
557
566
|
fontFamily: "var(--dsw-font-family, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Helvetica Neue\", Helvetica, Arial, sans-serif)",
|
|
558
567
|
success: "var(--dsw-alias-state-success-primary, #22c55e)",
|
|
@@ -584,31 +593,36 @@ const PANEL_CSS = [
|
|
|
584
593
|
".ci-description{padding:3px 0 0 24px;line-height:18px;color:var(--dsw-alias-label-tertiary,#81858c);word-break:break-word}",
|
|
585
594
|
".ci-chevron{display:grid;place-items:center;width:18px;height:18px;flex:none;color:var(--dsw-alias-label-tertiary,#81858c);border-radius:4px}",
|
|
586
595
|
".ci-chevron svg{transition:transform .12s var(--ds-ease-in-out,ease)}",
|
|
587
|
-
".ci-server-trigger[aria-expanded=\"true\"] .ci-chevron svg,.ci-disclosure-trigger[aria-expanded=\"true\"] .ci-chevron svg{transform:rotate(90deg)}",
|
|
588
|
-
".ci-tabs{display:flex;gap:2px;padding:2px;border-radius:8px;background:var(--dsw-alias-bg-
|
|
596
|
+
".ci-server-trigger[aria-expanded=\"true\"] .ci-chevron svg,.ci-disclosure-trigger[aria-expanded=\"true\"] .ci-chevron svg,.ci-preset-part-trigger[aria-expanded=\"true\"] .ci-chevron svg{transform:rotate(90deg)}",
|
|
597
|
+
".ci-tabs{display:flex;gap:2px;padding:2px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}",
|
|
589
598
|
".ci-tab{flex:1;height:24px;border:none;border-radius:6px;background:transparent;color:var(--dsw-alias-label-secondary,#61666b);font:inherit;font-size:12px;line-height:1;cursor:pointer;font-variant-numeric:tabular-nums;padding:0 4px}",
|
|
590
599
|
".ci-tab:hover{color:var(--dsw-alias-label-primary,#0f1115)}",
|
|
591
|
-
".ci-tab[data-active]{background:var(--dsw-
|
|
592
|
-
".ci-preset-section{max-width:
|
|
593
|
-
".ci-settings-title{margin:0
|
|
594
|
-
".ci-settings-intro,.ci-settings-description,.ci-settings-note{margin:0
|
|
600
|
+
".ci-tab[data-active]{background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#0f1115);box-shadow:var(--dsw-elevation-soft,0 1px 2px rgba(0,0,0,.08))}",
|
|
601
|
+
".ci-preset-section{width:100%;max-width:760px;color:var(--dsw-alias-label-primary,#0f1115);display:flex;flex-direction:column;gap:14px}",
|
|
602
|
+
".ci-settings-title{margin:0;color:var(--dsw-alias-label-primary,#0f1115);font-size:18px;font-weight:600;line-height:26px}",
|
|
603
|
+
".ci-settings-intro,.ci-settings-description,.ci-settings-note{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary,#81858c)}",
|
|
595
604
|
".ci-settings-note{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:8px}",
|
|
596
|
-
".ci-preset-toolbar{display:flex;gap:10px;align-items:
|
|
597
|
-
".ci-
|
|
598
|
-
".ci-
|
|
599
|
-
".ci-preset-
|
|
600
|
-
".ci-preset-
|
|
601
|
-
".ci-preset-
|
|
605
|
+
".ci-preset-toolbar{display:flex;gap:10px;align-items:center;margin:0}",
|
|
606
|
+
".ci-search{position:relative;flex:1 1 auto;min-width:180px;display:flex;align-items:center;color:var(--dsw-alias-label-tertiary,#81858c)}",
|
|
607
|
+
".ci-search>svg{position:absolute;left:12px;pointer-events:none}",
|
|
608
|
+
".ci-preset-filter{width:100%;height:36px;box-sizing:border-box;padding:0 34px 0 36px;border:.5px solid var(--dsw-alias-border-l4,rgba(0,0,0,.16));border-radius:var(--dsw-radius-md,12px);background-color:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#0f1115);font:inherit;font-size:13px;font-weight:400;outline:none}",
|
|
609
|
+
".ci-preset-filter:focus-visible{border-color:var(--dsw-alias-state-business-primary,#4176e6);box-shadow:0 0 0 2px color-mix(in srgb,var(--dsw-alias-state-business-primary,#4176e6) 18%,transparent)}",
|
|
610
|
+
".ci-preset-part{display:flex;flex-direction:column;gap:10px;margin:0;padding:14px 0 0;border-top:.5px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}",
|
|
611
|
+
".ci-preset-part:first-of-type{border-top:0;padding-top:0}",
|
|
612
|
+
".ci-preset-part-trigger{display:flex;align-items:center;gap:8px;min-height:32px;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}",
|
|
613
|
+
".ci-preset-part-trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4176e6);outline-offset:2px;border-radius:4px}",
|
|
614
|
+
".ci-preset-part-title{margin:0;font-size:14px;font-weight:400;line-height:22px;color:var(--dsw-alias-label-primary,#0f1115)}",
|
|
615
|
+
".ci-preset-part-sub{margin:-4px 0 0 26px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary,#81858c);font-variant-numeric:tabular-nums}",
|
|
616
|
+
".ci-preset-badge{display:inline-block;margin-left:6px;padding:1px 6px;line-height:1.5;border-radius:999px;font-size:11px;font-weight:500;vertical-align:middle;background-color:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05));color:var(--dsw-alias-label-tertiary,#81858c)}",
|
|
602
617
|
".ci-preset-group{padding:0}",
|
|
603
618
|
".ci-preset-server-trigger{display:flex;align-items:center;gap:8px;flex:1;min-width:0;background:none;border:none;padding:0;text-align:left;font:inherit;color:inherit;cursor:pointer}",
|
|
604
619
|
".ci-preset-server-trigger:disabled{cursor:default}",
|
|
605
620
|
".ci-preset-group .ci-preset-tool-list{margin:0;padding-left:26px}",
|
|
606
|
-
".ci-preset-picker-
|
|
607
|
-
".ci-preset-picker-trigger{height:28px;display:flex;align-items:center;gap:4px;padding:0 4px 0 8px;border:none;border-radius:24px;background:transparent;color:var(--dsw-alias-label-secondary,#61666b);font-size:13px;font-weight:500;line-height:20px;cursor:pointer;outline:none;max-width:280px}",
|
|
621
|
+
".ci-preset-picker-trigger{height:36px;display:inline-flex;align-items:center;gap:8px;padding:0 14px;border:none;border-radius:var(--dsw-radius-md,12px);background:var(--dsw-alias-bg-module-platform,rgba(38,49,72,.06));color:var(--dsw-alias-label-primary,#0f1115);font:inherit;font-size:14px;font-weight:400;line-height:22px;cursor:pointer;outline:none;max-width:280px;flex:none;white-space:nowrap}",
|
|
608
622
|
".ci-preset-picker-trigger:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}",
|
|
609
|
-
".ci-preset-picker-trigger:focus-visible{
|
|
623
|
+
".ci-preset-picker-trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4176e6);outline-offset:2px}",
|
|
610
624
|
".ci-preset-picker-name{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}",
|
|
611
|
-
".ci-preset-picker-chevron{color:var(--dsw-alias-label-
|
|
625
|
+
".ci-preset-picker-chevron{color:var(--dsw-alias-label-tertiary,#81858c);flex:none;display:inline-grid;place-items:center;transition:transform .12s}",
|
|
612
626
|
".ci-preset-picker-chevron-open{transform:rotate(180deg)}",
|
|
613
627
|
".ci-settings-subtitle{margin:0 0 6px;color:var(--dsw-alias-label-primary,#0f1115);font-size:14px;line-height:22px}",
|
|
614
628
|
".ci-preset-tool-list{list-style:none;margin:0;padding:0}",
|
|
@@ -620,7 +634,7 @@ const PANEL_CSS = [
|
|
|
620
634
|
".ci-preset-disclosure{display:block}",
|
|
621
635
|
".ci-preset-spacer{width:18px;flex:none}",
|
|
622
636
|
".ci-preset-detail{padding:0 0 10px 24px;color:var(--dsw-alias-label-tertiary,#81858c);line-height:18px;overflow-wrap:anywhere}",
|
|
623
|
-
".ci-preset-kinds{margin:0
|
|
637
|
+
".ci-preset-kinds{margin:0}",
|
|
624
638
|
".ci-preset-kinds .ci-tabs{display:inline-flex}",
|
|
625
639
|
".ci-preset-kinds .ci-tab{flex:0 0 auto;padding:0 12px}",
|
|
626
640
|
".ci-source-header:hover .ci-folder-icon{opacity:1 !important}",
|
|
@@ -637,6 +651,7 @@ const PANEL_CSS = [
|
|
|
637
651
|
".ci-feedback-link:hover{color:var(--dsw-alias-label-primary,#0f1115);text-decoration:underline}",
|
|
638
652
|
".ci-feedback-link:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4176e6);outline-offset:2px;border-radius:3px}",
|
|
639
653
|
".ci-feedback-icon{display:inline-grid;place-items:center;flex:none}",
|
|
654
|
+
".ci-settings-link{border:0;background:none;padding:0;font-family:inherit}",
|
|
640
655
|
"@media (prefers-reduced-motion: reduce){.ci-thumb,.ci-panel,.ci-collapse,.ci-chevron svg{transition:none !important}}"
|
|
641
656
|
].join("\n");
|
|
642
657
|
|
|
@@ -1969,14 +1984,22 @@ const SwitchThumb = /* @__PURE__ */ react.forwardRef(function SwitchThumb$1(comp
|
|
|
1969
1984
|
/**
|
|
1970
1985
|
* The capability switch, in one place for both panels.
|
|
1971
1986
|
*
|
|
1972
|
-
*
|
|
1973
|
-
*
|
|
1974
|
-
*
|
|
1975
|
-
*
|
|
1976
|
-
*
|
|
1987
|
+
* dsh 0.1.7 ships a design-system `Switch` (36×20 capsule, brand-primary on
|
|
1988
|
+
* state, its own disabled dimming and focus ring) — using it keeps the panel's
|
|
1989
|
+
* toggles pixel-identical to every settings page the host ships, which is the
|
|
1990
|
+
* alignment this file exists for. Hosts older than that export fall back to
|
|
1991
|
+
* the local Base UI rendition below, so one build still serves both
|
|
1992
|
+
* generations; the probe runs per call, the same way the icon table resolves.
|
|
1977
1993
|
*/
|
|
1978
1994
|
function capabilitySwitch(options) {
|
|
1979
1995
|
const inert = options.disabled || options.busy;
|
|
1996
|
+
const HostSwitch = __deepseek_ai_dsh_client_ui_primitives.Switch;
|
|
1997
|
+
if (HostSwitch !== void 0) return react.createElement(HostSwitch, {
|
|
1998
|
+
checked: options.checked,
|
|
1999
|
+
onChange: options.onCheckedChange,
|
|
2000
|
+
label: options.label,
|
|
2001
|
+
disabled: inert
|
|
2002
|
+
});
|
|
1980
2003
|
return react.createElement(SwitchRoot, {
|
|
1981
2004
|
className: "ci-switch",
|
|
1982
2005
|
checked: options.checked,
|
|
@@ -4553,6 +4576,45 @@ const TabsList = /* @__PURE__ */ react.forwardRef(function TabsList$1(componentP
|
|
|
4553
4576
|
});
|
|
4554
4577
|
});
|
|
4555
4578
|
|
|
4579
|
+
//#endregion
|
|
4580
|
+
//#region src/client/icons.ts
|
|
4581
|
+
/** Rendered when a host generation has neither name: the panel stays usable. */
|
|
4582
|
+
const MissingIcon = () => null;
|
|
4583
|
+
/**
|
|
4584
|
+
* Pick the first export name the host's primitives package actually provides.
|
|
4585
|
+
* Exported separately from the module-level constants so tests can drive every
|
|
4586
|
+
* branch with a fake table.
|
|
4587
|
+
*/
|
|
4588
|
+
function pickIcon(table$1, modern, legacy) {
|
|
4589
|
+
const found = table$1[modern] ?? table$1[legacy];
|
|
4590
|
+
return typeof found === "function" ? found : MissingIcon;
|
|
4591
|
+
}
|
|
4592
|
+
const table = __deepseek_ai_dsh_client_ui_primitives;
|
|
4593
|
+
const IconChevronRight = pickIcon(table, "IconChevronRightOutlineRegular", "IconChevronRightOutline14");
|
|
4594
|
+
const IconContextInjection = pickIcon(table, "IconContextInjectionOutlineRegular", "IconContextInjectionOutline16");
|
|
4595
|
+
const IconFolderClose = pickIcon(table, "IconFolderCloseRegular", "IconFolderClose16");
|
|
4596
|
+
const IconSend = pickIcon(table, "IconSendOutlineRegular", "IconSendOutline14");
|
|
4597
|
+
const IconSearch = pickIcon(table, "IconSearchOutlineRegular", "IconSearchOutline16");
|
|
4598
|
+
const IconRefresh = pickIcon(table, "IconRefreshOutlineRegular", "IconRefreshOutline14");
|
|
4599
|
+
const IconChevronDown = pickIcon(table, "IconChevronDownOutlineRegular", "IconChevronDownOutline14");
|
|
4600
|
+
const IconSettings = pickIcon(table, "IconSettingsOutlineRegular", "IconSettingsOutline16");
|
|
4601
|
+
/**
|
|
4602
|
+
* Whether the host ships the 0.1.7 stroke-weight icon set. Exported as a
|
|
4603
|
+
* function so tests can drive both branches; the module constant resolves it
|
|
4604
|
+
* against the real package.
|
|
4605
|
+
*
|
|
4606
|
+
* One consumer: the footer settings entry. The `settings.open` keybinding that
|
|
4607
|
+
* entry drives shipped in the SAME host generation as the renamed icon set
|
|
4608
|
+
* (verified: 0.1.6's settings bundle has no such binding), so this is the
|
|
4609
|
+
* closest client-visible signal that the shortcut exists. If a future host
|
|
4610
|
+
* renames icons again this reads false and the entry hides — the safe
|
|
4611
|
+
* direction.
|
|
4612
|
+
*/
|
|
4613
|
+
function hasModernShell(table$1) {
|
|
4614
|
+
return typeof table$1["IconSettingsOutlineRegular"] === "function";
|
|
4615
|
+
}
|
|
4616
|
+
const HOST_HAS_MODERN_SHELL = hasModernShell(table);
|
|
4617
|
+
|
|
4556
4618
|
//#endregion
|
|
4557
4619
|
//#region src/client/disclosure-row.ts
|
|
4558
4620
|
/**
|
|
@@ -4667,7 +4729,8 @@ function parsePresetToolPayload(value) {
|
|
|
4667
4729
|
for (const raw of rawPresets) {
|
|
4668
4730
|
if (!isRecord(raw)) return null;
|
|
4669
4731
|
const { id, name, description, broken, trust, skills: rawSkills, mcp: rawMcp, systemTools: rawSystem } = raw;
|
|
4670
|
-
if (typeof id !== "string" || typeof name !== "string"
|
|
4732
|
+
if (typeof id !== "string" || typeof name !== "string") return null;
|
|
4733
|
+
if (trust !== void 0 && trust !== "system" && trust !== "user") return null;
|
|
4671
4734
|
if (!Array.isArray(rawMcp) || !Array.isArray(rawSystem) || !Array.isArray(rawSkills)) return null;
|
|
4672
4735
|
if (description !== void 0 && typeof description !== "string") return null;
|
|
4673
4736
|
if (broken !== void 0 && typeof broken !== "string") return null;
|
|
@@ -4701,7 +4764,7 @@ function parsePresetToolPayload(value) {
|
|
|
4701
4764
|
name,
|
|
4702
4765
|
...description === void 0 ? {} : { description },
|
|
4703
4766
|
...broken === void 0 ? {} : { broken },
|
|
4704
|
-
trust,
|
|
4767
|
+
...trust === void 0 ? {} : { trust },
|
|
4705
4768
|
skills,
|
|
4706
4769
|
mcp,
|
|
4707
4770
|
systemTools
|
|
@@ -4914,6 +4977,7 @@ function PresetToolSection(props) {
|
|
|
4914
4977
|
}, []);
|
|
4915
4978
|
const [query, setQuery] = react.useState("");
|
|
4916
4979
|
const [expanded, setExpanded] = react.useState({});
|
|
4980
|
+
const [partOpen, setPartOpen] = react.useState({});
|
|
4917
4981
|
const [kind, setKind] = react.useState("all");
|
|
4918
4982
|
const [pickerOpen, setPickerOpen] = react.useState(false);
|
|
4919
4983
|
const [reconnecting, setReconnecting] = react.useState(null);
|
|
@@ -5014,7 +5078,7 @@ function PresetToolSection(props) {
|
|
|
5014
5078
|
opacity: 0,
|
|
5015
5079
|
transition: "opacity 0.15s"
|
|
5016
5080
|
}
|
|
5017
|
-
}, react.createElement(
|
|
5081
|
+
}, react.createElement(IconFolderClose, { size: 12 })) : null, `${label} (${items.length})`), rule(true)));
|
|
5018
5082
|
};
|
|
5019
5083
|
const toggle$1 = (tool, presetId) => switchFor(tool.enabled, tool.reserved === true, tool.reserved === true ? t("preset.reserved", { name: tool.label }) : t(tool.enabled ? "action.disable" : "action.enable", { name: tool.label }), (checked) => {
|
|
5020
5084
|
setPresetTool(presetId, tool.name, checked);
|
|
@@ -5096,18 +5160,29 @@ function PresetToolSection(props) {
|
|
|
5096
5160
|
systemTools: selected.systemTools.length
|
|
5097
5161
|
};
|
|
5098
5162
|
const groups = [];
|
|
5099
|
-
const group = (key,
|
|
5163
|
+
const group = (key, title, rows, total, shown) => {
|
|
5100
5164
|
if (kind !== "all" && kind !== key) return;
|
|
5101
5165
|
if (rows.length === 0) return;
|
|
5102
|
-
|
|
5166
|
+
const open = filtering || (partOpen[key] ?? true);
|
|
5167
|
+
groups.push(react.createElement(CollapsibleRoot, {
|
|
5103
5168
|
key,
|
|
5104
|
-
className: "ci-preset-part"
|
|
5105
|
-
|
|
5169
|
+
className: "ci-preset-part",
|
|
5170
|
+
open,
|
|
5171
|
+
onOpenChange: (next) => {
|
|
5172
|
+
setPartOpen((prev) => ({
|
|
5173
|
+
...prev,
|
|
5174
|
+
[key]: next
|
|
5175
|
+
}));
|
|
5176
|
+
}
|
|
5177
|
+
}, react.createElement(CollapsibleTrigger, { className: "ci-preset-part-trigger" }, react.createElement("span", {
|
|
5178
|
+
className: "ci-chevron",
|
|
5179
|
+
"aria-hidden": true
|
|
5180
|
+
}, chevronIcon), react.createElement("h3", { className: "ci-preset-part-title" }, title)), react.createElement("p", { className: "ci-preset-part-sub" }, t("group.count", {
|
|
5181
|
+
shown,
|
|
5182
|
+
total
|
|
5183
|
+
})), react.createElement(CollapsiblePanel, { className: "ci-collapse" }, react.createElement("ul", { className: "ci-preset-tool-list" }, ...rows))));
|
|
5106
5184
|
};
|
|
5107
|
-
group("skills", t("
|
|
5108
|
-
shown: view.skills.length,
|
|
5109
|
-
total: totals.skills
|
|
5110
|
-
}), groupBy(view.skills, (skill) => skill.group ?? skill.source ?? "unknown").flatMap(([groupKey, items], i) => [sourceDivider(groupKey, items, i === 0), ...items.map((skill) => skillRow(skill, selected.id))]));
|
|
5185
|
+
group("skills", t("tab.skills"), groupBy(view.skills, (skill) => skill.group ?? skill.source ?? "unknown").flatMap(([groupKey, items], i) => [sourceDivider(groupKey, items, i === 0), ...items.map((skill) => skillRow(skill, selected.id))]), totals.skills, view.skills.length);
|
|
5111
5186
|
const serverRow = (server) => {
|
|
5112
5187
|
const key = `mcp:${server.server}`;
|
|
5113
5188
|
const disclosure = resolveDisclosure(expanded[key] === true, filtering);
|
|
@@ -5151,16 +5226,10 @@ function PresetToolSection(props) {
|
|
|
5151
5226
|
}, react.createElement("span", {
|
|
5152
5227
|
className: "ci-reconnect-glyph",
|
|
5153
5228
|
"aria-hidden": true
|
|
5154
|
-
}, react.createElement(
|
|
5229
|
+
}, react.createElement(IconRefresh, { size: 12 })), t("action.reload.label")) : null), react.createElement(CollapsiblePanel, { className: "ci-collapse" }, react.createElement("ul", { className: "ci-preset-tool-list" }, ...server.tools.map((tool) => toolRow(tool, selected.id, true))))));
|
|
5155
5230
|
};
|
|
5156
|
-
group("mcp", t("
|
|
5157
|
-
|
|
5158
|
-
total: totals.mcp
|
|
5159
|
-
}), groupBy(view.mcp, (server) => server.source === void 0 || server.source === "host" ? "host" : `preset:${server.source}`).flatMap(([groupKey, items], i) => [sourceDivider(groupKey, items, i === 0), ...items.map((server) => serverRow(server))]));
|
|
5160
|
-
group("system", t("group.system", {
|
|
5161
|
-
shown: view.systemTools.length,
|
|
5162
|
-
total: totals.systemTools
|
|
5163
|
-
}), view.systemTools.map((tool) => toolRow(tool, selected.id, false)));
|
|
5231
|
+
group("mcp", t("tab.mcp"), groupBy(view.mcp, (server) => server.source === void 0 || server.source === "host" ? "host" : `preset:${server.source}`).flatMap(([groupKey, items], i) => [sourceDivider(groupKey, items, i === 0), ...items.map((server) => serverRow(server))]), totals.mcp, view.mcp.length);
|
|
5232
|
+
group("system", t("group.systemTools"), view.systemTools.map((tool) => toolRow(tool, selected.id, false)), totals.systemTools, view.systemTools.length);
|
|
5164
5233
|
if (groups.length === 0) return react.createElement("p", null, filtering ? t("empty.match") : t("preset.noTools"));
|
|
5165
5234
|
return react.createElement(react.Fragment, null, ...groups);
|
|
5166
5235
|
};
|
|
@@ -5173,7 +5242,21 @@ function PresetToolSection(props) {
|
|
|
5173
5242
|
}, t("status.loading")) : null, state.payload === null ? null : react.createElement(react.Fragment, null, writable ? null : react.createElement("p", {
|
|
5174
5243
|
role: "note",
|
|
5175
5244
|
className: "ci-settings-note"
|
|
5176
|
-
}, t("preset.readonly")), react.createElement("div", { className: "ci-preset-toolbar" }, react.createElement("
|
|
5245
|
+
}, t("preset.readonly")), react.createElement("div", { className: "ci-preset-toolbar" }, react.createElement("div", { className: "ci-search" }, react.createElement(IconSearch, { size: 16 }), react.createElement(Input, {
|
|
5246
|
+
className: "ci-filter ci-preset-filter",
|
|
5247
|
+
value: query,
|
|
5248
|
+
placeholder: t("filter.placeholder"),
|
|
5249
|
+
"aria-label": t("filter.aria"),
|
|
5250
|
+
autoComplete: "off",
|
|
5251
|
+
spellCheck: false,
|
|
5252
|
+
name: "ci-preset-filter",
|
|
5253
|
+
onChange: (event) => {
|
|
5254
|
+
setQuery(event.target.value);
|
|
5255
|
+
},
|
|
5256
|
+
onKeyDown: (event) => {
|
|
5257
|
+
if (event.key === "Escape" && filtering) setQuery("");
|
|
5258
|
+
}
|
|
5259
|
+
})), react.createElement(__deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
5177
5260
|
open: pickerOpen,
|
|
5178
5261
|
anchor: react.createElement("button", {
|
|
5179
5262
|
type: "button",
|
|
@@ -5187,7 +5270,7 @@ function PresetToolSection(props) {
|
|
|
5187
5270
|
}, react.createElement("span", { className: "ci-preset-picker-name" }, selected?.name ?? ""), react.createElement("span", {
|
|
5188
5271
|
className: `ci-preset-picker-chevron${pickerOpen ? " ci-preset-picker-chevron-open" : ""}`,
|
|
5189
5272
|
"aria-hidden": true
|
|
5190
|
-
}, react.createElement(
|
|
5273
|
+
}, react.createElement(IconChevronDown, { size: 14 }))),
|
|
5191
5274
|
items: state.payload.presets.map((preset) => ({
|
|
5192
5275
|
id: preset.id,
|
|
5193
5276
|
label: preset.name
|
|
@@ -5200,43 +5283,58 @@ function PresetToolSection(props) {
|
|
|
5200
5283
|
onClose: () => {
|
|
5201
5284
|
setPickerOpen(false);
|
|
5202
5285
|
}
|
|
5203
|
-
})),
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5286
|
+
})), selected === void 0 ? null : (() => {
|
|
5287
|
+
const Segmented = __deepseek_ai_dsh_client_ui_primitives.SegmentedControl;
|
|
5288
|
+
if (Segmented !== void 0) return react.createElement(Segmented, {
|
|
5289
|
+
id: "ci-preset-kinds",
|
|
5290
|
+
label: t("preset.kindAria"),
|
|
5291
|
+
value: kind,
|
|
5292
|
+
options: [
|
|
5293
|
+
{
|
|
5294
|
+
value: "all",
|
|
5295
|
+
label: t("tab.all")
|
|
5296
|
+
},
|
|
5297
|
+
{
|
|
5298
|
+
value: "skills",
|
|
5299
|
+
label: `${t("tab.skills")} ${selected.skills.length}`
|
|
5300
|
+
},
|
|
5301
|
+
{
|
|
5302
|
+
value: "mcp",
|
|
5303
|
+
label: `${t("tab.mcp")} ${selected.mcp.length}`
|
|
5304
|
+
},
|
|
5305
|
+
{
|
|
5306
|
+
value: "system",
|
|
5307
|
+
label: `${t("tab.system")} ${selected.systemTools.length}`
|
|
5308
|
+
}
|
|
5309
|
+
],
|
|
5310
|
+
onChange: (next) => {
|
|
5311
|
+
setKind(next);
|
|
5312
|
+
}
|
|
5313
|
+
});
|
|
5314
|
+
return react.createElement(TabsRoot, {
|
|
5315
|
+
value: kind,
|
|
5316
|
+
onValueChange: (value) => {
|
|
5317
|
+
setKind(value);
|
|
5318
|
+
},
|
|
5319
|
+
className: "ci-preset-kinds"
|
|
5320
|
+
}, react.createElement(TabsList, {
|
|
5321
|
+
"aria-label": t("preset.kindAria"),
|
|
5322
|
+
className: "ci-tabs"
|
|
5323
|
+
}, react.createElement(TabsTab, {
|
|
5324
|
+
value: "all",
|
|
5325
|
+
className: "ci-tab"
|
|
5326
|
+
}, t("tab.all")), react.createElement(TabsTab, {
|
|
5327
|
+
value: "skills",
|
|
5328
|
+
className: "ci-tab"
|
|
5329
|
+
}, `${t("tab.skills")} ${selected.skills.length}`), react.createElement(TabsTab, {
|
|
5330
|
+
value: "mcp",
|
|
5331
|
+
className: "ci-tab"
|
|
5332
|
+
}, `${t("tab.mcp")} ${selected.mcp.length}`), react.createElement(TabsTab, {
|
|
5333
|
+
value: "system",
|
|
5334
|
+
className: "ci-tab",
|
|
5335
|
+
"aria-label": t("tab.system.aria", { count: selected.systemTools.length })
|
|
5336
|
+
}, `${t("tab.system")} ${selected.systemTools.length}`)));
|
|
5337
|
+
})(), selected?.description === void 0 ? null : react.createElement("p", { className: "ci-settings-description" }, selected.description), view === null || !filtering ? null : react.createElement("p", {
|
|
5240
5338
|
"aria-live": "polite",
|
|
5241
5339
|
className: "ci-settings-description"
|
|
5242
5340
|
}, t("filter.count", {
|
|
@@ -10924,6 +11022,75 @@ const STATE_ORDER = {
|
|
|
10924
11022
|
function sortSkills(skills) {
|
|
10925
11023
|
return [...skills].sort((a, b) => STATE_ORDER[a.state] - STATE_ORDER[b.state] || a.name.localeCompare(b.name));
|
|
10926
11024
|
}
|
|
11025
|
+
/**
|
|
11026
|
+
* Platform for the settings shortcut's modifier: the host binds
|
|
11027
|
+
* `settings.open` to Cmd+, on macOS and Ctrl+, elsewhere (the `primary`
|
|
11028
|
+
* modifier in its binding table resolves the same way).
|
|
11029
|
+
*/
|
|
11030
|
+
function isMacPlatform() {
|
|
11031
|
+
const platform$2 = navigator.platform ?? "";
|
|
11032
|
+
return platform$2 !== "" ? /mac/i.test(platform$2) : /mac/i.test(navigator.userAgent ?? "");
|
|
11033
|
+
}
|
|
11034
|
+
/**
|
|
11035
|
+
* Open the Settings modal by driving its official keybinding through the input
|
|
11036
|
+
* pipeline. The host's shortcuts service listens for `keydown` on `window`
|
|
11037
|
+
* with no `isTrusted` gate, so a synthesized event is processed exactly like a
|
|
11038
|
+
* physical press — region "page" (no editable/terminal ancestor), no open
|
|
11039
|
+
* shortcut-modal, both of which the `settings.open` command accepts.
|
|
11040
|
+
*
|
|
11041
|
+
* This deliberately uses the input seam, not a host internal: the shortcuts
|
|
11042
|
+
* service is not visible to plugin contexts, and the settings shell exposes no
|
|
11043
|
+
* section deep-link (`openSection` stays internal to the shell). Caveats,
|
|
11044
|
+
* accepted over shipping no entry at all: a user who rebound the settings
|
|
11045
|
+
* shortcut changed what this gesture triggers, and hosts older than 0.1.7 have
|
|
11046
|
+
* no such binding at all — the caller gates the entry on `HOST_HAS_MODERN_SHELL`.
|
|
11047
|
+
*/
|
|
11048
|
+
function dispatchOpenSettings() {
|
|
11049
|
+
const mac$1 = isMacPlatform();
|
|
11050
|
+
window.dispatchEvent(new KeyboardEvent("keydown", {
|
|
11051
|
+
code: "Comma",
|
|
11052
|
+
key: ",",
|
|
11053
|
+
metaKey: mac$1,
|
|
11054
|
+
ctrlKey: !mac$1,
|
|
11055
|
+
bubbles: true,
|
|
11056
|
+
cancelable: true
|
|
11057
|
+
}));
|
|
11058
|
+
}
|
|
11059
|
+
/**
|
|
11060
|
+
* Select our own section inside an open Settings dialog by clicking its nav
|
|
11061
|
+
* row — the official user interaction, located through two anchors that cannot
|
|
11062
|
+
* drift with host internals: the dialog's own `data-shortcut-modal="settings"`
|
|
11063
|
+
* attribute (the shortcut system's public hook) and OUR OWN localized section
|
|
11064
|
+
* label as the row's text. Returns false when the row is not (yet) there, so
|
|
11065
|
+
* the caller can retry while the modal mounts.
|
|
11066
|
+
*/
|
|
11067
|
+
function selectCapabilitySection(label) {
|
|
11068
|
+
const buttons = document.querySelector("[data-shortcut-modal=\"settings\"]")?.querySelectorAll("nav button") ?? [];
|
|
11069
|
+
for (const button of buttons) if (button.textContent?.trim() === label) {
|
|
11070
|
+
button.click();
|
|
11071
|
+
return true;
|
|
11072
|
+
}
|
|
11073
|
+
return false;
|
|
11074
|
+
}
|
|
11075
|
+
/**
|
|
11076
|
+
* Open Settings ON the capability-panel section. The shell offers no section
|
|
11077
|
+
* deep-link, so this drives the two official gestures in sequence: the
|
|
11078
|
+
* settings.open keybinding (which TOGGLES — skipped when the dialog is already
|
|
11079
|
+
* open, or it would close it), then a nav-row click once the dialog has
|
|
11080
|
+
* mounted. The retry is bounded; if the row never appears the user still lands
|
|
11081
|
+
* on the settings landing page, which is the pre-existing behavior.
|
|
11082
|
+
*/
|
|
11083
|
+
function openGlobalSettings(sectionLabel) {
|
|
11084
|
+
close();
|
|
11085
|
+
if (document.querySelector("[data-shortcut-modal=\"settings\"]") === null) dispatchOpenSettings();
|
|
11086
|
+
let attempts = 0;
|
|
11087
|
+
const trySelect = () => {
|
|
11088
|
+
attempts += 1;
|
|
11089
|
+
if (selectCapabilitySection(sectionLabel)) return;
|
|
11090
|
+
if (attempts < 20) requestAnimationFrame(trySelect);
|
|
11091
|
+
};
|
|
11092
|
+
requestAnimationFrame(trySelect);
|
|
11093
|
+
}
|
|
10927
11094
|
function apply(ctx) {
|
|
10928
11095
|
const react$1 = react;
|
|
10929
11096
|
const h = react$1.createElement;
|
|
@@ -10946,14 +11113,14 @@ function apply(ctx) {
|
|
|
10946
11113
|
};
|
|
10947
11114
|
}, "capability-panel: stylesheet");
|
|
10948
11115
|
/** Host iconography: the panel inspects what lands in the session's context. */
|
|
10949
|
-
const layersIcon = (size$3) => h(
|
|
11116
|
+
const layersIcon = (size$3) => h(IconContextInjection, { size: size$3 });
|
|
10950
11117
|
/** Magnifier sitting inside the filter input. */
|
|
10951
|
-
const searchIcon = (size$3) => h(
|
|
11118
|
+
const searchIcon = (size$3) => h(IconSearch, { size: size$3 });
|
|
10952
11119
|
/** Paper plane: the row action lands the command in the composer,
|
|
10953
11120
|
* ready for the user's own Enter. */
|
|
10954
|
-
const insertIcon = (size$3) => h(
|
|
11121
|
+
const insertIcon = (size$3) => h(IconSend, { size: size$3 });
|
|
10955
11122
|
/** Circular arrows: pull a declared-but-offline server's connection up now. */
|
|
10956
|
-
const reconnectIcon = (size$3) => h(
|
|
11123
|
+
const reconnectIcon = (size$3) => h(IconRefresh, { size: size$3 });
|
|
10957
11124
|
/** The GitHub mark. Not in the host icon set (brand logos are not shipped
|
|
10958
11125
|
* there), so this one path is inlined for the feedback link's recognizability. */
|
|
10959
11126
|
const githubIcon = (size$3) => h("svg", {
|
|
@@ -11119,7 +11286,7 @@ function apply(ctx) {
|
|
|
11119
11286
|
opacity: 0,
|
|
11120
11287
|
transition: "opacity 0.15s"
|
|
11121
11288
|
}
|
|
11122
|
-
}, h(
|
|
11289
|
+
}, h(IconFolderClose, { size: 12 })) : null, `${label} (${count})`), rule(true));
|
|
11123
11290
|
};
|
|
11124
11291
|
/** Group items by source, preserving order within each group. */
|
|
11125
11292
|
const groupBySource = (items, getSource) => {
|
|
@@ -11191,7 +11358,7 @@ function apply(ctx) {
|
|
|
11191
11358
|
}
|
|
11192
11359
|
});
|
|
11193
11360
|
/** Right chevron the disclosure CSS rotates 90° when expanded. */
|
|
11194
|
-
const chevronIcon$1 = h(
|
|
11361
|
+
const chevronIcon$1 = h(IconChevronRight, { size: 12 });
|
|
11195
11362
|
const groupLabel = (text, first) => h("div", {
|
|
11196
11363
|
key: `group:${text}`,
|
|
11197
11364
|
style: {
|
|
@@ -11478,9 +11645,12 @@ function apply(ctx) {
|
|
|
11478
11645
|
boxSizing: "border-box",
|
|
11479
11646
|
width: "480px",
|
|
11480
11647
|
maxHeight: "min(60vh, var(--available-height, 60vh))",
|
|
11481
|
-
|
|
11648
|
+
display: "flex",
|
|
11649
|
+
flexDirection: "column",
|
|
11650
|
+
overflow: "hidden",
|
|
11482
11651
|
padding: "10px 12px",
|
|
11483
11652
|
background: TOK.menuBg,
|
|
11653
|
+
backdropFilter: TOK.menuBlur,
|
|
11484
11654
|
color: TOK.textSecondary,
|
|
11485
11655
|
border: `1px solid ${TOK.menuBorder}`,
|
|
11486
11656
|
borderRadius: "12px",
|
|
@@ -11490,7 +11660,14 @@ function apply(ctx) {
|
|
|
11490
11660
|
lineHeight: "20px",
|
|
11491
11661
|
cursor: "default"
|
|
11492
11662
|
}
|
|
11493
|
-
}, h("div", { style: {
|
|
11663
|
+
}, h("div", { style: {
|
|
11664
|
+
flex: "1 1 auto",
|
|
11665
|
+
minHeight: 0,
|
|
11666
|
+
overflowY: "auto",
|
|
11667
|
+
overflowX: "hidden",
|
|
11668
|
+
margin: "0 -12px",
|
|
11669
|
+
padding: "0 12px"
|
|
11670
|
+
} }, h("div", { style: { marginBottom: "6px" } }, h("div", { style: {
|
|
11494
11671
|
display: "flex",
|
|
11495
11672
|
alignItems: "center",
|
|
11496
11673
|
gap: "6px"
|
|
@@ -11567,11 +11744,27 @@ function apply(ctx) {
|
|
|
11567
11744
|
}, t("filter.count", {
|
|
11568
11745
|
shown: view?.total ?? 0,
|
|
11569
11746
|
total: totalAll
|
|
11570
|
-
})) : null), ...notices, ...body, h("div", { style: {
|
|
11747
|
+
})) : null), ...notices, ...body), h("div", { style: {
|
|
11748
|
+
flex: "none",
|
|
11571
11749
|
display: "flex",
|
|
11572
|
-
justifyContent: "
|
|
11573
|
-
|
|
11574
|
-
|
|
11750
|
+
justifyContent: "space-between",
|
|
11751
|
+
alignItems: "center",
|
|
11752
|
+
marginTop: "6px",
|
|
11753
|
+
paddingTop: "8px",
|
|
11754
|
+
borderTop: "0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,.1))"
|
|
11755
|
+
} }, (() => {
|
|
11756
|
+
return HOST_HAS_MODERN_SHELL ? h("button", {
|
|
11757
|
+
type: "button",
|
|
11758
|
+
className: "ci-feedback-link ci-settings-link",
|
|
11759
|
+
title: t("footer.openSettingsHint"),
|
|
11760
|
+
onClick: () => {
|
|
11761
|
+
openGlobalSettings(t("preset.nav"));
|
|
11762
|
+
}
|
|
11763
|
+
}, h("span", {
|
|
11764
|
+
className: "ci-feedback-icon",
|
|
11765
|
+
"aria-hidden": true
|
|
11766
|
+
}, h(IconSettings, { size: 12 })), t("footer.openSettings")) : h("span");
|
|
11767
|
+
})(), h("a", {
|
|
11575
11768
|
href: FEEDBACK_URL,
|
|
11576
11769
|
target: "_blank",
|
|
11577
11770
|
rel: "noopener noreferrer",
|