dshmarket 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client/client.js CHANGED
@@ -148,14 +148,44 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
148
148
  const desc = plugin.description && (plugin.description[lang] || plugin.description.en) || "";
149
149
  return /\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name + " " + desc);
150
150
  }
151
- /** A registry plugin counts as installed when its package name, npm name, or GitHub spec appears in the profile dependencies. */
152
- function isInstalled(plugin, installed) {
153
- if (installed[plugin.name] !== void 0) return true;
154
- if (plugin.npm && installed[plugin.npm] !== void 0) return true;
151
+ /**
152
+ * Unified installed-state matching (#15): both sides collapse to lowercase
153
+ * identity sets the registry entry contributes its bare name, npm name and
154
+ * owner/repo; the dependency contributes its key and the repo inside its
155
+ * spec — and any exact intersection counts. Exact equality, not substrings,
156
+ * so prefix-related repo names cannot cross-match.
157
+ */
158
+ function entryIdentities(plugin) {
159
+ const ids = /* @__PURE__ */ new Set([plugin.name.toLowerCase()]);
160
+ if (plugin.npm) ids.add(plugin.npm.toLowerCase());
155
161
  const repo = repoOf(plugin.url);
156
- if (repo === null) return false;
157
- const needle = ("github:" + repo).toLowerCase();
158
- return Object.values(installed).some((spec) => String(spec).toLowerCase().includes(needle));
162
+ if (repo !== null) ids.add(repo.toLowerCase());
163
+ return ids;
164
+ }
165
+ function depIdentities(name, spec) {
166
+ const ids = /* @__PURE__ */ new Set([name.toLowerCase()]);
167
+ const scoped = /^@([^/]+)\/(.+)$/.exec(name);
168
+ if (scoped !== null) ids.add(`${scoped[1].toLowerCase()}/${scoped[2].toLowerCase()}`);
169
+ const match = /github:([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)/i.exec(spec);
170
+ if (match !== null) ids.add(match[1].toLowerCase());
171
+ return ids;
172
+ }
173
+ /** The installed dependency name a registry entry corresponds to, or null. */
174
+ function matchInstalledName(plugin, installed) {
175
+ const ids = entryIdentities(plugin);
176
+ for (const [name, spec] of Object.entries(installed)) for (const id of depIdentities(name, String(spec))) if (ids.has(id)) return name;
177
+ return null;
178
+ }
179
+ /** The registry entry an installed dependency corresponds to, or undefined. */
180
+ function entryForDep(plugins, name, spec) {
181
+ const ids = depIdentities(name, String(spec));
182
+ return plugins.find((plugin) => {
183
+ for (const id of entryIdentities(plugin)) if (ids.has(id)) return true;
184
+ return false;
185
+ });
186
+ }
187
+ function isInstalled(plugin, installed) {
188
+ return matchInstalledName(plugin, installed) !== null;
159
189
  }
160
190
  /**
161
191
  * The brand mark (assets/logo.svg — shared block-grid mark with
@@ -215,59 +245,59 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
215
245
  document.head.appendChild(tag);
216
246
  }
217
247
  var Market_module_css_default = {
218
- "head": "eGUBIq_head",
219
- "grid": "eGUBIq_grid",
220
- "restart": "eGUBIq_restart",
221
- "nm": "eGUBIq_nm",
222
- "row1": "eGUBIq_row1",
223
- "err": "eGUBIq_err",
224
- "empty": "eGUBIq_empty",
225
- "owner": "eGUBIq_owner",
226
248
  "tabs": "eGUBIq_tabs",
227
- "modalNote": "eGUBIq_modalNote",
228
- "cmdSummary": "eGUBIq_cmdSummary",
229
249
  "swatches": "eGUBIq_swatches",
230
- "spec": "eGUBIq_spec",
250
+ "star": "eGUBIq_star",
231
251
  "okState": "eGUBIq_okState",
232
- "catsCollapsed": "eGUBIq_catsCollapsed",
233
- "irow": "eGUBIq_irow",
252
+ "themesGrid": "eGUBIq_themesGrid",
253
+ "dangerBtn": "eGUBIq_dangerBtn",
254
+ "modalNote": "eGUBIq_modalNote",
255
+ "nm": "eGUBIq_nm",
234
256
  "btn": "eGUBIq_btn",
235
- "star": "eGUBIq_star",
236
- "tab": "eGUBIq_tab",
237
- "cmdDetails": "eGUBIq_cmdDetails",
238
- "searchInline": "eGUBIq_searchInline",
239
- "cmd": "eGUBIq_cmd",
240
- "sort": "eGUBIq_sort",
257
+ "descTight": "eGUBIq_descTight",
258
+ "empty": "eGUBIq_empty",
259
+ "cats": "eGUBIq_cats",
260
+ "title": "eGUBIq_title",
261
+ "on": "eGUBIq_on",
262
+ "row1": "eGUBIq_row1",
241
263
  "body": "eGUBIq_body",
264
+ "top": "eGUBIq_top",
265
+ "searchInline": "eGUBIq_searchInline",
266
+ "sub": "eGUBIq_sub",
242
267
  "catsWrap": "eGUBIq_catsWrap",
243
- "sect": "eGUBIq_sect",
244
- "themesGrid": "eGUBIq_themesGrid",
268
+ "head": "eGUBIq_head",
245
269
  "av": "eGUBIq_av",
246
- "dangerBtn": "eGUBIq_dangerBtn",
247
- "top": "eGUBIq_top",
248
- "desc": "eGUBIq_desc",
249
- "titleRow": "eGUBIq_titleRow",
250
- "sp": "eGUBIq_sp",
251
270
  "warnBtn": "eGUBIq_warnBtn",
252
- "warnLine": "eGUBIq_warnLine",
253
- "src": "eGUBIq_src",
254
- "spin": "eGUBIq_spin",
255
- "progress": "eGUBIq_progress",
256
- "sub": "eGUBIq_sub",
257
- "title": "eGUBIq_title",
258
- "descTight": "eGUBIq_descTight",
271
+ "owner": "eGUBIq_owner",
272
+ "cmdDetails": "eGUBIq_cmdDetails",
273
+ "restart": "eGUBIq_restart",
259
274
  "catsRow": "eGUBIq_catsRow",
260
- "catsToggle": "eGUBIq_catsToggle",
261
- "cats": "eGUBIq_cats",
262
- "tag": "eGUBIq_tag",
263
- "dangerArmed": "eGUBIq_dangerArmed",
264
- "grow": "eGUBIq_grow",
275
+ "foot": "eGUBIq_foot",
276
+ "src": "eGUBIq_src",
265
277
  "root": "eGUBIq_root",
266
- "on": "eGUBIq_on",
278
+ "tab": "eGUBIq_tab",
279
+ "desc": "eGUBIq_desc",
280
+ "sect": "eGUBIq_sect",
281
+ "catsToggle": "eGUBIq_catsToggle",
267
282
  "card": "eGUBIq_card",
268
- "foot": "eGUBIq_foot",
283
+ "titleRow": "eGUBIq_titleRow",
269
284
  "dot": "eGUBIq_dot",
270
- "loading": "eGUBIq_loading"
285
+ "progress": "eGUBIq_progress",
286
+ "tag": "eGUBIq_tag",
287
+ "sp": "eGUBIq_sp",
288
+ "cmd": "eGUBIq_cmd",
289
+ "cmdSummary": "eGUBIq_cmdSummary",
290
+ "grid": "eGUBIq_grid",
291
+ "catsCollapsed": "eGUBIq_catsCollapsed",
292
+ "sort": "eGUBIq_sort",
293
+ "grow": "eGUBIq_grow",
294
+ "warnLine": "eGUBIq_warnLine",
295
+ "dangerArmed": "eGUBIq_dangerArmed",
296
+ "loading": "eGUBIq_loading",
297
+ "spin": "eGUBIq_spin",
298
+ "irow": "eGUBIq_irow",
299
+ "err": "eGUBIq_err",
300
+ "spec": "eGUBIq_spec"
271
301
  };
272
302
  //#endregion
273
303
  //#region src/client/MarketSection.tsx
@@ -641,14 +671,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
641
671
  ]
642
672
  }, p.url);
643
673
  };
644
- const installedNameOf = (p) => {
645
- if (installed[p.name] !== void 0) return p.name;
646
- const repo = repoOf(p.url);
647
- if (repo === null) return null;
648
- const needle = ("github:" + repo).toLowerCase();
649
- for (const [name, spec] of Object.entries(installed)) if (String(spec).toLowerCase().includes(needle)) return name;
650
- return null;
651
- };
674
+ const installedNameOf = (p) => matchInstalledName(p, installed);
652
675
  const bootEntries = typeof window !== "undefined" && window.__DSH_BOOT__ && Array.isArray(window.__DSH_BOOT__.entries) ? window.__DSH_BOOT__.entries : [];
653
676
  const themePluginCard = (p) => {
654
677
  const instName = installedNameOf(p);
@@ -1028,7 +1051,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
1028
1051
  className: Market_module_css_default.empty,
1029
1052
  children: t("installedEmpty")
1030
1053
  }) : Object.entries(installed).map(([name, spec]) => {
1031
- const entry = data === null ? void 0 : data.plugins.find((p) => p.name === name || repoOf(p.url) !== null && String(spec).toLowerCase().includes(("github:" + repoOf(p.url)).toLowerCase()));
1054
+ const entry = data === null ? void 0 : entryForDep(data.plugins, name, String(spec));
1032
1055
  const status = updates[name];
1033
1056
  const version = status && status.version ? "v" + status.version : "";
1034
1057
  const specText = String(spec);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","Toast","useState","css","useSyncExternalStore","useRef","useCallback","useMemo","Button","StateDot","Input","IconSearchOutline16","Pill","IconChevronUpOutline14","IconChevronDownOutline14","Modal","h"],"sources":["../src/client/locales.ts","../src/client/market-data.ts","../src/client/InstallToast.tsx","../src/client/MarketSection.tsx","../src/client/index.ts"],"sourcesContent":["/** zh/en dictionaries for the Market settings section and install toast. */\n\nexport const zh = {\n nav: '插件市场',\n subtitle: '发现社区为 DeepSeek Harness 打造的能力',\n searchPh: '搜索插件,比如:通知、终端、记忆…',\n tabDiscover: '发现',\n tabInstalled: '已安装',\n all: '全部',\n install: '安装',\n installing: '安装中…',\n installedBadge: '✓ 已装好',\n alreadyInstalled: '✓ 已安装',\n restartBanner: '项变更完成,重启 DeepSeek Harness 后生效',\n uninstall: '卸载',\n confirmRemove: '确认卸载?',\n uninstalling: '卸载中…',\n restartHint: '重启方式:关闭当前 dsh 进程后重新运行(例如 dsh web)',\n confirmTitle: '安装',\n confirmWarn: '插件是社区第三方代码。安装即表示你信任该来源;构建脚本默认被禁止执行。',\n cancel: '取消',\n empty: '没有匹配的插件',\n installedEmpty: '还没有装过社区插件,去「发现」页逛逛吧',\n loadFail: '插件目录加载失败,请稍后重试',\n installFail: '安装失败',\n viewSource: '源码',\n hotBanner: '个新插件已装好,刷新页面即可使用',\n refresh: '刷新页面',\n update: '更新',\n updating: '更新中…',\n updated: '✓ 已更新,重启后生效',\n updateFail: '更新失败',\n upToDate: '已是最新',\n linkedDev: '本地开发链接',\n exportLog: '导出日志',\n readme: '使用说明',\n terminalWarn: '这看起来是终端/命令行插件:装进网页版可能无效,甚至导致 DeepSeek Harness 无法启动。建议先看它的使用说明,按说明装进对应的 profile。',\n envMissing: '还差一个小组件才能安装插件',\n envFix: '自动装好',\n envFixing: '正在准备…',\n envFixFail: '自动准备没成功,请点\"导出日志\"把文件发给我们反馈',\n loading: '正在加载插件目录…',\n backTop: '回到顶部',\n confirm: '确认',\n cmdDetails: '安装命令',\n catsMore: '更多分类',\n catsLess: '收起',\n sortHot: '最热',\n sortNew: '最新',\n marketUpdate: '市场有新版本,升级',\n updateAll: '全部更新',\n tabThemes: '主题',\n themeApply: '使用',\n themeActive: '使用中',\n themeEmpty: '目录里暂时还没有主题,敬请期待',\n progressHint: '首次安装需要下载与解析依赖,大插件可能要 1-3 分钟',\n toastReady: '已装好并已生效',\n toastTheme: '已启用。到 设置 → 插件市场 → 主题 可随时切换',\n gotIt: '知道了',\n}\n\n/** A dictionary key; zh is the source of truth, en mirrors it 1:1. */\nexport type MarketKey = keyof typeof zh\n\nexport const en: Record<MarketKey, string> = {\n nav: 'Plugin Market',\n subtitle: 'Discover community plugins for DeepSeek Harness',\n searchPh: 'Search plugins: notify, terminal, memory…',\n tabDiscover: 'Discover',\n tabInstalled: 'Installed',\n all: 'All',\n install: 'Install',\n installing: 'Installing…',\n installedBadge: '✓ Installed',\n alreadyInstalled: '✓ Installed',\n restartBanner: 'change(s) done — restart DeepSeek Harness to apply',\n uninstall: 'Uninstall',\n confirmRemove: 'Confirm?',\n uninstalling: 'Removing…',\n restartHint: 'To restart: stop the current dsh process and run it again (e.g. dsh web)',\n confirmTitle: 'Install',\n confirmWarn: 'Plugins are third-party community code. Installing means you trust this source; build scripts are blocked by default.',\n cancel: 'Cancel',\n empty: 'No plugins match',\n installedEmpty: 'No community plugins yet — browse the Discover tab',\n loadFail: 'Failed to load the plugin catalog, please retry later',\n installFail: 'Install failed',\n viewSource: 'Source',\n hotBanner: 'new plugin(s) ready — refresh the page to use them',\n refresh: 'Refresh',\n update: 'Update',\n updating: 'Updating…',\n updated: '✓ Updated — restart to apply',\n updateFail: 'Update failed',\n upToDate: 'Up to date',\n linkedDev: 'linked (dev)',\n exportLog: 'Export log',\n readme: 'README',\n terminalWarn: 'This looks like a terminal/CLI plugin: installing it into the web profile may do nothing, or even break DeepSeek Harness startup. Read its README and install it into the profile it targets.',\n envMissing: 'One small component is needed before installing plugins',\n envFix: 'Set up automatically',\n envFixing: 'Setting up…',\n envFixFail: 'Automatic setup failed — please use \"Export log\" and send us the file',\n loading: 'Loading the catalog…',\n backTop: 'Back to top',\n confirm: 'Confirm',\n cmdDetails: 'Install command',\n catsMore: 'More',\n catsLess: 'Less',\n sortHot: 'Top',\n sortNew: 'New',\n marketUpdate: 'Market update available — upgrade',\n updateAll: 'Update all',\n tabThemes: 'Themes',\n themeApply: 'Use',\n themeActive: 'Active',\n themeEmpty: 'No more theme plugins in the catalog yet — stay tuned',\n progressHint: 'First installs download and resolve dependencies — large plugins can take 1-3 minutes',\n toastReady: 'installed and live',\n toastTheme: 'is now active. Switch any time in Settings → Plugin Market → Themes',\n gotIt: 'Got it',\n}\n","/**\n * Response shapes of the /dsh-market/* host routes plus the pure helpers the\n * Market UI shares between its section and toast components.\n */\n\n/** Localized text keyed by language ('zh' / 'en'). */\nexport type LocalizedText = Record<string, string | undefined>\n\n/** One registry entry from /dsh-market/registry. */\nexport interface RegistryPlugin {\n name: string\n owner: string\n url: string\n npm?: string\n category: string\n description?: LocalizedText\n stars?: number\n added?: string\n install?: string\n}\n\n/** The catalog payload under `registry` in /dsh-market/registry. */\nexport interface Registry {\n count: number\n categories: Record<string, LocalizedText>\n plugins: RegistryPlugin[]\n}\n\n/** Profile dependency map: package name → install spec. */\nexport type InstalledMap = Record<string, string>\n\n/** Per-package update status from /dsh-market/updates. */\nexport interface UpdateStatus {\n updateAvailable?: boolean\n version?: string\n kind?: string\n}\n\n/** Poll payload from /dsh-market/status. */\nexport interface MarketStatus {\n active?: boolean\n lastLine?: string\n seconds?: number\n installed?: InstalledMap\n pnpm?: boolean\n boot?: string\n}\n\n/** Registered theme definition surfaced by the theme service snapshot. */\nexport interface ThemeDef {\n id: string\n colorScheme?: string\n tokens?: Record<string, string | undefined>\n}\n\n/** Theme service snapshot; null when the composition has no theme service. */\nexport interface ThemeSnapshot {\n preference: string\n themes: ThemeDef[]\n}\n\n/** Bound locale translator for the dsh-market namespace. */\nexport type Translate = (key: string) => string\n\nexport function avatarColor(name: string): string {\n let hash = 0\n for (let i = 0; i < name.length; i++) hash = (hash * 31 + name.charCodeAt(i)) | 0\n return 'hsl(' + (((hash % 360) + 360) % 360) + ' 55% 52%)'\n}\n\nexport function repoOf(url: string): string | null {\n // Plain repo urls plus /tree/<branch>/<subpath> monorepo links.\n const m = /^https:\\/\\/github\\.com\\/([^/]+\\/[^/]+?)(?:\\/tree\\/.+)?\\/?$/.exec(url)\n return m ? m[1]! : null\n}\n\nexport function readSession(key: string): any {\n try { return JSON.parse(sessionStorage.getItem(key) || 'null') } catch { return null }\n}\n\n/** Heuristic: plugins that target a terminal surface rather than the web UI. */\nexport function looksTerminal(plugin: RegistryPlugin, lang: string): boolean {\n const desc = (plugin.description && (plugin.description[lang] || plugin.description.en)) || ''\n return /\\b(tui|cli|tty|terminal)\\b|终端|命令行/i.test(plugin.name + ' ' + desc)\n}\n\n/** A registry plugin counts as installed when its package name, npm name, or GitHub spec appears in the profile dependencies. */\nexport function isInstalled(plugin: RegistryPlugin, installed: InstalledMap): boolean {\n if (installed[plugin.name] !== undefined) return true\n if (plugin.npm && installed[plugin.npm] !== undefined) return true\n const repo = repoOf(plugin.url)\n if (repo === null) return false\n const needle = ('github:' + repo).toLowerCase()\n return Object.values(installed).some(spec => String(spec).toLowerCase().includes(needle))\n}\n\n/**\n * The brand mark (assets/logo.svg — shared block-grid mark with\n * awesome-dsh-plugin), inlined so the header needs no extra request.\n */\nexport const LOGO_URI = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 128\"><rect width=\"128\" height=\"128\" rx=\"28\" fill=\"#f6f2ea\"/><g transform=\"translate(15.7 16.7) scale(0.3) translate(-112 -78)\"><g fill=\"#2b2620\"><rect x=\"112\" y=\"112\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"112\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"112\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"112\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"312\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"312\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/></g><rect x=\"346\" y=\"78\" width=\"88\" height=\"88\" rx=\"14\" fill=\"#c0392b\" transform=\"rotate(9 390 122)\"/></g></svg>')\n\n/** Four representative colors for a theme card's preview strip. */\nexport function themeSwatch(def: ThemeDef): string[] {\n const tk = def.tokens || {}\n const pick = (names: string[]) => { for (const n of names) { if (tk[n]) return tk[n]! } return null }\n const dark = def.colorScheme === 'dark'\n return [\n pick(['--dsw-alias-bg-base', '--dsw-alias-bg-layer-1']) || (dark ? '#0f1115' : '#ffffff'),\n pick(['--dsw-alias-bg-layer-2', '--dsw-alias-bg-overlay']) || (dark ? '#1a1d23' : '#f3f4f6'),\n pick(['--dsw-alias-brand-primary']) || '#4f6ef7',\n pick(['--dsw-alias-label-primary']) || (dark ? '#e5e7eb' : '#1f2328'),\n ]\n}\n","/**\n * Post-reload confirmation via the official Toast primitive: shown once after\n * the refresh that follows a hot install or theme switch, so the user lands\n * back in their flow with visible proof.\n */\nimport { useState } from 'react'\nimport { Toast } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { readSession } from './market-data.ts'\nimport type { Translate } from './market-data.ts'\n\nexport function InstallToast(props: { t: Translate }) {\n const t = props.t\n const [mode] = useState(() => {\n const value = sessionStorage.getItem('dshm-toast-mode')\n sessionStorage.removeItem('dshm-toast-mode')\n return value\n })\n const [names, setNames] = useState<string[]>(() => {\n const value = readSession('dshm-toast')\n sessionStorage.removeItem('dshm-toast')\n return Array.isArray(value) ? value : []\n })\n if (names.length === 0) return null\n return (\n <Toast\n text={names.join(', ') + ' ' + t(mode === 'theme' ? 'toastTheme' : 'toastReady')}\n icon={<span>✨</span>}\n onDone={() => setNames([])}\n />\n )\n}\n","/**\n * The Market settings section: Discover / Themes / Installed tabs over the\n * /dsh-market/* host routes, with install/update/uninstall flows and the\n * pending-restart bookkeeping in sessionStorage.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport { Button, IconChevronDownOutline14, IconChevronUpOutline14, IconSearchOutline16, Input, Modal, Pill, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './Market.module.css'\nimport {\n avatarColor, isInstalled, LOGO_URI, looksTerminal, readSession, repoOf, themeSwatch,\n} from './market-data.ts'\nimport type {\n InstalledMap, Registry, RegistryPlugin, ThemeSnapshot, Translate, UpdateStatus,\n} from './market-data.ts'\n\n/**\n * Card avatar: the plugin owner's GitHub avatar (no API, browser-cached),\n * falling back to the initial-letter tile when it can't load.\n */\nfunction OwnerAvatar({ name, owner }: { name: string; owner: string }) {\n const [failed, setFailed] = useState(false)\n if (failed || owner === '') {\n return (\n <div className={css.av} style={{ background: avatarColor(name) }}>\n {name.replace(/^dsh[-_]/i, '').charAt(0).toUpperCase() || 'P'}\n </div>\n )\n }\n return (\n <img\n className={css.av}\n src={`https://github.com/${encodeURIComponent(owner)}.png?size=96`}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setFailed(true)}\n />\n )\n}\n\nexport interface MarketSectionProps {\n t: Translate\n locale: {\n subscribe(callback: () => void): () => void\n getSnapshot(): { active: string }\n }\n theme: { setTheme(id: string): void }\n themeStore: {\n subscribe(callback: () => void): () => void\n getSnapshot(): ThemeSnapshot | null\n }\n}\n\nexport function MarketSection(props: MarketSectionProps) {\n const t = props.t\n const localeSnap = useSyncExternalStore(\n cb => props.locale.subscribe(cb),\n () => props.locale.getSnapshot(),\n )\n const lang = String(localeSnap.active).toLowerCase().startsWith('zh') ? 'zh' : 'en'\n // null when the composition has no theme service — the Themes tab hides.\n const themeSnap = useSyncExternalStore(\n props.themeStore.subscribe,\n props.themeStore.getSnapshot,\n )\n const [data, setData] = useState<Registry | null>(null)\n const [loadError, setLoadError] = useState(false)\n const [installed, setInstalled] = useState<InstalledMap>({})\n const [skins, setSkins] = useState<string[]>([])\n const [tab, setTab] = useState(() => {\n const saved = sessionStorage.getItem('dshm-tab')\n if (saved !== null) sessionStorage.removeItem('dshm-tab')\n return saved || 'discover'\n })\n const [q, setQ] = useState('')\n const [cat, setCat] = useState('all')\n const [confirming, setConfirming] = useState<RegistryPlugin | null>(null)\n const [busyUrl, setBusyUrl] = useState<string | null>(null)\n const [doneUrls, setDoneUrls] = useState<string[]>([])\n const [installError, setInstallError] = useState<string | null>(null)\n const [updates, setUpdates] = useState<Record<string, UpdateStatus>>({})\n const [updatingName, setUpdatingName] = useState<string | null>(null)\n const [updatingAll, setUpdatingAll] = useState(false)\n const [updatedNames, setUpdatedNames] = useState<string[]>([])\n const [hotUrls, setHotUrls] = useState<string[]>([])\n const [hotNames, setHotNames] = useState<string[]>([])\n const [progressLine, setProgressLine] = useState<string | null>(null)\n const [removeArmed, setRemoveArmed] = useState<string | null>(null)\n const [removingName, setRemovingName] = useState<string | null>(null)\n const [removedCount, setRemovedCount] = useState(0)\n const [envReady, setEnvReady] = useState(true)\n const [envFixing, setEnvFixing] = useState(false)\n const [envFailed, setEnvFailed] = useState(false)\n const [bootId, setBootId] = useState<string | null>(null)\n const [showTop, setShowTop] = useState(false)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const [sort, setSort] = useState('hot')\n const [catsOpen, setCatsOpen] = useState(false)\n // How many category pills fit in the two collapsed rows (measured once —\n // the settings panel width is fixed); null = measuring render with all\n // pills clamped, then slice so the chevron flows inline after the last one.\n const [visibleCats, setVisibleCats] = useState<number | null>(null)\n const catsWrapRef = useRef<HTMLDivElement | null>(null)\n\n const refreshInstalled = useCallback((force?: boolean) => {\n fetch('/dsh-market/installed', { cache: 'no-store' })\n .then(res => res.json())\n .then(body => {\n setInstalled(body.installed || {})\n setSkins(body.live || [])\n })\n .catch(() => {})\n fetch('/dsh-market/updates' + (force === true ? '?force=1' : ''), { cache: 'no-store' })\n .then(res => res.json())\n .then(body => setUpdates(body.updates || {}))\n .catch(() => {})\n }, [])\n\n useEffect(() => {\n fetch('/dsh-market/registry', { cache: 'no-store' })\n .then(res => { if (!res.ok) throw new Error('HTTP ' + res.status); return res.json() })\n .then(body => setData(body.registry))\n .catch(() => setLoadError(true))\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then(status => {\n setEnvReady(status.pnpm !== false)\n if (typeof status.boot === 'string') setBootId(status.boot)\n })\n .catch(() => {})\n refreshInstalled()\n }, [refreshInstalled])\n\n // Pending-restart flags survive tab switches and page reloads, scoped to\n // one host process: a different boot id means the restart happened and the\n // stale banner must not resurrect.\n useEffect(() => {\n if (bootId === null) return\n const saved = readSession('dshm-restart')\n if (saved === null) return\n if (saved.boot !== bootId) {\n sessionStorage.removeItem('dshm-restart')\n return\n }\n if (Array.isArray(saved.doneUrls) && saved.doneUrls.length > 0) setDoneUrls(saved.doneUrls)\n if (Array.isArray(saved.updated) && saved.updated.length > 0) setUpdatedNames(saved.updated)\n if (typeof saved.removed === 'number' && saved.removed > 0) setRemovedCount(saved.removed)\n }, [bootId])\n\n useEffect(() => {\n if (bootId === null) return\n if (doneUrls.length === 0 && updatedNames.length === 0 && removedCount === 0) return\n sessionStorage.setItem('dshm-restart', JSON.stringify({\n boot: bootId,\n doneUrls,\n updated: updatedNames,\n removed: removedCount,\n }))\n }, [bootId, doneUrls, updatedNames, removedCount])\n\n const fixEnv = useCallback(() => {\n setEnvFixing(true)\n setEnvFailed(false)\n fetch('/dsh-market/setup-pnpm', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .then(res => res.json())\n .then(body => {\n if (body.ok) setEnvReady(true)\n else setEnvFailed(true)\n })\n .catch(() => setEnvFailed(true))\n .finally(() => setEnvFixing(false))\n }, [])\n\n // Recover an install whose HTTP response was lost (page navigated away or\n // the connection dropped): the pending marker survives in sessionStorage and\n // the poll below converges the button state from the host's ground truth.\n useEffect(() => {\n const pending = readSession('dshm-pending')\n if (pending !== null && typeof pending.url === 'string') setBusyUrl(pending.url)\n }, [])\n\n useEffect(() => {\n if (busyUrl === null && updatingName === null) {\n setProgressLine(null)\n return\n }\n const timer = setInterval(() => {\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then(status => {\n if (status.active) {\n setProgressLine((status.lastLine || '…') + ' (' + status.seconds + 's)')\n } else {\n setProgressLine(null)\n setInstalled(status.installed || {})\n const pending = readSession('dshm-pending')\n if (pending !== null && busyUrl !== null) {\n const nowInstalled = data !== null && data.plugins.some(p =>\n p.url === busyUrl && isInstalled(p, status.installed || {}))\n if (nowInstalled) {\n sessionStorage.removeItem('dshm-pending')\n setDoneUrls(urls => urls.includes(busyUrl) ? urls : urls.concat(busyUrl))\n setBusyUrl(null)\n }\n }\n }\n })\n .catch(() => {})\n }, 2000)\n return () => clearInterval(timer)\n }, [busyUrl, updatingName, data])\n\n const plugins = useMemo(() => {\n if (data === null) return []\n const query = q.trim().toLowerCase()\n const list = data.plugins.filter(p => {\n if (cat !== 'all' && p.category !== cat) return false\n if (query === '') return true\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n return p.name.toLowerCase().includes(query)\n || p.owner.toLowerCase().includes(query)\n || desc.toLowerCase().includes(query)\n })\n if (sort === 'hot') {\n return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1))\n }\n if (sort === 'new') {\n return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)))\n }\n return list\n }, [data, q, cat, lang, sort])\n\n const doInstall = useCallback((plugin: RegistryPlugin) => {\n setConfirming(null)\n setInstallError(null)\n setBusyUrl(plugin.url)\n sessionStorage.setItem('dshm-pending', JSON.stringify({ url: plugin.url }))\n fetch('/dsh-market/install', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ url: plugin.url }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n sessionStorage.removeItem('dshm-pending')\n if (status === 200 && body.ok && body.hot && plugin.category === 'theme') {\n // Themes auto-activate on install; reload straight into the Themes\n // tab so the new look is on screen immediately.\n sessionStorage.setItem('dshm-toast', JSON.stringify([plugin.name]))\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n return\n }\n if (status === 200 && body.ok) {\n sessionStorage.setItem('dshm-tab', 'installed')\n if (body.hot) {\n setHotUrls(urls => urls.includes(plugin.url) ? urls : urls.concat(plugin.url))\n setHotNames(names => names.includes(plugin.name) ? names : names.concat(plugin.name))\n } else {\n setDoneUrls(urls => urls.includes(plugin.url) ? urls : urls.concat(plugin.url))\n }\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n const detail = text(body.error) || [text(body.stderr), text(body.stdout)].filter(Boolean).join('\\n').trim() || ('exit ' + body.exitCode)\n setInstallError(t('installFail') + ': ' + plugin.name + ' — ' + detail.trim().slice(-600))\n }\n })\n .catch(error => {\n sessionStorage.removeItem('dshm-pending')\n setInstallError(t('installFail') + ': ' + String(error))\n })\n .finally(() => setBusyUrl(null))\n }, [refreshInstalled, t])\n\n const doUpdate = useCallback((name: string) => {\n setInstallError(null)\n setUpdatingName(name)\n return fetch('/dsh-market/update', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n setUpdatedNames(names => names.concat(name))\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n const detail = text(body.error) || [text(body.stderr), text(body.stdout)].filter(Boolean).join('\\n').trim() || ('exit ' + body.exitCode)\n setInstallError(t('updateFail') + ': ' + name + ' — ' + detail.trim().slice(-600))\n }\n })\n .catch(error => setInstallError(t('updateFail') + ': ' + String(error)))\n .finally(() => setUpdatingName(null))\n }, [refreshInstalled, t])\n\n const doUseSkin = useCallback((name: string) => {\n setInstallError(null)\n fetch('/dsh-market/use-skin', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n sessionStorage.setItem('dshm-toast', JSON.stringify([name]))\n sessionStorage.setItem('dshm-toast-mode', 'theme')\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n } else {\n setInstallError(String(body.error || 'failed'))\n }\n })\n .catch(error => setInstallError(String(error)))\n }, [])\n\n const doUninstall = useCallback((name: string) => {\n setRemoveArmed(null)\n setInstallError(null)\n setRemovingName(name)\n return fetch('/dsh-market/uninstall', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n if (!body.hot) setRemovedCount(n => n + 1)\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n setInstallError((text(body.error) || text(body.stderr) || 'error').trim().slice(-600))\n }\n })\n .catch(error => setInstallError(String(error)))\n .finally(() => setRemovingName(null))\n }, [refreshInstalled])\n\n // The market itself stays out of the batch: its update reloads this page\n // mid-run, which would strand the remaining items.\n const selfName = installed['dshmarket'] !== undefined ? 'dshmarket' : 'dsh-market'\n const updatableNames = Object.keys(installed).filter(\n name => name !== selfName && !updatedNames.includes(name) && updates[name] && updates[name].updateAvailable,\n )\n\n const doUpdateAll = useCallback(() => {\n const names = updatableNames.slice()\n setUpdatingAll(true)\n const next = () => {\n const name = names.shift()\n if (name === undefined) {\n setUpdatingAll(false)\n return\n }\n doUpdate(name).then(next, next)\n }\n next()\n }, [updatableNames, doUpdate])\n\n const pendingRestart = doneUrls.length + updatedNames.length + removedCount\n const hasUpdates = Object.keys(installed).some(\n name => !updatedNames.includes(name) && updates[name] && updates[name].updateAvailable,\n )\n\n const themePlugins = data === null ? [] : data.plugins\n .filter(p => p.category === 'theme')\n .sort((a, b) => (b.stars || 0) - (a.stars || 0))\n\n const pluginCard = (p: RegistryPlugin) => {\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n const done = doneUrls.includes(p.url) || hotUrls.includes(p.url)\n const already = isInstalled(p, installed)\n const busy = busyUrl === p.url\n return (\n <div key={p.url} className={css.card}>\n <div className={css.row1}>\n <OwnerAvatar name={p.name} owner={p.owner || ''} />\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{p.name}</div>\n <div className={css.owner}>\n {p.owner}\n {typeof p.stars === 'number' && <span className={css.star}>{' · ★ ' + p.stars}</span>}\n </div>\n </div>\n <span className={css.grow} />\n <a className={css.src} href={p.url} target=\"_blank\" rel=\"noreferrer\" style={{ alignSelf: 'flex-start', flexShrink: 0 }}>{t('viewSource')}</a>\n </div>\n <div className={css.desc}>{desc}</div>\n <div className={css.foot}>\n <span className={css.tag}>\n {(data!.categories[p.category] && (data!.categories[p.category]![lang] || data!.categories[p.category]!.en)) || p.category}\n </span>\n <span className={css.grow} />\n {done\n ? <span className={css.okState}>{t('installedBadge')}</span>\n : already\n ? <span className={css.okState}>{t('alreadyInstalled')}</span>\n : busy\n ? <Button variant=\"primary\" size=\"sm\" disabled>{t('installing')}</Button>\n : (\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={busyUrl !== null || !envReady}\n onClick={() => setConfirming(p)}\n >{t('install')}</Button>\n )}\n </div>\n {busy && (\n <div className={css.progress}>\n <span className={css.spin} />\n <code className={css.grow}>{progressLine || t('progressHint')}</code>\n </div>\n )}\n </div>\n )\n }\n\n const installedNameOf = (p: RegistryPlugin) => {\n if (installed[p.name] !== undefined) return p.name\n const repo = repoOf(p.url)\n if (repo === null) return null\n const needle = ('github:' + repo).toLowerCase()\n for (const [name, spec] of Object.entries(installed)) {\n if (String(spec).toLowerCase().includes(needle)) return name\n }\n return null\n }\n\n // Plugins loaded at boot (bundle-layer skins) aren't in the shim list but\n // are just as live; the boot manifest is the page's own record of them.\n const bootEntries = (typeof window !== 'undefined' && window.__DSH_BOOT__ && Array.isArray(window.__DSH_BOOT__.entries))\n ? window.__DSH_BOOT__.entries\n : []\n\n // Unified card for the Themes tab: install → use/in-use → uninstall.\n const themePluginCard = (p: RegistryPlugin) => {\n const instName = installedNameOf(p)\n if (instName === null) return pluginCard(p)\n const mounted = skins.includes(instName) || bootEntries.some(e => e.id === instName)\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n return (\n <div key={p.url} className={css.card}>\n <div className={css.row1}>\n <OwnerAvatar name={p.name} owner={p.owner || ''} />\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{p.name}</div>\n <div className={css.owner}>\n {p.owner}\n {typeof p.stars === 'number' && <span className={css.star}>{' · ★ ' + p.stars}</span>}\n </div>\n </div>\n <span className={css.grow} />\n <a className={css.src} href={p.url} target=\"_blank\" rel=\"noreferrer\" style={{ alignSelf: 'flex-start', flexShrink: 0 }}>{t('viewSource')}</a>\n </div>\n <div className={css.desc}>{desc}</div>\n <div className={css.foot}>\n <span className={css.grow} />\n {removingName === instName\n ? <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} disabled>{t('uninstalling')}</Button>\n : removeArmed === instName\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.dangerArmed}\n onClick={() => doUninstall(instName).then(() => {\n if (mounted) {\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n }\n })}\n >{t('confirmRemove')}</Button>\n )\n : <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} onClick={() => setRemoveArmed(instName)}>{t('uninstall')}</Button>}\n {mounted\n ? <span className={css.okState}>{t('themeActive')}</span>\n : <Button variant=\"primary\" size=\"sm\" onClick={() => doUseSkin(instName)}>{t('themeApply')}</Button>}\n </div>\n </div>\n )\n }\n\n const themeCard = (id: string, label: string, swatch: string[]) => {\n const active = themeSnap !== null && themeSnap.preference === id\n return (\n <div key={'th-' + id} className={css.card}>\n <div className={css.swatches}>{swatch.map((c, i) => <i key={i} style={{ background: c }} />)}</div>\n <div className={css.foot}>\n <span className={css.nm}>{label}</span>\n <span className={css.grow} />\n {active\n ? <span className={css.okState}>{t('themeActive')}</span>\n : (\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => { try { props.theme.setTheme(id) } catch (error) { setInstallError(String(error)) } }}\n >{t('themeApply')}</Button>\n )}\n </div>\n </div>\n )\n }\n\n const categories = data === null ? [] : Object.keys(data.categories)\n\n useLayoutEffect(() => { setVisibleCats(null) }, [lang, categories.length])\n useLayoutEffect(() => {\n if (catsOpen || visibleCats !== null) return\n const el = catsWrapRef.current\n if (el === null) return\n const chips = [...el.children].filter((c): c is HTMLElement => (c as HTMLElement).dataset?.chip === '1')\n if (chips.length === 0) return\n const first = chips[0]!\n const rowThreeTop = first.offsetTop + (first.offsetHeight + 6) * 2 - 3\n let fits = 0\n for (const chip of chips) { if (chip.offsetTop < rowThreeTop) fits += 1 }\n // Reserve the tail slot of row two for the chevron itself.\n setVisibleCats(fits >= chips.length ? fits : Math.max(1, fits - 1))\n }, [catsOpen, visibleCats, data])\n\n return (\n <div className={css.root}>\n <div className={css.head}>\n <div className={css.titleRow}>\n <img src={LOGO_URI} width={22} height={22} alt=\"\" style={{ borderRadius: '5px', flexShrink: 0 }} />\n <h2 className={css.title}>{t('nav')}</h2>\n {(() => {\n const self = installed['dshmarket'] !== undefined ? 'dshmarket' : 'dsh-market'\n return updates[self] && updates[self].updateAvailable && !updatedNames.includes(self)\n && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingName !== null || busyUrl !== null}\n onClick={() => { setTab('installed'); doUpdate(self) }}\n >{updatingName === self ? t('updating') : t('marketUpdate')}</Button>\n )\n })()}\n {updatableNames.length >= 2 && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingAll || updatingName !== null || busyUrl !== null || removingName !== null}\n onClick={() => { setTab('installed'); doUpdateAll() }}\n >{updatingAll ? t('updating') : t('updateAll') + ' (' + updatableNames.length + ')'}</Button>\n )}\n </div>\n <div className={css.sub}>\n {t('subtitle') + (data ? ' · ' + data.count : '') + ' · '}\n <a className={css.src} href=\"/dsh-market/logs\" download=\"dsh-market-log.txt\">{t('exportLog')}</a>\n </div>\n <div className={css.tabs}>\n <button className={tab === 'discover' ? `${css.tab} ${css.on}` : css.tab} onClick={() => setTab('discover')}>{t('tabDiscover')}</button>\n {themeSnap !== null && <button className={tab === 'themes' ? `${css.tab} ${css.on}` : css.tab} onClick={() => setTab('themes')}>{t('tabThemes')}</button>}\n <button className={tab === 'installed' ? `${css.tab} ${css.on}` : css.tab} onClick={() => { setTab('installed'); refreshInstalled(true) }}>\n {t('tabInstalled') + (Object.keys(installed).length > 0 ? ' (' + Object.keys(installed).length + ')' : '')}\n {hasUpdates && <StateDot state=\"error\" size={7} className={css.dot} />}\n </button>\n <span className={css.grow} />\n <Input className={css.searchInline} icon={<IconSearchOutline16 size={14} />} placeholder={t('searchPh')} value={q} onChange={e => setQ(e.target.value)} />\n </div>\n {!envReady && (\n <div className={css.restart}>\n <span>🧩</span>\n <span className={css.grow}>{envFailed ? t('envFixFail') : t('envMissing')}</span>\n {!envFailed && (\n <Button variant=\"primary\" size=\"sm\" disabled={envFixing} onClick={fixEnv}>\n {envFixing ? t('envFixing') : t('envFix')}\n </Button>\n )}\n </div>\n )}\n {hotUrls.length > 0 && (\n <div className={css.restart}>\n <span>✨</span>\n <span className={css.grow}><b>{hotUrls.length}</b> {t('hotBanner')}</span>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => {\n sessionStorage.setItem('dshm-toast', JSON.stringify(hotNames))\n sessionStorage.setItem('dshm-tab', 'installed')\n location.reload()\n }}\n >{t('refresh')}</Button>\n </div>\n )}\n {pendingRestart > 0 && (\n <div className={css.restart}>\n <span>🔄</span>\n <span className={css.grow}><b>{pendingRestart}</b> {t('restartBanner')}</span>\n <span title={t('restartHint')}>ℹ️</span>\n </div>\n )}\n </div>\n {installError !== null && <div className={css.err}>{installError}</div>}\n <div\n className={css.body}\n ref={bodyRef}\n onScroll={e => setShowTop(e.currentTarget.scrollTop > 400)}\n >\n {tab === 'discover'\n ? loadError\n ? <div className={css.empty}>{t('loadFail')}</div>\n : data === null\n ? <div className={css.loading}><span className={css.spin} />{t('loading')}</div>\n : (\n <>\n <div className={css.cats}>\n <div className={css.catsRow}>\n <div ref={catsWrapRef} className={catsOpen || visibleCats === null ? `${css.catsWrap} ${css.catsCollapsed}` : css.catsWrap}>\n {(() => {\n // Collapsed, the selected category is pulled to the front so it never hides.\n const ordered = catsOpen || cat === 'all' ? categories : [cat, ...categories.filter(id => id !== cat)]\n const shown = catsOpen || visibleCats === null ? ordered : ordered.slice(0, Math.max(0, visibleCats - 1))\n return (\n <>\n <Pill data-chip=\"1\" active={cat === 'all'} onClick={() => setCat('all')}>{t('all')}</Pill>\n {shown.map(id => (\n <Pill\n key={id}\n data-chip=\"1\"\n active={cat === id}\n onClick={() => setCat(id)}\n >{(data.categories[id] && (data.categories[id]![lang] || data.categories[id]!.en)) || id}</Pill>\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={css.catsToggle}\n icon={catsOpen ? <IconChevronUpOutline14 size={14} /> : <IconChevronDownOutline14 size={14} />}\n aria-label={catsOpen ? t('catsLess') : t('catsMore')}\n onClick={() => setCatsOpen(o => !o)}\n />\n </>\n )\n })()}\n </div>\n <div className={css.sort}>\n {['hot', 'new'].map(key => (\n <button\n key={key}\n className={sort === key ? css.on : ''}\n onClick={() => setSort(key)}\n >{t(key === 'hot' ? 'sortHot' : 'sortNew')}</button>\n ))}\n </div>\n </div>\n </div>\n {plugins.length === 0\n ? <div className={css.empty}>{t('empty')}</div>\n : <div className={css.grid}>{plugins.map(pluginCard)}</div>}\n </>\n )\n : tab === 'themes' && themeSnap !== null\n ? (\n <>\n {/* Light/dark/system live in the official Appearance setting; this\n tab only shows what that setting can't: registered third-party\n palettes (none in the wild yet) and installable theme plugins. */}\n {(() => {\n const extra = themeSnap.themes.filter(def => def.id !== 'light' && def.id !== 'dark')\n return extra.length > 0 && (\n <div className={`${css.grid} ${css.themesGrid}`}>\n {extra.map(def => themeCard(def.id, def.id, themeSwatch(def)))}\n </div>\n )\n })()}\n {data === null\n ? <div className={css.loading}><span className={css.spin} />{t('loading')}</div>\n : themePlugins.length === 0\n ? <div className={css.empty}>{t('themeEmpty')}</div>\n : <div className={css.grid}>{themePlugins.map(themePluginCard)}</div>}\n </>\n )\n : Object.keys(installed).length === 0\n ? <div className={css.empty}>{t('installedEmpty')}</div>\n : Object.entries(installed).map(([name, spec]) => {\n const entry = data === null ? undefined : data.plugins.find(p => p.name === name\n || (repoOf(p.url) !== null && String(spec).toLowerCase().includes(('github:' + repoOf(p.url)).toLowerCase())))\n const status = updates[name]\n const version = status && status.version ? 'v' + status.version : ''\n const specText = String(spec)\n const ghSpec = /^github:([A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+?)(?:#|$)/.exec(specText)\n const repoUrl = entry !== undefined ? entry.url : ghSpec !== null ? 'https://github.com/' + ghSpec[1] : null\n return (\n <div key={name} className={css.irow}>\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{name}{version && <span className={css.owner}>{' ' + version}</span>}</div>\n {repoUrl !== null\n ? <a className={`${css.spec} ${css.src}`} href={repoUrl} target=\"_blank\" rel=\"noreferrer\" style={{ display: 'inline-block' }}>{specText}</a>\n : <div className={css.spec}>{specText}</div>}\n {entry !== undefined && (\n <div className={`${css.desc} ${css.descTight}`}>\n {(entry.description && (entry.description[lang] || entry.description.en)) || ''}\n </div>\n )}\n {updatingName === name && (\n <div className={css.progress}>\n <span className={css.spin} />\n <code className={css.grow}>{progressLine || t('progressHint')}</code>\n </div>\n )}\n </div>\n <span className={css.grow} />\n {repoUrl !== null && <a className={css.src} href={repoUrl + '#readme'} target=\"_blank\" rel=\"noreferrer\">{t('readme')}</a>}\n {updatedNames.includes(name)\n ? <span className={css.okState}>{t('updated')}</span>\n : updatingName === name\n ? <Button variant=\"primary\" size=\"sm\" className={css.warnBtn} disabled>{t('updating')}</Button>\n : status && status.updateAvailable\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingName !== null}\n onClick={() => doUpdate(name)}\n >{t('update')}</Button>\n )\n : status && status.kind === 'linked'\n ? <span className={css.owner}>{t('linkedDev')}</span>\n : <span className={css.owner}>{t('upToDate')}</span>}\n {name !== 'dsh-market' && name !== 'dshmarket' && (\n removingName === name\n ? <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} disabled>{t('uninstalling')}</Button>\n : removeArmed === name\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.dangerArmed}\n onClick={() => doUninstall(name)}\n onMouseLeave={() => setRemoveArmed(null)}\n >{t('confirmRemove')}</Button>\n )\n : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={css.dangerBtn}\n disabled={removingName !== null || busyUrl !== null || updatingName !== null}\n onClick={() => setRemoveArmed(name)}\n >{t('uninstall')}</Button>\n )\n )}\n </div>\n )\n })}\n </div>\n {showTop && (\n <button\n className={css.top}\n title={t('backTop')}\n onClick={() => { const el = bodyRef.current; if (el) el.scrollTo({ top: 0, behavior: 'smooth' }) }}\n >↑</button>\n )}\n {confirming !== null && (\n <Modal\n open\n onClose={() => setConfirming(null)}\n title={t('confirmTitle') + ' ' + confirming.name + '?'}\n description={(confirming.description && (confirming.description[lang] || confirming.description.en)) || ''}\n footer={(\n <>\n <Button variant=\"ghost\" onClick={() => setConfirming(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" onClick={() => doInstall(confirming)}>{t('confirm')}</Button>\n </>\n )}\n >\n <details className={css.cmdDetails}>\n <summary className={css.cmdSummary}>{t('cmdDetails')}</summary>\n <div className={css.cmd}>{confirming.install}</div>\n </details>\n {looksTerminal(confirming, lang) && (\n <p className={css.warnLine}>\n {'🖥️ ' + t('terminalWarn') + ' '}\n <a className={css.src} href={confirming.url + '#readme'} target=\"_blank\" rel=\"noreferrer\">{t('readme')}</a>\n </p>\n )}\n <p className={css.modalNote}>{'⚠️ ' + t('confirmWarn')}</p>\n </Modal>\n )}\n </div>\n )\n}\n","/**\n * dsh-market client: registers a \"Market\" settings section rendering the\n * plugin market UI, plus the post-install toast in the shell overlay layer.\n * Built by tsdown into the __ModuleLoader__ factory bundle at\n * client/client.js; the only externals are the loader module table's react\n * entries.\n */\nimport { createElement as h } from 'react'\nimport { en, zh } from './locales.ts'\nimport { InstallToast } from './InstallToast.tsx'\nimport { MarketSection } from './MarketSection.tsx'\nimport type { ThemeSnapshot, Translate } from './market-data.ts'\n\nconst NS = 'dsh-market'\n\n/** The subset of the theme service this plugin touches. */\ninterface ThemeService {\n getTheme(): ThemeSnapshot | null\n setTheme(id: string): void\n}\n\n/** The subset of the locale service this plugin touches. */\ninterface LocaleService {\n register(namespace: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\n bind(namespace: string): Translate\n subscribe(callback: () => void): () => void\n getSnapshot(): { active: string }\n}\n\n/** The subset of the slots service this plugin touches. */\ninterface SlotsService {\n inject(slot: string, register: () => unknown): void\n register(meta: Record<string, unknown>, component: () => unknown): unknown\n}\n\n/** The client cordis context shape this plugin relies on (structural: the\n * host provides the real Context; typing the touched surface keeps this\n * external package free of monorepo-internal type dependencies). */\ninterface MarketClientContext {\n effect(callback: () => unknown, label?: string): void\n on(event: string, callback: () => void): () => void\n locale: LocaleService\n slots: SlotsService\n theme: ThemeService\n}\n\nexport const name = 'dsh-market'\n// 'theme' is safe to require: ui-layout (mandatory in every web composition)\n// already hard-depends on it. This cordis's object-form inject means\n// intercept config, NOT {required,optional} — do not use it here.\nexport const inject = ['slots', 'locale', 'theme']\nexport function apply(ctx: MarketClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-market: dictionaries')\n const t = ctx.locale.bind(NS)\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'market',\n order: 40,\n label: () => t('nav'),\n locale: NS,\n inject: () => ({ t }),\n }, () => h(MarketSection, {\n t,\n locale: ctx.locale,\n theme: ctx.theme,\n themeStore: {\n subscribe: (cb: () => void) => ctx.on('theme/change', cb),\n getSnapshot: () => ctx.theme.getTheme(),\n },\n })))\n\n const Toast = () => h(InstallToast, { t })\n ctx.slots.inject('shell.overlay', () => ctx.slots.register({\n name: 'shell.overlay',\n id: 'dsh-market-toast',\n label: () => 'dsh-market',\n }, Toast))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useState","Toast","useState","css","useSyncExternalStore","useRef","useCallback","useMemo","Button","StateDot","Input","IconSearchOutline16","Pill","IconChevronUpOutline14","IconChevronDownOutline14","Modal","h"],"sources":["../src/client/locales.ts","../src/client/market-data.ts","../src/client/InstallToast.tsx","../src/client/MarketSection.tsx","../src/client/index.ts"],"sourcesContent":["/** zh/en dictionaries for the Market settings section and install toast. */\n\nexport const zh = {\n nav: '插件市场',\n subtitle: '发现社区为 DeepSeek Harness 打造的能力',\n searchPh: '搜索插件,比如:通知、终端、记忆…',\n tabDiscover: '发现',\n tabInstalled: '已安装',\n all: '全部',\n install: '安装',\n installing: '安装中…',\n installedBadge: '✓ 已装好',\n alreadyInstalled: '✓ 已安装',\n restartBanner: '项变更完成,重启 DeepSeek Harness 后生效',\n uninstall: '卸载',\n confirmRemove: '确认卸载?',\n uninstalling: '卸载中…',\n restartHint: '重启方式:关闭当前 dsh 进程后重新运行(例如 dsh web)',\n confirmTitle: '安装',\n confirmWarn: '插件是社区第三方代码。安装即表示你信任该来源;构建脚本默认被禁止执行。',\n cancel: '取消',\n empty: '没有匹配的插件',\n installedEmpty: '还没有装过社区插件,去「发现」页逛逛吧',\n loadFail: '插件目录加载失败,请稍后重试',\n installFail: '安装失败',\n viewSource: '源码',\n hotBanner: '个新插件已装好,刷新页面即可使用',\n refresh: '刷新页面',\n update: '更新',\n updating: '更新中…',\n updated: '✓ 已更新,重启后生效',\n updateFail: '更新失败',\n upToDate: '已是最新',\n linkedDev: '本地开发链接',\n exportLog: '导出日志',\n readme: '使用说明',\n terminalWarn: '这看起来是终端/命令行插件:装进网页版可能无效,甚至导致 DeepSeek Harness 无法启动。建议先看它的使用说明,按说明装进对应的 profile。',\n envMissing: '还差一个小组件才能安装插件',\n envFix: '自动装好',\n envFixing: '正在准备…',\n envFixFail: '自动准备没成功,请点\"导出日志\"把文件发给我们反馈',\n loading: '正在加载插件目录…',\n backTop: '回到顶部',\n confirm: '确认',\n cmdDetails: '安装命令',\n catsMore: '更多分类',\n catsLess: '收起',\n sortHot: '最热',\n sortNew: '最新',\n marketUpdate: '市场有新版本,升级',\n updateAll: '全部更新',\n tabThemes: '主题',\n themeApply: '使用',\n themeActive: '使用中',\n themeEmpty: '目录里暂时还没有主题,敬请期待',\n progressHint: '首次安装需要下载与解析依赖,大插件可能要 1-3 分钟',\n toastReady: '已装好并已生效',\n toastTheme: '已启用。到 设置 → 插件市场 → 主题 可随时切换',\n gotIt: '知道了',\n}\n\n/** A dictionary key; zh is the source of truth, en mirrors it 1:1. */\nexport type MarketKey = keyof typeof zh\n\nexport const en: Record<MarketKey, string> = {\n nav: 'Plugin Market',\n subtitle: 'Discover community plugins for DeepSeek Harness',\n searchPh: 'Search plugins: notify, terminal, memory…',\n tabDiscover: 'Discover',\n tabInstalled: 'Installed',\n all: 'All',\n install: 'Install',\n installing: 'Installing…',\n installedBadge: '✓ Installed',\n alreadyInstalled: '✓ Installed',\n restartBanner: 'change(s) done — restart DeepSeek Harness to apply',\n uninstall: 'Uninstall',\n confirmRemove: 'Confirm?',\n uninstalling: 'Removing…',\n restartHint: 'To restart: stop the current dsh process and run it again (e.g. dsh web)',\n confirmTitle: 'Install',\n confirmWarn: 'Plugins are third-party community code. Installing means you trust this source; build scripts are blocked by default.',\n cancel: 'Cancel',\n empty: 'No plugins match',\n installedEmpty: 'No community plugins yet — browse the Discover tab',\n loadFail: 'Failed to load the plugin catalog, please retry later',\n installFail: 'Install failed',\n viewSource: 'Source',\n hotBanner: 'new plugin(s) ready — refresh the page to use them',\n refresh: 'Refresh',\n update: 'Update',\n updating: 'Updating…',\n updated: '✓ Updated — restart to apply',\n updateFail: 'Update failed',\n upToDate: 'Up to date',\n linkedDev: 'linked (dev)',\n exportLog: 'Export log',\n readme: 'README',\n terminalWarn: 'This looks like a terminal/CLI plugin: installing it into the web profile may do nothing, or even break DeepSeek Harness startup. Read its README and install it into the profile it targets.',\n envMissing: 'One small component is needed before installing plugins',\n envFix: 'Set up automatically',\n envFixing: 'Setting up…',\n envFixFail: 'Automatic setup failed — please use \"Export log\" and send us the file',\n loading: 'Loading the catalog…',\n backTop: 'Back to top',\n confirm: 'Confirm',\n cmdDetails: 'Install command',\n catsMore: 'More',\n catsLess: 'Less',\n sortHot: 'Top',\n sortNew: 'New',\n marketUpdate: 'Market update available — upgrade',\n updateAll: 'Update all',\n tabThemes: 'Themes',\n themeApply: 'Use',\n themeActive: 'Active',\n themeEmpty: 'No more theme plugins in the catalog yet — stay tuned',\n progressHint: 'First installs download and resolve dependencies — large plugins can take 1-3 minutes',\n toastReady: 'installed and live',\n toastTheme: 'is now active. Switch any time in Settings → Plugin Market → Themes',\n gotIt: 'Got it',\n}\n","/**\n * Response shapes of the /dsh-market/* host routes plus the pure helpers the\n * Market UI shares between its section and toast components.\n */\n\n/** Localized text keyed by language ('zh' / 'en'). */\nexport type LocalizedText = Record<string, string | undefined>\n\n/** One registry entry from /dsh-market/registry. */\nexport interface RegistryPlugin {\n name: string\n owner: string\n url: string\n npm?: string\n category: string\n description?: LocalizedText\n stars?: number\n added?: string\n install?: string\n}\n\n/** The catalog payload under `registry` in /dsh-market/registry. */\nexport interface Registry {\n count: number\n categories: Record<string, LocalizedText>\n plugins: RegistryPlugin[]\n}\n\n/** Profile dependency map: package name → install spec. */\nexport type InstalledMap = Record<string, string>\n\n/** Per-package update status from /dsh-market/updates. */\nexport interface UpdateStatus {\n updateAvailable?: boolean\n version?: string\n kind?: string\n}\n\n/** Poll payload from /dsh-market/status. */\nexport interface MarketStatus {\n active?: boolean\n lastLine?: string\n seconds?: number\n installed?: InstalledMap\n pnpm?: boolean\n boot?: string\n}\n\n/** Registered theme definition surfaced by the theme service snapshot. */\nexport interface ThemeDef {\n id: string\n colorScheme?: string\n tokens?: Record<string, string | undefined>\n}\n\n/** Theme service snapshot; null when the composition has no theme service. */\nexport interface ThemeSnapshot {\n preference: string\n themes: ThemeDef[]\n}\n\n/** Bound locale translator for the dsh-market namespace. */\nexport type Translate = (key: string) => string\n\nexport function avatarColor(name: string): string {\n let hash = 0\n for (let i = 0; i < name.length; i++) hash = (hash * 31 + name.charCodeAt(i)) | 0\n return 'hsl(' + (((hash % 360) + 360) % 360) + ' 55% 52%)'\n}\n\nexport function repoOf(url: string): string | null {\n // Plain repo urls plus /tree/<branch>/<subpath> monorepo links.\n const m = /^https:\\/\\/github\\.com\\/([^/]+\\/[^/]+?)(?:\\/tree\\/.+)?\\/?$/.exec(url)\n return m ? m[1]! : null\n}\n\nexport function readSession(key: string): any {\n try { return JSON.parse(sessionStorage.getItem(key) || 'null') } catch { return null }\n}\n\n/** Heuristic: plugins that target a terminal surface rather than the web UI. */\nexport function looksTerminal(plugin: RegistryPlugin, lang: string): boolean {\n const desc = (plugin.description && (plugin.description[lang] || plugin.description.en)) || ''\n return /\\b(tui|cli|tty|terminal)\\b|终端|命令行/i.test(plugin.name + ' ' + desc)\n}\n\n/**\n * Unified installed-state matching (#15): both sides collapse to lowercase\n * identity sets — the registry entry contributes its bare name, npm name and\n * owner/repo; the dependency contributes its key and the repo inside its\n * spec — and any exact intersection counts. Exact equality, not substrings,\n * so prefix-related repo names cannot cross-match.\n */\nfunction entryIdentities(plugin: RegistryPlugin): Set<string> {\n const ids = new Set<string>([plugin.name.toLowerCase()])\n if (plugin.npm) ids.add(plugin.npm.toLowerCase())\n const repo = repoOf(plugin.url)\n if (repo !== null) ids.add(repo.toLowerCase())\n return ids\n}\n\nfunction depIdentities(name: string, spec: string): Set<string> {\n const ids = new Set<string>([name.toLowerCase()])\n // A scoped npm key usually mirrors owner/repo — expose that identity so an\n // npm-installed plugin still matches an entry whose npm field is unset.\n const scoped = /^@([^/]+)\\/(.+)$/.exec(name)\n if (scoped !== null) ids.add(`${scoped[1]!.toLowerCase()}/${scoped[2]!.toLowerCase()}`)\n const match = /github:([A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+)/i.exec(spec)\n if (match !== null) ids.add(match[1]!.toLowerCase())\n return ids\n}\n\n/** The installed dependency name a registry entry corresponds to, or null. */\nexport function matchInstalledName(plugin: RegistryPlugin, installed: InstalledMap): string | null {\n const ids = entryIdentities(plugin)\n for (const [name, spec] of Object.entries(installed)) {\n for (const id of depIdentities(name, String(spec))) {\n if (ids.has(id)) return name\n }\n }\n return null\n}\n\n/** The registry entry an installed dependency corresponds to, or undefined. */\nexport function entryForDep(plugins: RegistryPlugin[], name: string, spec: string): RegistryPlugin | undefined {\n const ids = depIdentities(name, String(spec))\n return plugins.find((plugin) => {\n for (const id of entryIdentities(plugin)) if (ids.has(id)) return true\n return false\n })\n}\n\nexport function isInstalled(plugin: RegistryPlugin, installed: InstalledMap): boolean {\n return matchInstalledName(plugin, installed) !== null\n}\n\n/**\n * The brand mark (assets/logo.svg — shared block-grid mark with\n * awesome-dsh-plugin), inlined so the header needs no extra request.\n */\nexport const LOGO_URI = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 128\"><rect width=\"128\" height=\"128\" rx=\"28\" fill=\"#f6f2ea\"/><g transform=\"translate(15.7 16.7) scale(0.3) translate(-112 -78)\"><g fill=\"#2b2620\"><rect x=\"112\" y=\"112\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"112\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"112\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"112\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"212\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"312\" y=\"212\" width=\"88\" height=\"88\" rx=\"14\"/><rect x=\"312\" y=\"312\" width=\"88\" height=\"88\" rx=\"14\"/></g><rect x=\"346\" y=\"78\" width=\"88\" height=\"88\" rx=\"14\" fill=\"#c0392b\" transform=\"rotate(9 390 122)\"/></g></svg>')\n\n/** Four representative colors for a theme card's preview strip. */\nexport function themeSwatch(def: ThemeDef): string[] {\n const tk = def.tokens || {}\n const pick = (names: string[]) => { for (const n of names) { if (tk[n]) return tk[n]! } return null }\n const dark = def.colorScheme === 'dark'\n return [\n pick(['--dsw-alias-bg-base', '--dsw-alias-bg-layer-1']) || (dark ? '#0f1115' : '#ffffff'),\n pick(['--dsw-alias-bg-layer-2', '--dsw-alias-bg-overlay']) || (dark ? '#1a1d23' : '#f3f4f6'),\n pick(['--dsw-alias-brand-primary']) || '#4f6ef7',\n pick(['--dsw-alias-label-primary']) || (dark ? '#e5e7eb' : '#1f2328'),\n ]\n}\n","/**\n * Post-reload confirmation via the official Toast primitive: shown once after\n * the refresh that follows a hot install or theme switch, so the user lands\n * back in their flow with visible proof.\n */\nimport { useState } from 'react'\nimport { Toast } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { readSession } from './market-data.ts'\nimport type { Translate } from './market-data.ts'\n\nexport function InstallToast(props: { t: Translate }) {\n const t = props.t\n const [mode] = useState(() => {\n const value = sessionStorage.getItem('dshm-toast-mode')\n sessionStorage.removeItem('dshm-toast-mode')\n return value\n })\n const [names, setNames] = useState<string[]>(() => {\n const value = readSession('dshm-toast')\n sessionStorage.removeItem('dshm-toast')\n return Array.isArray(value) ? value : []\n })\n if (names.length === 0) return null\n return (\n <Toast\n text={names.join(', ') + ' ' + t(mode === 'theme' ? 'toastTheme' : 'toastReady')}\n icon={<span>✨</span>}\n onDone={() => setNames([])}\n />\n )\n}\n","/**\n * The Market settings section: Discover / Themes / Installed tabs over the\n * /dsh-market/* host routes, with install/update/uninstall flows and the\n * pending-restart bookkeeping in sessionStorage.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport { Button, IconChevronDownOutline14, IconChevronUpOutline14, IconSearchOutline16, Input, Modal, Pill, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './Market.module.css'\nimport {\n avatarColor, entryForDep, isInstalled, LOGO_URI, looksTerminal, matchInstalledName, readSession, repoOf, themeSwatch,\n} from './market-data.ts'\nimport type {\n InstalledMap, Registry, RegistryPlugin, ThemeSnapshot, Translate, UpdateStatus,\n} from './market-data.ts'\n\n/**\n * Card avatar: the plugin owner's GitHub avatar (no API, browser-cached),\n * falling back to the initial-letter tile when it can't load.\n */\nfunction OwnerAvatar({ name, owner }: { name: string; owner: string }) {\n const [failed, setFailed] = useState(false)\n if (failed || owner === '') {\n return (\n <div className={css.av} style={{ background: avatarColor(name) }}>\n {name.replace(/^dsh[-_]/i, '').charAt(0).toUpperCase() || 'P'}\n </div>\n )\n }\n return (\n <img\n className={css.av}\n src={`https://github.com/${encodeURIComponent(owner)}.png?size=96`}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setFailed(true)}\n />\n )\n}\n\nexport interface MarketSectionProps {\n t: Translate\n locale: {\n subscribe(callback: () => void): () => void\n getSnapshot(): { active: string }\n }\n theme: { setTheme(id: string): void }\n themeStore: {\n subscribe(callback: () => void): () => void\n getSnapshot(): ThemeSnapshot | null\n }\n}\n\nexport function MarketSection(props: MarketSectionProps) {\n const t = props.t\n const localeSnap = useSyncExternalStore(\n cb => props.locale.subscribe(cb),\n () => props.locale.getSnapshot(),\n )\n const lang = String(localeSnap.active).toLowerCase().startsWith('zh') ? 'zh' : 'en'\n // null when the composition has no theme service — the Themes tab hides.\n const themeSnap = useSyncExternalStore(\n props.themeStore.subscribe,\n props.themeStore.getSnapshot,\n )\n const [data, setData] = useState<Registry | null>(null)\n const [loadError, setLoadError] = useState(false)\n const [installed, setInstalled] = useState<InstalledMap>({})\n const [skins, setSkins] = useState<string[]>([])\n const [tab, setTab] = useState(() => {\n const saved = sessionStorage.getItem('dshm-tab')\n if (saved !== null) sessionStorage.removeItem('dshm-tab')\n return saved || 'discover'\n })\n const [q, setQ] = useState('')\n const [cat, setCat] = useState('all')\n const [confirming, setConfirming] = useState<RegistryPlugin | null>(null)\n const [busyUrl, setBusyUrl] = useState<string | null>(null)\n const [doneUrls, setDoneUrls] = useState<string[]>([])\n const [installError, setInstallError] = useState<string | null>(null)\n const [updates, setUpdates] = useState<Record<string, UpdateStatus>>({})\n const [updatingName, setUpdatingName] = useState<string | null>(null)\n const [updatingAll, setUpdatingAll] = useState(false)\n const [updatedNames, setUpdatedNames] = useState<string[]>([])\n const [hotUrls, setHotUrls] = useState<string[]>([])\n const [hotNames, setHotNames] = useState<string[]>([])\n const [progressLine, setProgressLine] = useState<string | null>(null)\n const [removeArmed, setRemoveArmed] = useState<string | null>(null)\n const [removingName, setRemovingName] = useState<string | null>(null)\n const [removedCount, setRemovedCount] = useState(0)\n const [envReady, setEnvReady] = useState(true)\n const [envFixing, setEnvFixing] = useState(false)\n const [envFailed, setEnvFailed] = useState(false)\n const [bootId, setBootId] = useState<string | null>(null)\n const [showTop, setShowTop] = useState(false)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const [sort, setSort] = useState('hot')\n const [catsOpen, setCatsOpen] = useState(false)\n // How many category pills fit in the two collapsed rows (measured once —\n // the settings panel width is fixed); null = measuring render with all\n // pills clamped, then slice so the chevron flows inline after the last one.\n const [visibleCats, setVisibleCats] = useState<number | null>(null)\n const catsWrapRef = useRef<HTMLDivElement | null>(null)\n\n const refreshInstalled = useCallback((force?: boolean) => {\n fetch('/dsh-market/installed', { cache: 'no-store' })\n .then(res => res.json())\n .then(body => {\n setInstalled(body.installed || {})\n setSkins(body.live || [])\n })\n .catch(() => {})\n fetch('/dsh-market/updates' + (force === true ? '?force=1' : ''), { cache: 'no-store' })\n .then(res => res.json())\n .then(body => setUpdates(body.updates || {}))\n .catch(() => {})\n }, [])\n\n useEffect(() => {\n fetch('/dsh-market/registry', { cache: 'no-store' })\n .then(res => { if (!res.ok) throw new Error('HTTP ' + res.status); return res.json() })\n .then(body => setData(body.registry))\n .catch(() => setLoadError(true))\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then(status => {\n setEnvReady(status.pnpm !== false)\n if (typeof status.boot === 'string') setBootId(status.boot)\n })\n .catch(() => {})\n refreshInstalled()\n }, [refreshInstalled])\n\n // Pending-restart flags survive tab switches and page reloads, scoped to\n // one host process: a different boot id means the restart happened and the\n // stale banner must not resurrect.\n useEffect(() => {\n if (bootId === null) return\n const saved = readSession('dshm-restart')\n if (saved === null) return\n if (saved.boot !== bootId) {\n sessionStorage.removeItem('dshm-restart')\n return\n }\n if (Array.isArray(saved.doneUrls) && saved.doneUrls.length > 0) setDoneUrls(saved.doneUrls)\n if (Array.isArray(saved.updated) && saved.updated.length > 0) setUpdatedNames(saved.updated)\n if (typeof saved.removed === 'number' && saved.removed > 0) setRemovedCount(saved.removed)\n }, [bootId])\n\n useEffect(() => {\n if (bootId === null) return\n if (doneUrls.length === 0 && updatedNames.length === 0 && removedCount === 0) return\n sessionStorage.setItem('dshm-restart', JSON.stringify({\n boot: bootId,\n doneUrls,\n updated: updatedNames,\n removed: removedCount,\n }))\n }, [bootId, doneUrls, updatedNames, removedCount])\n\n const fixEnv = useCallback(() => {\n setEnvFixing(true)\n setEnvFailed(false)\n fetch('/dsh-market/setup-pnpm', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .then(res => res.json())\n .then(body => {\n if (body.ok) setEnvReady(true)\n else setEnvFailed(true)\n })\n .catch(() => setEnvFailed(true))\n .finally(() => setEnvFixing(false))\n }, [])\n\n // Recover an install whose HTTP response was lost (page navigated away or\n // the connection dropped): the pending marker survives in sessionStorage and\n // the poll below converges the button state from the host's ground truth.\n useEffect(() => {\n const pending = readSession('dshm-pending')\n if (pending !== null && typeof pending.url === 'string') setBusyUrl(pending.url)\n }, [])\n\n useEffect(() => {\n if (busyUrl === null && updatingName === null) {\n setProgressLine(null)\n return\n }\n const timer = setInterval(() => {\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then(status => {\n if (status.active) {\n setProgressLine((status.lastLine || '…') + ' (' + status.seconds + 's)')\n } else {\n setProgressLine(null)\n setInstalled(status.installed || {})\n const pending = readSession('dshm-pending')\n if (pending !== null && busyUrl !== null) {\n const nowInstalled = data !== null && data.plugins.some(p =>\n p.url === busyUrl && isInstalled(p, status.installed || {}))\n if (nowInstalled) {\n sessionStorage.removeItem('dshm-pending')\n setDoneUrls(urls => urls.includes(busyUrl) ? urls : urls.concat(busyUrl))\n setBusyUrl(null)\n }\n }\n }\n })\n .catch(() => {})\n }, 2000)\n return () => clearInterval(timer)\n }, [busyUrl, updatingName, data])\n\n const plugins = useMemo(() => {\n if (data === null) return []\n const query = q.trim().toLowerCase()\n const list = data.plugins.filter(p => {\n if (cat !== 'all' && p.category !== cat) return false\n if (query === '') return true\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n return p.name.toLowerCase().includes(query)\n || p.owner.toLowerCase().includes(query)\n || desc.toLowerCase().includes(query)\n })\n if (sort === 'hot') {\n return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1))\n }\n if (sort === 'new') {\n return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)))\n }\n return list\n }, [data, q, cat, lang, sort])\n\n const doInstall = useCallback((plugin: RegistryPlugin) => {\n setConfirming(null)\n setInstallError(null)\n setBusyUrl(plugin.url)\n sessionStorage.setItem('dshm-pending', JSON.stringify({ url: plugin.url }))\n fetch('/dsh-market/install', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ url: plugin.url }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n sessionStorage.removeItem('dshm-pending')\n if (status === 200 && body.ok && body.hot && plugin.category === 'theme') {\n // Themes auto-activate on install; reload straight into the Themes\n // tab so the new look is on screen immediately.\n sessionStorage.setItem('dshm-toast', JSON.stringify([plugin.name]))\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n return\n }\n if (status === 200 && body.ok) {\n sessionStorage.setItem('dshm-tab', 'installed')\n if (body.hot) {\n setHotUrls(urls => urls.includes(plugin.url) ? urls : urls.concat(plugin.url))\n setHotNames(names => names.includes(plugin.name) ? names : names.concat(plugin.name))\n } else {\n setDoneUrls(urls => urls.includes(plugin.url) ? urls : urls.concat(plugin.url))\n }\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n const detail = text(body.error) || [text(body.stderr), text(body.stdout)].filter(Boolean).join('\\n').trim() || ('exit ' + body.exitCode)\n setInstallError(t('installFail') + ': ' + plugin.name + ' — ' + detail.trim().slice(-600))\n }\n })\n .catch(error => {\n sessionStorage.removeItem('dshm-pending')\n setInstallError(t('installFail') + ': ' + String(error))\n })\n .finally(() => setBusyUrl(null))\n }, [refreshInstalled, t])\n\n const doUpdate = useCallback((name: string) => {\n setInstallError(null)\n setUpdatingName(name)\n return fetch('/dsh-market/update', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n setUpdatedNames(names => names.concat(name))\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n const detail = text(body.error) || [text(body.stderr), text(body.stdout)].filter(Boolean).join('\\n').trim() || ('exit ' + body.exitCode)\n setInstallError(t('updateFail') + ': ' + name + ' — ' + detail.trim().slice(-600))\n }\n })\n .catch(error => setInstallError(t('updateFail') + ': ' + String(error)))\n .finally(() => setUpdatingName(null))\n }, [refreshInstalled, t])\n\n const doUseSkin = useCallback((name: string) => {\n setInstallError(null)\n fetch('/dsh-market/use-skin', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n sessionStorage.setItem('dshm-toast', JSON.stringify([name]))\n sessionStorage.setItem('dshm-toast-mode', 'theme')\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n } else {\n setInstallError(String(body.error || 'failed'))\n }\n })\n .catch(error => setInstallError(String(error)))\n }, [])\n\n const doUninstall = useCallback((name: string) => {\n setRemoveArmed(null)\n setInstallError(null)\n setRemovingName(name)\n return fetch('/dsh-market/uninstall', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status === 200 && body.ok) {\n if (!body.hot) setRemovedCount(n => n + 1)\n refreshInstalled()\n } else {\n const text = (v: unknown) => typeof v === 'string' ? v : (v && typeof (v as any).text === 'string') ? (v as any).text : v == null ? '' : JSON.stringify(v)\n setInstallError((text(body.error) || text(body.stderr) || 'error').trim().slice(-600))\n }\n })\n .catch(error => setInstallError(String(error)))\n .finally(() => setRemovingName(null))\n }, [refreshInstalled])\n\n // The market itself stays out of the batch: its update reloads this page\n // mid-run, which would strand the remaining items.\n const selfName = installed['dshmarket'] !== undefined ? 'dshmarket' : 'dsh-market'\n const updatableNames = Object.keys(installed).filter(\n name => name !== selfName && !updatedNames.includes(name) && updates[name] && updates[name].updateAvailable,\n )\n\n const doUpdateAll = useCallback(() => {\n const names = updatableNames.slice()\n setUpdatingAll(true)\n const next = () => {\n const name = names.shift()\n if (name === undefined) {\n setUpdatingAll(false)\n return\n }\n doUpdate(name).then(next, next)\n }\n next()\n }, [updatableNames, doUpdate])\n\n const pendingRestart = doneUrls.length + updatedNames.length + removedCount\n const hasUpdates = Object.keys(installed).some(\n name => !updatedNames.includes(name) && updates[name] && updates[name].updateAvailable,\n )\n\n const themePlugins = data === null ? [] : data.plugins\n .filter(p => p.category === 'theme')\n .sort((a, b) => (b.stars || 0) - (a.stars || 0))\n\n const pluginCard = (p: RegistryPlugin) => {\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n const done = doneUrls.includes(p.url) || hotUrls.includes(p.url)\n const already = isInstalled(p, installed)\n const busy = busyUrl === p.url\n return (\n <div key={p.url} className={css.card}>\n <div className={css.row1}>\n <OwnerAvatar name={p.name} owner={p.owner || ''} />\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{p.name}</div>\n <div className={css.owner}>\n {p.owner}\n {typeof p.stars === 'number' && <span className={css.star}>{' · ★ ' + p.stars}</span>}\n </div>\n </div>\n <span className={css.grow} />\n <a className={css.src} href={p.url} target=\"_blank\" rel=\"noreferrer\" style={{ alignSelf: 'flex-start', flexShrink: 0 }}>{t('viewSource')}</a>\n </div>\n <div className={css.desc}>{desc}</div>\n <div className={css.foot}>\n <span className={css.tag}>\n {(data!.categories[p.category] && (data!.categories[p.category]![lang] || data!.categories[p.category]!.en)) || p.category}\n </span>\n <span className={css.grow} />\n {done\n ? <span className={css.okState}>{t('installedBadge')}</span>\n : already\n ? <span className={css.okState}>{t('alreadyInstalled')}</span>\n : busy\n ? <Button variant=\"primary\" size=\"sm\" disabled>{t('installing')}</Button>\n : (\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={busyUrl !== null || !envReady}\n onClick={() => setConfirming(p)}\n >{t('install')}</Button>\n )}\n </div>\n {busy && (\n <div className={css.progress}>\n <span className={css.spin} />\n <code className={css.grow}>{progressLine || t('progressHint')}</code>\n </div>\n )}\n </div>\n )\n }\n\n const installedNameOf = (p: RegistryPlugin) => matchInstalledName(p, installed)\n\n // Plugins loaded at boot (bundle-layer skins) aren't in the shim list but\n // are just as live; the boot manifest is the page's own record of them.\n const bootEntries = (typeof window !== 'undefined' && window.__DSH_BOOT__ && Array.isArray(window.__DSH_BOOT__.entries))\n ? window.__DSH_BOOT__.entries\n : []\n\n // Unified card for the Themes tab: install → use/in-use → uninstall.\n const themePluginCard = (p: RegistryPlugin) => {\n const instName = installedNameOf(p)\n if (instName === null) return pluginCard(p)\n const mounted = skins.includes(instName) || bootEntries.some(e => e.id === instName)\n const desc = (p.description && (p.description[lang] || p.description.en)) || ''\n return (\n <div key={p.url} className={css.card}>\n <div className={css.row1}>\n <OwnerAvatar name={p.name} owner={p.owner || ''} />\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{p.name}</div>\n <div className={css.owner}>\n {p.owner}\n {typeof p.stars === 'number' && <span className={css.star}>{' · ★ ' + p.stars}</span>}\n </div>\n </div>\n <span className={css.grow} />\n <a className={css.src} href={p.url} target=\"_blank\" rel=\"noreferrer\" style={{ alignSelf: 'flex-start', flexShrink: 0 }}>{t('viewSource')}</a>\n </div>\n <div className={css.desc}>{desc}</div>\n <div className={css.foot}>\n <span className={css.grow} />\n {removingName === instName\n ? <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} disabled>{t('uninstalling')}</Button>\n : removeArmed === instName\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.dangerArmed}\n onClick={() => doUninstall(instName).then(() => {\n if (mounted) {\n sessionStorage.setItem('dshm-tab', 'themes')\n location.reload()\n }\n })}\n >{t('confirmRemove')}</Button>\n )\n : <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} onClick={() => setRemoveArmed(instName)}>{t('uninstall')}</Button>}\n {mounted\n ? <span className={css.okState}>{t('themeActive')}</span>\n : <Button variant=\"primary\" size=\"sm\" onClick={() => doUseSkin(instName)}>{t('themeApply')}</Button>}\n </div>\n </div>\n )\n }\n\n const themeCard = (id: string, label: string, swatch: string[]) => {\n const active = themeSnap !== null && themeSnap.preference === id\n return (\n <div key={'th-' + id} className={css.card}>\n <div className={css.swatches}>{swatch.map((c, i) => <i key={i} style={{ background: c }} />)}</div>\n <div className={css.foot}>\n <span className={css.nm}>{label}</span>\n <span className={css.grow} />\n {active\n ? <span className={css.okState}>{t('themeActive')}</span>\n : (\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => { try { props.theme.setTheme(id) } catch (error) { setInstallError(String(error)) } }}\n >{t('themeApply')}</Button>\n )}\n </div>\n </div>\n )\n }\n\n const categories = data === null ? [] : Object.keys(data.categories)\n\n useLayoutEffect(() => { setVisibleCats(null) }, [lang, categories.length])\n useLayoutEffect(() => {\n if (catsOpen || visibleCats !== null) return\n const el = catsWrapRef.current\n if (el === null) return\n const chips = [...el.children].filter((c): c is HTMLElement => (c as HTMLElement).dataset?.chip === '1')\n if (chips.length === 0) return\n const first = chips[0]!\n const rowThreeTop = first.offsetTop + (first.offsetHeight + 6) * 2 - 3\n let fits = 0\n for (const chip of chips) { if (chip.offsetTop < rowThreeTop) fits += 1 }\n // Reserve the tail slot of row two for the chevron itself.\n setVisibleCats(fits >= chips.length ? fits : Math.max(1, fits - 1))\n }, [catsOpen, visibleCats, data])\n\n return (\n <div className={css.root}>\n <div className={css.head}>\n <div className={css.titleRow}>\n <img src={LOGO_URI} width={22} height={22} alt=\"\" style={{ borderRadius: '5px', flexShrink: 0 }} />\n <h2 className={css.title}>{t('nav')}</h2>\n {(() => {\n const self = installed['dshmarket'] !== undefined ? 'dshmarket' : 'dsh-market'\n return updates[self] && updates[self].updateAvailable && !updatedNames.includes(self)\n && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingName !== null || busyUrl !== null}\n onClick={() => { setTab('installed'); doUpdate(self) }}\n >{updatingName === self ? t('updating') : t('marketUpdate')}</Button>\n )\n })()}\n {updatableNames.length >= 2 && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingAll || updatingName !== null || busyUrl !== null || removingName !== null}\n onClick={() => { setTab('installed'); doUpdateAll() }}\n >{updatingAll ? t('updating') : t('updateAll') + ' (' + updatableNames.length + ')'}</Button>\n )}\n </div>\n <div className={css.sub}>\n {t('subtitle') + (data ? ' · ' + data.count : '') + ' · '}\n <a className={css.src} href=\"/dsh-market/logs\" download=\"dsh-market-log.txt\">{t('exportLog')}</a>\n </div>\n <div className={css.tabs}>\n <button className={tab === 'discover' ? `${css.tab} ${css.on}` : css.tab} onClick={() => setTab('discover')}>{t('tabDiscover')}</button>\n {themeSnap !== null && <button className={tab === 'themes' ? `${css.tab} ${css.on}` : css.tab} onClick={() => setTab('themes')}>{t('tabThemes')}</button>}\n <button className={tab === 'installed' ? `${css.tab} ${css.on}` : css.tab} onClick={() => { setTab('installed'); refreshInstalled(true) }}>\n {t('tabInstalled') + (Object.keys(installed).length > 0 ? ' (' + Object.keys(installed).length + ')' : '')}\n {hasUpdates && <StateDot state=\"error\" size={7} className={css.dot} />}\n </button>\n <span className={css.grow} />\n <Input className={css.searchInline} icon={<IconSearchOutline16 size={14} />} placeholder={t('searchPh')} value={q} onChange={e => setQ(e.target.value)} />\n </div>\n {!envReady && (\n <div className={css.restart}>\n <span>🧩</span>\n <span className={css.grow}>{envFailed ? t('envFixFail') : t('envMissing')}</span>\n {!envFailed && (\n <Button variant=\"primary\" size=\"sm\" disabled={envFixing} onClick={fixEnv}>\n {envFixing ? t('envFixing') : t('envFix')}\n </Button>\n )}\n </div>\n )}\n {hotUrls.length > 0 && (\n <div className={css.restart}>\n <span>✨</span>\n <span className={css.grow}><b>{hotUrls.length}</b> {t('hotBanner')}</span>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => {\n sessionStorage.setItem('dshm-toast', JSON.stringify(hotNames))\n sessionStorage.setItem('dshm-tab', 'installed')\n location.reload()\n }}\n >{t('refresh')}</Button>\n </div>\n )}\n {pendingRestart > 0 && (\n <div className={css.restart}>\n <span>🔄</span>\n <span className={css.grow}><b>{pendingRestart}</b> {t('restartBanner')}</span>\n <span title={t('restartHint')}>ℹ️</span>\n </div>\n )}\n </div>\n {installError !== null && <div className={css.err}>{installError}</div>}\n <div\n className={css.body}\n ref={bodyRef}\n onScroll={e => setShowTop(e.currentTarget.scrollTop > 400)}\n >\n {tab === 'discover'\n ? loadError\n ? <div className={css.empty}>{t('loadFail')}</div>\n : data === null\n ? <div className={css.loading}><span className={css.spin} />{t('loading')}</div>\n : (\n <>\n <div className={css.cats}>\n <div className={css.catsRow}>\n <div ref={catsWrapRef} className={catsOpen || visibleCats === null ? `${css.catsWrap} ${css.catsCollapsed}` : css.catsWrap}>\n {(() => {\n // Collapsed, the selected category is pulled to the front so it never hides.\n const ordered = catsOpen || cat === 'all' ? categories : [cat, ...categories.filter(id => id !== cat)]\n const shown = catsOpen || visibleCats === null ? ordered : ordered.slice(0, Math.max(0, visibleCats - 1))\n return (\n <>\n <Pill data-chip=\"1\" active={cat === 'all'} onClick={() => setCat('all')}>{t('all')}</Pill>\n {shown.map(id => (\n <Pill\n key={id}\n data-chip=\"1\"\n active={cat === id}\n onClick={() => setCat(id)}\n >{(data.categories[id] && (data.categories[id]![lang] || data.categories[id]!.en)) || id}</Pill>\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={css.catsToggle}\n icon={catsOpen ? <IconChevronUpOutline14 size={14} /> : <IconChevronDownOutline14 size={14} />}\n aria-label={catsOpen ? t('catsLess') : t('catsMore')}\n onClick={() => setCatsOpen(o => !o)}\n />\n </>\n )\n })()}\n </div>\n <div className={css.sort}>\n {['hot', 'new'].map(key => (\n <button\n key={key}\n className={sort === key ? css.on : ''}\n onClick={() => setSort(key)}\n >{t(key === 'hot' ? 'sortHot' : 'sortNew')}</button>\n ))}\n </div>\n </div>\n </div>\n {plugins.length === 0\n ? <div className={css.empty}>{t('empty')}</div>\n : <div className={css.grid}>{plugins.map(pluginCard)}</div>}\n </>\n )\n : tab === 'themes' && themeSnap !== null\n ? (\n <>\n {/* Light/dark/system live in the official Appearance setting; this\n tab only shows what that setting can't: registered third-party\n palettes (none in the wild yet) and installable theme plugins. */}\n {(() => {\n const extra = themeSnap.themes.filter(def => def.id !== 'light' && def.id !== 'dark')\n return extra.length > 0 && (\n <div className={`${css.grid} ${css.themesGrid}`}>\n {extra.map(def => themeCard(def.id, def.id, themeSwatch(def)))}\n </div>\n )\n })()}\n {data === null\n ? <div className={css.loading}><span className={css.spin} />{t('loading')}</div>\n : themePlugins.length === 0\n ? <div className={css.empty}>{t('themeEmpty')}</div>\n : <div className={css.grid}>{themePlugins.map(themePluginCard)}</div>}\n </>\n )\n : Object.keys(installed).length === 0\n ? <div className={css.empty}>{t('installedEmpty')}</div>\n : Object.entries(installed).map(([name, spec]) => {\n const entry = data === null ? undefined : entryForDep(data.plugins, name, String(spec))\n const status = updates[name]\n const version = status && status.version ? 'v' + status.version : ''\n const specText = String(spec)\n const ghSpec = /^github:([A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+?)(?:#|$)/.exec(specText)\n const repoUrl = entry !== undefined ? entry.url : ghSpec !== null ? 'https://github.com/' + ghSpec[1] : null\n return (\n <div key={name} className={css.irow}>\n <div style={{ minWidth: 0 }}>\n <div className={css.nm}>{name}{version && <span className={css.owner}>{' ' + version}</span>}</div>\n {repoUrl !== null\n ? <a className={`${css.spec} ${css.src}`} href={repoUrl} target=\"_blank\" rel=\"noreferrer\" style={{ display: 'inline-block' }}>{specText}</a>\n : <div className={css.spec}>{specText}</div>}\n {entry !== undefined && (\n <div className={`${css.desc} ${css.descTight}`}>\n {(entry.description && (entry.description[lang] || entry.description.en)) || ''}\n </div>\n )}\n {updatingName === name && (\n <div className={css.progress}>\n <span className={css.spin} />\n <code className={css.grow}>{progressLine || t('progressHint')}</code>\n </div>\n )}\n </div>\n <span className={css.grow} />\n {repoUrl !== null && <a className={css.src} href={repoUrl + '#readme'} target=\"_blank\" rel=\"noreferrer\">{t('readme')}</a>}\n {updatedNames.includes(name)\n ? <span className={css.okState}>{t('updated')}</span>\n : updatingName === name\n ? <Button variant=\"primary\" size=\"sm\" className={css.warnBtn} disabled>{t('updating')}</Button>\n : status && status.updateAvailable\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.warnBtn}\n disabled={updatingName !== null}\n onClick={() => doUpdate(name)}\n >{t('update')}</Button>\n )\n : status && status.kind === 'linked'\n ? <span className={css.owner}>{t('linkedDev')}</span>\n : <span className={css.owner}>{t('upToDate')}</span>}\n {name !== 'dsh-market' && name !== 'dshmarket' && (\n removingName === name\n ? <Button variant=\"outline\" size=\"sm\" className={css.dangerBtn} disabled>{t('uninstalling')}</Button>\n : removeArmed === name\n ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n className={css.dangerArmed}\n onClick={() => doUninstall(name)}\n onMouseLeave={() => setRemoveArmed(null)}\n >{t('confirmRemove')}</Button>\n )\n : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={css.dangerBtn}\n disabled={removingName !== null || busyUrl !== null || updatingName !== null}\n onClick={() => setRemoveArmed(name)}\n >{t('uninstall')}</Button>\n )\n )}\n </div>\n )\n })}\n </div>\n {showTop && (\n <button\n className={css.top}\n title={t('backTop')}\n onClick={() => { const el = bodyRef.current; if (el) el.scrollTo({ top: 0, behavior: 'smooth' }) }}\n >↑</button>\n )}\n {confirming !== null && (\n <Modal\n open\n onClose={() => setConfirming(null)}\n title={t('confirmTitle') + ' ' + confirming.name + '?'}\n description={(confirming.description && (confirming.description[lang] || confirming.description.en)) || ''}\n footer={(\n <>\n <Button variant=\"ghost\" onClick={() => setConfirming(null)}>{t('cancel')}</Button>\n <Button variant=\"primary\" onClick={() => doInstall(confirming)}>{t('confirm')}</Button>\n </>\n )}\n >\n <details className={css.cmdDetails}>\n <summary className={css.cmdSummary}>{t('cmdDetails')}</summary>\n <div className={css.cmd}>{confirming.install}</div>\n </details>\n {looksTerminal(confirming, lang) && (\n <p className={css.warnLine}>\n {'🖥️ ' + t('terminalWarn') + ' '}\n <a className={css.src} href={confirming.url + '#readme'} target=\"_blank\" rel=\"noreferrer\">{t('readme')}</a>\n </p>\n )}\n <p className={css.modalNote}>{'⚠️ ' + t('confirmWarn')}</p>\n </Modal>\n )}\n </div>\n )\n}\n","/**\n * dsh-market client: registers a \"Market\" settings section rendering the\n * plugin market UI, plus the post-install toast in the shell overlay layer.\n * Built by tsdown into the __ModuleLoader__ factory bundle at\n * client/client.js; the only externals are the loader module table's react\n * entries.\n */\nimport { createElement as h } from 'react'\nimport { en, zh } from './locales.ts'\nimport { InstallToast } from './InstallToast.tsx'\nimport { MarketSection } from './MarketSection.tsx'\nimport type { ThemeSnapshot, Translate } from './market-data.ts'\n\nconst NS = 'dsh-market'\n\n/** The subset of the theme service this plugin touches. */\ninterface ThemeService {\n getTheme(): ThemeSnapshot | null\n setTheme(id: string): void\n}\n\n/** The subset of the locale service this plugin touches. */\ninterface LocaleService {\n register(namespace: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\n bind(namespace: string): Translate\n subscribe(callback: () => void): () => void\n getSnapshot(): { active: string }\n}\n\n/** The subset of the slots service this plugin touches. */\ninterface SlotsService {\n inject(slot: string, register: () => unknown): void\n register(meta: Record<string, unknown>, component: () => unknown): unknown\n}\n\n/** The client cordis context shape this plugin relies on (structural: the\n * host provides the real Context; typing the touched surface keeps this\n * external package free of monorepo-internal type dependencies). */\ninterface MarketClientContext {\n effect(callback: () => unknown, label?: string): void\n on(event: string, callback: () => void): () => void\n locale: LocaleService\n slots: SlotsService\n theme: ThemeService\n}\n\nexport const name = 'dsh-market'\n// 'theme' is safe to require: ui-layout (mandatory in every web composition)\n// already hard-depends on it. This cordis's object-form inject means\n// intercept config, NOT {required,optional} — do not use it here.\nexport const inject = ['slots', 'locale', 'theme']\nexport function apply(ctx: MarketClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-market: dictionaries')\n const t = ctx.locale.bind(NS)\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'market',\n order: 40,\n label: () => t('nav'),\n locale: NS,\n inject: () => ({ t }),\n }, () => h(MarketSection, {\n t,\n locale: ctx.locale,\n theme: ctx.theme,\n themeStore: {\n subscribe: (cb: () => void) => ctx.on('theme/change', cb),\n getSnapshot: () => ctx.theme.getTheme(),\n },\n })))\n\n const Toast = () => h(InstallToast, { t })\n ctx.slots.inject('shell.overlay', () => ctx.slots.register({\n name: 'shell.overlay',\n id: 'dsh-market-toast',\n label: () => 'dsh-market',\n }, Toast))\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dshmarket",
3
3
  "description": "Visual plugin market inside DeepSeek Harness — browse, search, and one-click install community plugins. · DSH 可视化插件市场:逛一逛,点一下,装好。",
4
- "version": "1.2.1",
4
+ "version": "1.2.2",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/types/index.d.ts",
@@ -7,7 +7,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, use
7
7
  import { Button, IconChevronDownOutline14, IconChevronUpOutline14, IconSearchOutline16, Input, Modal, Pill, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'
8
8
  import css from './Market.module.css'
9
9
  import {
10
- avatarColor, isInstalled, LOGO_URI, looksTerminal, readSession, repoOf, themeSwatch,
10
+ avatarColor, entryForDep, isInstalled, LOGO_URI, looksTerminal, matchInstalledName, readSession, repoOf, themeSwatch,
11
11
  } from './market-data.ts'
12
12
  import type {
13
13
  InstalledMap, Registry, RegistryPlugin, ThemeSnapshot, Translate, UpdateStatus,
@@ -419,16 +419,7 @@ export function MarketSection(props: MarketSectionProps) {
419
419
  )
420
420
  }
421
421
 
422
- const installedNameOf = (p: RegistryPlugin) => {
423
- if (installed[p.name] !== undefined) return p.name
424
- const repo = repoOf(p.url)
425
- if (repo === null) return null
426
- const needle = ('github:' + repo).toLowerCase()
427
- for (const [name, spec] of Object.entries(installed)) {
428
- if (String(spec).toLowerCase().includes(needle)) return name
429
- }
430
- return null
431
- }
422
+ const installedNameOf = (p: RegistryPlugin) => matchInstalledName(p, installed)
432
423
 
433
424
  // Plugins loaded at boot (bundle-layer skins) aren't in the shim list but
434
425
  // are just as live; the boot manifest is the page's own record of them.
@@ -683,8 +674,7 @@ export function MarketSection(props: MarketSectionProps) {
683
674
  : Object.keys(installed).length === 0
684
675
  ? <div className={css.empty}>{t('installedEmpty')}</div>
685
676
  : Object.entries(installed).map(([name, spec]) => {
686
- const entry = data === null ? undefined : data.plugins.find(p => p.name === name
687
- || (repoOf(p.url) !== null && String(spec).toLowerCase().includes(('github:' + repoOf(p.url)).toLowerCase())))
677
+ const entry = data === null ? undefined : entryForDep(data.plugins, name, String(spec))
688
678
  const status = updates[name]
689
679
  const version = status && status.version ? 'v' + status.version : ''
690
680
  const specText = String(spec)
@@ -84,14 +84,54 @@ export function looksTerminal(plugin: RegistryPlugin, lang: string): boolean {
84
84
  return /\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name + ' ' + desc)
85
85
  }
86
86
 
87
- /** A registry plugin counts as installed when its package name, npm name, or GitHub spec appears in the profile dependencies. */
88
- export function isInstalled(plugin: RegistryPlugin, installed: InstalledMap): boolean {
89
- if (installed[plugin.name] !== undefined) return true
90
- if (plugin.npm && installed[plugin.npm] !== undefined) return true
87
+ /**
88
+ * Unified installed-state matching (#15): both sides collapse to lowercase
89
+ * identity sets — the registry entry contributes its bare name, npm name and
90
+ * owner/repo; the dependency contributes its key and the repo inside its
91
+ * spec — and any exact intersection counts. Exact equality, not substrings,
92
+ * so prefix-related repo names cannot cross-match.
93
+ */
94
+ function entryIdentities(plugin: RegistryPlugin): Set<string> {
95
+ const ids = new Set<string>([plugin.name.toLowerCase()])
96
+ if (plugin.npm) ids.add(plugin.npm.toLowerCase())
91
97
  const repo = repoOf(plugin.url)
92
- if (repo === null) return false
93
- const needle = ('github:' + repo).toLowerCase()
94
- return Object.values(installed).some(spec => String(spec).toLowerCase().includes(needle))
98
+ if (repo !== null) ids.add(repo.toLowerCase())
99
+ return ids
100
+ }
101
+
102
+ function depIdentities(name: string, spec: string): Set<string> {
103
+ const ids = new Set<string>([name.toLowerCase()])
104
+ // A scoped npm key usually mirrors owner/repo — expose that identity so an
105
+ // npm-installed plugin still matches an entry whose npm field is unset.
106
+ const scoped = /^@([^/]+)\/(.+)$/.exec(name)
107
+ if (scoped !== null) ids.add(`${scoped[1]!.toLowerCase()}/${scoped[2]!.toLowerCase()}`)
108
+ const match = /github:([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)/i.exec(spec)
109
+ if (match !== null) ids.add(match[1]!.toLowerCase())
110
+ return ids
111
+ }
112
+
113
+ /** The installed dependency name a registry entry corresponds to, or null. */
114
+ export function matchInstalledName(plugin: RegistryPlugin, installed: InstalledMap): string | null {
115
+ const ids = entryIdentities(plugin)
116
+ for (const [name, spec] of Object.entries(installed)) {
117
+ for (const id of depIdentities(name, String(spec))) {
118
+ if (ids.has(id)) return name
119
+ }
120
+ }
121
+ return null
122
+ }
123
+
124
+ /** The registry entry an installed dependency corresponds to, or undefined. */
125
+ export function entryForDep(plugins: RegistryPlugin[], name: string, spec: string): RegistryPlugin | undefined {
126
+ const ids = depIdentities(name, String(spec))
127
+ return plugins.find((plugin) => {
128
+ for (const id of entryIdentities(plugin)) if (ids.has(id)) return true
129
+ return false
130
+ })
131
+ }
132
+
133
+ export function isInstalled(plugin: RegistryPlugin, installed: InstalledMap): boolean {
134
+ return matchInstalledName(plugin, installed) !== null
95
135
  }
96
136
 
97
137
  /**