dsh-plugin-capabilities 0.1.4 → 0.1.6

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.
Files changed (35) hide show
  1. package/README.md +4 -2
  2. package/lib/client.js +119 -24
  3. package/lib/client.js.map +4 -4
  4. package/lib/index.js +11 -2
  5. package/lib/index.js.map +4 -4
  6. package/package.json +2 -1
  7. package/skills/find-skills/LICENSE +21 -0
  8. package/skills/find-skills/SKILL.md +141 -0
  9. package/skills/skill-creator/LICENSE.txt +202 -0
  10. package/skills/skill-creator/SKILL.md +485 -0
  11. package/skills/skill-creator/agents/analyzer.md +274 -0
  12. package/skills/skill-creator/agents/comparator.md +202 -0
  13. package/skills/skill-creator/agents/grader.md +223 -0
  14. package/skills/skill-creator/assets/eval_review.html +146 -0
  15. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  16. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  17. package/skills/skill-creator/references/schemas.md +430 -0
  18. package/skills/skill-creator/scripts/__init__.py +0 -0
  19. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  20. package/skills/skill-creator/scripts/generate_report.py +326 -0
  21. package/skills/skill-creator/scripts/improve_description.py +247 -0
  22. package/skills/skill-creator/scripts/package_skill.py +136 -0
  23. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  24. package/skills/skill-creator/scripts/run_eval.py +310 -0
  25. package/skills/skill-creator/scripts/run_loop.py +328 -0
  26. package/skills/skill-creator/scripts/utils.py +47 -0
  27. package/src/client/CapabilitiesSection.tsx +102 -0
  28. package/src/client/McpTab.tsx +2 -0
  29. package/src/client/SkillsTab.tsx +2 -0
  30. package/src/client/css.ts +16 -2
  31. package/src/client/index.ts +15 -22
  32. package/src/client/locales.ts +2 -0
  33. package/src/index.ts +22 -6
  34. package/src/packaged-skills.test.ts +40 -0
  35. package/src/smoke.test.ts +8 -1
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 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/** 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
- "names": ["import_react", "import_react", "import_dsh_client_ui_primitives", "import_jsx_runtime", "name", "skills", "name", "h"]
3
+ "sources": ["../src/client/index.ts", "../src/client/CapabilitiesSection.tsx", "../src/client/css.ts", "../src/client/McpTab.tsx", "../src/client/SkillsTab.tsx", "../src/client/locales.ts"],
4
+ "sourcesContent": ["/** dsh-plugin-capabilities client entry: contributes the top-level\n * \u201C\u6280\u80FD\u4E0E MCP\u201D section into Settings (beside \u901A\u7528\u8BBE\u7F6E/\u6A21\u578B, with Skills and\n * MCP as internal tabs). Calls the host routes with fetch. */\n\nimport { createElement as h } from 'react'\nimport { CapabilitiesSection } from './CapabilitiesSection.tsx'\nimport type { McpInjected, McpRow } from './McpTab.tsx'\nimport type { SkillsInjected, 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 // One top-level nav entry (between \u6A21\u578B and \u63D2\u4EF6), not a tab under the\n // Plugins section \u2014 the section component owns its internal Skills/MCP\n // tabs directly, so nothing registers into settings.plugins.tab anymore.\n ctx.slots.inject('settings.section', () => {\n return ctx.slots.register({\n name: 'settings.section',\n id: 'capabilities',\n order: 12,\n label: () => t('sectionNav'),\n locale: NS,\n }, () => h(CapabilitiesSection, { t, skills: skillsInjected, mcp: mcpInjected }))\n })\n}\n", "/** Settings top-level \u201C\u6280\u80FD\u4E0E MCP\u201D section: one nav entry beside \u901A\u7528\u8BBE\u7F6E and\n * \u6A21\u578B, with the Skills and MCP pages as internal tabs. The two pages are the\n * same components the Plugins section used to host \u2014 promoted a level instead\n * of squeezed under \u63D2\u4EF6. Pure composition; data still arrives through the\n * injected faces. */\n\nimport { useEffect, useId, useRef, useState } from 'react'\nimport type { ReactElement } from 'react'\nimport { CSS } from './css.ts'\nimport { McpTab } from './McpTab.tsx'\nimport type { McpInjected } from './McpTab.tsx'\nimport { SkillsTab } from './SkillsTab.tsx'\nimport type { SkillsInjected } from './SkillsTab.tsx'\nimport type { Translate } from './index.ts'\n\nexport function CapabilitiesSection(props: {\n t: Translate\n skills: SkillsInjected\n mcp: McpInjected\n}): ReactElement {\n const { t, skills, mcp } = props\n const tabsId = useId()\n const tabRefs = useRef<Array<HTMLButtonElement | null>>([])\n const rows = [\n { id: 'skills', label: t('skillsTab') },\n { id: 'mcp', label: t('mcpTab') },\n ]\n const [activeId, setActiveId] = useState('skills')\n // The skills page mounts immediately; a tab mounts only when first\n // selected, then stays mounted while hidden so editor drafts and outcome\n // banners survive switching between the two views.\n const [visitedIds, setVisitedIds] = useState<ReadonlySet<string>>(() => new Set(['skills']))\n\n useEffect(() => {\n setVisitedIds((previous) => {\n if (previous.has(activeId)) return previous\n return new Set([...previous, activeId])\n })\n }, [activeId])\n\n return (\n <div className=\"dpc-section\">\n <style>{CSS}</style>\n\n <h2 className=\"dpc-heading\">{t('sectionNav')}</h2>\n <div className=\"dpc-tabs\" role=\"tablist\" aria-label={t('sectionNav')}>\n {rows.map((row, index) => {\n const selected = row.id === activeId\n return (\n <button\n key={row.id}\n ref={(element) => { tabRefs.current[index] = element }}\n id={`${tabsId}-tab-${row.id}`}\n type=\"button\"\n role=\"tab\"\n className=\"dpc-tab\"\n aria-selected={selected}\n aria-controls={`${tabsId}-panel-${row.id}`}\n data-active={selected ? 'true' : undefined}\n tabIndex={selected ? 0 : -1}\n onClick={() => { setActiveId(row.id) }}\n onKeyDown={(event) => {\n let nextIndex: number\n switch (event.key) {\n case 'ArrowRight': nextIndex = (index + 1) % rows.length; break\n case 'ArrowLeft': nextIndex = (index - 1 + rows.length) % rows.length; break\n case 'Home': nextIndex = 0; break\n case 'End': nextIndex = rows.length - 1; break\n default: return\n }\n event.preventDefault()\n setActiveId(rows[nextIndex]?.id ?? 'skills')\n tabRefs.current[nextIndex]?.focus()\n }}\n >\n {row.label}\n </button>\n )\n })}\n </div>\n {rows\n .filter(row => row.id === activeId || visitedIds.has(row.id))\n .map((row) => {\n const selected = row.id === activeId\n return (\n <div\n key={row.id}\n id={`${tabsId}-panel-${row.id}`}\n className=\"dpc-tabPanel\"\n role=\"tabpanel\"\n aria-labelledby={`${tabsId}-tab-${row.id}`}\n hidden={!selected}\n >\n {row.id === 'skills'\n ? <SkillsTab t={t} injected={skills} />\n : <McpTab t={t} injected={mcp} />}\n </div>\n )\n })}\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-heading{margin:0;font-size:18px;line-height:26px;font-weight:600}\n/* Top-level section's internal tabs \u2014 same underline-tab look as the host's\n Plugins section so the promoted placement still reads as one family. */\n.dpc-tabs{display:flex;align-items:flex-end;gap:22px;border-bottom:1px solid var(--dsw-alias-border-l2);margin-top:2px}\n.dpc-tab{position:relative;border:0;padding:7px 1px 9px;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:13px;line-height:20px;cursor:pointer}\n.dpc-tab:hover,.dpc-tab[data-active='true']{color:var(--dsw-alias-label-primary)}\n.dpc-tab[data-active='true']::after,.dpc-tab:focus-visible::after{position:absolute;right:0;bottom:-1px;left:0;height:2px;border-radius:2px 2px 0 0;background:var(--dsw-alias-label-primary);content:''}\n.dpc-tab:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:2px;color:var(--dsw-alias-label-primary)}\n.dpc-tabPanel{min-width:0;padding-top:2px}\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:240px;resize:vertical;font-family:var(--ds-font-family-code);line-height:1.5}\n.dpc-textarea[data-short='true']{min-height:96px}\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/* Editor dialogs (new skill / server): 640px wide so markdown bodies and\n command/arg/env lines stop wrapping mid-token; the content column scrolls\n on short viewports instead of clipping past the dialog edge. */\n.dpc-modalForm.dpc-modalForm{width:min(640px,100%)}\n.dpc-modalScroll.dpc-modalScroll{max-height:calc(100vh - 160px);overflow-y:auto}\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 \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 className=\"dpc-modalForm\"\n contentClassName=\"dpc-modalScroll\"\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", "/** 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 className=\"dpc-modalForm\"\n contentClassName=\"dpc-modalScroll\"\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 sectionNav: '\u6280\u80FD\u4E0E MCP',\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 sectionNav: 'Skills & MCP',\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
+ "names": ["import_react", "import_react", "import_react", "import_dsh_client_ui_primitives", "import_jsx_runtime", "name", "skills", "import_jsx_runtime", "name", "h"]
7
7
  }
package/lib/index.js CHANGED
@@ -1,3 +1,8 @@
1
+ // src/index.ts
2
+ import { existsSync as existsSync4 } from "node:fs";
3
+ import { dirname as dirname2, join as join5 } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
1
6
  // src/agents.ts
2
7
  import { existsSync, readFileSync } from "node:fs";
3
8
  import { homedir } from "node:os";
@@ -1358,6 +1363,9 @@ function mountCapabilitiesRoutes(host, config) {
1358
1363
 
1359
1364
  // src/index.ts
1360
1365
  var name = "dsh-plugin-capabilities";
1366
+ function packagedSkillsDir() {
1367
+ return join5(dirname2(fileURLToPath(import.meta.url)), "..", "skills");
1368
+ }
1361
1369
  var inject = ["webServer", "skills"];
1362
1370
  function apply(ctx, config) {
1363
1371
  const profile = config?.profile ?? argvProfile() ?? "web";
@@ -1366,7 +1374,7 @@ function apply(ctx, config) {
1366
1374
  try {
1367
1375
  const mod = await import("@deepseek-ai/dsh-skill-filesystem");
1368
1376
  const plugin = mod.default ?? mod;
1369
- const roots = agentSkillRoots();
1377
+ const roots = [packagedSkillsDir(), ...agentSkillRoots()].filter((dir) => existsSync4(dir));
1370
1378
  hostCtx.plugin(plugin, roots.length > 0 ? { customSkillDirs: roots } : {});
1371
1379
  } catch {
1372
1380
  }
@@ -1380,7 +1388,8 @@ function apply(ctx, config) {
1380
1388
  export {
1381
1389
  apply,
1382
1390
  inject,
1383
- name
1391
+ name,
1392
+ packagedSkillsDir
1384
1393
  };
1385
1394
  /*! Bundled license information:
1386
1395