dsh-plugin-capabilities 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,9 +17,9 @@
17
17
 
18
18
  ![「MCP」标签页](docs/images/screenshot-mcp.png)
19
19
 
20
- 「MCP」页管理 profile patch 中的 MCP 服务器行,每行对应一个 `@deepseek-ai/dsh-mcp-client` 实例。stdio 服务器填写命令与参数,streamable-http 服务器填写 URL,编辑、停用、移除都在页面上完成。YAML 读写采用文档级 API,文件中的其他行与注释不受影响。
20
+ 「MCP」页管理 profile patch 中的 MCP 服务器行,每行对应一个 `@deepseek-ai/dsh-mcp-client` 实例。stdio 服务器填写命令与参数,streamable-http 服务器填写 URL,编辑、停用、移除都在页面上完成。YAML 读写采用文档级 API,文件中的其他行与注释不受影响。新行写在一个 `- insert:` 块里——加载器只会挂载 insert 形式的行,裸的 `- id:` 条目是对已有行的覆盖,目标不存在时会被跳过;0.1.3 之前写入的裸行会在下一次保存时自动迁入 insert 块。
21
21
 
22
- 也可以从其他 agent 导入:一键扫描 Claude Code(`~/.claude.json`、`~/.claude/settings.json`)与 Codex(`~/.codex/config.toml`)的 MCP 配置,勾选所需条目后转为本 profile 的服务器行。stdio 与 http 两种传输都会处理,已存在的同名服务器置灰跳过。需要注意的是,Claude 配置里的 `${VAR}` 环境变量引用按字面值导入,如有需要请在导入后手动改回。
22
+ 也可以从其他 agent 导入:一键扫描 Claude Code(`~/.claude.json`、`~/.claude/settings.json`)与 Codex(`~/.codex/config.toml`)的 MCP 配置,勾选所需条目后转为本 profile 的服务器行。弹窗按来源分成 Claude Code 和 Codex 两组,各自带数量与「全选」;stdio 与 http 两种传输都会处理,已存在的同名服务器置灰跳过。需要注意的是,Claude 配置里的 `${VAR}` 环境变量引用按字面值导入,如有需要请在导入后手动改回。
23
23
 
24
24
  MCP 行的变更需要重启 dsh 才会进入组合。MCP 页头部有常驻的「重启」按钮,变更后无需离开界面:在 [DSH Desktop](https://github.com/qinyre/dsh-Desktop) 中由桌面壳层重启受监督的 sidecar,完成后窗口自动重载;直接运行 `dsh web` 时插件会拉起一个替代进程再退出自身,页面在恢复后自动刷新——若启动时端口是随机的,按横幅提示在终端查看新地址。重启会中断正在进行的回合,点击后会先弹出确认。
25
25
 
package/lib/client.js CHANGED
@@ -76,11 +76,36 @@ var CSS = `
76
76
  .dpc-checks{display:flex;gap:16px;font-size:13px;line-height:20px}
77
77
  .dpc-checks label{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
78
78
  .dpc-formError{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}
79
+ /* Import dialog: wider than the host's 380px default; the server list gets
80
+ its own scroll so title, intro, and footer stay pinned. The doubled class
81
+ beats the host dialog's module CSS regardless of injection order. */
82
+ .dpc-modalWide.dpc-modalWide{width:min(680px,100%)}
83
+ .dpc-importScroll{display:flex;flex-direction:column;gap:14px;max-height:min(400px,52vh);overflow-y:auto;padding:2px 4px 2px 2px}
84
+ .dpc-importGroup{display:flex;flex-direction:column;gap:8px}
85
+ .dpc-importHead{display:flex;align-items:center;gap:8px;padding:0 2px}
86
+ .dpc-importCount{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums}
87
+ .dpc-importAll{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer}
79
88
  @media(max-width:680px){.dpc-cards{grid-template-columns:minmax(0,1fr)}}
80
89
  `;
81
90
 
82
91
  // src/client/McpTab.tsx
83
92
  var import_jsx_runtime = require("react/jsx-runtime");
93
+ function importGroups(items) {
94
+ const label = (agent) => agent === "claude-code" ? "Claude Code" : agent === "codex" ? "Codex" : agent;
95
+ const order = ["claude-code", "codex"];
96
+ const agents = [...new Set(items.map((item) => item.server.agent))].sort((a, b) => {
97
+ const rank = (agent) => {
98
+ const at = order.indexOf(agent);
99
+ return at === -1 ? order.length : at;
100
+ };
101
+ return rank(a) - rank(b) || a.localeCompare(b);
102
+ });
103
+ return agents.map((agent) => ({
104
+ agent,
105
+ label: label(agent),
106
+ items: items.map((item, index) => ({ item, index })).filter(({ item }) => item.server.agent === agent)
107
+ }));
108
+ }
84
109
  function parsePairs(text, separator) {
85
110
  const map = {};
86
111
  for (const line of text.split(/\r?\n/)) {
@@ -404,34 +429,62 @@ function McpTab(props) {
404
429
  open: importOpen,
405
430
  onClose: () => setImportOpen(false),
406
431
  title: t("importServers"),
432
+ className: "dpc-modalWide",
407
433
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-form", children: [
408
434
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-intro", style: { margin: 0 }, children: t("importIntro") }),
409
435
  importItems === null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("loading") }),
410
436
  importItems !== null && importItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-empty", children: t("importEmpty") }),
411
- importItems !== null && importItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", style: { gridTemplateColumns: "minmax(0, 1fr)" }, children: importItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", style: { opacity: item.existing ? 0.55 : 1 }, children: [
412
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardTop", children: [
413
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: 8, minWidth: 0, cursor: item.existing ? "default" : "pointer" }, children: [
414
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
415
- "input",
416
- {
417
- type: "checkbox",
418
- checked: item.checked,
419
- disabled: item.existing,
420
- onChange: (event) => {
421
- const next = importItems.slice();
422
- next[index] = { ...item, checked: event.target.checked };
423
- setImportItems(next);
437
+ importItems !== null && importItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dpc-importScroll", children: importGroups(importItems).map((group) => {
438
+ const selectable = group.items.filter(({ item }) => !item.existing).map(({ index }) => index);
439
+ const allChecked = selectable.length > 0 && selectable.every((index) => importItems[index].checked);
440
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "dpc-importGroup", children: [
441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-importHead", children: [
442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", "data-kind": "source", children: group.label }),
443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-importCount", children: group.items.length }),
444
+ selectable.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "dpc-importAll", children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
446
+ "input",
447
+ {
448
+ type: "checkbox",
449
+ checked: allChecked,
450
+ onChange: (event) => {
451
+ const next = importItems.slice();
452
+ for (const index of selectable) next[index] = { ...next[index], checked: event.target.checked };
453
+ setImportItems(next);
454
+ }
424
455
  }
425
- }
426
- ),
427
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "dpc-cardTitle", title: item.server.name, children: item.server.name })
456
+ ),
457
+ t("importSelectAll")
458
+ ] })
428
459
  ] }),
429
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", "data-kind": "source", children: item.server.agent === "claude-code" ? "Claude Code" : "Codex" }),
430
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: item.server.transport }),
431
- item.existing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: t("importExisting") })
432
- ] }),
433
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-cardDesc", children: item.server.transport === "stdio" ? `${item.server.command ?? ""} ${(item.server.args ?? []).join(" ")}` : item.server.url ?? "" })
434
- ] }, `${item.server.agent}/${item.server.name}`)) }),
460
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "dpc-cards", style: { gridTemplateColumns: "minmax(0, 1fr)" }, children: group.items.map(({ item, index }) => {
461
+ const command = item.server.transport === "stdio" ? `${item.server.command ?? ""} ${(item.server.args ?? []).join(" ")}`.trim() : item.server.url ?? "";
462
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "dpc-card", style: { opacity: item.existing ? 0.55 : 1 }, children: [
463
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardTop", children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: 8, minWidth: 0, cursor: item.existing ? "default" : "pointer" }, children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
466
+ "input",
467
+ {
468
+ type: "checkbox",
469
+ checked: item.checked,
470
+ disabled: item.existing,
471
+ onChange: (event) => {
472
+ const next = importItems.slice();
473
+ next[index] = { ...item, checked: event.target.checked };
474
+ setImportItems(next);
475
+ }
476
+ }
477
+ ),
478
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "dpc-cardTitle", title: item.server.name, children: item.server.name })
479
+ ] }),
480
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: item.server.transport }),
481
+ item.existing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-tag", children: t("importExisting") })
482
+ ] }),
483
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-cardDesc", title: command, children: command })
484
+ ] }, `${item.server.agent}/${item.server.name}`);
485
+ }) })
486
+ ] }, group.agent);
487
+ }) }),
435
488
  formError !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dpc-formError", children: formError }),
436
489
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dpc-cardRow", children: [
437
490
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dpc-spacer" }),
@@ -769,6 +822,7 @@ var zh = {
769
822
  importServers: "\u4ECE\u5176\u4ED6 Agent \u5BFC\u5165",
770
823
  importIntro: "\u626B\u63CF Claude Code\uFF08~/.claude.json\uFF09\u4E0E Codex\uFF08~/.codex/config.toml\uFF09\u7684 MCP \u670D\u52A1\u5668\u914D\u7F6E\uFF0C\u52FE\u9009\u540E\u5BFC\u5165\u4E3A\u672C profile \u7684\u670D\u52A1\u5668\u884C\u3002",
771
824
  importEmpty: "\u6CA1\u6709\u53D1\u73B0\u53EF\u5BFC\u5165\u7684 MCP \u670D\u52A1\u5668",
825
+ importSelectAll: "\u5168\u9009",
772
826
  importExisting: "\u5DF2\u5B58\u5728",
773
827
  importSelected: "\u5BFC\u5165\u9009\u4E2D\u9879",
774
828
  restartNeeded: "\u914D\u7F6E\u5DF2\u5199\u5165\uFF0C\u91CD\u542F dsh \u540E\u751F\u6548\u3002",
@@ -838,6 +892,7 @@ var en = {
838
892
  importServers: "Import from other agents",
839
893
  importIntro: "Scans Claude Code (~/.claude.json) and Codex (~/.codex/config.toml) MCP server configs; selected entries become server rows in this profile.",
840
894
  importEmpty: "No importable MCP servers found",
895
+ importSelectAll: "Select all",
841
896
  importExisting: "already here",
842
897
  importSelected: "Import selected",
843
898
  restartNeeded: "Configuration written \u2014 restart dsh to apply.",
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client/index.ts", "../src/client/McpTab.tsx", "../src/client/css.ts", "../src/client/SkillsTab.tsx", "../src/client/locales.ts"],
4
- "sourcesContent": ["/** dsh-plugin-capabilities client entry: contributes the \u201C\u6280\u80FD/Skills\u201D and\n * \u201CMCP\u201D tabs into Settings \u2192 Plugins. Calls the host routes with fetch. */\n\nimport { createElement as h } from 'react'\nimport { McpTab, type McpInjected, type McpRow } from './McpTab.tsx'\nimport { SkillsTab, type SkillsInjected, type SkillRowView } from './SkillsTab.tsx'\nimport { zh, en } from './locales.ts'\n\n/** Locale dictionary namespace owned by this plugin. */\nexport const NS = 'settings.pluginCapabilities'\n\n/** The `t` function bound by the locale service. */\nexport interface Translate {\n (key: string): string\n}\n\n/** Minimal structural subset of the slots service. */\ninterface SlotsService {\n inject(slot: string, register: () => unknown): void\n register(meta: Record<string, unknown>, component: () => unknown): unknown\n}\n\n/** Minimal structural subset of the locale service. */\ninterface LocaleService {\n register(namespace: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\n bind(namespace: string): Translate\n}\n\n/** The client cordis context this plugin relies on (structural). */\ninterface CapabilitiesClientContext {\n effect(callback: () => unknown, label?: string): void\n locale: LocaleService\n slots: SlotsService\n}\n\n/** Same-origin fetch of the manager's host routes. */\nasync function fetchJson<T>(path: string, init?: RequestInit): Promise<T> {\n const response = await fetch(path, init)\n const body = (await response.json()) as T & { error?: string }\n if (!response.ok) throw new Error(body.error ?? `HTTP ${response.status}`)\n return body\n}\n\nconst post = (path: string, body: unknown): Promise<unknown> =>\n fetchJson(path, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) })\n\nexport const name = 'dsh-plugin-capabilities'\nexport const inject = ['slots', 'locale']\n\nexport interface SkillBody { content: string }\n\n/** One foreign-agent server from the import scan. */\nexport interface ImportedServerView {\n agent: 'claude-code' | 'codex'\n name: string\n transport: 'stdio' | 'streamable-http'\n command?: string\n args?: string[]\n env?: Record<string, string>\n url?: string\n headers?: Record<string, string>\n}\n\nexport function apply(ctx: CapabilitiesClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-plugin-capabilities: dictionaries')\n const t = ctx.locale.bind(NS)\n\n const skillsInjected: SkillsInjected = {\n list: () => fetchJson<{ skills: SkillRowView[] }>('/dsh-plugin-capabilities/skills'),\n get: (name: string) => fetchJson<SkillBody>(`/dsh-plugin-capabilities/skill?name=${encodeURIComponent(name)}`),\n save: (input: unknown) => post('/dsh-plugin-capabilities/skill/save', input) as Promise<{ ok: boolean }>,\n remove: (name: string) => post('/dsh-plugin-capabilities/skill/delete', { name }) as Promise<{ ok: boolean }>,\n }\n\n const mcpInjected: McpInjected = {\n list: () => fetchJson<{ servers: McpRow[] }>('/dsh-plugin-capabilities/mcp'),\n save: (input: unknown) => post('/dsh-plugin-capabilities/mcp/save', input) as Promise<{ ok: boolean; id: string }>,\n toggle: (id: string, disabled: boolean) => post('/dsh-plugin-capabilities/mcp/toggle', { id, disabled }) as Promise<{ ok: boolean }>,\n remove: (id: string) => post('/dsh-plugin-capabilities/mcp/remove', { id }) as Promise<{ ok: boolean }>,\n scanImport: () => fetchJson<{ servers: ImportedServerView[]; existing: string[] }>('/dsh-plugin-capabilities/import/scan'),\n applyImport: (items: Array<{ agent: string; name: string }>) =>\n post('/dsh-plugin-capabilities/import/apply', { items }) as Promise<{ ok: boolean; results: Array<{ name: string; ok: boolean; error?: string }> }>,\n restart: async (): Promise<void> => {\n if (window.dshDesktop !== undefined) {\n window.dshDesktop.restartSidecar?.()\n return\n }\n // \u72EC\u7ACB dsh web\uFF1A\u81EA\u91CD\u542F\u8DEF\u7531\u3002\u8FDE\u63A5\u5728\u5173\u505C\u9014\u4E2D\u65AD\u5F00\u5C5E\u9884\u671F\uFF0C\u4E0D\u7B97\u5931\u8D25\u3002\n try { await post('/dsh-plugin-capabilities/restart', {}) } catch { /* dying mid-restart is expected */ }\n },\n desktop: window.dshDesktop !== undefined,\n }\n\n ctx.slots.inject('settings.plugins.tab', () => {\n return ctx.slots.register({\n name: 'settings.plugins.tab',\n id: 'capabilities-skills',\n order: 30,\n label: () => t('skillsTab'),\n locale: NS,\n inject: () => skillsInjected,\n }, () => h(SkillsTab, { t, injected: skillsInjected }))\n })\n\n ctx.slots.inject('settings.plugins.tab', () => {\n return ctx.slots.register({\n name: 'settings.plugins.tab',\n id: 'capabilities-mcp',\n order: 40,\n label: () => t('mcpTab'),\n locale: NS,\n inject: () => mcpInjected,\n }, () => h(McpTab, { t, injected: mcpInjected }))\n })\n}\n", "/** Settings \u2192 Plugins \u201CMCP\u201D tab: manage the profile's mcp-client rows.\n * Mutations rewrite the profile patch and need a dsh restart \u2014 the banner\n * hands the restart to the desktop shell when one is present. */\n\nimport { useEffect, useState } from 'react'\nimport type { ReactElement } from 'react'\nimport { Button, IconApiOutline14, IconRefreshOutline14, Modal, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { CSS } from './css.ts'\nimport type { ImportedServerView, Translate } from './index.ts'\n\nexport interface McpRow {\n id: string\n serverName: string\n transport: 'stdio' | 'streamable-http'\n disabled: boolean\n command?: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n url?: string\n headers?: Record<string, string>\n}\n\nexport interface McpInjected {\n list(): Promise<{ servers: McpRow[] }>\n save(input: Record<string, unknown>): Promise<{ ok: boolean; id: string }>\n toggle(id: string, disabled: boolean): Promise<{ ok: boolean }>\n remove(id: string): Promise<{ ok: boolean }>\n scanImport(): Promise<{ servers: ImportedServerView[]; existing: string[] }>\n applyImport(items: Array<{ agent: string; name: string }>): Promise<{ ok: boolean; results: Array<{ name: string; ok: boolean; error?: string }> }>\n restart(): Promise<void>\n desktop: boolean\n}\n\n/** Editor dialog state; null when closed. Textareas hold line-based values. */\ninterface EditorState {\n id: string\n serverName: string\n transport: 'stdio' | 'streamable-http'\n command: string\n args: string\n env: string\n url: string\n headers: string\n}\n\n/** KEY=VALUE / KEY: VALUE lines to a map. */\nfunction parsePairs(text: string, separator: ':' | '='): Record<string, string> {\n const map: Record<string, string> = {}\n for (const line of text.split(/\\r?\\n/)) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('#')) continue\n const at = trimmed.indexOf(separator)\n if (at <= 0) continue\n map[trimmed.slice(0, at).trim()] = trimmed.slice(at + 1).trim()\n }\n return map\n}\n\nfunction mapToPairs(map: Record<string, string> | undefined, separator: string): string {\n if (map === undefined) return ''\n return Object.entries(map).map(([key, value]) => `${key}${separator}${value.includes('\\n') ? JSON.stringify(value) : value}`).join('\\n')\n}\n\nexport function McpTab(props: { t: Translate; injected: McpInjected }): ReactElement {\n const { t, injected } = props\n const [servers, setServers] = useState<McpRow[] | null>(null)\n const [editor, setEditor] = useState<EditorState | null>(null)\n const [confirmId, setConfirmId] = useState<string | null>(null)\n const [importOpen, setImportOpen] = useState(false)\n const [importItems, setImportItems] = useState<Array<{ server: ImportedServerView; existing: boolean; checked: boolean }> | null>(null)\n const [busy, setBusy] = useState(false)\n const [pending, setPending] = useState(false)\n const [restartConfirm, setRestartConfirm] = useState(false)\n const [restarting, setRestarting] = useState(false)\n const [outcome, setOutcome] = useState<{ ok: boolean; text: string } | null>(null)\n const [formError, setFormError] = useState<string | null>(null)\n const [reload, setReload] = useState(0)\n\n const openImport = async (): Promise<void> => {\n setImportOpen(true)\n setImportItems(null)\n try {\n const body = await injected.scanImport()\n const existing = new Set(body.existing)\n setImportItems(body.servers.map(server => ({\n server,\n existing: existing.has(server.name),\n checked: !existing.has(server.name),\n })))\n } catch (error) {\n setImportItems([])\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n }\n }\n\n const doImport = async (): Promise<void> => {\n if (importItems === null) return\n const items = importItems.filter(item => item.checked && !item.existing).map(item => ({ agent: item.server.agent, name: item.server.name }))\n setBusy(true)\n try {\n const body = await injected.applyImport(items)\n const failed = body.results.filter(item => !item.ok)\n setOutcome(failed.length === 0\n ? { ok: true, text: t('restartNeeded') }\n : { ok: false, text: `${t('failed')}: ${failed.map(item => `${item.name} (${item.error})`).join(', ')}` })\n setImportOpen(false)\n setPending(true)\n setReload((value) => value + 1)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n const reloadList = (showPending: boolean): void => {\n setReload((value) => value + 1)\n if (showPending) setPending(true)\n }\n\n useEffect(() => {\n let current = true\n void injected.list().then(\n (body) => { if (current) setServers(body.servers) },\n (error: Error) => { if (current) { setServers([]); setOutcome({ ok: false, text: `${t('failed')}: ${String(error.message ?? error)}` }) } },\n )\n return () => { current = false }\n }, [injected, reload, t])\n\n const openCreate = (): void => {\n setFormError(null)\n setEditor({ id: '', serverName: '', transport: 'stdio', command: '', args: '', env: '', url: '', headers: '' })\n }\n\n const openEdit = (row: McpRow): void => {\n setFormError(null)\n setEditor({\n id: row.id,\n serverName: row.serverName,\n transport: row.transport,\n command: row.command ?? '',\n args: (row.args ?? []).join('\\n'),\n env: mapToPairs(row.env, '='),\n url: row.url ?? '',\n headers: mapToPairs(row.headers, ':'),\n })\n }\n\n const doSave = async (): Promise<void> => {\n if (editor === null) return\n setBusy(true)\n setFormError(null)\n try {\n await injected.save({\n id: editor.id,\n serverName: editor.serverName.trim(),\n transport: editor.transport,\n ...(editor.transport === 'stdio'\n ? {\n command: editor.command.trim(),\n args: editor.args.split(/\\r?\\n/).map(line => line.trim()).filter(line => line !== ''),\n env: parsePairs(editor.env, '='),\n }\n : {\n url: editor.url.trim(),\n headers: parsePairs(editor.headers, ':'),\n }),\n })\n setEditor(null)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setFormError(String(error instanceof Error ? error.message : error))\n } finally {\n setBusy(false)\n }\n }\n\n const doToggle = async (row: McpRow): Promise<void> => {\n setBusy(true)\n try {\n await injected.toggle(row.id, !row.disabled)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n const doRemove = async (): Promise<void> => {\n if (confirmId === null) return\n setBusy(true)\n try {\n await injected.remove(confirmId)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n setConfirmId(null)\n }\n }\n\n const doRestart = (): void => {\n setRestartConfirm(false)\n setRestarting(true)\n void injected.restart()\n // \u684C\u9762\u6A21\u5F0F\uFF1A\u58F3\u5C42\u91CD\u542F\u5B8C\u6210\u540E\u4F1A\u91CD\u8F7D\u7A97\u53E3\u3002\u72EC\u7ACB\u6A21\u5F0F\uFF1A\u8F6E\u8BE2\u672C\u6E90\uFF0C\u6062\u590D\u5373\u5237\u65B0\u3002\n if (injected.desktop) return\n const deadline = Date.now() + 60_000\n const poll = (): void => {\n if (Date.now() > deadline) return\n window.setTimeout(() => {\n void injected.list().then(\n () => { window.location.reload() },\n () => { poll() },\n )\n }, 1500)\n }\n window.setTimeout(poll, 3000)\n }\n\n const restartBanner = (\n <div className=\"dpc-banner\" data-kind=\"info\" role=\"status\">\n <StateDot state=\"ongoing\" size={10} />\n <div className=\"dpc-bannerBody\">\n <span>{restarting ? t('restarting') : t('restartNeeded')}</span>\n <span className=\"dpc-bannerHint\">\n {restarting\n ? (!injected.desktop && t('restartPortHint'))\n : injected.desktop\n ? <>{t('restartDesktopHint')}{' '}<Button variant=\"outline\" size=\"sm\" onClick={() => setRestartConfirm(true)}>{t('restartNow')}</Button></>\n : t('restartOtherHint')}\n </span>\n </div>\n </div>\n )\n\n return (\n <div className=\"dpc-section\">\n <style>{CSS}</style>\n\n <div className=\"dpc-head\">\n <IconApiOutline14 aria-hidden=\"true\" />\n <h3>{t('mcpTitle')}</h3>\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={restarting} onClick={() => setRestartConfirm(true)}>{t('restart')}</Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void openImport()}>{t('importServers')}</Button>\n <Button variant=\"primary\" size=\"sm\" onClick={openCreate}>{t('addServer')}</Button>\n </div>\n <p className=\"dpc-intro\">{t('mcpIntro')}</p>\n\n {outcome !== null && (\n <div className=\"dpc-banner\" data-kind={outcome.ok ? 'ok' : 'error'} role=\"status\">\n <StateDot state={outcome.ok ? 'done' : 'error'} size={10} />\n <div className=\"dpc-bannerBody\"><span>{outcome.text}</span></div>\n </div>\n )}\n {(pending || restarting) && restartBanner}\n\n <div className=\"dpc-listHead\">\n <h3>{t('mcpTab')}</h3>\n {servers !== null && <span className=\"dpc-count\">{servers.length}</span>}\n <span className=\"dpc-spacer\" />\n <button type=\"button\" className=\"dpc-refresh\" aria-label={t('view')} title={t('view')} disabled={busy} onClick={() => setReload((value) => value + 1)}>\n <IconRefreshOutline14 size={14} aria-hidden=\"true\" />\n </button>\n </div>\n\n {servers === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {servers !== null && servers.length === 0 && <p className=\"dpc-empty\">{t('emptyMcp')}</p>}\n {servers !== null && servers.length > 0 && (\n <ul className=\"dpc-cards\">\n {servers.map((row) => (\n <li className=\"dpc-card\" key={row.id}>\n <div className=\"dpc-cardTop\">\n <strong className=\"dpc-cardTitle\" title={row.id}>{row.serverName}</strong>\n <span className=\"dpc-tag\">{row.transport}</span>\n <span className=\"dpc-tag\" data-kind={row.disabled ? 'off' : undefined}>{row.disabled ? t('disabled') : t('enabled')}</span>\n </div>\n <p className=\"dpc-cardDesc\">\n {row.transport === 'stdio' ? `${row.command ?? ''} ${(row.args ?? []).join(' ')}` : row.url ?? ''}\n </p>\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => void doToggle(row)}>{t('toggle')}</Button>\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => openEdit(row)}>{t('edit')}</Button>\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => setConfirmId(row.id)}>{t('delete')}</Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Modal\n open={editor !== null}\n onClose={() => setEditor(null)}\n title={editor !== null && editor.id !== '' ? t('editServer') : t('addServer')}\n >\n {editor !== null && (\n <div className=\"dpc-form\">\n <label className=\"dpc-label\">\n <span>{t('serverName')}</span>\n <input\n className=\"dpc-input\"\n value={editor.serverName}\n disabled={editor.id !== ''}\n onChange={(event) => setEditor({ ...editor, serverName: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('transport')}</span>\n <select\n className=\"dpc-select\"\n value={editor.transport}\n disabled={editor.id !== ''}\n onChange={(event) => setEditor({ ...editor, transport: event.target.value as EditorState['transport'] })}\n >\n <option value=\"stdio\">{t('transportStdio')}</option>\n <option value=\"streamable-http\">{t('transportHttp')}</option>\n </select>\n </label>\n {editor.transport === 'stdio' ? (\n <>\n <label className=\"dpc-label\">\n <span>{t('command')}</span>\n <input className=\"dpc-input\" value={editor.command} onChange={(event) => setEditor({ ...editor, command: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('args')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.args} onChange={(event) => setEditor({ ...editor, args: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('envPairs')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.env} onChange={(event) => setEditor({ ...editor, env: event.target.value })} />\n </label>\n </>\n ) : (\n <>\n <label className=\"dpc-label\">\n <span>{t('url')}</span>\n <input className=\"dpc-input\" value={editor.url} onChange={(event) => setEditor({ ...editor, url: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('headersPairs')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.headers} onChange={(event) => setEditor({ ...editor, headers: event.target.value })} />\n </label>\n </>\n )}\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setEditor(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doSave()}>{t('save')}</Button>\n </div>\n </div>\n )}\n </Modal>\n\n <Modal\n open={confirmId !== null}\n onClose={() => setConfirmId(null)}\n title={t('confirmRemove')}\n description={confirmId ?? undefined}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setConfirmId(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doRemove()}>{t('delete')}</Button>\n </>\n }\n >\n <p>{t('removeWarn')}</p>\n </Modal>\n\n <Modal\n open={restartConfirm}\n onClose={() => setRestartConfirm(false)}\n title={t('restartConfirmTitle')}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setRestartConfirm(false)}>{t('cancel')}</Button>\n <Button variant=\"primary\" onClick={doRestart}>{t('restartNow')}</Button>\n </>\n }\n >\n <p>{t('restartConfirmBody')}</p>\n </Modal>\n\n <Modal\n open={importOpen}\n onClose={() => setImportOpen(false)}\n title={t('importServers')}\n >\n <div className=\"dpc-form\">\n <p className=\"dpc-intro\" style={{ margin: 0 }}>{t('importIntro')}</p>\n {importItems === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {importItems !== null && importItems.length === 0 && <p className=\"dpc-empty\">{t('importEmpty')}</p>}\n {importItems !== null && importItems.length > 0 && (\n <ul className=\"dpc-cards\" style={{ gridTemplateColumns: 'minmax(0, 1fr)' }}>\n {importItems.map((item, index) => (\n <li className=\"dpc-card\" key={`${item.server.agent}/${item.server.name}`} style={{ opacity: item.existing ? 0.55 : 1 }}>\n <div className=\"dpc-cardTop\">\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, minWidth: 0, cursor: item.existing ? 'default' : 'pointer' }}>\n <input\n type=\"checkbox\"\n checked={item.checked}\n disabled={item.existing}\n onChange={(event) => {\n const next = importItems.slice()\n next[index] = { ...item, checked: event.target.checked }\n setImportItems(next)\n }}\n />\n <strong className=\"dpc-cardTitle\" title={item.server.name}>{item.server.name}</strong>\n </label>\n <span className=\"dpc-tag\" data-kind=\"source\">{item.server.agent === 'claude-code' ? 'Claude Code' : 'Codex'}</span>\n <span className=\"dpc-tag\">{item.server.transport}</span>\n {item.existing && <span className=\"dpc-tag\">{t('importExisting')}</span>}\n </div>\n <p className=\"dpc-cardDesc\">\n {item.server.transport === 'stdio'\n ? `${item.server.command ?? ''} ${(item.server.args ?? []).join(' ')}`\n : item.server.url ?? ''}\n </p>\n </li>\n ))}\n </ul>\n )}\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setImportOpen(false)}>{t('cancel')}</Button>\n <Button\n variant=\"primary\"\n disabled={busy || importItems === null || !importItems.some(item => item.checked && !item.existing)}\n onClick={() => void doImport()}\n >\n {t('importSelected')}\n </Button>\n </div>\n </div>\n </Modal>\n </div>\n )\n}\n", "/** Shared scoped stylesheet for the capabilities tabs \u2014 rides the host's\n * --dsw-* tokens (same design language as the plugin-inventory and install\n * tabs) so light and dark themes both stay correct. Prefix: dpc-. */\n\nexport const CSS = `\n.dpc-section{display:flex;flex-direction:column;gap:14px;width:100%;max-width:760px;color:var(--dsw-alias-label-primary)}\n.dpc-head{display:flex;align-items:center;gap:8px}\n.dpc-head h3{margin:0;font-size:13px;line-height:20px;font-weight:600}\n.dpc-head>svg{flex:none;color:var(--dsw-alias-label-tertiary)}\n.dpc-intro{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}\n.dpc-listHead{display:flex;align-items:baseline;gap:7px;padding:0 2px;margin-top:2px}\n.dpc-listHead h3{margin:0;font-size:13px;line-height:20px;font-weight:600}\n.dpc-count{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums}\n.dpc-spacer{flex:1}\n.dpc-refresh{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer}\n.dpc-refresh:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dpc-refresh:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}\n.dpc-empty{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}\n.dpc-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch;gap:10px;margin:0;padding:0;list-style:none}\n.dpc-card{display:flex;flex-direction:column;gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-3);padding:12px 14px}\n.dpc-card:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dpc-cardTop{display:flex;align-items:center;gap:8px}\n.dpc-cardTitle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px;font-weight:600;font-family:var(--ds-font-family-code)}\n.dpc-cardDesc{margin:0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n.dpc-cardRow{display:flex;align-items:center;gap:6px;flex-wrap:wrap}\n.dpc-tag{display:inline-flex;align-items:center;min-height:20px;border-radius:5px;padding:1px 6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font-size:11px;line-height:16px;white-space:nowrap}\n.dpc-tag[data-kind='source']{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}\n.dpc-tag[data-kind='off']{background:color-mix(in srgb,var(--dsw-alias-state-warning-primary,var(--dsw-alias-label-tertiary)) 12%,transparent);color:var(--dsw-alias-label-secondary)}\n.dpc-cardActions{display:flex;align-items:center;gap:6px;margin-left:auto}\n.dpc-banner{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px 12px;background:var(--dsw-alias-bg-layer-3);font-size:13px;line-height:20px}\n.dpc-banner[data-kind='ok']{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent)}\n.dpc-banner[data-kind='error']{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent)}\n.dpc-banner[data-kind='info']{border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 8%,transparent)}\n.dpc-bannerBody{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}\n.dpc-bannerHint{display:flex;align-items:center;gap:8px;flex-wrap:wrap;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}\n.dpc-form{display:flex;flex-direction:column;gap:10px}\n.dpc-label{display:flex;flex-direction:column;gap:4px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.dpc-label>span:first-child{color:var(--dsw-alias-label-tertiary)}\n.dpc-input,.dpc-textarea,.dpc-select{width:100%;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:7px 10px;outline:none;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}\n.dpc-textarea{min-height:120px;resize:vertical;font-family:var(--ds-font-family-code);line-height:1.5}\n.dpc-textarea[data-short='true']{min-height:64px}\n.dpc-input:focus-visible,.dpc-textarea:focus-visible,.dpc-select:focus-visible{border-color:var(--dsw-alias-state-business-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--dsw-alias-state-business-primary) 18%,transparent)}\n.dpc-checks{display:flex;gap:16px;font-size:13px;line-height:20px}\n.dpc-checks label{display:inline-flex;align-items:center;gap:6px;cursor:pointer}\n.dpc-formError{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}\n@media(max-width:680px){.dpc-cards{grid-template-columns:minmax(0,1fr)}}\n`\n", "/** Settings \u2192 Plugins \u201C\u6280\u80FD/Skills\u201D tab: view the discovered catalog, edit the\n * user-owned root. Pure presentation-layer \u2014 data arrives through props. */\n\nimport { useEffect, useState } from 'react'\nimport type { ReactElement } from 'react'\nimport { Button, IconRefreshOutline14, IconSkillOutline16, Modal, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { CSS } from './css.ts'\nimport type { Translate } from './index.ts'\n\n/** One skill as the host reports it (plus the editable flag the route adds). */\nexport interface SkillRowView {\n name: string\n description: string\n whenToUse?: string\n invocation: { modelInvocable: boolean; userInvocable: boolean }\n source: string\n provider: string\n editable: boolean\n}\n\nexport interface SkillsInjected {\n list(): Promise<{ skills: SkillRowView[] }>\n get(name: string): Promise<{ content: string }>\n save(input: { name: string; description: string; whenToUse?: string; modelInvocable: boolean; userInvocable: boolean; content: string }): Promise<{ ok: boolean }>\n remove(name: string): Promise<{ ok: boolean }>\n}\n\n/** Editor dialog state; null when closed. */\ninterface EditorState {\n mode: 'create' | 'edit' | 'view'\n name: string\n description: string\n whenToUse: string\n modelInvocable: boolean\n userInvocable: boolean\n content: string\n}\n\nconst SOURCE_KEYS: Record<string, string> = {\n 'project-dsh': 'sourceProjectDsh',\n 'project-agents': 'sourceProjectAgents',\n 'user-dsh': 'sourceUserDsh',\n 'user-agents': 'sourceUserAgents',\n runtime: 'sourceRuntime',\n bundled: 'sourceBundled',\n custom: 'sourceCustom',\n}\n\nexport function SkillsTab(props: { t: Translate; injected: SkillsInjected }): ReactElement {\n const { t, injected } = props\n const [skills, setSkills] = useState<SkillRowView[] | null>(null)\n const [editor, setEditor] = useState<EditorState | null>(null)\n const [confirmName, setConfirmName] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n const [outcome, setOutcome] = useState<{ ok: boolean; text: string } | null>(null)\n const [formError, setFormError] = useState<string | null>(null)\n const [reload, setReload] = useState(0)\n\n useEffect(() => {\n let current = true\n void injected.list().then(\n (body) => { if (current) setSkills(body.skills) },\n (error: Error) => { if (current) { setSkills([]); setOutcome({ ok: false, text: `${t('failed')}: ${String(error.message ?? error)}` }) } },\n )\n return () => { current = false }\n }, [injected, reload, t])\n\n const openCreate = (): void => {\n setFormError(null)\n setEditor({ mode: 'create', name: '', description: '', whenToUse: '', modelInvocable: true, userInvocable: true, content: '' })\n }\n\n const openExisting = async (skill: SkillRowView): Promise<void> => {\n setBusy(true)\n setFormError(null)\n try {\n const body = await injected.get(skill.name)\n setEditor({\n mode: skill.editable ? 'edit' : 'view',\n name: skill.name,\n description: skill.description,\n whenToUse: skill.whenToUse ?? '',\n modelInvocable: skill.invocation.modelInvocable,\n userInvocable: skill.invocation.userInvocable,\n content: body.content,\n })\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n /**\n * After a write/delete, the watched directory takes a moment to invalidate\n * the catalog \u2014 poll until the change is visible (bounded), then stop.\n */\n const refreshUntil = (predicate: (skills: SkillRowView[]) => boolean, timeoutMs = 10_000): void => {\n const deadline = Date.now() + timeoutMs\n const tick = (): void => {\n if (Date.now() > deadline) return\n setTimeout(() => {\n void injected.list().then(\n (body) => {\n setSkills(body.skills)\n if (!predicate(body.skills)) tick()\n },\n () => tick(),\n )\n }, 1000)\n }\n tick()\n }\n\n const doSave = async (): Promise<void> => {\n if (editor === null) return\n setBusy(true)\n setFormError(null)\n try {\n const name = editor.name.trim()\n await injected.save({\n name,\n description: editor.description,\n whenToUse: editor.whenToUse.trim() === '' ? undefined : editor.whenToUse,\n modelInvocable: editor.modelInvocable,\n userInvocable: editor.userInvocable,\n content: editor.content,\n })\n setOutcome({ ok: true, text: t('saved') })\n setEditor(null)\n refreshUntil(skills => skills.some(skill => skill.name === name))\n } catch (error) {\n setFormError(String(error instanceof Error ? error.message : error))\n } finally {\n setBusy(false)\n }\n }\n\n const doDelete = async (): Promise<void> => {\n if (confirmName === null) return\n const name = confirmName\n setBusy(true)\n try {\n await injected.remove(name)\n setOutcome({ ok: true, text: t('saved') })\n refreshUntil(skills => !skills.some(skill => skill.name === name))\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n setConfirmName(null)\n }\n }\n\n const readOnly = editor?.mode === 'view'\n\n return (\n <div className=\"dpc-section\">\n <style>{CSS}</style>\n\n <div className=\"dpc-head\">\n <IconSkillOutline16 aria-hidden=\"true\" />\n <h3>{t('skillsTitle')}</h3>\n <span className=\"dpc-spacer\" />\n <Button variant=\"primary\" size=\"sm\" onClick={openCreate}>{t('newSkill')}</Button>\n </div>\n <p className=\"dpc-intro\">{t('skillsIntro')}</p>\n\n {outcome !== null && (\n <div className=\"dpc-banner\" data-kind={outcome.ok ? 'ok' : 'error'} role=\"status\">\n <StateDot state={outcome.ok ? 'done' : 'error'} size={10} />\n <div className=\"dpc-bannerBody\"><span>{outcome.text}</span></div>\n </div>\n )}\n\n <div className=\"dpc-listHead\">\n <h3>{t('skillsTab')}</h3>\n {skills !== null && <span className=\"dpc-count\">{skills.length}</span>}\n <span className=\"dpc-spacer\" />\n <button type=\"button\" className=\"dpc-refresh\" aria-label={t('view')} title={t('view')} disabled={busy} onClick={() => setReload((value) => value + 1)}>\n <IconRefreshOutline14 size={14} aria-hidden=\"true\" />\n </button>\n </div>\n\n {skills === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {skills !== null && skills.length === 0 && <p className=\"dpc-empty\">{t('emptySkills')}</p>}\n {skills !== null && skills.length > 0 && (\n <ul className=\"dpc-cards\">\n {skills.map((skill) => (\n <li className=\"dpc-card\" key={`${skill.source}/${skill.name}`}>\n <div className=\"dpc-cardTop\">\n <strong className=\"dpc-cardTitle\" title={skill.name}>{skill.name}</strong>\n <span className=\"dpc-tag\" data-kind=\"source\">{t(SOURCE_KEYS[skill.source] ?? 'sourceCustom')}</span>\n </div>\n <p className=\"dpc-cardDesc\" title={skill.description}>{skill.description}</p>\n <div className=\"dpc-cardRow\">\n {!skill.invocation.modelInvocable && <span className=\"dpc-tag\">\u2699</span>}\n {!skill.invocation.userInvocable && <span className=\"dpc-tag\">/</span>}\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => void openExisting(skill)}>\n {skill.editable ? t('edit') : t('view')}\n </Button>\n {skill.editable && (\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => setConfirmName(skill.name)}>{t('delete')}</Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Modal\n open={editor !== null}\n onClose={() => setEditor(null)}\n title={editor === null ? '' : editor.mode === 'create' ? t('newSkill') : editor.mode === 'edit' ? t('editSkill') : t('viewSkill')}\n >\n {editor !== null && (\n <div className=\"dpc-form\">\n <label className=\"dpc-label\">\n <span>{t('skillName')}</span>\n <input\n className=\"dpc-input\"\n value={editor.name}\n disabled={readOnly || editor.mode === 'edit'}\n onChange={(event) => setEditor({ ...editor, name: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('skillDescription')}</span>\n <input\n className=\"dpc-input\"\n value={editor.description}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, description: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('skillWhenToUse')}</span>\n <input\n className=\"dpc-input\"\n value={editor.whenToUse}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, whenToUse: event.target.value })}\n />\n </label>\n <div className=\"dpc-checks\">\n <label>\n <input\n type=\"checkbox\"\n checked={editor.modelInvocable}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, modelInvocable: event.target.checked })}\n />\n {t('modelInvocable')}\n </label>\n <label>\n <input\n type=\"checkbox\"\n checked={editor.userInvocable}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, userInvocable: event.target.checked })}\n />\n {t('userInvocable')}\n </label>\n </div>\n <label className=\"dpc-label\">\n <span>{t('skillContent')}</span>\n <textarea\n className=\"dpc-textarea\"\n value={editor.content}\n readOnly={readOnly}\n onChange={(event) => setEditor({ ...editor, content: event.target.value })}\n />\n </label>\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setEditor(null)}>{readOnly ? t('close') : t('cancel')}</Button>\n {!readOnly && <Button variant=\"primary\" disabled={busy} onClick={() => void doSave()}>{t('save')}</Button>}\n </div>\n </div>\n )}\n </Modal>\n\n <Modal\n open={confirmName !== null}\n onClose={() => setConfirmName(null)}\n title={t('confirmDelete')}\n description={confirmName ?? undefined}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setConfirmName(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doDelete()}>{t('delete')}</Button>\n </>\n }\n >\n <p>{t('deleteWarn')}</p>\n </Modal>\n </div>\n )\n}\n", "/** zh/en dictionaries for the Settings capabilities tabs. */\n\nexport const zh = {\n skillsTab: '\u6280\u80FD',\n mcpTab: 'MCP',\n skillsTitle: '\u6280\u80FD\u7BA1\u7406',\n skillsIntro: '\u67E5\u770B\u4E0E\u7F16\u8F91 dsh \u53D1\u73B0\u7684\u6280\u80FD\uFF1B\u7528\u6237\u7EA7\u6280\u80FD\uFF08DSH_HOME/skills\uFF09\u53EF\u5728\u6B64\u65B0\u5EFA\u3001\u4FEE\u6539\u3001\u5220\u9664\uFF0C\u6587\u4EF6\u88AB\u76D1\u542C\uFF0C\u4FDD\u5B58\u5373\u751F\u6548\u3002\u82E5\u5B58\u5728 ~/.claude/skills \u6216 ~/.codex/skills\uFF0C\u4F1A\u81EA\u52A8\u7EB3\u5165\u626B\u63CF\uFF08\u96F6\u62F7\u8D1D\u3001\u5B9E\u65F6\u540C\u6B65\uFF09\u3002',\n newSkill: '\u65B0\u5EFA\u6280\u80FD',\n editSkill: '\u7F16\u8F91\u6280\u80FD',\n viewSkill: '\u67E5\u770B\u6280\u80FD',\n skillName: '\u540D\u79F0\uFF08kebab-case\uFF09',\n skillDescription: '\u63CF\u8FF0',\n skillWhenToUse: '\u4F7F\u7528\u65F6\u673A\uFF08\u53EF\u9009\uFF09',\n skillContent: '\u6B63\u6587\uFF08Markdown\uFF09',\n modelInvocable: '\u5141\u8BB8\u6A21\u578B\u8C03\u7528',\n userInvocable: '\u5141\u8BB8\u7528\u6237 / \u8C03\u7528',\n save: '\u4FDD\u5B58',\n cancel: '\u53D6\u6D88',\n delete: '\u5220\u9664',\n edit: '\u7F16\u8F91',\n view: '\u67E5\u770B',\n close: '\u5173\u95ED',\n emptySkills: '\u8FD8\u6CA1\u6709\u53D1\u73B0\u4EFB\u4F55\u6280\u80FD',\n loading: '\u8F7D\u5165\u4E2D\u2026',\n source: '\u6765\u6E90',\n sourceProjectDsh: '\u9879\u76EE',\n sourceProjectAgents: '\u9879\u76EE',\n sourceUserDsh: '\u7528\u6237',\n sourceUserAgents: '\u7528\u6237',\n sourceRuntime: '\u8FD0\u884C\u65F6',\n sourceBundled: '\u5185\u7F6E',\n sourceCustom: '\u81EA\u5B9A\u4E49',\n readOnly: '\u53EA\u8BFB',\n confirmDelete: '\u786E\u8BA4\u5220\u9664\u6280\u80FD\uFF1F',\n deleteWarn: '\u5C06\u5220\u9664 DSH_HOME/skills \u4E0B\u7684\u6574\u4E2A\u6280\u80FD\u76EE\u5F55\uFF0C\u6B64\u64CD\u4F5C\u4E0D\u53EF\u64A4\u9500\u3002',\n saved: '\u5DF2\u4FDD\u5B58\uFF0C\u6280\u80FD\u76EE\u5F55\u88AB\u76D1\u542C\uFF0C\u7A0D\u5019\u5373\u53EF\u5728\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u3002',\n mcpTitle: 'MCP \u670D\u52A1\u5668',\n mcpIntro: '\u7BA1\u7406 profile \u4E2D\u7684 MCP \u670D\u52A1\u5668\u884C\uFF08@deepseek-ai/dsh-mcp-client\uFF09\u3002\u65B0\u589E\u3001\u4FEE\u6539\u6216\u5220\u9664\u540E\u9700\u8981\u91CD\u542F dsh \u624D\u751F\u6548\u3002',\n addServer: '\u6DFB\u52A0\u670D\u52A1\u5668',\n editServer: '\u7F16\u8F91\u670D\u52A1\u5668',\n serverName: '\u670D\u52A1\u5668\u540D\uFF08\u5DE5\u5177\u540D\u524D\u7F00\uFF09',\n transport: '\u4F20\u8F93\u65B9\u5F0F',\n transportStdio: 'stdio\uFF08\u672C\u5730\u547D\u4EE4\uFF09',\n transportHttp: 'streamable-http\uFF08URL\uFF09',\n command: '\u547D\u4EE4',\n args: '\u53C2\u6570\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF09',\n envPairs: '\u73AF\u5883\u53D8\u91CF\uFF08\u6BCF\u884C KEY=VALUE\uFF09',\n url: 'URL',\n headersPairs: '\u8BF7\u6C42\u5934\uFF08\u6BCF\u884C KEY: VALUE\uFF09',\n disabled: '\u5DF2\u505C\u7528',\n enabled: '\u542F\u7528\u4E2D',\n toggle: '\u505C\u7528/\u542F\u7528',\n confirmRemove: '\u786E\u8BA4\u79FB\u9664\u8BE5\u670D\u52A1\u5668\uFF1F',\n removeWarn: '\u5C06\u4ECE profile \u914D\u7F6E\u4E2D\u79FB\u9664\u8FD9\u4E00\u884C\uFF0C\u91CD\u542F dsh \u540E\u5176\u5DE5\u5177\u4E0D\u518D\u51FA\u73B0\u3002',\n emptyMcp: '\u8FD8\u6CA1\u6709\u914D\u7F6E MCP \u670D\u52A1\u5668',\n importServers: '\u4ECE\u5176\u4ED6 Agent \u5BFC\u5165',\n importIntro: '\u626B\u63CF Claude Code\uFF08~/.claude.json\uFF09\u4E0E Codex\uFF08~/.codex/config.toml\uFF09\u7684 MCP \u670D\u52A1\u5668\u914D\u7F6E\uFF0C\u52FE\u9009\u540E\u5BFC\u5165\u4E3A\u672C profile \u7684\u670D\u52A1\u5668\u884C\u3002',\n importEmpty: '\u6CA1\u6709\u53D1\u73B0\u53EF\u5BFC\u5165\u7684 MCP \u670D\u52A1\u5668',\n importExisting: '\u5DF2\u5B58\u5728',\n importSelected: '\u5BFC\u5165\u9009\u4E2D\u9879',\n restartNeeded: '\u914D\u7F6E\u5DF2\u5199\u5165\uFF0C\u91CD\u542F dsh \u540E\u751F\u6548\u3002',\n restartDesktopHint: '\u91CD\u542F\u7531\u684C\u9762\u5E94\u7528\u8D1F\u8D23\uFF1A\u6258\u76D8\u83DC\u5355\u300C\u91CD\u542F\u670D\u52A1\u300D\u3002',\n restartOtherHint: '\u91CD\u542F\u65B9\u5F0F\uFF1A\u5173\u95ED\u5F53\u524D dsh \u8FDB\u7A0B\u540E\u91CD\u65B0\u8FD0\u884C\u3002',\n restartNow: '\u91CD\u542F\u670D\u52A1',\n restart: '\u91CD\u542F',\n restartConfirmTitle: '\u91CD\u542F dsh\uFF1F',\n restartConfirmBody: '\u91CD\u542F\u4F1A\u4E2D\u65AD\u6B63\u5728\u8FDB\u884C\u7684\u56DE\u5408\uFF0C\u672A\u4FDD\u5B58\u7684\u8F93\u5165\u53EF\u80FD\u4E22\u5931\uFF1BMCP \u884C\u7684\u53D8\u66F4\u5C06\u5728\u91CD\u542F\u540E\u751F\u6548\u3002',\n restarting: '\u6B63\u5728\u91CD\u542F\uFF0C\u6062\u590D\u540E\u5C06\u81EA\u52A8\u5237\u65B0\u9875\u9762\u2026',\n restartPortHint: '\u82E5\u91CD\u542F\u540E\u9875\u9762\u957F\u65F6\u95F4\u672A\u6062\u590D\uFF0C\u53EF\u80FD\u662F\u7AEF\u53E3\u5DF2\u53D8\u5316\uFF1A\u5728\u7EC8\u7AEF\u67E5\u770B\u65B0\u5730\u5740\u540E\u6253\u5F00\u3002',\n failed: '\u64CD\u4F5C\u5931\u8D25',\n}\n\nexport const en = {\n skillsTab: 'Skills',\n mcpTab: 'MCP',\n skillsTitle: 'Skills',\n skillsIntro: 'View and edit the skills dsh discovers; user-level skills (DSH_HOME/skills) can be created, edited, and deleted here \u2014 the directory is watched, saves apply without a restart. ~/.claude/skills and ~/.codex/skills are scanned too when present (zero-copy, live-synced).',\n newSkill: 'New skill',\n editSkill: 'Edit skill',\n viewSkill: 'View skill',\n skillName: 'Name (kebab-case)',\n skillDescription: 'Description',\n skillWhenToUse: 'When to use (optional)',\n skillContent: 'Body (Markdown)',\n modelInvocable: 'Model-invocable',\n userInvocable: 'User-invocable (/)',\n save: 'Save',\n cancel: 'Cancel',\n delete: 'Delete',\n edit: 'Edit',\n view: 'View',\n close: 'Close',\n emptySkills: 'No skills discovered yet',\n loading: 'Loading\u2026',\n source: 'Source',\n sourceProjectDsh: 'project',\n sourceProjectAgents: 'project',\n sourceUserDsh: 'user',\n sourceUserAgents: 'user',\n sourceRuntime: 'runtime',\n sourceBundled: 'bundled',\n sourceCustom: 'custom',\n readOnly: 'read-only',\n confirmDelete: 'Delete this skill?',\n deleteWarn: 'Removes the whole skill directory under DSH_HOME/skills. This cannot be undone.',\n saved: 'Saved. The skills directory is watched; the skill is usable in sessions shortly.',\n mcpTitle: 'MCP servers',\n mcpIntro: 'Manage the MCP server rows (@deepseek-ai/dsh-mcp-client) in this profile. Additions, edits, and removals take effect after a dsh restart.',\n addServer: 'Add server',\n editServer: 'Edit server',\n serverName: 'Server name (tool name prefix)',\n transport: 'Transport',\n transportStdio: 'stdio (local command)',\n transportHttp: 'streamable-http (URL)',\n command: 'Command',\n args: 'Arguments (one per line)',\n envPairs: 'Environment (KEY=VALUE per line)',\n url: 'URL',\n headersPairs: 'Headers (KEY: VALUE per line)',\n disabled: 'Disabled',\n enabled: 'Enabled',\n toggle: 'Enable/disable',\n confirmRemove: 'Remove this server?',\n removeWarn: 'Removes the row from the profile configuration; its tools disappear after the next dsh restart.',\n emptyMcp: 'No MCP servers configured yet',\n importServers: 'Import from other agents',\n importIntro: 'Scans Claude Code (~/.claude.json) and Codex (~/.codex/config.toml) MCP server configs; selected entries become server rows in this profile.',\n importEmpty: 'No importable MCP servers found',\n importExisting: 'already here',\n importSelected: 'Import selected',\n restartNeeded: 'Configuration written \u2014 restart dsh to apply.',\n restartDesktopHint: 'The desktop app owns restarts: use the tray \u201CRestart service\u201D.',\n restartOtherHint: 'Restart by closing this dsh process and running it again.',\n restartNow: 'Restart service',\n restart: 'Restart',\n restartConfirmTitle: 'Restart dsh?',\n restartConfirmBody: 'Restarting interrupts any running turn and may lose unsaved input; pending MCP changes apply after the restart.',\n restarting: 'Restarting \u2014 the page will reload once the host is back\u2026',\n restartPortHint: 'If the page does not recover, the port may have changed: check the terminal for the new URL.',\n failed: 'Operation failed',\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/** dsh-plugin-capabilities client entry: contributes the \u201C\u6280\u80FD/Skills\u201D and\n * \u201CMCP\u201D tabs into Settings \u2192 Plugins. Calls the host routes with fetch. */\n\nimport { createElement as h } from 'react'\nimport { McpTab, type McpInjected, type McpRow } from './McpTab.tsx'\nimport { SkillsTab, type SkillsInjected, type SkillRowView } from './SkillsTab.tsx'\nimport { zh, en } from './locales.ts'\n\n/** Locale dictionary namespace owned by this plugin. */\nexport const NS = 'settings.pluginCapabilities'\n\n/** The `t` function bound by the locale service. */\nexport interface Translate {\n (key: string): string\n}\n\n/** Minimal structural subset of the slots service. */\ninterface SlotsService {\n inject(slot: string, register: () => unknown): void\n register(meta: Record<string, unknown>, component: () => unknown): unknown\n}\n\n/** Minimal structural subset of the locale service. */\ninterface LocaleService {\n register(namespace: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\n bind(namespace: string): Translate\n}\n\n/** The client cordis context this plugin relies on (structural). */\ninterface CapabilitiesClientContext {\n effect(callback: () => unknown, label?: string): void\n locale: LocaleService\n slots: SlotsService\n}\n\n/** Same-origin fetch of the manager's host routes. */\nasync function fetchJson<T>(path: string, init?: RequestInit): Promise<T> {\n const response = await fetch(path, init)\n const body = (await response.json()) as T & { error?: string }\n if (!response.ok) throw new Error(body.error ?? `HTTP ${response.status}`)\n return body\n}\n\nconst post = (path: string, body: unknown): Promise<unknown> =>\n fetchJson(path, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) })\n\nexport const name = 'dsh-plugin-capabilities'\nexport const inject = ['slots', 'locale']\n\nexport interface SkillBody { content: string }\n\n/** One foreign-agent server from the import scan. */\nexport interface ImportedServerView {\n agent: 'claude-code' | 'codex'\n name: string\n transport: 'stdio' | 'streamable-http'\n command?: string\n args?: string[]\n env?: Record<string, string>\n url?: string\n headers?: Record<string, string>\n}\n\nexport function apply(ctx: CapabilitiesClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-plugin-capabilities: dictionaries')\n const t = ctx.locale.bind(NS)\n\n const skillsInjected: SkillsInjected = {\n list: () => fetchJson<{ skills: SkillRowView[] }>('/dsh-plugin-capabilities/skills'),\n get: (name: string) => fetchJson<SkillBody>(`/dsh-plugin-capabilities/skill?name=${encodeURIComponent(name)}`),\n save: (input: unknown) => post('/dsh-plugin-capabilities/skill/save', input) as Promise<{ ok: boolean }>,\n remove: (name: string) => post('/dsh-plugin-capabilities/skill/delete', { name }) as Promise<{ ok: boolean }>,\n }\n\n const mcpInjected: McpInjected = {\n list: () => fetchJson<{ servers: McpRow[] }>('/dsh-plugin-capabilities/mcp'),\n save: (input: unknown) => post('/dsh-plugin-capabilities/mcp/save', input) as Promise<{ ok: boolean; id: string }>,\n toggle: (id: string, disabled: boolean) => post('/dsh-plugin-capabilities/mcp/toggle', { id, disabled }) as Promise<{ ok: boolean }>,\n remove: (id: string) => post('/dsh-plugin-capabilities/mcp/remove', { id }) as Promise<{ ok: boolean }>,\n scanImport: () => fetchJson<{ servers: ImportedServerView[]; existing: string[] }>('/dsh-plugin-capabilities/import/scan'),\n applyImport: (items: Array<{ agent: string; name: string }>) =>\n post('/dsh-plugin-capabilities/import/apply', { items }) as Promise<{ ok: boolean; results: Array<{ name: string; ok: boolean; error?: string }> }>,\n restart: async (): Promise<void> => {\n if (window.dshDesktop !== undefined) {\n window.dshDesktop.restartSidecar?.()\n return\n }\n // \u72EC\u7ACB dsh web\uFF1A\u81EA\u91CD\u542F\u8DEF\u7531\u3002\u8FDE\u63A5\u5728\u5173\u505C\u9014\u4E2D\u65AD\u5F00\u5C5E\u9884\u671F\uFF0C\u4E0D\u7B97\u5931\u8D25\u3002\n try { await post('/dsh-plugin-capabilities/restart', {}) } catch { /* dying mid-restart is expected */ }\n },\n desktop: window.dshDesktop !== undefined,\n }\n\n ctx.slots.inject('settings.plugins.tab', () => {\n return ctx.slots.register({\n name: 'settings.plugins.tab',\n id: 'capabilities-skills',\n order: 30,\n label: () => t('skillsTab'),\n locale: NS,\n inject: () => skillsInjected,\n }, () => h(SkillsTab, { t, injected: skillsInjected }))\n })\n\n ctx.slots.inject('settings.plugins.tab', () => {\n return ctx.slots.register({\n name: 'settings.plugins.tab',\n id: 'capabilities-mcp',\n order: 40,\n label: () => t('mcpTab'),\n locale: NS,\n inject: () => mcpInjected,\n }, () => h(McpTab, { t, injected: mcpInjected }))\n })\n}\n", "/** Settings \u2192 Plugins \u201CMCP\u201D tab: manage the profile's mcp-client rows.\n * Mutations rewrite the profile patch and need a dsh restart \u2014 the banner\n * hands the restart to the desktop shell when one is present. */\n\nimport { useEffect, useState } from 'react'\nimport type { ReactElement } from 'react'\nimport { Button, IconApiOutline14, IconRefreshOutline14, Modal, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { CSS } from './css.ts'\nimport type { ImportedServerView, Translate } from './index.ts'\n\nexport interface McpRow {\n id: string\n serverName: string\n transport: 'stdio' | 'streamable-http'\n disabled: boolean\n command?: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n url?: string\n headers?: Record<string, string>\n}\n\nexport interface McpInjected {\n list(): Promise<{ servers: McpRow[] }>\n save(input: Record<string, unknown>): Promise<{ ok: boolean; id: string }>\n toggle(id: string, disabled: boolean): Promise<{ ok: boolean }>\n remove(id: string): Promise<{ ok: boolean }>\n scanImport(): Promise<{ servers: ImportedServerView[]; existing: string[] }>\n applyImport(items: Array<{ agent: string; name: string }>): Promise<{ ok: boolean; results: Array<{ name: string; ok: boolean; error?: string }> }>\n restart(): Promise<void>\n desktop: boolean\n}\n\n/** Editor dialog state; null when closed. Textareas hold line-based values. */\ninterface EditorState {\n id: string\n serverName: string\n transport: 'stdio' | 'streamable-http'\n command: string\n args: string\n env: string\n url: string\n headers: string\n}\n\n/** One import entry together with its index in the flat state array \u2014\n * checkbox handlers rewrite the flat array, so indices must survive grouping. */\ntype ImportItem = { server: ImportedServerView; existing: boolean; checked: boolean }\n\n/** Group import candidates by source agent, known agents first. */\nexport function importGroups(items: ImportItem[]): Array<{ agent: string; label: string; items: Array<{ item: ImportItem; index: number }> }> {\n const label = (agent: string) => agent === 'claude-code' ? 'Claude Code' : agent === 'codex' ? 'Codex' : agent\n const order = ['claude-code', 'codex']\n const agents = [...new Set(items.map(item => item.server.agent))]\n .sort((a, b) => {\n const rank = (agent: string) => { const at = order.indexOf(agent); return at === -1 ? order.length : at }\n return rank(a) - rank(b) || a.localeCompare(b)\n })\n return agents.map(agent => ({\n agent,\n label: label(agent),\n items: items.map((item, index) => ({ item, index })).filter(({ item }) => item.server.agent === agent),\n }))\n}\n\n/** KEY=VALUE / KEY: VALUE lines to a map. */\nfunction parsePairs(text: string, separator: ':' | '='): Record<string, string> {\n const map: Record<string, string> = {}\n for (const line of text.split(/\\r?\\n/)) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('#')) continue\n const at = trimmed.indexOf(separator)\n if (at <= 0) continue\n map[trimmed.slice(0, at).trim()] = trimmed.slice(at + 1).trim()\n }\n return map\n}\n\nfunction mapToPairs(map: Record<string, string> | undefined, separator: string): string {\n if (map === undefined) return ''\n return Object.entries(map).map(([key, value]) => `${key}${separator}${value.includes('\\n') ? JSON.stringify(value) : value}`).join('\\n')\n}\n\nexport function McpTab(props: { t: Translate; injected: McpInjected }): ReactElement {\n const { t, injected } = props\n const [servers, setServers] = useState<McpRow[] | null>(null)\n const [editor, setEditor] = useState<EditorState | null>(null)\n const [confirmId, setConfirmId] = useState<string | null>(null)\n const [importOpen, setImportOpen] = useState(false)\n const [importItems, setImportItems] = useState<Array<{ server: ImportedServerView; existing: boolean; checked: boolean }> | null>(null)\n const [busy, setBusy] = useState(false)\n const [pending, setPending] = useState(false)\n const [restartConfirm, setRestartConfirm] = useState(false)\n const [restarting, setRestarting] = useState(false)\n const [outcome, setOutcome] = useState<{ ok: boolean; text: string } | null>(null)\n const [formError, setFormError] = useState<string | null>(null)\n const [reload, setReload] = useState(0)\n\n const openImport = async (): Promise<void> => {\n setImportOpen(true)\n setImportItems(null)\n try {\n const body = await injected.scanImport()\n const existing = new Set(body.existing)\n setImportItems(body.servers.map(server => ({\n server,\n existing: existing.has(server.name),\n checked: !existing.has(server.name),\n })))\n } catch (error) {\n setImportItems([])\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n }\n }\n\n const doImport = async (): Promise<void> => {\n if (importItems === null) return\n const items = importItems.filter(item => item.checked && !item.existing).map(item => ({ agent: item.server.agent, name: item.server.name }))\n setBusy(true)\n try {\n const body = await injected.applyImport(items)\n const failed = body.results.filter(item => !item.ok)\n setOutcome(failed.length === 0\n ? { ok: true, text: t('restartNeeded') }\n : { ok: false, text: `${t('failed')}: ${failed.map(item => `${item.name} (${item.error})`).join(', ')}` })\n setImportOpen(false)\n setPending(true)\n setReload((value) => value + 1)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n const reloadList = (showPending: boolean): void => {\n setReload((value) => value + 1)\n if (showPending) setPending(true)\n }\n\n useEffect(() => {\n let current = true\n void injected.list().then(\n (body) => { if (current) setServers(body.servers) },\n (error: Error) => { if (current) { setServers([]); setOutcome({ ok: false, text: `${t('failed')}: ${String(error.message ?? error)}` }) } },\n )\n return () => { current = false }\n }, [injected, reload, t])\n\n const openCreate = (): void => {\n setFormError(null)\n setEditor({ id: '', serverName: '', transport: 'stdio', command: '', args: '', env: '', url: '', headers: '' })\n }\n\n const openEdit = (row: McpRow): void => {\n setFormError(null)\n setEditor({\n id: row.id,\n serverName: row.serverName,\n transport: row.transport,\n command: row.command ?? '',\n args: (row.args ?? []).join('\\n'),\n env: mapToPairs(row.env, '='),\n url: row.url ?? '',\n headers: mapToPairs(row.headers, ':'),\n })\n }\n\n const doSave = async (): Promise<void> => {\n if (editor === null) return\n setBusy(true)\n setFormError(null)\n try {\n await injected.save({\n id: editor.id,\n serverName: editor.serverName.trim(),\n transport: editor.transport,\n ...(editor.transport === 'stdio'\n ? {\n command: editor.command.trim(),\n args: editor.args.split(/\\r?\\n/).map(line => line.trim()).filter(line => line !== ''),\n env: parsePairs(editor.env, '='),\n }\n : {\n url: editor.url.trim(),\n headers: parsePairs(editor.headers, ':'),\n }),\n })\n setEditor(null)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setFormError(String(error instanceof Error ? error.message : error))\n } finally {\n setBusy(false)\n }\n }\n\n const doToggle = async (row: McpRow): Promise<void> => {\n setBusy(true)\n try {\n await injected.toggle(row.id, !row.disabled)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n const doRemove = async (): Promise<void> => {\n if (confirmId === null) return\n setBusy(true)\n try {\n await injected.remove(confirmId)\n setOutcome({ ok: true, text: t('restartNeeded') })\n reloadList(true)\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n setConfirmId(null)\n }\n }\n\n const doRestart = (): void => {\n setRestartConfirm(false)\n setRestarting(true)\n void injected.restart()\n // \u684C\u9762\u6A21\u5F0F\uFF1A\u58F3\u5C42\u91CD\u542F\u5B8C\u6210\u540E\u4F1A\u91CD\u8F7D\u7A97\u53E3\u3002\u72EC\u7ACB\u6A21\u5F0F\uFF1A\u8F6E\u8BE2\u672C\u6E90\uFF0C\u6062\u590D\u5373\u5237\u65B0\u3002\n if (injected.desktop) return\n const deadline = Date.now() + 60_000\n const poll = (): void => {\n if (Date.now() > deadline) return\n window.setTimeout(() => {\n void injected.list().then(\n () => { window.location.reload() },\n () => { poll() },\n )\n }, 1500)\n }\n window.setTimeout(poll, 3000)\n }\n\n const restartBanner = (\n <div className=\"dpc-banner\" data-kind=\"info\" role=\"status\">\n <StateDot state=\"ongoing\" size={10} />\n <div className=\"dpc-bannerBody\">\n <span>{restarting ? t('restarting') : t('restartNeeded')}</span>\n <span className=\"dpc-bannerHint\">\n {restarting\n ? (!injected.desktop && t('restartPortHint'))\n : injected.desktop\n ? <>{t('restartDesktopHint')}{' '}<Button variant=\"outline\" size=\"sm\" onClick={() => setRestartConfirm(true)}>{t('restartNow')}</Button></>\n : t('restartOtherHint')}\n </span>\n </div>\n </div>\n )\n\n return (\n <div className=\"dpc-section\">\n <style>{CSS}</style>\n\n <div className=\"dpc-head\">\n <IconApiOutline14 aria-hidden=\"true\" />\n <h3>{t('mcpTitle')}</h3>\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={restarting} onClick={() => setRestartConfirm(true)}>{t('restart')}</Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void openImport()}>{t('importServers')}</Button>\n <Button variant=\"primary\" size=\"sm\" onClick={openCreate}>{t('addServer')}</Button>\n </div>\n <p className=\"dpc-intro\">{t('mcpIntro')}</p>\n\n {outcome !== null && (\n <div className=\"dpc-banner\" data-kind={outcome.ok ? 'ok' : 'error'} role=\"status\">\n <StateDot state={outcome.ok ? 'done' : 'error'} size={10} />\n <div className=\"dpc-bannerBody\"><span>{outcome.text}</span></div>\n </div>\n )}\n {(pending || restarting) && restartBanner}\n\n <div className=\"dpc-listHead\">\n <h3>{t('mcpTab')}</h3>\n {servers !== null && <span className=\"dpc-count\">{servers.length}</span>}\n <span className=\"dpc-spacer\" />\n <button type=\"button\" className=\"dpc-refresh\" aria-label={t('view')} title={t('view')} disabled={busy} onClick={() => setReload((value) => value + 1)}>\n <IconRefreshOutline14 size={14} aria-hidden=\"true\" />\n </button>\n </div>\n\n {servers === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {servers !== null && servers.length === 0 && <p className=\"dpc-empty\">{t('emptyMcp')}</p>}\n {servers !== null && servers.length > 0 && (\n <ul className=\"dpc-cards\">\n {servers.map((row) => (\n <li className=\"dpc-card\" key={row.id}>\n <div className=\"dpc-cardTop\">\n <strong className=\"dpc-cardTitle\" title={row.id}>{row.serverName}</strong>\n <span className=\"dpc-tag\">{row.transport}</span>\n <span className=\"dpc-tag\" data-kind={row.disabled ? 'off' : undefined}>{row.disabled ? t('disabled') : t('enabled')}</span>\n </div>\n <p className=\"dpc-cardDesc\">\n {row.transport === 'stdio' ? `${row.command ?? ''} ${(row.args ?? []).join(' ')}` : row.url ?? ''}\n </p>\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => void doToggle(row)}>{t('toggle')}</Button>\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => openEdit(row)}>{t('edit')}</Button>\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => setConfirmId(row.id)}>{t('delete')}</Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Modal\n open={editor !== null}\n onClose={() => setEditor(null)}\n title={editor !== null && editor.id !== '' ? t('editServer') : t('addServer')}\n >\n {editor !== null && (\n <div className=\"dpc-form\">\n <label className=\"dpc-label\">\n <span>{t('serverName')}</span>\n <input\n className=\"dpc-input\"\n value={editor.serverName}\n disabled={editor.id !== ''}\n onChange={(event) => setEditor({ ...editor, serverName: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('transport')}</span>\n <select\n className=\"dpc-select\"\n value={editor.transport}\n disabled={editor.id !== ''}\n onChange={(event) => setEditor({ ...editor, transport: event.target.value as EditorState['transport'] })}\n >\n <option value=\"stdio\">{t('transportStdio')}</option>\n <option value=\"streamable-http\">{t('transportHttp')}</option>\n </select>\n </label>\n {editor.transport === 'stdio' ? (\n <>\n <label className=\"dpc-label\">\n <span>{t('command')}</span>\n <input className=\"dpc-input\" value={editor.command} onChange={(event) => setEditor({ ...editor, command: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('args')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.args} onChange={(event) => setEditor({ ...editor, args: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('envPairs')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.env} onChange={(event) => setEditor({ ...editor, env: event.target.value })} />\n </label>\n </>\n ) : (\n <>\n <label className=\"dpc-label\">\n <span>{t('url')}</span>\n <input className=\"dpc-input\" value={editor.url} onChange={(event) => setEditor({ ...editor, url: event.target.value })} />\n </label>\n <label className=\"dpc-label\">\n <span>{t('headersPairs')}</span>\n <textarea className=\"dpc-textarea\" data-short=\"true\" value={editor.headers} onChange={(event) => setEditor({ ...editor, headers: event.target.value })} />\n </label>\n </>\n )}\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setEditor(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doSave()}>{t('save')}</Button>\n </div>\n </div>\n )}\n </Modal>\n\n <Modal\n open={confirmId !== null}\n onClose={() => setConfirmId(null)}\n title={t('confirmRemove')}\n description={confirmId ?? undefined}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setConfirmId(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doRemove()}>{t('delete')}</Button>\n </>\n }\n >\n <p>{t('removeWarn')}</p>\n </Modal>\n\n <Modal\n open={restartConfirm}\n onClose={() => setRestartConfirm(false)}\n title={t('restartConfirmTitle')}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setRestartConfirm(false)}>{t('cancel')}</Button>\n <Button variant=\"primary\" onClick={doRestart}>{t('restartNow')}</Button>\n </>\n }\n >\n <p>{t('restartConfirmBody')}</p>\n </Modal>\n\n <Modal\n open={importOpen}\n onClose={() => setImportOpen(false)}\n title={t('importServers')}\n className=\"dpc-modalWide\"\n >\n <div className=\"dpc-form\">\n <p className=\"dpc-intro\" style={{ margin: 0 }}>{t('importIntro')}</p>\n {importItems === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {importItems !== null && importItems.length === 0 && <p className=\"dpc-empty\">{t('importEmpty')}</p>}\n {importItems !== null && importItems.length > 0 && (\n <div className=\"dpc-importScroll\">\n {importGroups(importItems).map(group => {\n const selectable = group.items\n .filter(({ item }) => !item.existing)\n .map(({ index }) => index)\n const allChecked = selectable.length > 0\n && selectable.every(index => importItems[index].checked)\n return (\n <section className=\"dpc-importGroup\" key={group.agent}>\n <div className=\"dpc-importHead\">\n <span className=\"dpc-tag\" data-kind=\"source\">{group.label}</span>\n <span className=\"dpc-importCount\">{group.items.length}</span>\n {selectable.length > 0 && (\n <label className=\"dpc-importAll\">\n <input\n type=\"checkbox\"\n checked={allChecked}\n onChange={(event) => {\n const next = importItems.slice()\n for (const index of selectable) next[index] = { ...next[index], checked: event.target.checked }\n setImportItems(next)\n }}\n />\n {t('importSelectAll')}\n </label>\n )}\n </div>\n <ul className=\"dpc-cards\" style={{ gridTemplateColumns: 'minmax(0, 1fr)' }}>\n {group.items.map(({ item, index }) => {\n const command = item.server.transport === 'stdio'\n ? `${item.server.command ?? ''} ${(item.server.args ?? []).join(' ')}`.trim()\n : item.server.url ?? ''\n return (\n <li className=\"dpc-card\" key={`${item.server.agent}/${item.server.name}`} style={{ opacity: item.existing ? 0.55 : 1 }}>\n <div className=\"dpc-cardTop\">\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, minWidth: 0, cursor: item.existing ? 'default' : 'pointer' }}>\n <input\n type=\"checkbox\"\n checked={item.checked}\n disabled={item.existing}\n onChange={(event) => {\n const next = importItems.slice()\n next[index] = { ...item, checked: event.target.checked }\n setImportItems(next)\n }}\n />\n <strong className=\"dpc-cardTitle\" title={item.server.name}>{item.server.name}</strong>\n </label>\n <span className=\"dpc-tag\">{item.server.transport}</span>\n {item.existing && <span className=\"dpc-tag\">{t('importExisting')}</span>}\n </div>\n <p className=\"dpc-cardDesc\" title={command}>{command}</p>\n </li>\n )\n })}\n </ul>\n </section>\n )\n })}\n </div>\n )}\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setImportOpen(false)}>{t('cancel')}</Button>\n <Button\n variant=\"primary\"\n disabled={busy || importItems === null || !importItems.some(item => item.checked && !item.existing)}\n onClick={() => void doImport()}\n >\n {t('importSelected')}\n </Button>\n </div>\n </div>\n </Modal>\n </div>\n )\n}\n", "/** Shared scoped stylesheet for the capabilities tabs \u2014 rides the host's\n * --dsw-* tokens (same design language as the plugin-inventory and install\n * tabs) so light and dark themes both stay correct. Prefix: dpc-. */\n\nexport const CSS = `\n.dpc-section{display:flex;flex-direction:column;gap:14px;width:100%;max-width:760px;color:var(--dsw-alias-label-primary)}\n.dpc-head{display:flex;align-items:center;gap:8px}\n.dpc-head h3{margin:0;font-size:13px;line-height:20px;font-weight:600}\n.dpc-head>svg{flex:none;color:var(--dsw-alias-label-tertiary)}\n.dpc-intro{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}\n.dpc-listHead{display:flex;align-items:baseline;gap:7px;padding:0 2px;margin-top:2px}\n.dpc-listHead h3{margin:0;font-size:13px;line-height:20px;font-weight:600}\n.dpc-count{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums}\n.dpc-spacer{flex:1}\n.dpc-refresh{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer}\n.dpc-refresh:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dpc-refresh:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}\n.dpc-empty{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}\n.dpc-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch;gap:10px;margin:0;padding:0;list-style:none}\n.dpc-card{display:flex;flex-direction:column;gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-3);padding:12px 14px}\n.dpc-card:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dpc-cardTop{display:flex;align-items:center;gap:8px}\n.dpc-cardTitle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px;font-weight:600;font-family:var(--ds-font-family-code)}\n.dpc-cardDesc{margin:0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n.dpc-cardRow{display:flex;align-items:center;gap:6px;flex-wrap:wrap}\n.dpc-tag{display:inline-flex;align-items:center;min-height:20px;border-radius:5px;padding:1px 6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font-size:11px;line-height:16px;white-space:nowrap}\n.dpc-tag[data-kind='source']{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}\n.dpc-tag[data-kind='off']{background:color-mix(in srgb,var(--dsw-alias-state-warning-primary,var(--dsw-alias-label-tertiary)) 12%,transparent);color:var(--dsw-alias-label-secondary)}\n.dpc-cardActions{display:flex;align-items:center;gap:6px;margin-left:auto}\n.dpc-banner{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px 12px;background:var(--dsw-alias-bg-layer-3);font-size:13px;line-height:20px}\n.dpc-banner[data-kind='ok']{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent)}\n.dpc-banner[data-kind='error']{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent)}\n.dpc-banner[data-kind='info']{border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 35%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 8%,transparent)}\n.dpc-bannerBody{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}\n.dpc-bannerHint{display:flex;align-items:center;gap:8px;flex-wrap:wrap;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}\n.dpc-form{display:flex;flex-direction:column;gap:10px}\n.dpc-label{display:flex;flex-direction:column;gap:4px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.dpc-label>span:first-child{color:var(--dsw-alias-label-tertiary)}\n.dpc-input,.dpc-textarea,.dpc-select{width:100%;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:7px 10px;outline:none;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}\n.dpc-textarea{min-height:120px;resize:vertical;font-family:var(--ds-font-family-code);line-height:1.5}\n.dpc-textarea[data-short='true']{min-height:64px}\n.dpc-input:focus-visible,.dpc-textarea:focus-visible,.dpc-select:focus-visible{border-color:var(--dsw-alias-state-business-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--dsw-alias-state-business-primary) 18%,transparent)}\n.dpc-checks{display:flex;gap:16px;font-size:13px;line-height:20px}\n.dpc-checks label{display:inline-flex;align-items:center;gap:6px;cursor:pointer}\n.dpc-formError{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}\n/* Import dialog: wider than the host's 380px default; the server list gets\n its own scroll so title, intro, and footer stay pinned. The doubled class\n beats the host dialog's module CSS regardless of injection order. */\n.dpc-modalWide.dpc-modalWide{width:min(680px,100%)}\n.dpc-importScroll{display:flex;flex-direction:column;gap:14px;max-height:min(400px,52vh);overflow-y:auto;padding:2px 4px 2px 2px}\n.dpc-importGroup{display:flex;flex-direction:column;gap:8px}\n.dpc-importHead{display:flex;align-items:center;gap:8px;padding:0 2px}\n.dpc-importCount{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums}\n.dpc-importAll{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer}\n@media(max-width:680px){.dpc-cards{grid-template-columns:minmax(0,1fr)}}\n`\n", "/** Settings \u2192 Plugins \u201C\u6280\u80FD/Skills\u201D tab: view the discovered catalog, edit the\n * user-owned root. Pure presentation-layer \u2014 data arrives through props. */\n\nimport { useEffect, useState } from 'react'\nimport type { ReactElement } from 'react'\nimport { Button, IconRefreshOutline14, IconSkillOutline16, Modal, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { CSS } from './css.ts'\nimport type { Translate } from './index.ts'\n\n/** One skill as the host reports it (plus the editable flag the route adds). */\nexport interface SkillRowView {\n name: string\n description: string\n whenToUse?: string\n invocation: { modelInvocable: boolean; userInvocable: boolean }\n source: string\n provider: string\n editable: boolean\n}\n\nexport interface SkillsInjected {\n list(): Promise<{ skills: SkillRowView[] }>\n get(name: string): Promise<{ content: string }>\n save(input: { name: string; description: string; whenToUse?: string; modelInvocable: boolean; userInvocable: boolean; content: string }): Promise<{ ok: boolean }>\n remove(name: string): Promise<{ ok: boolean }>\n}\n\n/** Editor dialog state; null when closed. */\ninterface EditorState {\n mode: 'create' | 'edit' | 'view'\n name: string\n description: string\n whenToUse: string\n modelInvocable: boolean\n userInvocable: boolean\n content: string\n}\n\nconst SOURCE_KEYS: Record<string, string> = {\n 'project-dsh': 'sourceProjectDsh',\n 'project-agents': 'sourceProjectAgents',\n 'user-dsh': 'sourceUserDsh',\n 'user-agents': 'sourceUserAgents',\n runtime: 'sourceRuntime',\n bundled: 'sourceBundled',\n custom: 'sourceCustom',\n}\n\nexport function SkillsTab(props: { t: Translate; injected: SkillsInjected }): ReactElement {\n const { t, injected } = props\n const [skills, setSkills] = useState<SkillRowView[] | null>(null)\n const [editor, setEditor] = useState<EditorState | null>(null)\n const [confirmName, setConfirmName] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n const [outcome, setOutcome] = useState<{ ok: boolean; text: string } | null>(null)\n const [formError, setFormError] = useState<string | null>(null)\n const [reload, setReload] = useState(0)\n\n useEffect(() => {\n let current = true\n void injected.list().then(\n (body) => { if (current) setSkills(body.skills) },\n (error: Error) => { if (current) { setSkills([]); setOutcome({ ok: false, text: `${t('failed')}: ${String(error.message ?? error)}` }) } },\n )\n return () => { current = false }\n }, [injected, reload, t])\n\n const openCreate = (): void => {\n setFormError(null)\n setEditor({ mode: 'create', name: '', description: '', whenToUse: '', modelInvocable: true, userInvocable: true, content: '' })\n }\n\n const openExisting = async (skill: SkillRowView): Promise<void> => {\n setBusy(true)\n setFormError(null)\n try {\n const body = await injected.get(skill.name)\n setEditor({\n mode: skill.editable ? 'edit' : 'view',\n name: skill.name,\n description: skill.description,\n whenToUse: skill.whenToUse ?? '',\n modelInvocable: skill.invocation.modelInvocable,\n userInvocable: skill.invocation.userInvocable,\n content: body.content,\n })\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n }\n }\n\n /**\n * After a write/delete, the watched directory takes a moment to invalidate\n * the catalog \u2014 poll until the change is visible (bounded), then stop.\n */\n const refreshUntil = (predicate: (skills: SkillRowView[]) => boolean, timeoutMs = 10_000): void => {\n const deadline = Date.now() + timeoutMs\n const tick = (): void => {\n if (Date.now() > deadline) return\n setTimeout(() => {\n void injected.list().then(\n (body) => {\n setSkills(body.skills)\n if (!predicate(body.skills)) tick()\n },\n () => tick(),\n )\n }, 1000)\n }\n tick()\n }\n\n const doSave = async (): Promise<void> => {\n if (editor === null) return\n setBusy(true)\n setFormError(null)\n try {\n const name = editor.name.trim()\n await injected.save({\n name,\n description: editor.description,\n whenToUse: editor.whenToUse.trim() === '' ? undefined : editor.whenToUse,\n modelInvocable: editor.modelInvocable,\n userInvocable: editor.userInvocable,\n content: editor.content,\n })\n setOutcome({ ok: true, text: t('saved') })\n setEditor(null)\n refreshUntil(skills => skills.some(skill => skill.name === name))\n } catch (error) {\n setFormError(String(error instanceof Error ? error.message : error))\n } finally {\n setBusy(false)\n }\n }\n\n const doDelete = async (): Promise<void> => {\n if (confirmName === null) return\n const name = confirmName\n setBusy(true)\n try {\n await injected.remove(name)\n setOutcome({ ok: true, text: t('saved') })\n refreshUntil(skills => !skills.some(skill => skill.name === name))\n } catch (error) {\n setOutcome({ ok: false, text: `${t('failed')}: ${String(error instanceof Error ? error.message : error)}` })\n } finally {\n setBusy(false)\n setConfirmName(null)\n }\n }\n\n const readOnly = editor?.mode === 'view'\n\n return (\n <div className=\"dpc-section\">\n <style>{CSS}</style>\n\n <div className=\"dpc-head\">\n <IconSkillOutline16 aria-hidden=\"true\" />\n <h3>{t('skillsTitle')}</h3>\n <span className=\"dpc-spacer\" />\n <Button variant=\"primary\" size=\"sm\" onClick={openCreate}>{t('newSkill')}</Button>\n </div>\n <p className=\"dpc-intro\">{t('skillsIntro')}</p>\n\n {outcome !== null && (\n <div className=\"dpc-banner\" data-kind={outcome.ok ? 'ok' : 'error'} role=\"status\">\n <StateDot state={outcome.ok ? 'done' : 'error'} size={10} />\n <div className=\"dpc-bannerBody\"><span>{outcome.text}</span></div>\n </div>\n )}\n\n <div className=\"dpc-listHead\">\n <h3>{t('skillsTab')}</h3>\n {skills !== null && <span className=\"dpc-count\">{skills.length}</span>}\n <span className=\"dpc-spacer\" />\n <button type=\"button\" className=\"dpc-refresh\" aria-label={t('view')} title={t('view')} disabled={busy} onClick={() => setReload((value) => value + 1)}>\n <IconRefreshOutline14 size={14} aria-hidden=\"true\" />\n </button>\n </div>\n\n {skills === null && <p className=\"dpc-empty\">{t('loading')}</p>}\n {skills !== null && skills.length === 0 && <p className=\"dpc-empty\">{t('emptySkills')}</p>}\n {skills !== null && skills.length > 0 && (\n <ul className=\"dpc-cards\">\n {skills.map((skill) => (\n <li className=\"dpc-card\" key={`${skill.source}/${skill.name}`}>\n <div className=\"dpc-cardTop\">\n <strong className=\"dpc-cardTitle\" title={skill.name}>{skill.name}</strong>\n <span className=\"dpc-tag\" data-kind=\"source\">{t(SOURCE_KEYS[skill.source] ?? 'sourceCustom')}</span>\n </div>\n <p className=\"dpc-cardDesc\" title={skill.description}>{skill.description}</p>\n <div className=\"dpc-cardRow\">\n {!skill.invocation.modelInvocable && <span className=\"dpc-tag\">\u2699</span>}\n {!skill.invocation.userInvocable && <span className=\"dpc-tag\">/</span>}\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => void openExisting(skill)}>\n {skill.editable ? t('edit') : t('view')}\n </Button>\n {skill.editable && (\n <Button variant=\"ghost\" size=\"sm\" disabled={busy} onClick={() => setConfirmName(skill.name)}>{t('delete')}</Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Modal\n open={editor !== null}\n onClose={() => setEditor(null)}\n title={editor === null ? '' : editor.mode === 'create' ? t('newSkill') : editor.mode === 'edit' ? t('editSkill') : t('viewSkill')}\n >\n {editor !== null && (\n <div className=\"dpc-form\">\n <label className=\"dpc-label\">\n <span>{t('skillName')}</span>\n <input\n className=\"dpc-input\"\n value={editor.name}\n disabled={readOnly || editor.mode === 'edit'}\n onChange={(event) => setEditor({ ...editor, name: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('skillDescription')}</span>\n <input\n className=\"dpc-input\"\n value={editor.description}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, description: event.target.value })}\n />\n </label>\n <label className=\"dpc-label\">\n <span>{t('skillWhenToUse')}</span>\n <input\n className=\"dpc-input\"\n value={editor.whenToUse}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, whenToUse: event.target.value })}\n />\n </label>\n <div className=\"dpc-checks\">\n <label>\n <input\n type=\"checkbox\"\n checked={editor.modelInvocable}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, modelInvocable: event.target.checked })}\n />\n {t('modelInvocable')}\n </label>\n <label>\n <input\n type=\"checkbox\"\n checked={editor.userInvocable}\n disabled={readOnly}\n onChange={(event) => setEditor({ ...editor, userInvocable: event.target.checked })}\n />\n {t('userInvocable')}\n </label>\n </div>\n <label className=\"dpc-label\">\n <span>{t('skillContent')}</span>\n <textarea\n className=\"dpc-textarea\"\n value={editor.content}\n readOnly={readOnly}\n onChange={(event) => setEditor({ ...editor, content: event.target.value })}\n />\n </label>\n {formError !== null && <p className=\"dpc-formError\">{formError}</p>}\n <div className=\"dpc-cardRow\">\n <span className=\"dpc-spacer\" />\n <Button variant=\"ghost\" onClick={() => setEditor(null)}>{readOnly ? t('close') : t('cancel')}</Button>\n {!readOnly && <Button variant=\"primary\" disabled={busy} onClick={() => void doSave()}>{t('save')}</Button>}\n </div>\n </div>\n )}\n </Modal>\n\n <Modal\n open={confirmName !== null}\n onClose={() => setConfirmName(null)}\n title={t('confirmDelete')}\n description={confirmName ?? undefined}\n footer={\n <>\n <Button variant=\"ghost\" onClick={() => setConfirmName(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy} onClick={() => void doDelete()}>{t('delete')}</Button>\n </>\n }\n >\n <p>{t('deleteWarn')}</p>\n </Modal>\n </div>\n )\n}\n", "/** zh/en dictionaries for the Settings capabilities tabs. */\n\nexport const zh = {\n skillsTab: '\u6280\u80FD',\n mcpTab: 'MCP',\n skillsTitle: '\u6280\u80FD\u7BA1\u7406',\n skillsIntro: '\u67E5\u770B\u4E0E\u7F16\u8F91 dsh \u53D1\u73B0\u7684\u6280\u80FD\uFF1B\u7528\u6237\u7EA7\u6280\u80FD\uFF08DSH_HOME/skills\uFF09\u53EF\u5728\u6B64\u65B0\u5EFA\u3001\u4FEE\u6539\u3001\u5220\u9664\uFF0C\u6587\u4EF6\u88AB\u76D1\u542C\uFF0C\u4FDD\u5B58\u5373\u751F\u6548\u3002\u82E5\u5B58\u5728 ~/.claude/skills \u6216 ~/.codex/skills\uFF0C\u4F1A\u81EA\u52A8\u7EB3\u5165\u626B\u63CF\uFF08\u96F6\u62F7\u8D1D\u3001\u5B9E\u65F6\u540C\u6B65\uFF09\u3002',\n newSkill: '\u65B0\u5EFA\u6280\u80FD',\n editSkill: '\u7F16\u8F91\u6280\u80FD',\n viewSkill: '\u67E5\u770B\u6280\u80FD',\n skillName: '\u540D\u79F0\uFF08kebab-case\uFF09',\n skillDescription: '\u63CF\u8FF0',\n skillWhenToUse: '\u4F7F\u7528\u65F6\u673A\uFF08\u53EF\u9009\uFF09',\n skillContent: '\u6B63\u6587\uFF08Markdown\uFF09',\n modelInvocable: '\u5141\u8BB8\u6A21\u578B\u8C03\u7528',\n userInvocable: '\u5141\u8BB8\u7528\u6237 / \u8C03\u7528',\n save: '\u4FDD\u5B58',\n cancel: '\u53D6\u6D88',\n delete: '\u5220\u9664',\n edit: '\u7F16\u8F91',\n view: '\u67E5\u770B',\n close: '\u5173\u95ED',\n emptySkills: '\u8FD8\u6CA1\u6709\u53D1\u73B0\u4EFB\u4F55\u6280\u80FD',\n loading: '\u8F7D\u5165\u4E2D\u2026',\n source: '\u6765\u6E90',\n sourceProjectDsh: '\u9879\u76EE',\n sourceProjectAgents: '\u9879\u76EE',\n sourceUserDsh: '\u7528\u6237',\n sourceUserAgents: '\u7528\u6237',\n sourceRuntime: '\u8FD0\u884C\u65F6',\n sourceBundled: '\u5185\u7F6E',\n sourceCustom: '\u81EA\u5B9A\u4E49',\n readOnly: '\u53EA\u8BFB',\n confirmDelete: '\u786E\u8BA4\u5220\u9664\u6280\u80FD\uFF1F',\n deleteWarn: '\u5C06\u5220\u9664 DSH_HOME/skills \u4E0B\u7684\u6574\u4E2A\u6280\u80FD\u76EE\u5F55\uFF0C\u6B64\u64CD\u4F5C\u4E0D\u53EF\u64A4\u9500\u3002',\n saved: '\u5DF2\u4FDD\u5B58\uFF0C\u6280\u80FD\u76EE\u5F55\u88AB\u76D1\u542C\uFF0C\u7A0D\u5019\u5373\u53EF\u5728\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u3002',\n mcpTitle: 'MCP \u670D\u52A1\u5668',\n mcpIntro: '\u7BA1\u7406 profile \u4E2D\u7684 MCP \u670D\u52A1\u5668\u884C\uFF08@deepseek-ai/dsh-mcp-client\uFF09\u3002\u65B0\u589E\u3001\u4FEE\u6539\u6216\u5220\u9664\u540E\u9700\u8981\u91CD\u542F dsh \u624D\u751F\u6548\u3002',\n addServer: '\u6DFB\u52A0\u670D\u52A1\u5668',\n editServer: '\u7F16\u8F91\u670D\u52A1\u5668',\n serverName: '\u670D\u52A1\u5668\u540D\uFF08\u5DE5\u5177\u540D\u524D\u7F00\uFF09',\n transport: '\u4F20\u8F93\u65B9\u5F0F',\n transportStdio: 'stdio\uFF08\u672C\u5730\u547D\u4EE4\uFF09',\n transportHttp: 'streamable-http\uFF08URL\uFF09',\n command: '\u547D\u4EE4',\n args: '\u53C2\u6570\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF09',\n envPairs: '\u73AF\u5883\u53D8\u91CF\uFF08\u6BCF\u884C KEY=VALUE\uFF09',\n url: 'URL',\n headersPairs: '\u8BF7\u6C42\u5934\uFF08\u6BCF\u884C KEY: VALUE\uFF09',\n disabled: '\u5DF2\u505C\u7528',\n enabled: '\u542F\u7528\u4E2D',\n toggle: '\u505C\u7528/\u542F\u7528',\n confirmRemove: '\u786E\u8BA4\u79FB\u9664\u8BE5\u670D\u52A1\u5668\uFF1F',\n removeWarn: '\u5C06\u4ECE profile \u914D\u7F6E\u4E2D\u79FB\u9664\u8FD9\u4E00\u884C\uFF0C\u91CD\u542F dsh \u540E\u5176\u5DE5\u5177\u4E0D\u518D\u51FA\u73B0\u3002',\n emptyMcp: '\u8FD8\u6CA1\u6709\u914D\u7F6E MCP \u670D\u52A1\u5668',\n importServers: '\u4ECE\u5176\u4ED6 Agent \u5BFC\u5165',\n importIntro: '\u626B\u63CF Claude Code\uFF08~/.claude.json\uFF09\u4E0E Codex\uFF08~/.codex/config.toml\uFF09\u7684 MCP \u670D\u52A1\u5668\u914D\u7F6E\uFF0C\u52FE\u9009\u540E\u5BFC\u5165\u4E3A\u672C profile \u7684\u670D\u52A1\u5668\u884C\u3002',\n importEmpty: '\u6CA1\u6709\u53D1\u73B0\u53EF\u5BFC\u5165\u7684 MCP \u670D\u52A1\u5668',\n importSelectAll: '\u5168\u9009',\n importExisting: '\u5DF2\u5B58\u5728',\n importSelected: '\u5BFC\u5165\u9009\u4E2D\u9879',\n restartNeeded: '\u914D\u7F6E\u5DF2\u5199\u5165\uFF0C\u91CD\u542F dsh \u540E\u751F\u6548\u3002',\n restartDesktopHint: '\u91CD\u542F\u7531\u684C\u9762\u5E94\u7528\u8D1F\u8D23\uFF1A\u6258\u76D8\u83DC\u5355\u300C\u91CD\u542F\u670D\u52A1\u300D\u3002',\n restartOtherHint: '\u91CD\u542F\u65B9\u5F0F\uFF1A\u5173\u95ED\u5F53\u524D dsh \u8FDB\u7A0B\u540E\u91CD\u65B0\u8FD0\u884C\u3002',\n restartNow: '\u91CD\u542F\u670D\u52A1',\n restart: '\u91CD\u542F',\n restartConfirmTitle: '\u91CD\u542F dsh\uFF1F',\n restartConfirmBody: '\u91CD\u542F\u4F1A\u4E2D\u65AD\u6B63\u5728\u8FDB\u884C\u7684\u56DE\u5408\uFF0C\u672A\u4FDD\u5B58\u7684\u8F93\u5165\u53EF\u80FD\u4E22\u5931\uFF1BMCP \u884C\u7684\u53D8\u66F4\u5C06\u5728\u91CD\u542F\u540E\u751F\u6548\u3002',\n restarting: '\u6B63\u5728\u91CD\u542F\uFF0C\u6062\u590D\u540E\u5C06\u81EA\u52A8\u5237\u65B0\u9875\u9762\u2026',\n restartPortHint: '\u82E5\u91CD\u542F\u540E\u9875\u9762\u957F\u65F6\u95F4\u672A\u6062\u590D\uFF0C\u53EF\u80FD\u662F\u7AEF\u53E3\u5DF2\u53D8\u5316\uFF1A\u5728\u7EC8\u7AEF\u67E5\u770B\u65B0\u5730\u5740\u540E\u6253\u5F00\u3002',\n failed: '\u64CD\u4F5C\u5931\u8D25',\n}\n\nexport const en = {\n skillsTab: 'Skills',\n mcpTab: 'MCP',\n skillsTitle: 'Skills',\n skillsIntro: 'View and edit the skills dsh discovers; user-level skills (DSH_HOME/skills) can be created, edited, and deleted here \u2014 the directory is watched, saves apply without a restart. ~/.claude/skills and ~/.codex/skills are scanned too when present (zero-copy, live-synced).',\n newSkill: 'New skill',\n editSkill: 'Edit skill',\n viewSkill: 'View skill',\n skillName: 'Name (kebab-case)',\n skillDescription: 'Description',\n skillWhenToUse: 'When to use (optional)',\n skillContent: 'Body (Markdown)',\n modelInvocable: 'Model-invocable',\n userInvocable: 'User-invocable (/)',\n save: 'Save',\n cancel: 'Cancel',\n delete: 'Delete',\n edit: 'Edit',\n view: 'View',\n close: 'Close',\n emptySkills: 'No skills discovered yet',\n loading: 'Loading\u2026',\n source: 'Source',\n sourceProjectDsh: 'project',\n sourceProjectAgents: 'project',\n sourceUserDsh: 'user',\n sourceUserAgents: 'user',\n sourceRuntime: 'runtime',\n sourceBundled: 'bundled',\n sourceCustom: 'custom',\n readOnly: 'read-only',\n confirmDelete: 'Delete this skill?',\n deleteWarn: 'Removes the whole skill directory under DSH_HOME/skills. This cannot be undone.',\n saved: 'Saved. The skills directory is watched; the skill is usable in sessions shortly.',\n mcpTitle: 'MCP servers',\n mcpIntro: 'Manage the MCP server rows (@deepseek-ai/dsh-mcp-client) in this profile. Additions, edits, and removals take effect after a dsh restart.',\n addServer: 'Add server',\n editServer: 'Edit server',\n serverName: 'Server name (tool name prefix)',\n transport: 'Transport',\n transportStdio: 'stdio (local command)',\n transportHttp: 'streamable-http (URL)',\n command: 'Command',\n args: 'Arguments (one per line)',\n envPairs: 'Environment (KEY=VALUE per line)',\n url: 'URL',\n headersPairs: 'Headers (KEY: VALUE per line)',\n disabled: 'Disabled',\n enabled: 'Enabled',\n toggle: 'Enable/disable',\n confirmRemove: 'Remove this server?',\n removeWarn: 'Removes the row from the profile configuration; its tools disappear after the next dsh restart.',\n emptyMcp: 'No MCP servers configured yet',\n importServers: 'Import from other agents',\n importIntro: 'Scans Claude Code (~/.claude.json) and Codex (~/.codex/config.toml) MCP server configs; selected entries become server rows in this profile.',\n importEmpty: 'No importable MCP servers found',\n importSelectAll: 'Select all',\n importExisting: 'already here',\n importSelected: 'Import selected',\n restartNeeded: 'Configuration written \u2014 restart dsh to apply.',\n restartDesktopHint: 'The desktop app owns restarts: use the tray \u201CRestart service\u201D.',\n restartOtherHint: 'Restart by closing this dsh process and running it again.',\n restartNow: 'Restart service',\n restart: 'Restart',\n restartConfirmTitle: 'Restart dsh?',\n restartConfirmBody: 'Restarting interrupts any running turn and may lose unsaved input; pending MCP changes apply after the restart.',\n restarting: 'Restarting \u2014 the page will reload once the host is back\u2026',\n restartPortHint: 'If the page does not recover, the port may have changed: check the terminal for the new URL.',\n failed: 'Operation failed',\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "import_react", "import_dsh_client_ui_primitives", "import_jsx_runtime", "name", "skills", "name", "h"]
7
7
  }