dsh-m 0.9.44 → 0.9.46

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/CHANGELOG.md CHANGED
@@ -8,6 +8,23 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
8
8
 
9
9
  ## 中文
10
10
 
11
+ ### 0.9.46 变更:双语 README 精简重构+实拍 WebP 截图集(文档版)
12
+
13
+ - **README×2 重构**:中文 17.5KB → 8.3KB、英文 18.1KB → 9.4KB——以用户任务动线重组(30 秒上手 → 浏览/搜索/安装 → 已装与设置 → Agent 工具与 CLI → 兼容与 FAQ);获取线路、缓存语义等实现细节不再展开,统一移交 [`docs/DESIGN.md`](docs/DESIGN.md) 与 ADR 承接;运行相位/生效时机表述与激活分桶语义对齐(不硬承诺「一定重启/一定刷新」,以操作返回为准)。
14
+ - **截图集(`docs/images/`,8 张 WebP ≈248KB)**:市场首页、社区分类条、精选分类条、跨区搜索(精选置顶+社区分组)、插件详情(未装态安装入口)、已装管理、设置页全部换为当前实机实拍;官方安装对话框图沿用。已装图对宿主本机 profile 绝对路径做脱敏改写。
15
+ - **新增 `scripts/capture-readme.mjs`(开发用,不入 npm 包——`assert-pack` 的 scripts/ 禁带清单继续兜底)**:playwright 只读驱动当前 Web 实例复现整套截图(`npm run capture:readme`);不执行安装/升级/开关/删除,仅浏览态与弹窗;每张截图前断言面板内无未脱敏的 profile 绝对路径。新增 devDependency `playwright-core@1.62.1`(锁官方 registry 解析)。
16
+ - **验证**:typecheck 零错误;全量测试 1165/1165(首轮 1 项进程树终止时序断言在并发负载下偶发,单跑与全量重跑均通过,未改运行时代码);`npm pack --dry-run` + `assert-pack` 白名单通过;双语 README 各 8 处 WebP 引用与文件一一对应、无缺失无冗余。
17
+
18
+ ### 0.9.45 变更:市场页两段加载 + 强制刷新穿透探测 + 精选页动线批
19
+
20
+ - **市场页两段加载([ADR-0013](docs/adr/0013-market-two-phase-probe.md))**:浏览态 market 查询拆两段——第一段 `probeMode:'cache-only'` 只回 TTL 内缓存命中、零网络瞬时回页,有缺口(`latestComplete=false`,豁免社区 github 条目——Q46 永久缺口不构成第二段理由)才自动发起第二段既有探测语义就地补徽标;重启后首开不再被全页重探阻塞(弱网 8–16s → 恒秒开 + 徽标异步补全)。`mergeLatestFields` 纯函数保证会话内切换筛选态时徽标不回退;快照只在终态写入。服务端 latest 缓存保持纯内存不动(ADR-0006 不翻案);tools/CLI 的 `withLatest:false` 通路零变化。
21
+ - **force 探测穿透(重开 ADR-0006 暂缓裁决)**:设置页「强制刷新」新链路 onForceMarket → marketReloadAll(true) → core「peek 旧值兜底 + 全页重探」——严格落实 ADR-0006 在案约束「peek 不删除语义而非 ttlMin=0 先删后探」,重探失败保留旧值 + latestError,不产生空徽标窗口;强刷后精选清单与「有更新」徽标同时刷新。市场页 probeMode 只有 full/cache-only 两态(不设 'only')。
22
+ - **详情 Modal 升级动线(U10)**:已装且可升级条目的 Modal 动作区新增「升级」主按钮(市场区与收藏区两挂载点;record.target=安装包名,走 ops 泵与 0.9.22 生效判定分流文案,guard/opSuperseded/普通失败三分支对齐已装页);新增 README 折叠页(展开才拉取,收起态零请求);「收录日期」走 fmtDate 本地化。**修复(实机验收发现)**:README 折叠页原直接复用已装页本地读取接口,未安装条目(市场浏览的主体)恒报「web profile 未安装该插件」——现本地未装时回源 npm packument 顶层 readme 字段兜底(HTTPS/8MB 上限/超时;无 readme 字段显示「没有 README」;兜底失败如实抛原始错误),已装条目仍走本地读取。
23
+ - **错误恢复与空态(U9)**:错误行内联「重试」按钮(此前只能关开面板或绕道设置页);空态三分支——registry unavailable 主文案 / 分类空桶专用文案 / 通用文案。
24
+ - **收藏身份(U12)**:收藏快照增补 verified/audience/decoupled 三字段(只存不标——§2.7 裁决⑤「收藏页不打标」不动);收藏区为精选条目补「精选」身份徽标与「已实测」质量徽标(此前精选条目进收藏区连「精选」标识都丢失)。
25
+ - **可达性与杂项(U8/U3/U7)**:详情 Modal 补 role=dialog/aria-modal/aria-label 与打开时聚焦关闭钮,截图缩放支持键盘 Enter/Space(Tab 圈闭明确不做);精选区 0 计数桶显式渲染「0」+ 降透明;跨桶条目使分类计数之和大于总数时 chips 行容器给出 title 说明。
26
+ - **测试**:market/host-api/client-market-state/client-render-smoke 净增用例与断言(probeMode 两态与 force peek 语义、缺口豁免、cache-only outdated、mergeLatestFields、两段与强刷接线、Modal 升级/README/可达性、收藏徽标、0 计数桶);全量测试 Windows 本机除既有 symlink 族基线 15 项外零新增失败;typecheck 零错误。
27
+
11
28
  ### 0.9.44 变更:插件卡片网格按容器宽度自适应列数(全屏显出更多卡片)
12
29
 
13
30
  - **自适应网格**:市场/已装/收藏三视图共用的卡片网格从固定两列改为按容器实际可用宽度自适应——`grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr))`。列数 ≈ `max(1, floor((W+8)/368))`(最小卡宽 360px、列距 8px,剩余宽度各列均分):浮动态(~920px 面板)保持 2 列零回归;全屏 1920 宽约 5 列、1280 宽 3 列,显著显出更多插件卡片。
@@ -332,6 +349,23 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
332
349
 
333
350
  ## English
334
351
 
352
+ ### Added in 0.9.46 — bilingual README restructure + live-captured WebP screenshot set (docs release)
353
+
354
+ - **README×2 restructured**: zh-CN 17.5KB → 8.3KB, en 18.1KB → 9.4KB — reorganized around the user's task flow (quick start → browse/search/install → installed & settings → agent tools & CLI → compatibility & FAQ). Fetch-chain and cache-semantics details no longer live here; they are delegated to [`docs/DESIGN.md`](docs/DESIGN.md) and the ADRs. Runtime-phase / takes-effect wording now matches the activation-bucket semantics (no hard promises of "always restart" or "always refresh" — follow the operation result).
355
+ - **Screenshot set (`docs/images/`, 8 WebP ≈248KB)**: marketplace home, community category strip, curated category strip, cross-catalog search (curated hits first, community grouped), plugin detail (not-installed state with install action), installed management, and settings are all re-captured from the current live Web instance; the official install-dialog shot is retained. The installed shot redacts the host's absolute profile path.
356
+ - **New `scripts/capture-readme.mjs` (development-only, not shipped in the npm package — `assert-pack`'s scripts/ deny-list keeps enforcing that)**: drives the running Web instance read-only via playwright to reproduce the full set (`npm run capture:readme`); performs no install/upgrade/toggle/uninstall — browsing and modals only; every shot first asserts no unredacted absolute profile path inside the panel. New devDependency `playwright-core@1.62.1` (pinned to the official registry resolution).
357
+ - **Verification**: typecheck clean; full suite 1165/1165 (one process-tree termination timing assertion flaked once under concurrent load; passed both in isolation and on a full rerun, with no runtime code changes); `npm pack --dry-run` + `assert-pack` allowlist green; each README's 8 WebP references match files one-to-one — nothing missing, nothing unreferenced.
358
+
359
+ ### Added in 0.9.45 — market two-phase loading + force probe passthrough + curated-zone motion batch
360
+
361
+ - **Market two-phase loading ([ADR-0013](docs/adr/0013-market-two-phase-probe.md))**: browsing market queries split into two phases — phase 1 sends `probeMode:'cache-only'` (TTL-fresh cache hits only, zero network, instant page), and only when gaps exist (`latestComplete=false`, community github entries exempt — a Q46 permanent gap is never a phase-2 reason) does phase 2 run the existing probe semantics to patch badges in place. First open after a DSH restart is no longer blocked by a full-page re-probe (8–16s on weak networks → always instant page + async badge completion). `mergeLatestFields` keeps badges from regressing during in-session filter switches; snapshots are written at terminal states only. The server-side latest cache stays memory-only (ADR-0006 untouched); the tools/CLI `withLatest:false` path is unchanged.
362
+ - **Force probe passthrough (reopens ADR-0006's deferred ruling)**: the settings-page "Force refresh" gains the onForceMarket → marketReloadAll(true) → core "peek old values as fallback + full-page re-probe" chain — strictly honoring ADR-0006's on-record constraint ("peek without delete, not ttlMin=0 delete-then-probe"); a failed re-probe keeps old values + latestError with no empty-badge window, and one click now refreshes both the curated list and the update badges. Market probeMode has exactly two values (full/cache-only) — no 'only'.
363
+ - **Detail Modal upgrade motion (U10)**: installed-and-outdated entries get a primary "Upgrade" button in the Modal actions (both the market and favorites mount points; record.target = installed package name, routed through the ops pump with 0.9.22 activation-based messaging; guard/opSuperseded/generic failure branches aligned with the Installed tab); a README fold (fetched on expand, zero requests while collapsed); "Added" date localized via fmtDate. **Fix (found in real-machine acceptance)**: the fold originally reused the Installed tab's local-read endpoint, so every not-installed entry (the majority of market browsing) errored with "web profile 未安装该插件" — not-installed entries now fall back to the npm packument top-level readme field (HTTPS/8MB cap/timeout; a missing readme field renders "no README"; a failed fallback surfaces the original error honestly), while installed entries keep the local read.
364
+ - **Error recovery & empty states (U9)**: inline "Retry" button on the error row (previously only panel reopen or a detour to Settings); three-way empty copy — registry-unavailable primary message / curated-bucket-specific message / generic.
365
+ - **Favorites identity (U12)**: favorite snapshots store verified/audience/decoupled (stored but not labeled — DESIGN §2.7 ruling ⑤ "favorites stay unmarked" untouched); curated entries in Favorites regain a "Curated" identity badge plus the "Verified" quality badge (previously they lost even the Curated marker).
366
+ - **Accessibility & misc (U8/U3/U7)**: Detail Modal gains role=dialog/aria-modal/aria-label and initial focus on the close button; screenshot lightboxes open via keyboard Enter/Space (focus trap explicitly out of scope); zero-count curated buckets render an explicit "0" at reduced opacity; the chips row gets a title explanation whenever cross-bucket double counting pushes Σchip counts above the total.
367
+ - **Tests**: new cases and assertions across market / host-api / client-market-state / client-render-smoke (two-state probeMode and force peek semantics, gap exemption, cache-only outdated, mergeLatestFields, two-phase and force-refresh wiring, Modal upgrade/README/a11y, favorites badges, zero-count chips); on this Windows machine the full suite has zero new failures beyond the 15 pre-existing symlink-family baseline cases; typecheck clean.
368
+
335
369
  ### Added in 0.9.44 — plugin card grid adapts column count to available width (more cards in fullscreen)
336
370
 
337
371
  - **Adaptive grid**: the card grid shared by the Market / Installed / Favorites views switches from a fixed two-column layout to container-width adaptation — `grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr))`. Column count ≈ `max(1, floor((W+8)/368))` (360px min card width, 8px gap, remaining width split evenly): the floating panel (~920px) keeps its 2 columns with zero regression; fullscreen at 1920px shows ~5 columns and 1280px shows 3 — noticeably more plugin cards on screen.
package/README.en.md CHANGED
@@ -1,194 +1,96 @@
1
1
  # dsh-m — Plugin Marketplace for DeepSeek Harness
2
2
 
3
- [![Release](https://img.shields.io/github/v/release/iasiv5/dsh-m?label=Release&sort=semver)](../../releases)
3
+ [![Release](https://img.shields.io/github/v/release/iasiv5/dsh-m?label=Release&sort=semver)](https://github.com/iasiv5/dsh-m/releases)
4
4
  [![npm](https://img.shields.io/npm/v/dsh-m?label=npm)](https://www.npmjs.com/package/dsh-m)
5
- [![Registry Check](https://img.shields.io/github/actions/workflow/status/iasiv5/dsh-m/registry.yml?branch=main&label=Registry%20Check)](../../actions/workflows/registry.yml)
5
+ [![Registry Check](https://img.shields.io/github/actions/workflow/status/iasiv5/dsh-m/registry.yml?branch=main&label=Registry%20Check)](https://github.com/iasiv5/dsh-m/actions/workflows/registry.yml)
6
6
  [![License](https://img.shields.io/github/license/iasiv5/dsh-m?label=License)](./LICENSE)
7
- [![DSH Web](https://img.shields.io/badge/DSH%20Web-0.1.2--rc.1%20%E2%86%92%200.2.0--rc.2-2563eb)](#faq)
7
+ [![DSH Web](https://img.shields.io/badge/DSH%20Web-0.1.2--rc.1%20%E2%86%92%200.2.0--rc.2-2563eb)](#compatibility--faq)
8
8
 
9
9
  English · [中文](./README.md)
10
10
 
11
- dsh-m is a plugin marketplace for DeepSeek Harness (DSH): **browse · install · uninstall · upgrade**, entirely on your machine — no server, no account. The "Plugin Marketplace" panel opens from the sidebar, with agent-tool and CLI surfaces sharing the same core.
11
+ dsh-m brings **plugin discovery, installation, management, and updates** into one DeepSeek Harness (DSH) panel. Search the community directory and hand-curated picks together. The sidebar panel, eight Agent tools, and the `dshm` CLI share marketplace data. No additional marketplace server or account is needed; the local DSH host performs plugin operations.
12
12
 
13
- **Highlights**
13
+ ![Plugin Marketplace: curated zone, categories, and plugin cards](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/marketplace.webp)
14
14
 
15
- - **Dual profile** — the same package installs into Web (`web`) and official Desktop (`desktop`); everything manages the host's current profile;
16
- - **Dual-catalog market** — the 4,000+ entry community catalog (awesome-dsh-plugin) is the default, layered with a hand-curated registry; zoned browsing with click-to-install;
17
- - **Three consistent surfaces** — the GUI panel, eight `dshm_*` agent tools, and the `dshm` CLI share one data model and semantics;
18
- - **Security baseline** — npm exact versions with integrity checks, GitHub installs pinned to commit SHA, official pluginManager delegation, and key-by-key build approvals.
15
+ ## Quick start
19
16
 
20
- <div align="center">
21
- <img src="https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/marketplace.webp" alt="Plugin Marketplace panel — Market view: Community / Curated / Favorites zones, category chips, and plugin cards (verified / installed badges, npm & GitHub detail links)" width="100%">
22
- <p><sub>The "Plugin Marketplace" panel · browse Community, Curated, and Favorites with compatibility and install status</sub></p>
23
- </div>
17
+ In DSH's official **Plugin Manager → Add plugin**, enter `dsh-m`, select an installation source reachable from your network, and install. **Restart DSH Web and refresh the page; on Desktop, quit and reopen the app.** Open “Plugin Marketplace” at the bottom of the sidebar.
24
18
 
25
- ## Table of contents
19
+ ![Installing dsh-m with DSH's official plugin manager](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/official-plugin-install.webp)
26
20
 
27
- - [Requirements](#requirements)
28
- - [Quick start](#quick-start)
29
- - [Panel](#panel)
30
- - [Agent tools (8)](#agent-tools-8)
31
- - [CLI](#cli)
32
- - [Community catalog (awesome-dsh-plugin)](#community-catalog-awesome-dsh-plugin)
33
- - [Curated registry (registry.json)](#curated-registry-registryjson)
34
- - [Documentation](#documentation)
35
- - [FAQ](#faq)
21
+ On a headless Web host, you can also run `dsh plugin --profile web add dsh-m`. Requires Node.js ≥ 22; see the [compatibility table](#compatibility--faq). `npm install -g dsh-m` installs **only the standalone `dshm` CLI**, not the marketplace plugin in a DSH profile.
36
22
 
37
- Version history is not expanded on this page — see [`CHANGELOG.md`](https://github.com/iasiv5/dsh-m/blob/main/CHANGELOG.md) for the complete record.
23
+ > In-place update support in the official plugin manager depends on the host version. If it explicitly says updates are unsupported, follow its guidance to uninstall the old version and install the new one. Uninstall does not silently erase plugin data.
38
24
 
39
- ## Requirements
25
+ ## Browse, search, install
40
26
 
41
- - Node.js ≥ 22 on the host side;
42
- - DSH Web or official Desktop (supported host generations: see the [FAQ matrix](#faq));
43
- - No extra services or accounts — installing and managing plugins happens entirely locally.
27
+ - **Community + Curated**: the community directory is on by default, with 4,000+ listings. Curated picks are organized into Essentials / Cui's Picks / iasi In-house / Tencent Lighthouse / Watchlist. Curated entries win when both catalogs list the same plugin; the community zone doesn't duplicate them.
28
+ - **Zoned browsing, global search**: each zone remembers its own category, sort, and pagination. A Chinese or English query searches both catalogs and shows their separate hit counts. Favorites provide a shortcut within the local profile.
29
+ - **Inspect before installing**: cards show origin, installation status, and version; details show the description, compatibility information, and installation entry point. npm installs pin an **exact version with integrity verification**; GitHub installs pin a **commit SHA**. Peer-incompatible installs require explicit risk acknowledgment.
44
30
 
45
- ## Quick start
31
+ | Community categories | Curated buckets |
32
+ |---|---|
33
+ | ![Community directory and open category filters](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/community-catalog.webp) | ![The five curated marketplace buckets](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/curated-registry.webp) |
46
34
 
47
- 1. In DSH, open the official plugin manager and choose "Add plugin".
48
- 2. Enter `dsh-m`, select an install source that works for your network, then click "Install".
49
- 3. Follow the host lifecycle to activate it: restart DSH Web and refresh the page; on official Desktop, quit and reopen the app.
50
- 4. Once loaded, open "Plugin Marketplace" from the bottom of the sidebar.
35
+ ![Cross-catalog search for skins: curated matches first, community matches grouped below](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/search-results.webp)
51
36
 
52
- <div align="center">
53
- <img src="https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/official-plugin-install.webp" alt="DSH official plugin manager: the Add Plugin dialog with dsh-m entered and an install source selected" width="86%">
54
- <p><sub>Recommended · add and install dsh-m from DSH's official plugin manager</sub></p>
55
- </div>
37
+ ![Plugin details: category, version, origin, install command, and install action](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/plugin-detail.webp)
56
38
 
57
- > **Upgrade note:** The official plugin manager currently says in-place updates are not supported. To upgrade through it, uninstall `dsh-m` first, then install the newer version; follow the latest UI guidance if this changes.
39
+ > **Community listing is not a security review.** With 4,000+ entries from varied sources, inspect the author, code, and requested capabilities before installing. Missing capability data means “not scanned,” **not** “no risks found.”
58
40
 
59
- ## Panel
41
+ ## Installed plugins & settings
60
42
 
61
- | View | Capabilities |
62
- |---|---|
63
- | **Market** | Community (4,000+ entries) / Curated / Favorites zones; browsing state (category, sort, pagination) is kept per zone, while search is global across zones (community + curated hits together); cards open a detail modal with install progress and results shown in place. |
64
- | **Operations** | Installs, upgrades, uninstalls, and toggles flow through one global operation log — state lives off cards and resumes automatically after host reloads. |
65
- | **Installed** | What the current profile actually has: source annotation, live phase badge, one-click toggle, upgrade, and two-step confirmed uninstall. |
66
- | **Settings** | Curated registry configuration and status, community catalog toggle, dsh-m self-update. |
43
+ **Installed** reflects the current host profile's actual packages: marketplace/non-marketplace origin, runtime phase, available updates, toggles, upgrades, and confirmed uninstall. Operation progress and results are tracked together. A toggle may apply live or require a restart; follow the returned result. Uninstall removes the package reference without silently deleting user data and reports possible leftover paths separately.
67
44
 
68
- <div align="center">
69
- <img src="https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/settings.webp" alt="Settings view — community catalog status card (catalog version / route / entries), curated registry configuration card (address draft with force-refresh / validate & apply / restore default / download), and the About card" width="86%">
70
- <p><sub>Settings view · community catalog status, curated registry configuration, and dsh-m self-update</sub></p>
71
- </div>
45
+ ![Installed plugins: version, origin, runtime state, toggles; local profile path redacted](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/installed.webp)
72
46
 
73
- How changes take effect (Web only):
47
+ **Settings** shows the community catalog's version, fetch route, and cache state, and lets you disable or pin its version. You can download the default curated registry, provide a custom address, and **validate before replacing the Curated zone as a whole** (the Community zone is unaffected). Failed validation preserves the active configuration; successful apply and restore-default are live, without a restart.
74
48
 
75
- - After install / uninstall / upgrade, the Market and Installed views sync automatically — no need to close and reopen the panel;
76
- - A "⚡ Restart" banner follows: under systemd, the DSH launcher's `appExit` hands the restart to the unit's `Restart` policy; hosts without `appExit` fall back by design;
77
- - The client confirms the new process by boot id, dismisses the banner, and lets DSH Web's background reconnection restore the page — no forced full reload;
78
- - Installs stream live pnpm progress (resolve → download → link → build).
49
+ ![Settings: community-catalog status and curated-registry configuration](https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/settings.webp)
79
50
 
80
- On Desktop, changes take effect via the official app lifecycle: quit and reopen the app after installing. Restart-chain mechanics and per-generation verification records live in [`docs/DESIGN.md`](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md).
51
+ A custom registry may come from HTTPS, a local absolute path, or `file://` (HTTP is for loopback debugging only); limits are 2 MiB and 1,000 entries. A custom source is an independent snapshot and **does not sync automatically** with the default curated registry. If it fails, its own last good cache remains in use; dsh-m never silently switches back to the default. See the [registry copy guide](https://github.com/iasiv5/dsh-m/blob/main/docs/registry-copy-guide.md) and [design document](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md) for the full rules.
81
52
 
82
- ## Agent tools (8)
53
+ ## Agent tools & CLI
83
54
 
84
- | Tool | Purpose |
55
+ | Agent tools | Purpose |
85
56
  |---|---|
86
- | `dshm_search` | Search curated & community listings (renders cards in chat) |
87
- | `dshm_list` | List installed plugins (market / non-market annotated) |
88
- | `dshm_install` | Install by listing id (peer compatibility precheck before install; incompatible results return structured data for user confirmation, then `force` retries) |
89
- | `dshm_uninstall` | Uninstall (confirm first; data kept, leftovers reported) |
90
- | `dshm_outdated` | Check for newer versions |
91
- | `dshm_upgrade` | Upgrade to the latest |
92
- | `dshm_toggle` | Toggle a plugin on/off (confirm by default, execute directly when the user already asked in the same message) |
93
- | `dshm_restart` | Restart DSH Web (with user consent) |
94
-
95
- ## CLI
57
+ | `dshm_search` | Search community and curated catalogs; render cards in the conversation |
58
+ | `dshm_list` · `dshm_outdated` | List installed and outdated plugins in the current profile |
59
+ | `dshm_install` · `dshm_upgrade` · `dshm_uninstall` | Install, upgrade, and uninstall after confirmation; surface compatibility risks first |
60
+ | `dshm_toggle` · `dshm_restart` | Toggle runtime state; restart Web with the user's consent |
96
61
 
97
62
  ```sh
98
- dshm search [--query topic] [--category ui] [--source community|primary|all] [--limit N] [--offset N]
99
- dshm list | outdated | registry
100
- dshm install --id dsh-web-search [--force] # --force: skip the precheck gate after confirming the risk
101
- dshm upgrade --pkg dsh-web-search --yes [--force]
63
+ dshm search --query theme --source all
64
+ dshm list
65
+ dshm outdated
66
+ dshm install --id dsh-web-search
67
+ dshm upgrade --pkg dsh-web-search --yes
102
68
  dshm uninstall --pkg dsh-web-search --yes
103
- dshm toggle --pkg dsh-web-search --on|--off --yes # file-level edit; applies on restart
69
+ dshm toggle --pkg dsh-web-search --off --yes
104
70
  dshm restart --yes
105
71
  ```
106
72
 
107
- When the registry is unavailable, `registry` / `search` / `outdated` print the configured vs active address and exit 1; `list` still shows installed plugins. The CLI uses its own cache namespace and never touches the Web side's.
108
-
109
- **Profile target**: the CLI always acts on the web profile — `--profile web` makes it explicit; `--profile desktop` is rejected outright (Desktop plugin management belongs to the official Desktop app). On headless hosts you can still install the plugin via the official `dsh` CLI: `dsh plugin --profile web add dsh-m`.
110
-
111
- > `npm install -g dsh-m` installs only the `dshm` CLI (terminal management) — it does **not** register the plugin into the web profile; it can coexist with the official-manager install.
112
-
113
- ## Community catalog (awesome-dsh-plugin)
114
-
115
- **The community catalog is dsh-m's default catalog**: anchored to the npm package [`dsh-plugin-catalog`](https://www.npmjs.com/package/dsh-plugin-catalog) (CC0-1.0, the full awesome-dsh-plugin directory, 4,000+ entries). On top of it sits the hand-curated **curated registry** (registry.json); the data layer merges and dedupes (the curated registry **always takes precedence**, duplicate community entries displaced), and the display layer splits into Community / Curated zones (ADR-0004) — the community zone no longer shows entries duplicated by the curated registry, and the curated zone stays a single curated-order page.
116
-
117
- <div align="center">
118
- <img src="https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/community-catalog.webp" alt="Market view, Community zone — Community / Curated / Favorites tabs, the search row, and counted open category chips" width="86%">
119
- <p><sub>Community catalog · the default landing zone: zone tabs, persistent search, and counted open category chips</sub></p>
120
- </div>
121
-
122
- - **Fetch chain**: dist-tags probe → jsDelivr pinned fetch → npmmirror → unpkg fallback; unchanged versions are not re-fetched, probes are skipped within TTL. Latest-version probes use a memory-only cache: it is dropped on every DSH restart (publish a new version, restart, and the new version shows up), and a plugin's cached entry is invalidated immediately after a successful install/upgrade/uninstall via dsh-m. On failure it falls back to the runtime cache under `<cache dir>/awesome/` and **explicitly labels it "cached snapshot"** — stale data never masquerades as fresh.
123
- - **Switch & pin**: `communityCatalog` toggle in Settings (default on, live), `communityCatalogPin` to lock the catalog version (exact semver); CLI opt-out with `DSHM_COMMUNITY_CATALOG=0`, pin with `DSHM_COMMUNITY_CATALOG_PIN`.
124
- - **Categories & search**: community categories are an open set (23 known categories with bilingual labels — Chinese maintained in-repo as the single source of truth, English from the upstream catalog, served per UI language); search runs a relevance-weighted pipeline (Chinese + English) and is **global across zones** — either zone's search box hits community and curated listings together (browsing stays zoned; a summary line reports exact per-zone hit counts with curated hits grouped on top); the community zone offers a sort switch (downloads/stars/added × asc/desc, default downloads-desc; missing downloads ≠ zero downloads).
125
- - **Install semantics**: community entries go through the same install path as curated entries (npm exact version / GitHub pinned commit SHA); the browse page probes npm entries only — GitHub entries are not probed at page level (anonymous 60 req/h quota is uncontrollable).
126
- - **Installed-page budget (best-effort)**: update checks for GitHub-sourced plugins are capped at ≤25 wire requests per run and ≤50 per rolling hour per host process (passive checks only; active install/upgrade unaffected); capped items are honestly labeled "check incomplete" instead of "all up to date". A standalone CLI process does not share the host budget and makes no guarantee under concurrency.
127
- - **Capability disclosure**: capabilities/red lines appear only in the detail fold (**absent = not scanned ≠ not detected**), never as card badges; screenshots load only in the detail layer and pass a client-side allowlist.
128
- - **Not a security review**: the community catalog is all-inclusive and **not security-reviewed** — verify plugin origin and capabilities before installing; the curated registry's curation and CI checks do not apply to community entries.
129
-
130
- ## Curated registry (registry.json)
131
-
132
- The curated registry is hand-curated, layered on top of the community catalog (duplicates always defer to it), and organized into **five curated buckets**: Essentials / Cui's Picks / iasi In-house / Tencent Lighthouse / Watchlist. It currently includes DSH Skins, DSH TUI, ModSearch, Better Sidebar, DSH Context, and more.
73
+ The GUI and Agent tools manage the **current host profile** (Web or Desktop). The standalone CLI, by contrast, **always targets the web profile** and rejects `--profile desktop`. `--force` may be used with install/upgrade after the user accepts a peer-compatibility risk. If the catalog is unavailable, `registry`, `search`, and `outdated` fail explicitly while `list` still lists installed packages. See the [design document](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md) for full parameters and runtime policy.
133
74
 
134
- <div align="center">
135
- <img src="https://raw.githubusercontent.com/iasiv5/dsh-m/main/docs/images/curated-registry.webp" alt="Market view, Curated zone — Community / Curated / Favorites tabs and the five curated-bucket chips (Essentials / Cui's Picks / iasi In-house / Tencent Lighthouse / Watchlist)" width="86%">
136
- <p><sub>Curated registry · the five curated buckets: Essentials / Cui's Picks / iasi In-house / Tencent Lighthouse / Watchlist</sub></p>
137
- </div>
75
+ ## Compatibility & FAQ
138
76
 
139
- The registry is fetched at runtime over two lines — **GitHub raw (`@main`) → GitHub mirror (jsDelivr CDN, backup)** — ordered adaptively by the last successful route, falling back to the local 60-min TTL cache and the bundled snapshot. Listing updates stay decoupled from plugin releases: after a push, allow up to one cache period (or force a refresh in Settings). To add or amend a listing, edit `registry.json` and open a PR; CI validates the strict schema, npm/GitHub existence, duplicate ids and URL reachability.
140
-
141
- **Custom curated registry (replaces the default)**: the Settings tab supports a single custom registry address that **replaces** the default curated registry (no merging) and **only affects the Curated zone** — the community catalog is untouched:
142
-
143
- 1. "Download default registry" gives you a copy of the official listing;
144
- 2. edit the copy yourself (add/remove entries);
145
- 3. paste its address in Settings and hit "Validate & apply" — an **HTTPS URL**, a local **absolute path / `file://`** (HTTP only for 127.0.0.1/localhost debugging);
146
- 4. validation failures (bad fields, missing path, over 2 MiB / 1,000 entries, …) are never saved — the currently active registry stays; a successful apply takes effect **immediately, no restart** (only the first deploy of a new dsh-m version needs one restart);
147
- 5. "Restore default" switches back to the official registry in one click.
148
-
149
- Rules and limits: strict v1 schema (unknown fields / invalid ids / oversized values / duplicates reject the whole file, never truncated); the copy is a standalone snapshot and does **not** auto-sync with the official listing; a failing custom source keeps its own last good cache and never silently falls back to the official registry; old custom-source caches are cleaned after switching (the default cache is kept); custom registries are not validated by official CI — install only from sources you trust; full local paths appear only on the Settings tab, tools and cards show short statuses.
150
-
151
- Security baseline: HTTPS-only fetches (loopback HTTP excepted) with per-hop redirect checks, size caps and timeouts; npm installs verify the exact version's dist integrity against the pnpm lockfile — mismatches fail closed and roll back; GitHub installs pinned to commit SHA; pnpm build scripts are allowed-by-policy with an explicit report when unblocked.
152
-
153
- ## Documentation
154
-
155
- | Doc | Read it when |
156
- |---|---|
157
- | [CHANGELOG.md](https://github.com/iasiv5/dsh-m/blob/main/CHANGELOG.md) | You want the details of any release (bilingual, complete back to 0.4.x) |
158
- | [docs/DESIGN.md](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md) | Design consensus, panel behavior details, dual-generation compatibility, and the restart chain; development & release workflow in its §6 |
159
- | [docs/adr/](https://github.com/iasiv5/dsh-m/tree/main/docs/adr) | Architecture decisions: delegation & fallback, precise build approval, community catalog merge, zoned market, dual profile |
160
- | [docs/registry-copy-guide.md](https://github.com/iasiv5/dsh-m/blob/main/docs/registry-copy-guide.md) | Writing descriptions and tags for curated registry entries |
161
- | [docs/plans/](https://github.com/iasiv5/dsh-m/tree/main/docs/plans) | Implementation plan archive, one per release |
162
-
163
- ## FAQ
164
-
165
- **1. Why don't GitHub-sourced update hints follow main?**
166
- Intermediate commits on main can be unstable. dsh-m tracks **releases / tags** only (`releases/latest` first, tags list as fallback) and pins the commit SHA the tag points to.
167
-
168
- **1.5 What works on the official Desktop?**
169
- Desktop (the `desktop` profile) supports browsing the market, **installing new packages**, and plugin toggles. Since 0.9.8, upgrades, uninstalls, and dsh-m self-updates are also delegated to the official `pluginManager`; an unavailable service returns a structured refusal with guidance. One-click restart remains part of the official Desktop app lifecycle, so quit and reopen the app. Installed badges and the installed list reflect only the Desktop profile; favorites and operation logs do not sync with Web.
170
-
171
- **2. Does uninstalling dsh-m delete my data?**
172
- No. Only the package reference in the profile is removed (live UI disabled first), and suspected leftover paths are reported to you.
77
+ | DSH Web generation | Settings path | Verification |
78
+ |---|---|---|
79
+ | `0.1.2-rc.1` | cordis config-file fallback | Contract checked |
80
+ | `0.1.5-rc.1 / rc.2` | `register()` scope | Checked; rc.1 also page-tested |
81
+ | `0.1.7-rc.1 / rc.2` | `.volatile()` + `settings.update` | Checked |
82
+ | `0.2.0-rc.1 / rc.2` | Same as 0.1.7 | rc.2 and restart path live-tested |
173
83
 
174
- **3. Will a custom registry slow the market down?**
175
- The market list is server-paginated (32/64/96 per page); even a 1,000-entry registry queries latest versions for the current page only, so browsing stays fast.
84
+ **Is Desktop identical to Web?** No. Desktop browsing, new-package installation, and toggles act on the desktop profile. Upgrades and uninstalls require capabilities from the official host `pluginManager`; if absent, dsh-m returns a structured refusal and guidance. Desktop uses the official app lifecycle rather than Web's one-click restart; quit and reopen as instructed. Favorites, operations, and installed states are separate between profiles.
176
85
 
177
- **4. What if my custom source goes down?**
178
- dsh-m serves its last successful cache for that source (the Settings tab's effective-source row labels it honestly); with no cache at all the market reports the listing unavailable while installed plugins stay manageable. Fix the address or restore the default anytime.
86
+ **When do installs or updates take effect?** On Web, follow the activation result: a client-only update needs a refresh; operations marked restart-required need consent before the host restarts, followed by background reconnection. systemd deployments need `Restart=on-failure` or `Restart=always`; otherwise use your deployment's restart method.
179
87
 
180
- **5. Which DSH Web versions are supported?**
88
+ **Why don't GitHub updates follow `main`?** Intermediate commits may be unstable. dsh-m tracks releases/tags and pins their commit SHAs. Because anonymous GitHub API quota is limited, an incomplete passive check is labeled as such rather than “all up to date.”
181
89
 
182
- | DSH version | Settings path | Verification |
183
- |---|---|---|
184
- | `0.1.2-rc.1` | shape-detection fallback to the cordis config-file path | contract-checked |
185
- | `0.1.5-rc.1` / `rc.2` | `register()` scope path | checked; rc.1 additionally live-verified `/dshm` ping and authenticated `303 → 200` |
186
- | `0.1.7-rc.1` / `rc.2` | Config `.volatile()` fields + `settings.update` + the `loader/volatile-update` event | checked; the two rcs ship byte-identical dsh-settings, so one implementation covers both |
187
- | `0.2.0-rc.1` / `rc.2` | same as `0.1.7` | `rc.2` is the current live runtime; the restart chain was live-verified on 2026-10-01 |
90
+ **What if my custom registry goes down?** Its last successful cache is used first. Without any cache, the registry is reported unavailable while installed plugins remain manageable. Fix the address or restore the default in Settings.
188
91
 
189
- - The path is chosen by runtime **shape detection**, not version branching; unrecognized shapes degrade to the cordis config-file path with marketplace features unaffected. Implementation details: [`docs/DESIGN.md`](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md) §12.
190
- - Systemd deployments must configure `Restart=on-failure` or `Restart=always`; otherwise use the deployment's manual restart procedure.
92
+ Full history: [CHANGELOG](https://github.com/iasiv5/dsh-m/blob/main/CHANGELOG.md). Architecture and development details: [DESIGN](https://github.com/iasiv5/dsh-m/blob/main/docs/DESIGN.md), [ADRs](https://github.com/iasiv5/dsh-m/tree/main/docs/adr). Screenshots were taken from a Web instance; panel version, catalog counts, and installation states vary over time and by profile. To reproduce from the source checkout, run `npm install && npm run capture:readme` with dsh-m installed on the Web host. The development-only capture script is not distributed in the npm plugin package.
191
93
 
192
94
  ## License
193
95
 
194
- MIT
96
+ [MIT](./LICENSE)