dshmarket 1.4.0 → 1.4.1

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
@@ -66,6 +66,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
66
66
  catsLess: "收起",
67
67
  sortHot: "最热",
68
68
  sortNew: "最新",
69
+ sortOld: "最早",
69
70
  prevPage: "上一页",
70
71
  nextPage: "下一页",
71
72
  firstPage: "首页",
@@ -140,6 +141,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
140
141
  catsLess: "Less",
141
142
  sortHot: "Top",
142
143
  sortNew: "New",
144
+ sortOld: "Oldest",
143
145
  prevPage: "Previous",
144
146
  nextPage: "Next",
145
147
  firstPage: "First",
@@ -191,6 +193,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
191
193
  });
192
194
  if (options.sort === "hot") return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1));
193
195
  if (options.sort === "new") return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)));
196
+ if (options.sort === "old") return [...list].sort((a, b) => String(a.added).localeCompare(String(b.added)));
194
197
  return list;
195
198
  }
196
199
  /** The themes tab listing: theme category only, most-starred first. */
@@ -327,75 +330,75 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
327
330
  document.head.appendChild(tag);
328
331
  }
329
332
  var Market_module_css_default = {
330
- "catsWrap": "eGUBIq_catsWrap",
331
- "pageInfo": "eGUBIq_pageInfo",
332
- "cats": "eGUBIq_cats",
333
- "catsRow": "eGUBIq_catsRow",
334
- "themesGrid": "eGUBIq_themesGrid",
335
- "star": "eGUBIq_star",
336
- "grow": "eGUBIq_grow",
337
- "card": "eGUBIq_card",
338
- "pagerPages": "eGUBIq_pagerPages",
339
- "pageEllipsis": "eGUBIq_pageEllipsis",
340
- "pager": "eGUBIq_pager",
341
- "sort": "eGUBIq_sort",
342
- "warnBtn": "eGUBIq_warnBtn",
343
- "progress": "eGUBIq_progress",
344
- "okState": "eGUBIq_okState",
345
- "root": "eGUBIq_root",
346
- "sub": "eGUBIq_sub",
347
- "pageOn": "eGUBIq_pageOn",
348
- "tabs": "eGUBIq_tabs",
349
- "swatches": "eGUBIq_swatches",
350
- "descTight": "eGUBIq_descTight",
351
- "irow": "eGUBIq_irow",
352
- "sect": "eGUBIq_sect",
353
- "foot": "eGUBIq_foot",
354
- "sizeBtn": "eGUBIq_sizeBtn",
355
333
  "staleAction": "eGUBIq_staleAction",
356
- "pct": "eGUBIq_pct",
357
- "barWave": "eGUBIq_barWave",
358
- "catsToggle": "eGUBIq_catsToggle",
359
- "owner": "eGUBIq_owner",
360
- "body": "eGUBIq_body",
334
+ "sizeOn": "eGUBIq_sizeOn",
361
335
  "av": "eGUBIq_av",
362
- "cmd": "eGUBIq_cmd",
363
- "err": "eGUBIq_err",
364
- "head": "eGUBIq_head",
365
- "spec": "eGUBIq_spec",
366
- "grid": "eGUBIq_grid",
367
- "cancelBtn": "eGUBIq_cancelBtn",
368
- "pagerSize": "eGUBIq_pagerSize",
369
- "sizeLabel": "eGUBIq_sizeLabel",
370
- "cmdSummary": "eGUBIq_cmdSummary",
371
- "loading": "eGUBIq_loading",
372
- "top": "eGUBIq_top",
373
- "cmdDetails": "eGUBIq_cmdDetails",
374
- "src": "eGUBIq_src",
375
- "on": "eGUBIq_on",
376
- "catsCollapsed": "eGUBIq_catsCollapsed",
377
- "restart": "eGUBIq_restart",
378
- "dangerArmed": "eGUBIq_dangerArmed",
379
336
  "dangerBtn": "eGUBIq_dangerBtn",
380
- "dot": "eGUBIq_dot",
381
- "sp": "eGUBIq_sp",
382
- "desc": "eGUBIq_desc",
337
+ "head": "eGUBIq_head",
383
338
  "bar": "eGUBIq_bar",
339
+ "cmdDetails": "eGUBIq_cmdDetails",
340
+ "sect": "eGUBIq_sect",
341
+ "cmd": "eGUBIq_cmd",
342
+ "barWave": "eGUBIq_barWave",
343
+ "foot": "eGUBIq_foot",
344
+ "spec": "eGUBIq_spec",
384
345
  "empty": "eGUBIq_empty",
346
+ "pageEllipsis": "eGUBIq_pageEllipsis",
347
+ "title": "eGUBIq_title",
348
+ "star": "eGUBIq_star",
349
+ "searchInline": "eGUBIq_searchInline",
385
350
  "warnLine": "eGUBIq_warnLine",
386
- "pageBtn": "eGUBIq_pageBtn",
387
- "dshmSlide": "eGUBIq_dshmSlide",
388
- "tag": "eGUBIq_tag",
351
+ "warnBtn": "eGUBIq_warnBtn",
352
+ "catsRow": "eGUBIq_catsRow",
353
+ "dangerArmed": "eGUBIq_dangerArmed",
354
+ "cats": "eGUBIq_cats",
355
+ "grow": "eGUBIq_grow",
356
+ "dot": "eGUBIq_dot",
389
357
  "nm": "eGUBIq_nm",
358
+ "top": "eGUBIq_top",
359
+ "cmdSummary": "eGUBIq_cmdSummary",
360
+ "progress": "eGUBIq_progress",
390
361
  "spin": "eGUBIq_spin",
391
- "searchInline": "eGUBIq_searchInline",
392
- "sizeOn": "eGUBIq_sizeOn",
362
+ "pagerSize": "eGUBIq_pagerSize",
363
+ "src": "eGUBIq_src",
364
+ "err": "eGUBIq_err",
365
+ "row1": "eGUBIq_row1",
366
+ "desc": "eGUBIq_desc",
367
+ "pageBtn": "eGUBIq_pageBtn",
368
+ "pct": "eGUBIq_pct",
369
+ "grid": "eGUBIq_grid",
370
+ "catsToggle": "eGUBIq_catsToggle",
371
+ "sizeLabel": "eGUBIq_sizeLabel",
372
+ "catsCollapsed": "eGUBIq_catsCollapsed",
373
+ "cancelBtn": "eGUBIq_cancelBtn",
374
+ "pagerPages": "eGUBIq_pagerPages",
393
375
  "barFill": "eGUBIq_barFill",
394
- "title": "eGUBIq_title",
395
- "titleRow": "eGUBIq_titleRow",
376
+ "sp": "eGUBIq_sp",
377
+ "tag": "eGUBIq_tag",
378
+ "tabs": "eGUBIq_tabs",
396
379
  "tab": "eGUBIq_tab",
397
- "row1": "eGUBIq_row1",
398
- "modalNote": "eGUBIq_modalNote"
380
+ "dshmSlide": "eGUBIq_dshmSlide",
381
+ "themesGrid": "eGUBIq_themesGrid",
382
+ "pageInfo": "eGUBIq_pageInfo",
383
+ "body": "eGUBIq_body",
384
+ "pageOn": "eGUBIq_pageOn",
385
+ "pager": "eGUBIq_pager",
386
+ "root": "eGUBIq_root",
387
+ "on": "eGUBIq_on",
388
+ "okState": "eGUBIq_okState",
389
+ "catsWrap": "eGUBIq_catsWrap",
390
+ "modalNote": "eGUBIq_modalNote",
391
+ "sort": "eGUBIq_sort",
392
+ "swatches": "eGUBIq_swatches",
393
+ "card": "eGUBIq_card",
394
+ "descTight": "eGUBIq_descTight",
395
+ "loading": "eGUBIq_loading",
396
+ "irow": "eGUBIq_irow",
397
+ "restart": "eGUBIq_restart",
398
+ "sub": "eGUBIq_sub",
399
+ "owner": "eGUBIq_owner",
400
+ "sizeBtn": "eGUBIq_sizeBtn",
401
+ "titleRow": "eGUBIq_titleRow"
399
402
  };
400
403
  //#endregion
401
404
  //#region src/client/MarketSection.tsx
@@ -462,6 +465,17 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
462
465
  96
463
466
  ];
464
467
  const DEFAULT_PAGE_SIZE = 24;
468
+ /** Sort orders offered by the Discover toolbar, in display order. */
469
+ const SORT_KEYS = [
470
+ "hot",
471
+ "new",
472
+ "old"
473
+ ];
474
+ const SORT_LABELS = {
475
+ hot: "sortHot",
476
+ new: "sortNew",
477
+ old: "sortOld"
478
+ };
465
479
  function MarketSection(props) {
466
480
  const t = props.t;
467
481
  const localeSnap = (0, react.useSyncExternalStore)((cb) => props.locale.subscribe(cb), () => props.locale.getSnapshot());
@@ -1356,10 +1370,10 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
1356
1370
  })()
1357
1371
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1358
1372
  className: Market_module_css_default.sort,
1359
- children: ["hot", "new"].map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1373
+ children: SORT_KEYS.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1360
1374
  className: sort === key ? Market_module_css_default.on : "",
1361
1375
  onClick: () => setSort(key),
1362
- children: t(key === "hot" ? "sortHot" : "sortNew")
1376
+ children: t(SORT_LABELS[key])
1363
1377
  }, key))
1364
1378
  })]
1365
1379
  })
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","Toast","useState","css","useSyncExternalStore","useCallback","useRef","useMemo","themePlugins","themePluginsOf","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 cancelOp: '取消',\n cancelled: '已取消',\n busyWait: '已有操作正在进行,请等它结束(同一时间只执行一个安装/更新/卸载)',\n approveBuilds: '放行构建脚本并重试',\n buildsSkipped: '该插件需要运行构建脚本才能工作,出于安全默认被拦下。点击下方按钮为它放行并重装:',\n restartNow: '立即重启',\n restarting: '正在重启…',\n restartFail: '重启失败',\n restartTimeout: '等待 DeepSeek Harness 启动超时',\n updateNow: '立即更新',\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 prevPage: '上一页',\n nextPage: '下一页',\n firstPage: '首页',\n lastPage: '末页',\n pageInfo: '第 {0} / {1} 页',\n perPage: '每页',\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 cancelOp: 'Cancel',\n cancelled: 'Cancelled',\n busyWait: 'Another operation is already running — please wait for it to finish (one install/update/uninstall at a time)',\n approveBuilds: 'Allow build scripts and retry',\n buildsSkipped: 'This plugin needs its build scripts to run; they are blocked by default for safety. Click below to allow them and reinstall:',\n restartNow: 'Restart now',\n restarting: 'Restarting…',\n restartFail: 'Restart failed',\n restartTimeout: 'Timed out waiting for DeepSeek Harness to start',\n updateNow: 'Update now',\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 prevPage: 'Previous',\n nextPage: 'Next',\n firstPage: 'First',\n lastPage: 'Last',\n pageInfo: 'Page {0} of {1}',\n perPage: 'Per page',\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/** Filters and sort order driving the discover list. */\nexport interface ListQuery {\n /** Active category id, or 'all'. */\n category: string\n /** Raw search input (trimmed and lowercased internally). */\n query: string\n /** UI language for description matching ('zh' / 'en'). */\n lang: string\n /** 'hot' (stars desc), 'new' (added desc), anything else keeps registry order. */\n sort: string\n}\n\n/**\n * The discover list: category filter, then search across name / owner /\n * localized description, then the selected sort. Pure — the section renders\n * exactly this.\n */\nexport function visiblePlugins(plugins: RegistryPlugin[], options: ListQuery): RegistryPlugin[] {\n const query = options.query.trim().toLowerCase()\n const list = plugins.filter((p) => {\n if (options.category !== 'all' && p.category !== options.category) return false\n if (query === '') return true\n const desc = (p.description && (p.description[options.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 (options.sort === 'hot') {\n return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1))\n }\n if (options.sort === 'new') {\n return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)))\n }\n return list\n}\n\n/** The themes tab listing: theme category only, most-starred first. */\nexport function themePlugins(plugins: RegistryPlugin[]): RegistryPlugin[] {\n return plugins.filter(p => p.category === 'theme').sort((a, b) => (b.stars || 0) - (a.stars || 0))\n}\n\n/**\n * Category chip order: collapsed with an active non-'all' chip, the active\n * one moves to the front so it stays visible inside the two-row clip.\n */\nexport function orderedCategories(categories: string[], active: string, open: boolean): string[] {\n return open || active === 'all' ? categories : [active, ...categories.filter(id => id !== active)]\n}\n\n/**\n * Page-number list for the discover pager. With few pages it is simply\n * 1..total; with many it windows around the current page and inserts '…'\n * so a 400-plugin catalog stays a compact `1 … 4 5 6 … 17` instead of a\n * long row of numbered buttons. Always begins with 1 and ends with total.\n */\nexport function pageItems(current: number, total: number): Array<number | '…'> {\n if (total <= 7) {\n const all: number[] = []\n for (let i = 1; i <= total; i++) all.push(i)\n return all\n }\n const items: Array<number | '…'> = [1]\n let start = Math.max(2, current - 1)\n let end = Math.min(total - 1, current + 1)\n if (current <= 4) end = 5\n if (current >= total - 3) start = total - 4\n if (start > 2) items.push('…')\n for (let i = start; i <= end; i++) items.push(i)\n if (end < total - 1) items.push('…')\n items.push(total)\n return items\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 // Subpath-aware: a /tree/ entry identifies as repo#path:/sub, never the\n // bare repo — two subpackages of one monorepo must not cross-match.\n const m = /^https:\\/\\/github\\.com\\/([^/]+\\/[^/]+?)(?:\\/tree\\/[^/]+\\/(.+?))?\\/?$/.exec(plugin.url)\n if (m !== null) {\n ids.add(m[2] !== undefined ? `${m[1]!.toLowerCase()}#path:/${m[2].toLowerCase()}` : m[1]!.toLowerCase())\n }\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_.-]+)(?:#path:\\/([A-Za-z0-9_./-]+))?/i.exec(spec)\n if (match !== null) {\n ids.add(match[1]!.toLowerCase())\n if (match[2] !== undefined) ids.add(`${match[1]!.toLowerCase()}#path:/${match[2].toLowerCase()}`)\n }\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 header brand mark now lives in MarketSection.tsx as an inline SVG\n * (official-style monochrome glyph, fill=\"currentColor\") so it follows the\n * active theme; the colored assets/logo.svg tile is no longer inlined here.\n */\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, type CSSProperties } 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, looksTerminal, matchInstalledName, orderedCategories,\n pageItems, readSession, repoOf, themePlugins as themePluginsOf, themeSwatch, visiblePlugins,\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\n/**\n * Official-style market glyph: the shared block-grid brand mark converted to\n * the official monochrome icon form (16×16, fill=\"currentColor\") so it\n * follows the active theme. Mirrors the settings-nav glyph used for the\n * \"market\" section id.\n */\nfunction MarketLogo({ size = 16, style }: { size?: number; style?: CSSProperties }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\" style={style}>\n <path fill=\"currentColor\" d=\"M2.35 1.75H4.95A0.6 0.6 0 0 1 5.55 2.35V4.95A0.6 0.6 0 0 1 4.95 5.55H2.35A0.6 0.6 0 0 1 1.75 4.95V2.35A0.6 0.6 0 0 1 2.35 1.75ZM6.7 1.75H9.3A0.6 0.6 0 0 1 9.9 2.35V4.95A0.6 0.6 0 0 1 9.3 5.55H6.7A0.6 0.6 0 0 1 6.1 4.95V2.35A0.6 0.6 0 0 1 6.7 1.75ZM2.35 6.1H4.95A0.6 0.6 0 0 1 5.55 6.7V9.3A0.6 0.6 0 0 1 4.95 9.9H2.35A0.6 0.6 0 0 1 1.75 9.3V6.7A0.6 0.6 0 0 1 2.35 6.1ZM6.7 6.1H9.3A0.6 0.6 0 0 1 9.9 6.7V9.3A0.6 0.6 0 0 1 9.3 9.9H6.7A0.6 0.6 0 0 1 6.1 9.3V6.7A0.6 0.6 0 0 1 6.7 6.1ZM11.05 6.1H13.65A0.6 0.6 0 0 1 14.25 6.7V9.3A0.6 0.6 0 0 1 13.65 9.9H11.05A0.6 0.6 0 0 1 10.45 9.3V6.7A0.6 0.6 0 0 1 11.05 6.1ZM2.35 10.45H4.95A0.6 0.6 0 0 1 5.55 11.05V13.65A0.6 0.6 0 0 1 4.95 14.25H2.35A0.6 0.6 0 0 1 1.75 13.65V11.05A0.6 0.6 0 0 1 2.35 10.45ZM6.7 10.45H9.3A0.6 0.6 0 0 1 9.9 11.05V13.65A0.6 0.6 0 0 1 9.3 14.25H6.7A0.6 0.6 0 0 1 6.1 13.65V11.05A0.6 0.6 0 0 1 6.7 10.45ZM11.05 10.45H13.65A0.6 0.6 0 0 1 14.25 11.05V13.65A0.6 0.6 0 0 1 13.65 14.25H11.05A0.6 0.6 0 0 1 10.45 13.65V11.05A0.6 0.6 0 0 1 11.05 10.45Z\" />\n <path fill=\"currentColor\" d=\"M11.05 1.75H13.65A0.6 0.6 0 0 1 14.25 2.35V4.95A0.6 0.6 0 0 1 13.65 5.55H11.05A0.6 0.6 0 0 1 10.45 4.95V2.35A0.6 0.6 0 0 1 11.05 1.75Z\" transform=\"rotate(9 12.35 3.65)\" />\n </svg>\n )\n}\n\n/**\n * Module-scope caches so re-entering the section renders instantly instead\n * of refetching and rebuilding from a spinner (#30 by @StarsTom). Module\n * state survives section switches; a background refetch keeps it current.\n */\nlet cachedRegistry: Registry | null = null\nlet cachedInstalled: InstalledMap | null = null\n\n/** Discover grid page-size choices — the catalog grows daily, so cap each page. */\nconst PAGE_SIZES = [24, 48, 96]\nconst DEFAULT_PAGE_SIZE = 24\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>(cachedRegistry)\n const [loadError, setLoadError] = useState(false)\n const [installed, setInstalledState] = useState<InstalledMap>(cachedInstalled ?? {})\n const setInstalled = useCallback((value: InstalledMap) => { cachedInstalled = value; setInstalledState(value) }, [])\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 /** Consecutive idle polls with a pending install that never landed (#32). */\n const idleStrikes = useRef(0)\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 // Plugin blocked by pnpm's fresh-release safety wait; arms the update-now button.\n const [staleName, setStaleName] = useState<string | null>(null)\n /** 1-based discover page; reset to 1 whenever the list shape changes. */\n const [page, setPage] = useState(1)\n /** Cards per discover page; changing it jumps back to page 1. */\n const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE)\n\n /** Determinate percent parsed from pnpm's Progress line, when available. */\n const [progressPct, setProgressPct] = useState<number | null>(null)\n /** Blocked build scripts from the last install: enables approve-and-retry (#6). */\n const [buildsSkipped, setBuildsSkipped] = useState<{ plugin: RegistryPlugin; names: 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 /** One-click restart (#14 by @ysyyhhh): server capability + in-flight state. */\n const [restartEnabled, setRestartEnabled] = useState(false)\n const [restarting, setRestarting] = useState(false)\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 => { cachedRegistry = body.registry; 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 setRestartEnabled(status.restart === true)\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) {\n setEnvReady(true)\n } else {\n setEnvFailed(true)\n if (typeof body.error === 'string') setInstallError(body.error)\n }\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 const m = /resolved (\\d+), reused (\\d+), downloaded (\\d+), added (\\d+)/.exec(status.lastLine || '')\n if (m !== null && Number(m[1]) > 0) {\n const done = Number(m[2]) + Number(m[3]) + Number(m[4])\n setProgressPct(Math.max(4, Math.min(96, Math.round(done / Number(m[1]) * 100))))\n }\n } else {\n setProgressLine(null)\n setProgressPct(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 idleStrikes.current = 0\n sessionStorage.removeItem('dshm-pending')\n setDoneUrls(urls => urls.includes(busyUrl) ? urls : urls.concat(busyUrl))\n setBusyUrl(null)\n } else if (++idleStrikes.current >= 2) {\n // Host is idle and the plugin never landed: the install died\n // (e.g. exit 127) with its response lost. Without this the\n // button says \"installing\" forever — across reloads (#32).\n idleStrikes.current = 0\n sessionStorage.removeItem('dshm-pending')\n setBusyUrl(null)\n setInstallError(t('installFail') + ' — ' + t('exportLog'))\n }\n }\n }\n })\n .catch(() => {})\n }, 2000)\n return () => clearInterval(timer)\n }, [busyUrl, updatingName, data])\n\n const plugins = useMemo(\n () => (data === null ? [] : visiblePlugins(data.plugins, { category: cat, query: q, lang, sort })),\n [data, q, cat, lang, sort])\n\n useEffect(() => { setPage(1) }, [q, cat, sort])\n\n const totalPages = Math.max(1, Math.ceil(plugins.length / pageSize))\n // Clamp in case the list shrank while the user was on a later page.\n const currentPage = Math.min(page, totalPages)\n const pagePlugins = plugins.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n\n const scrollToTop = () => {\n const el = bodyRef.current\n if (el) {\n // jsdom (tests) lacks Element.scrollTo — fall back to the assignment.\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: 0, behavior: 'smooth' })\n else el.scrollTop = 0\n }\n }\n\n const goToPage = (next: number) => {\n setPage(Math.max(1, Math.min(next, totalPages)))\n scrollToTop()\n }\n\n const changePageSize = (size: number) => {\n setPageSize(size)\n setPage(1)\n scrollToTop()\n }\n\n const doInstall = useCallback((plugin: RegistryPlugin) => {\n setBuildsSkipped(null)\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 (body.cancelled === true) {\n // User-cancelled: quiet reset, nothing to report.\n refreshInstalled()\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 if (status === 409) {\n setInstallError(t('busyWait'))\n return\n }\n if (Array.isArray(body.ignoredBuilds) && body.ignoredBuilds.length > 0) {\n setBuildsSkipped({ plugin, names: body.ignoredBuilds.map(String) })\n }\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 /**\n * Restart the host and reload once the boot id changes (#14 by @ysyyhhh).\n * The 202 races the process's SIGTERM, so network errors on the initial\n * request are expected and treated as \"restart under way\".\n */\n const doRestart = useCallback(() => {\n if (bootId === null || restarting) return\n const previousBoot = bootId\n setRestarting(true)\n setInstallError(null)\n const awaitNewBoot = () => {\n const deadline = Date.now() + 60000\n const poll = () => {\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then((next) => {\n if (typeof next.boot === 'string' && next.boot !== previousBoot) {\n location.reload()\n return\n }\n retry()\n })\n .catch(retry)\n }\n const retry = () => {\n if (Date.now() > deadline) {\n setRestarting(false)\n setInstallError(t('restartTimeout'))\n return\n }\n setTimeout(poll, 1500)\n }\n poll()\n }\n fetch('/dsh-market/restart', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status !== 202 || body.ok !== true) {\n setRestarting(false)\n setInstallError(t('restartFail') + ': ' + String(body.error || ('HTTP ' + String(status))))\n return\n }\n awaitNewBoot()\n })\n .catch(awaitNewBoot) // the host may die mid-response; keep polling\n }, [bootId, restarting, t])\n\n /** Cancel the running plugin command (#6 by @qichuang321). */\n const doCancel = useCallback(() => {\n fetch('/dsh-market/cancel', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .catch(() => {})\n }, [])\n\n const doUpdate = useCallback((name: string, force = false) => {\n setInstallError(null)\n setStaleName(null)\n setUpdatingName(name)\n return fetch('/dsh-market/update', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(force ? { name, force: true } : { name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (body.cancelled === true) {\n refreshInstalled()\n return\n }\n if (status === 200 && body.ok) {\n setUpdatedNames(names => names.concat(name))\n refreshInstalled()\n } else {\n if (status === 409) { setInstallError(t('busyWait')); return }\n if (body.stale === true) setStaleName(name)\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 ? [] : themePluginsOf(data.plugins)\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 {progressPct !== null && <span className={css.pct}>{progressPct}%</span>}\n <button type=\"button\" className={css.cancelBtn} onClick={doCancel}>{t('cancelOp')}</button>\n <div className={css.bar}>\n <div\n className={progressPct !== null ? css.barFill : `${css.barFill} ${css.barWave}`}\n style={progressPct !== null ? { width: `${progressPct}%` } : undefined}\n />\n </div>\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 <MarketLogo size={22} style={{ 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 {restartEnabled && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={restarting || busyUrl !== null || updatingName !== null || removingName !== null}\n onClick={doRestart}\n >{restarting ? t('restarting') : t('restartNow')}</Button>\n )}\n </div>\n )}\n </div>\n {buildsSkipped !== null && (\n <div className={css.restart}>\n <span className={css.grow}>{t('buildsSkipped')} {buildsSkipped.names.join(', ')}</span>\n <Button\n size=\"sm\"\n disabled={busyUrl !== null}\n onClick={() => {\n const { plugin, names } = buildsSkipped\n setBuildsSkipped(null)\n fetch('/dsh-market/approve-builds', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ packages: names }),\n })\n .then(res => res.json())\n .then((body) => {\n if (body.ok) doInstall(plugin)\n else setInstallError(String(body.error || 'approve failed'))\n })\n .catch(error => setInstallError(String(error)))\n }}\n >{t('approveBuilds')}</Button>\n </div>\n )}\n {installError !== null && (\n <div className={css.err}>\n {installError}\n {staleName !== null && (\n <div className={css.staleAction}>\n <Button size=\"sm\" onClick={() => doUpdate(staleName, true)}>{t('updateNow')}</Button>\n </div>\n )}\n </div>\n )}\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 = orderedCategories(categories, cat, catsOpen)\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 : (\n <>\n <div className={css.grid}>{pagePlugins.map(pluginCard)}</div>\n <div className={css.pager}>\n <div className={css.pagerPages}>\n {totalPages > 1 && (\n <>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === 1} onClick={() => goToPage(1)} aria-label={t('firstPage')}>«</button>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === 1} onClick={() => goToPage(currentPage - 1)}>{t('prevPage')}</button>\n {pageItems(currentPage, totalPages).map((item, i) => (\n item === '…'\n ? <span key={'e' + i} className={css.pageEllipsis}>…</span>\n : (\n <button\n key={item}\n type=\"button\"\n className={item === currentPage ? `${css.pageBtn} ${css.pageOn}` : css.pageBtn}\n onClick={() => goToPage(item)}\n >{item}</button>\n )\n ))}\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === totalPages} onClick={() => goToPage(currentPage + 1)}>{t('nextPage')}</button>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === totalPages} onClick={() => goToPage(totalPages)} aria-label={t('lastPage')}>»</button>\n <span className={css.pageInfo}>{t('pageInfo').replace('{0}', String(currentPage)).replace('{1}', String(totalPages))}</span>\n </>\n )}\n </div>\n <div className={css.pagerSize}>\n <span className={css.sizeLabel}>{t('perPage')}</span>\n {PAGE_SIZES.map(size => (\n <button\n key={size}\n type=\"button\"\n className={size === pageSize ? `${css.sizeBtn} ${css.sizeOn}` : css.sizeBtn}\n onClick={() => changePageSize(size)}\n >{size}</button>\n ))}\n </div>\n </div>\n </>\n )}\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 {progressPct !== null && <span className={css.pct}>{progressPct}%</span>}\n <button type=\"button\" className={css.cancelBtn} onClick={doCancel}>{t('cancelOp')}</button>\n <div className={css.bar}>\n <div\n className={progressPct !== null ? css.barFill : `${css.barFill} ${css.barWave}`}\n style={progressPct !== null ? { width: `${progressPct}%` } : undefined}\n />\n </div>\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","useCallback","useRef","useMemo","themePlugins","themePluginsOf","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 cancelOp: '取消',\n cancelled: '已取消',\n busyWait: '已有操作正在进行,请等它结束(同一时间只执行一个安装/更新/卸载)',\n approveBuilds: '放行构建脚本并重试',\n buildsSkipped: '该插件需要运行构建脚本才能工作,出于安全默认被拦下。点击下方按钮为它放行并重装:',\n restartNow: '立即重启',\n restarting: '正在重启…',\n restartFail: '重启失败',\n restartTimeout: '等待 DeepSeek Harness 启动超时',\n updateNow: '立即更新',\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 sortOld: '最早',\n prevPage: '上一页',\n nextPage: '下一页',\n firstPage: '首页',\n lastPage: '末页',\n pageInfo: '第 {0} / {1} 页',\n perPage: '每页',\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 cancelOp: 'Cancel',\n cancelled: 'Cancelled',\n busyWait: 'Another operation is already running — please wait for it to finish (one install/update/uninstall at a time)',\n approveBuilds: 'Allow build scripts and retry',\n buildsSkipped: 'This plugin needs its build scripts to run; they are blocked by default for safety. Click below to allow them and reinstall:',\n restartNow: 'Restart now',\n restarting: 'Restarting…',\n restartFail: 'Restart failed',\n restartTimeout: 'Timed out waiting for DeepSeek Harness to start',\n updateNow: 'Update now',\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 sortOld: 'Oldest',\n prevPage: 'Previous',\n nextPage: 'Next',\n firstPage: 'First',\n lastPage: 'Last',\n pageInfo: 'Page {0} of {1}',\n perPage: 'Per page',\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/** Discover sort orders. */\nexport type SortKey = 'hot' | 'new' | 'old'\n\n/** Filters and sort order driving the discover list. */\nexport interface ListQuery {\n /** Active category id, or 'all'. */\n category: string\n /** Raw search input (trimmed and lowercased internally). */\n query: string\n /** UI language for description matching ('zh' / 'en'). */\n lang: string\n /** 'hot' (stars desc), 'new' (added desc), 'old' (added asc); anything else keeps registry order. */\n sort: string\n}\n\n/**\n * The discover list: category filter, then search across name / owner /\n * localized description, then the selected sort. Pure — the section renders\n * exactly this.\n */\nexport function visiblePlugins(plugins: RegistryPlugin[], options: ListQuery): RegistryPlugin[] {\n const query = options.query.trim().toLowerCase()\n const list = plugins.filter((p) => {\n if (options.category !== 'all' && p.category !== options.category) return false\n if (query === '') return true\n const desc = (p.description && (p.description[options.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 (options.sort === 'hot') {\n return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1))\n }\n if (options.sort === 'new') {\n return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)))\n }\n if (options.sort === 'old') {\n return [...list].sort((a, b) => String(a.added).localeCompare(String(b.added)))\n }\n return list\n}\n\n/** The themes tab listing: theme category only, most-starred first. */\nexport function themePlugins(plugins: RegistryPlugin[]): RegistryPlugin[] {\n return plugins.filter(p => p.category === 'theme').sort((a, b) => (b.stars || 0) - (a.stars || 0))\n}\n\n/**\n * Category chip order: collapsed with an active non-'all' chip, the active\n * one moves to the front so it stays visible inside the two-row clip.\n */\nexport function orderedCategories(categories: string[], active: string, open: boolean): string[] {\n return open || active === 'all' ? categories : [active, ...categories.filter(id => id !== active)]\n}\n\n/**\n * Page-number list for the discover pager. With few pages it is simply\n * 1..total; with many it windows around the current page and inserts '…'\n * so a 400-plugin catalog stays a compact `1 … 4 5 6 … 17` instead of a\n * long row of numbered buttons. Always begins with 1 and ends with total.\n */\nexport function pageItems(current: number, total: number): Array<number | '…'> {\n if (total <= 7) {\n const all: number[] = []\n for (let i = 1; i <= total; i++) all.push(i)\n return all\n }\n const items: Array<number | '…'> = [1]\n let start = Math.max(2, current - 1)\n let end = Math.min(total - 1, current + 1)\n if (current <= 4) end = 5\n if (current >= total - 3) start = total - 4\n if (start > 2) items.push('…')\n for (let i = start; i <= end; i++) items.push(i)\n if (end < total - 1) items.push('…')\n items.push(total)\n return items\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 // Subpath-aware: a /tree/ entry identifies as repo#path:/sub, never the\n // bare repo — two subpackages of one monorepo must not cross-match.\n const m = /^https:\\/\\/github\\.com\\/([^/]+\\/[^/]+?)(?:\\/tree\\/[^/]+\\/(.+?))?\\/?$/.exec(plugin.url)\n if (m !== null) {\n ids.add(m[2] !== undefined ? `${m[1]!.toLowerCase()}#path:/${m[2].toLowerCase()}` : m[1]!.toLowerCase())\n }\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_.-]+)(?:#path:\\/([A-Za-z0-9_./-]+))?/i.exec(spec)\n if (match !== null) {\n ids.add(match[1]!.toLowerCase())\n if (match[2] !== undefined) ids.add(`${match[1]!.toLowerCase()}#path:/${match[2].toLowerCase()}`)\n }\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 header brand mark now lives in MarketSection.tsx as an inline SVG\n * (official-style monochrome glyph, fill=\"currentColor\") so it follows the\n * active theme; the colored assets/logo.svg tile is no longer inlined here.\n */\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, type CSSProperties } 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, looksTerminal, matchInstalledName, orderedCategories,\n pageItems, readSession, repoOf, themePlugins as themePluginsOf, themeSwatch, visiblePlugins,\n} from './market-data.ts'\nimport type {\n InstalledMap, Registry, RegistryPlugin, SortKey, 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\n/**\n * Official-style market glyph: the shared block-grid brand mark converted to\n * the official monochrome icon form (16×16, fill=\"currentColor\") so it\n * follows the active theme. Mirrors the settings-nav glyph used for the\n * \"market\" section id.\n */\nfunction MarketLogo({ size = 16, style }: { size?: number; style?: CSSProperties }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\" style={style}>\n <path fill=\"currentColor\" d=\"M2.35 1.75H4.95A0.6 0.6 0 0 1 5.55 2.35V4.95A0.6 0.6 0 0 1 4.95 5.55H2.35A0.6 0.6 0 0 1 1.75 4.95V2.35A0.6 0.6 0 0 1 2.35 1.75ZM6.7 1.75H9.3A0.6 0.6 0 0 1 9.9 2.35V4.95A0.6 0.6 0 0 1 9.3 5.55H6.7A0.6 0.6 0 0 1 6.1 4.95V2.35A0.6 0.6 0 0 1 6.7 1.75ZM2.35 6.1H4.95A0.6 0.6 0 0 1 5.55 6.7V9.3A0.6 0.6 0 0 1 4.95 9.9H2.35A0.6 0.6 0 0 1 1.75 9.3V6.7A0.6 0.6 0 0 1 2.35 6.1ZM6.7 6.1H9.3A0.6 0.6 0 0 1 9.9 6.7V9.3A0.6 0.6 0 0 1 9.3 9.9H6.7A0.6 0.6 0 0 1 6.1 9.3V6.7A0.6 0.6 0 0 1 6.7 6.1ZM11.05 6.1H13.65A0.6 0.6 0 0 1 14.25 6.7V9.3A0.6 0.6 0 0 1 13.65 9.9H11.05A0.6 0.6 0 0 1 10.45 9.3V6.7A0.6 0.6 0 0 1 11.05 6.1ZM2.35 10.45H4.95A0.6 0.6 0 0 1 5.55 11.05V13.65A0.6 0.6 0 0 1 4.95 14.25H2.35A0.6 0.6 0 0 1 1.75 13.65V11.05A0.6 0.6 0 0 1 2.35 10.45ZM6.7 10.45H9.3A0.6 0.6 0 0 1 9.9 11.05V13.65A0.6 0.6 0 0 1 9.3 14.25H6.7A0.6 0.6 0 0 1 6.1 13.65V11.05A0.6 0.6 0 0 1 6.7 10.45ZM11.05 10.45H13.65A0.6 0.6 0 0 1 14.25 11.05V13.65A0.6 0.6 0 0 1 13.65 14.25H11.05A0.6 0.6 0 0 1 10.45 13.65V11.05A0.6 0.6 0 0 1 11.05 10.45Z\" />\n <path fill=\"currentColor\" d=\"M11.05 1.75H13.65A0.6 0.6 0 0 1 14.25 2.35V4.95A0.6 0.6 0 0 1 13.65 5.55H11.05A0.6 0.6 0 0 1 10.45 4.95V2.35A0.6 0.6 0 0 1 11.05 1.75Z\" transform=\"rotate(9 12.35 3.65)\" />\n </svg>\n )\n}\n\n/**\n * Module-scope caches so re-entering the section renders instantly instead\n * of refetching and rebuilding from a spinner (#30 by @StarsTom). Module\n * state survives section switches; a background refetch keeps it current.\n */\nlet cachedRegistry: Registry | null = null\nlet cachedInstalled: InstalledMap | null = null\n\n/** Discover grid page-size choices — the catalog grows daily, so cap each page. */\nconst PAGE_SIZES = [24, 48, 96]\nconst DEFAULT_PAGE_SIZE = 24\n\n/** Sort orders offered by the Discover toolbar, in display order. */\nconst SORT_KEYS = ['hot', 'new', 'old'] as const\nconst SORT_LABELS: Record<(typeof SORT_KEYS)[number], string> = {\n hot: 'sortHot',\n new: 'sortNew',\n old: 'sortOld',\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>(cachedRegistry)\n const [loadError, setLoadError] = useState(false)\n const [installed, setInstalledState] = useState<InstalledMap>(cachedInstalled ?? {})\n const setInstalled = useCallback((value: InstalledMap) => { cachedInstalled = value; setInstalledState(value) }, [])\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 /** Consecutive idle polls with a pending install that never landed (#32). */\n const idleStrikes = useRef(0)\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 // Plugin blocked by pnpm's fresh-release safety wait; arms the update-now button.\n const [staleName, setStaleName] = useState<string | null>(null)\n /** 1-based discover page; reset to 1 whenever the list shape changes. */\n const [page, setPage] = useState(1)\n /** Cards per discover page; changing it jumps back to page 1. */\n const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE)\n\n /** Determinate percent parsed from pnpm's Progress line, when available. */\n const [progressPct, setProgressPct] = useState<number | null>(null)\n /** Blocked build scripts from the last install: enables approve-and-retry (#6). */\n const [buildsSkipped, setBuildsSkipped] = useState<{ plugin: RegistryPlugin; names: 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 /** One-click restart (#14 by @ysyyhhh): server capability + in-flight state. */\n const [restartEnabled, setRestartEnabled] = useState(false)\n const [restarting, setRestarting] = useState(false)\n const [showTop, setShowTop] = useState(false)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const [sort, setSort] = useState<SortKey>('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 => { cachedRegistry = body.registry; 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 setRestartEnabled(status.restart === true)\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) {\n setEnvReady(true)\n } else {\n setEnvFailed(true)\n if (typeof body.error === 'string') setInstallError(body.error)\n }\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 const m = /resolved (\\d+), reused (\\d+), downloaded (\\d+), added (\\d+)/.exec(status.lastLine || '')\n if (m !== null && Number(m[1]) > 0) {\n const done = Number(m[2]) + Number(m[3]) + Number(m[4])\n setProgressPct(Math.max(4, Math.min(96, Math.round(done / Number(m[1]) * 100))))\n }\n } else {\n setProgressLine(null)\n setProgressPct(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 idleStrikes.current = 0\n sessionStorage.removeItem('dshm-pending')\n setDoneUrls(urls => urls.includes(busyUrl) ? urls : urls.concat(busyUrl))\n setBusyUrl(null)\n } else if (++idleStrikes.current >= 2) {\n // Host is idle and the plugin never landed: the install died\n // (e.g. exit 127) with its response lost. Without this the\n // button says \"installing\" forever — across reloads (#32).\n idleStrikes.current = 0\n sessionStorage.removeItem('dshm-pending')\n setBusyUrl(null)\n setInstallError(t('installFail') + ' — ' + t('exportLog'))\n }\n }\n }\n })\n .catch(() => {})\n }, 2000)\n return () => clearInterval(timer)\n }, [busyUrl, updatingName, data])\n\n const plugins = useMemo(\n () => (data === null ? [] : visiblePlugins(data.plugins, { category: cat, query: q, lang, sort })),\n [data, q, cat, lang, sort])\n\n useEffect(() => { setPage(1) }, [q, cat, sort])\n\n const totalPages = Math.max(1, Math.ceil(plugins.length / pageSize))\n // Clamp in case the list shrank while the user was on a later page.\n const currentPage = Math.min(page, totalPages)\n const pagePlugins = plugins.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n\n const scrollToTop = () => {\n const el = bodyRef.current\n if (el) {\n // jsdom (tests) lacks Element.scrollTo — fall back to the assignment.\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: 0, behavior: 'smooth' })\n else el.scrollTop = 0\n }\n }\n\n const goToPage = (next: number) => {\n setPage(Math.max(1, Math.min(next, totalPages)))\n scrollToTop()\n }\n\n const changePageSize = (size: number) => {\n setPageSize(size)\n setPage(1)\n scrollToTop()\n }\n\n const doInstall = useCallback((plugin: RegistryPlugin) => {\n setBuildsSkipped(null)\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 (body.cancelled === true) {\n // User-cancelled: quiet reset, nothing to report.\n refreshInstalled()\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 if (status === 409) {\n setInstallError(t('busyWait'))\n return\n }\n if (Array.isArray(body.ignoredBuilds) && body.ignoredBuilds.length > 0) {\n setBuildsSkipped({ plugin, names: body.ignoredBuilds.map(String) })\n }\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 /**\n * Restart the host and reload once the boot id changes (#14 by @ysyyhhh).\n * The 202 races the process's SIGTERM, so network errors on the initial\n * request are expected and treated as \"restart under way\".\n */\n const doRestart = useCallback(() => {\n if (bootId === null || restarting) return\n const previousBoot = bootId\n setRestarting(true)\n setInstallError(null)\n const awaitNewBoot = () => {\n const deadline = Date.now() + 60000\n const poll = () => {\n fetch('/dsh-market/status', { cache: 'no-store' })\n .then(res => res.json())\n .then((next) => {\n if (typeof next.boot === 'string' && next.boot !== previousBoot) {\n location.reload()\n return\n }\n retry()\n })\n .catch(retry)\n }\n const retry = () => {\n if (Date.now() > deadline) {\n setRestarting(false)\n setInstallError(t('restartTimeout'))\n return\n }\n setTimeout(poll, 1500)\n }\n poll()\n }\n fetch('/dsh-market/restart', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (status !== 202 || body.ok !== true) {\n setRestarting(false)\n setInstallError(t('restartFail') + ': ' + String(body.error || ('HTTP ' + String(status))))\n return\n }\n awaitNewBoot()\n })\n .catch(awaitNewBoot) // the host may die mid-response; keep polling\n }, [bootId, restarting, t])\n\n /** Cancel the running plugin command (#6 by @qichuang321). */\n const doCancel = useCallback(() => {\n fetch('/dsh-market/cancel', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n .catch(() => {})\n }, [])\n\n const doUpdate = useCallback((name: string, force = false) => {\n setInstallError(null)\n setStaleName(null)\n setUpdatingName(name)\n return fetch('/dsh-market/update', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(force ? { name, force: true } : { name }),\n })\n .then(res => res.json().then(body => ({ status: res.status, body })))\n .then(({ status, body }) => {\n if (body.cancelled === true) {\n refreshInstalled()\n return\n }\n if (status === 200 && body.ok) {\n setUpdatedNames(names => names.concat(name))\n refreshInstalled()\n } else {\n if (status === 409) { setInstallError(t('busyWait')); return }\n if (body.stale === true) setStaleName(name)\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 ? [] : themePluginsOf(data.plugins)\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 {progressPct !== null && <span className={css.pct}>{progressPct}%</span>}\n <button type=\"button\" className={css.cancelBtn} onClick={doCancel}>{t('cancelOp')}</button>\n <div className={css.bar}>\n <div\n className={progressPct !== null ? css.barFill : `${css.barFill} ${css.barWave}`}\n style={progressPct !== null ? { width: `${progressPct}%` } : undefined}\n />\n </div>\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 <MarketLogo size={22} style={{ 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 {restartEnabled && (\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={restarting || busyUrl !== null || updatingName !== null || removingName !== null}\n onClick={doRestart}\n >{restarting ? t('restarting') : t('restartNow')}</Button>\n )}\n </div>\n )}\n </div>\n {buildsSkipped !== null && (\n <div className={css.restart}>\n <span className={css.grow}>{t('buildsSkipped')} {buildsSkipped.names.join(', ')}</span>\n <Button\n size=\"sm\"\n disabled={busyUrl !== null}\n onClick={() => {\n const { plugin, names } = buildsSkipped\n setBuildsSkipped(null)\n fetch('/dsh-market/approve-builds', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ packages: names }),\n })\n .then(res => res.json())\n .then((body) => {\n if (body.ok) doInstall(plugin)\n else setInstallError(String(body.error || 'approve failed'))\n })\n .catch(error => setInstallError(String(error)))\n }}\n >{t('approveBuilds')}</Button>\n </div>\n )}\n {installError !== null && (\n <div className={css.err}>\n {installError}\n {staleName !== null && (\n <div className={css.staleAction}>\n <Button size=\"sm\" onClick={() => doUpdate(staleName, true)}>{t('updateNow')}</Button>\n </div>\n )}\n </div>\n )}\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 = orderedCategories(categories, cat, catsOpen)\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 {SORT_KEYS.map(key => (\n <button\n key={key}\n className={sort === key ? css.on : ''}\n onClick={() => setSort(key)}\n >{t(SORT_LABELS[key])}</button>\n ))}\n </div>\n </div>\n </div>\n {plugins.length === 0\n ? <div className={css.empty}>{t('empty')}</div>\n : (\n <>\n <div className={css.grid}>{pagePlugins.map(pluginCard)}</div>\n <div className={css.pager}>\n <div className={css.pagerPages}>\n {totalPages > 1 && (\n <>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === 1} onClick={() => goToPage(1)} aria-label={t('firstPage')}>«</button>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === 1} onClick={() => goToPage(currentPage - 1)}>{t('prevPage')}</button>\n {pageItems(currentPage, totalPages).map((item, i) => (\n item === '…'\n ? <span key={'e' + i} className={css.pageEllipsis}>…</span>\n : (\n <button\n key={item}\n type=\"button\"\n className={item === currentPage ? `${css.pageBtn} ${css.pageOn}` : css.pageBtn}\n onClick={() => goToPage(item)}\n >{item}</button>\n )\n ))}\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === totalPages} onClick={() => goToPage(currentPage + 1)}>{t('nextPage')}</button>\n <button type=\"button\" className={css.pageBtn} disabled={currentPage === totalPages} onClick={() => goToPage(totalPages)} aria-label={t('lastPage')}>»</button>\n <span className={css.pageInfo}>{t('pageInfo').replace('{0}', String(currentPage)).replace('{1}', String(totalPages))}</span>\n </>\n )}\n </div>\n <div className={css.pagerSize}>\n <span className={css.sizeLabel}>{t('perPage')}</span>\n {PAGE_SIZES.map(size => (\n <button\n key={size}\n type=\"button\"\n className={size === pageSize ? `${css.sizeBtn} ${css.sizeOn}` : css.sizeBtn}\n onClick={() => changePageSize(size)}\n >{size}</button>\n ))}\n </div>\n </div>\n </>\n )}\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 {progressPct !== null && <span className={css.pct}>{progressPct}%</span>}\n <button type=\"button\" className={css.cancelBtn} onClick={doCancel}>{t('cancelOp')}</button>\n <div className={css.bar}>\n <div\n className={progressPct !== null ? css.barFill : `${css.barFill} ${css.barWave}`}\n style={progressPct !== null ? { width: `${progressPct}%` } : undefined}\n />\n </div>\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/lib/routes.js CHANGED
@@ -16,7 +16,7 @@ import { BOOT_ID, cancelActive, probePnpm, progress, provisionPnpm, runDshPlugin
16
16
  import { profileDir, readInstalled, readInstalledVersion, readLockCommits, setAllowBuilds } from './profile.js';
17
17
  import { findInstalledAlias, installTargetFor } from './sources.js';
18
18
  import { isStaleUpdate, parseIgnoredBuilds, RELEASE_AGE_OVERRIDE, retargetCollections, validateAddedPlugins, withHoistRecovery } from './install.js';
19
- import { checkUpdates, invalidateUpdates } from './updates.js';
19
+ import { checkUpdates, invalidateUpdates, latestPublishedRecently } from './updates.js';
20
20
  import { createThemeManager } from './themes.js';
21
21
  import { readJsonBody, sameOrigin, sendJson } from './http.js';
22
22
  import { restartAllowed, scheduleRestart, trustedRestartRequest } from './restart.js';
@@ -272,15 +272,24 @@ export function mountMarketRoutes(host, config) {
272
272
  }
273
273
  if (ok)
274
274
  invalidateUpdates();
275
- const staleError = stale
276
- ? '这个新版本刚发布不久。为了安全,系统默认会等它发布满一天后再安装——刚发布的版本偶尔会被发现问题然后撤回。可以明天再试,或点「立即更新」不再等待。 / This version was just released; for safety, installs normally wait about a day after a release. Try again tomorrow, or click "Update now" to install it right away.'
277
- : null;
278
- logEvent(ok || cancelled ? 'info' : 'error', 'update', `${name} -> ${target} exit=${String(result.exitCode)}${result.timedOut ? ' TIMEOUT' : ''}${cancelled ? ' CANCELLED' : ''}${stale ? ' STALE(minimumReleaseAge?)' : ''}${ok || cancelled ? '' : ` stderr=${result.stderr.slice(-300)}`}`);
275
+ // Diagnose the stale outcome with EVIDENCE (#45 by @ayingQAQ):
276
+ // only blame pnpm's fresh-release wait when the target's latest
277
+ // release really is young; otherwise be honest that the cause is
278
+ // unconfirmed. Git installs never hit the age gate.
279
+ const youngRelease = stale && !isGit ? await latestPublishedRecently(name) : false;
280
+ const staleReason = stale ? (youngRelease === true ? 'release-age' : 'unknown') : null;
281
+ const staleError = !stale
282
+ ? null
283
+ : staleReason === 'release-age'
284
+ ? '这个新版本刚发布不久。为了安全,系统默认会等它发布满一天后再安装——刚发布的版本偶尔会被发现问题然后撤回。可以明天再试,或点「立即更新」不再等待。 / This version was just released; for safety, installs normally wait about a day after a release. Try again tomorrow, or click "Update now" to install it right away.'
285
+ : '更新命令执行完成,但版本没有变化,原因未能确认。点「立即更新」重试通常能解决;若仍不行,请导出日志反馈。 / The update command completed but the version did not change; the cause could not be confirmed. Clicking "Update now" to retry usually resolves it — if not, export the log and report it.';
286
+ logEvent(ok || cancelled ? 'info' : 'error', 'update', `${name} -> ${target} exit=${String(result.exitCode)}${result.timedOut ? ' TIMEOUT' : ''}${cancelled ? ' CANCELLED' : ''}${stale ? ` STALE(${staleReason ?? 'unknown'})` : ''}${ok || cancelled ? '' : ` stderr=${result.stderr.slice(-300)}`}`);
279
287
  // A user-cancelled run is a quiet outcome, not an error.
280
288
  sendJson(response, ok || cancelled ? 200 : 502, {
281
289
  ok,
282
290
  cancelled: cancelled || undefined,
283
291
  stale: stale || undefined,
292
+ staleReason: staleReason ?? undefined,
284
293
  error: staleError ?? undefined,
285
294
  exitCode: result.exitCode,
286
295
  timedOut: result.timedOut,
@@ -12,5 +12,15 @@ export interface UpdateStatus {
12
12
  }
13
13
  /** Drop the cached listing (after a successful install/update/uninstall). */
14
14
  export declare function invalidateUpdates(): void;
15
+ /**
16
+ * Evidence check behind the "wait a day" stale diagnosis (#45): whether the
17
+ * package's CURRENT latest release was published recently enough to sit
18
+ * inside pnpm's default fresh-release window. pnpm's silent hold leaves no
19
+ * trace in its output, so the publish time is the only verifiable signal.
20
+ * @returns true/false when the npm time metadata answers, null when it
21
+ * can't be determined (offline, unpublished, non-npm) — callers must NOT
22
+ * claim the safety wait on null.
23
+ */
24
+ export declare function latestPublishedRecently(name: string, windowMs?: number): Promise<boolean | null>;
15
25
  /** Per-plugin update checks; a failed check reports no update rather than failing the listing. */
16
26
  export declare function checkUpdates(profile: string, force?: boolean): Promise<Record<string, UpdateStatus>>;
package/lib/updates.js CHANGED
@@ -19,6 +19,29 @@ async function fetchJson(url) {
19
19
  throw new Error(`HTTP ${res.status}`);
20
20
  return res.json();
21
21
  }
22
+ /**
23
+ * Evidence check behind the "wait a day" stale diagnosis (#45): whether the
24
+ * package's CURRENT latest release was published recently enough to sit
25
+ * inside pnpm's default fresh-release window. pnpm's silent hold leaves no
26
+ * trace in its output, so the publish time is the only verifiable signal.
27
+ * @returns true/false when the npm time metadata answers, null when it
28
+ * can't be determined (offline, unpublished, non-npm) — callers must NOT
29
+ * claim the safety wait on null.
30
+ */
31
+ export async function latestPublishedRecently(name, windowMs = 26 * 60 * 60 * 1000) {
32
+ try {
33
+ const doc = (await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(name)}`));
34
+ const latest = doc['dist-tags']?.latest;
35
+ const published = latest !== undefined ? doc.time?.[latest] : undefined;
36
+ if (published === undefined)
37
+ return null;
38
+ const age = Date.now() - Date.parse(published);
39
+ return Number.isFinite(age) ? age < windowMs : null;
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
22
45
  /** Per-plugin update checks; a failed check reports no update rather than failing the listing. */
23
46
  export async function checkUpdates(profile, force = false) {
24
47
  if (!force && updatesCache && Date.now() - updatesCache.at < UPDATES_TTL_MS)
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.4.0",
4
+ "version": "1.4.1",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/types/index.d.ts",
@@ -11,7 +11,7 @@ import {
11
11
  pageItems, readSession, repoOf, themePlugins as themePluginsOf, themeSwatch, visiblePlugins,
12
12
  } from './market-data.ts'
13
13
  import type {
14
- InstalledMap, Registry, RegistryPlugin, ThemeSnapshot, Translate, UpdateStatus,
14
+ InstalledMap, Registry, RegistryPlugin, SortKey, ThemeSnapshot, Translate, UpdateStatus,
15
15
  } from './market-data.ts'
16
16
 
17
17
  /**
@@ -65,6 +65,14 @@ let cachedInstalled: InstalledMap | null = null
65
65
  const PAGE_SIZES = [24, 48, 96]
66
66
  const DEFAULT_PAGE_SIZE = 24
67
67
 
68
+ /** Sort orders offered by the Discover toolbar, in display order. */
69
+ const SORT_KEYS = ['hot', 'new', 'old'] as const
70
+ const SORT_LABELS: Record<(typeof SORT_KEYS)[number], string> = {
71
+ hot: 'sortHot',
72
+ new: 'sortNew',
73
+ old: 'sortOld',
74
+ }
75
+
68
76
  export interface MarketSectionProps {
69
77
  t: Translate
70
78
  locale: {
@@ -138,7 +146,7 @@ export function MarketSection(props: MarketSectionProps) {
138
146
  const [restarting, setRestarting] = useState(false)
139
147
  const [showTop, setShowTop] = useState(false)
140
148
  const bodyRef = useRef<HTMLDivElement | null>(null)
141
- const [sort, setSort] = useState('hot')
149
+ const [sort, setSort] = useState<SortKey>('hot')
142
150
  const [catsOpen, setCatsOpen] = useState(false)
143
151
  // How many category pills fit in the two collapsed rows (measured once —
144
152
  // the settings panel width is fixed); null = measuring render with all
@@ -831,12 +839,12 @@ export function MarketSection(props: MarketSectionProps) {
831
839
  })()}
832
840
  </div>
833
841
  <div className={css.sort}>
834
- {['hot', 'new'].map(key => (
842
+ {SORT_KEYS.map(key => (
835
843
  <button
836
844
  key={key}
837
845
  className={sort === key ? css.on : ''}
838
846
  onClick={() => setSort(key)}
839
- >{t(key === 'hot' ? 'sortHot' : 'sortNew')}</button>
847
+ >{t(SORT_LABELS[key])}</button>
840
848
  ))}
841
849
  </div>
842
850
  </div>
@@ -57,6 +57,7 @@ export const zh = {
57
57
  catsLess: '收起',
58
58
  sortHot: '最热',
59
59
  sortNew: '最新',
60
+ sortOld: '最早',
60
61
  prevPage: '上一页',
61
62
  nextPage: '下一页',
62
63
  firstPage: '首页',
@@ -135,6 +136,7 @@ export const en: Record<MarketKey, string> = {
135
136
  catsLess: 'Less',
136
137
  sortHot: 'Top',
137
138
  sortNew: 'New',
139
+ sortOld: 'Oldest',
138
140
  prevPage: 'Previous',
139
141
  nextPage: 'Next',
140
142
  firstPage: 'First',
@@ -84,6 +84,9 @@ 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
+ /** Discover sort orders. */
88
+ export type SortKey = 'hot' | 'new' | 'old'
89
+
87
90
  /** Filters and sort order driving the discover list. */
88
91
  export interface ListQuery {
89
92
  /** Active category id, or 'all'. */
@@ -92,7 +95,7 @@ export interface ListQuery {
92
95
  query: string
93
96
  /** UI language for description matching ('zh' / 'en'). */
94
97
  lang: string
95
- /** 'hot' (stars desc), 'new' (added desc), anything else keeps registry order. */
98
+ /** 'hot' (stars desc), 'new' (added desc), 'old' (added asc); anything else keeps registry order. */
96
99
  sort: string
97
100
  }
98
101
 
@@ -117,6 +120,9 @@ export function visiblePlugins(plugins: RegistryPlugin[], options: ListQuery): R
117
120
  if (options.sort === 'new') {
118
121
  return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)))
119
122
  }
123
+ if (options.sort === 'old') {
124
+ return [...list].sort((a, b) => String(a.added).localeCompare(String(b.added)))
125
+ }
120
126
  return list
121
127
  }
122
128
 
package/src/routes.ts CHANGED
@@ -21,7 +21,7 @@ import { BOOT_ID, cancelActive, probePnpm, progress, provisionPnpm, runDshPlugin
21
21
  import { profileDir, readInstalled, readInstalledVersion, readLockCommits, setAllowBuilds } from './profile.ts'
22
22
  import { findInstalledAlias, installTargetFor } from './sources.ts'
23
23
  import { isStaleUpdate, parseIgnoredBuilds, RELEASE_AGE_OVERRIDE, retargetCollections, validateAddedPlugins, withHoistRecovery } from './install.ts'
24
- import { checkUpdates, invalidateUpdates } from './updates.ts'
24
+ import { checkUpdates, invalidateUpdates, latestPublishedRecently } from './updates.ts'
25
25
  import { createThemeManager, type LoaderEntry } from './themes.ts'
26
26
  import { readJsonBody, sameOrigin, sendJson } from './http.ts'
27
27
  import { restartAllowed, scheduleRestart, trustedRestartRequest } from './restart.ts'
@@ -306,16 +306,25 @@ export function mountMarketRoutes(host: MarketHost, config: MarketConfig): () =>
306
306
  if (stale) ok = false
307
307
  }
308
308
  if (ok) invalidateUpdates()
309
- const staleError = stale
310
- ? '这个新版本刚发布不久。为了安全,系统默认会等它发布满一天后再安装——刚发布的版本偶尔会被发现问题然后撤回。可以明天再试,或点「立即更新」不再等待。 / This version was just released; for safety, installs normally wait about a day after a release. Try again tomorrow, or click "Update now" to install it right away.'
311
- : null
309
+ // Diagnose the stale outcome with EVIDENCE (#45 by @ayingQAQ):
310
+ // only blame pnpm's fresh-release wait when the target's latest
311
+ // release really is young; otherwise be honest that the cause is
312
+ // unconfirmed. Git installs never hit the age gate.
313
+ const youngRelease = stale && !isGit ? await latestPublishedRecently(name) : false
314
+ const staleReason = stale ? (youngRelease === true ? 'release-age' : 'unknown') : null
315
+ const staleError = !stale
316
+ ? null
317
+ : staleReason === 'release-age'
318
+ ? '这个新版本刚发布不久。为了安全,系统默认会等它发布满一天后再安装——刚发布的版本偶尔会被发现问题然后撤回。可以明天再试,或点「立即更新」不再等待。 / This version was just released; for safety, installs normally wait about a day after a release. Try again tomorrow, or click "Update now" to install it right away.'
319
+ : '更新命令执行完成,但版本没有变化,原因未能确认。点「立即更新」重试通常能解决;若仍不行,请导出日志反馈。 / The update command completed but the version did not change; the cause could not be confirmed. Clicking "Update now" to retry usually resolves it — if not, export the log and report it.'
312
320
  logEvent(ok || cancelled ? 'info' : 'error', 'update',
313
- `${name} -> ${target} exit=${String(result.exitCode)}${result.timedOut ? ' TIMEOUT' : ''}${cancelled ? ' CANCELLED' : ''}${stale ? ' STALE(minimumReleaseAge?)' : ''}${ok || cancelled ? '' : ` stderr=${result.stderr.slice(-300)}`}`)
321
+ `${name} -> ${target} exit=${String(result.exitCode)}${result.timedOut ? ' TIMEOUT' : ''}${cancelled ? ' CANCELLED' : ''}${stale ? ` STALE(${staleReason ?? 'unknown'})` : ''}${ok || cancelled ? '' : ` stderr=${result.stderr.slice(-300)}`}`)
314
322
  // A user-cancelled run is a quiet outcome, not an error.
315
323
  sendJson(response, ok || cancelled ? 200 : 502, {
316
324
  ok,
317
325
  cancelled: cancelled || undefined,
318
326
  stale: stale || undefined,
327
+ staleReason: staleReason ?? undefined,
319
328
  error: staleError ?? undefined,
320
329
  exitCode: result.exitCode,
321
330
  timedOut: result.timedOut,
package/src/updates.ts CHANGED
@@ -31,6 +31,31 @@ async function fetchJson(url: string): Promise<unknown> {
31
31
  return res.json() as unknown
32
32
  }
33
33
 
34
+ /**
35
+ * Evidence check behind the "wait a day" stale diagnosis (#45): whether the
36
+ * package's CURRENT latest release was published recently enough to sit
37
+ * inside pnpm's default fresh-release window. pnpm's silent hold leaves no
38
+ * trace in its output, so the publish time is the only verifiable signal.
39
+ * @returns true/false when the npm time metadata answers, null when it
40
+ * can't be determined (offline, unpublished, non-npm) — callers must NOT
41
+ * claim the safety wait on null.
42
+ */
43
+ export async function latestPublishedRecently(name: string, windowMs = 26 * 60 * 60 * 1000): Promise<boolean | null> {
44
+ try {
45
+ const doc = (await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(name)}`)) as {
46
+ 'dist-tags'?: Record<string, string>
47
+ time?: Record<string, string>
48
+ }
49
+ const latest = doc['dist-tags']?.latest
50
+ const published = latest !== undefined ? doc.time?.[latest] : undefined
51
+ if (published === undefined) return null
52
+ const age = Date.now() - Date.parse(published)
53
+ return Number.isFinite(age) ? age < windowMs : null
54
+ } catch {
55
+ return null
56
+ }
57
+ }
58
+
34
59
  /** Per-plugin update checks; a failed check reports no update rather than failing the listing. */
35
60
  export async function checkUpdates(profile: string, force = false): Promise<Record<string, UpdateStatus>> {
36
61
  if (!force && updatesCache && Date.now() - updatesCache.at < UPDATES_TTL_MS) return updatesCache.data