dsh-m 0.9.75 → 0.9.76

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,13 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
8
8
 
9
9
  ## 中文
10
10
 
11
+ ### 0.9.76 修复:三项展示层退役与吸顶跳动根治——「对话」徽章/「版本无关」徽章退役 + 分类行滚动锚定自激断路
12
+
13
+ - **① 「对话」来源徽章退役(主人实拍:界面全点按钮却全员误标「对话」)**:`meta.session` 是 0.7.0 终审·新伤1 的**泵所有权标记**(restore 跳过 / replaceAll 不回卷 / persist 时剥离),GUI 的 `runOp` 与对话区镜像两路无条件同打同一标——它区分不了来源,且重载后徽章整体蒸发。修复:opRowVm 删 session 派生、行渲染删徽章、CSS 与 i18n 键退役;`meta.session` 本职不动(数据模型零变更),来源区分留待未来 `meta.origin` 承载。
14
+ - **② 「版本无关」徽章退役(市场卡 + Modal 头)**:英文标签 Version-independent 19 字符把卡片最高价值资产——插件名——挤成 `D...`/`O...`;且同一事实在卡片描述文案(「版本无关,详见仓库。」)与 Modal Compat 行已双处存在,卡片徽章边际信息为零。设计原则落定:**卡片徽章行只放「别处拿不到且影响当下决策」的信息**(已实测/安装态/供给源),版本无关属详规层,由 Modal Compat 行(`modal.decoupled.*`)唯一承载;`snapshotOf` 数据字段保留(收藏/快照完整性);`badge.decoupled` 与 `badge.decoupled.tip` 两键退役。
15
+ - **③ 市场 tab 分类行吸顶高频跳动根治(主人实拍:三 tab 来回切换偶发疯狂上下蹦跳)**:Chrome 滚动锚定把「吸顶 stuck 翻转的高度变化」翻译成 scrollTop 补偿,哨兵(sticky wrap 内 top:-5px)被来回送进/送出视口 → IO stuck 每帧翻转 → sticky bar 在钉住/流内两形态间高频瞬移。触发面:tab 条件渲染重挂(stuck=false + IO 重新武装)× `.dshm-body` 保留的 scrollTop 落在哨兵边界 ±30px 敏感带(翻页 `scrollIntoView` 会把 scrollTop 送到 bar 边缘,命中概率大增)。修复:`.dshm-body` `overflow-anchor:none` 一行断驱动器;吸顶/哨兵/+N 裁剪几何零变更。非本批回归——吸顶/IO 为 0.9.52-0.9.59 机制,长期潜伏的边界 bug。
16
+ - **验证**:1379 项测试全绿(render-smoke 新增退役负向锚与锚定停用/吸顶几何契约锚)、typecheck 零错误;三项均为展示层修复,数据模型零迁移;client-only——刷新页面即生效。
17
+
11
18
  ### 0.9.75 功能:操作记录信息增强——行内时刻/按日分组/开关方向/耗时/版本变迁/来源标记(数据零迁移)
12
19
 
13
20
  - **背景(主人设置页实拍:开关记录读不出「开还是关」)**:操作记录行只有「状态 + 类型 + 包名」三要素——开关看不出方向(截图里连续两条 `开关 @iasiv5/dsh-quota-watch` 无法分辨先后开/关)、无任何时间、看不出耗时、看不出对话区发起还是界面点击、升级不知道版本从哪到哪。而这些信息**全部已在每条记录里**(`createdAt`/`updatedAt` 是 store 打点常态、`meta.on` 0.4.0 起就随开关入账、`meta.session` 是泵拾取标记)——纯展示层缺口,非数据缺失;浏览器 localStorage(`dshm-operations`)里的存量旧记录升级后立即可读,零迁移。
@@ -552,6 +559,13 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
552
559
 
553
560
  ## English
554
561
 
562
+ ### Fix in 0.9.76 — three presentation-layer retirements and sticky-chips jitter fixed at the root: "Chat" badge / "Version-independent" badge retired + scroll-anchoring self-excitation cut on the category row
563
+
564
+ - **① "Chat" source badge retired (owner screenshot: every row flagged despite all-UI clicks)**: `meta.session` is the **pump-ownership marker** from the 0.7.0 final review (restore skip / replaceAll no-rollback / stripped on persist) — both the GUI `runOp` path and the chat-mirror path set it unconditionally, so it cannot distinguish origins, and the badge vanishes entirely after a page reload. Fix: opRowVm drops the session derivation; the row badge, its CSS and i18n keys retire; `meta.session` keeps its day job (zero data-model change); a future `meta.origin` would be the honest carrier for source attribution.
565
+ - **② "Version-independent" badge retired (market card + modal head)**: the 19-character English label squeezed the card's highest-value asset — the plugin name — into `D...`/`O...`, while the same fact already lived twice next to it (the card description text and the modal Compat row), leaving the card badge zero marginal information. Design rule settled: **card badge rows carry only information unavailable elsewhere and relevant to the decision at hand** (verified / installed / source); decoupled belongs to the detail layer, solely carried by the modal Compat row (`modal.decoupled.*`); `snapshotOf` keeps the data field (favorites/snapshot integrity); `badge.decoupled` and `badge.decoupled.tip` retire.
566
+ - **③ Market-tab category-row high-frequency jitter fixed at the root (owner screenshot: wild bouncing after switching tabs back)**: Chrome scroll anchoring translated every stuck-toggle height change into a scrollTop compensation, shoving the sentinel (top:-5px inside the sticky wrap) in and out of the viewport → IO flipped stuck every frame → the sticky bar teleported between pinned and in-flow shapes. Trigger surface: conditional tab remount (stuck=false + re-armed IO) × `.dshm-body`'s preserved scrollTop landing in the ±30px sentinel boundary band (pagination `scrollIntoView` parks scrollTop right at the bar edge, raising the odds). Fix: one line — `.dshm-body` `overflow-anchor:none` — cuts the loop at its driver; sticky/sentinel/+N clip geometry untouched. Not a regression from this batch — the sticky/IO machinery dates to 0.9.52–0.9.59; a long-latent boundary bug.
567
+ - **Verification**: 1379 tests all green (render-smoke gains retirement negative anchors plus anchoring-off / sticky-geometry contract anchors), typecheck clean; all three are presentation-layer fixes with zero data-model migration; client-only — a page refresh takes effect.
568
+
555
569
  ### Feature in 0.9.75 — operations log enrichment: inline clock/day groups/toggle direction/duration/upgrade versions/chat source (zero data migration)
556
570
 
557
571
  - **Background (owner screenshot: toggle records unreadable as on/off)**: each operations row carried only "status + kind + package" — a toggle showed no direction (two consecutive `toggle @iasiv5/dsh-quota-watch` rows in the screenshot were indistinguishable), no timestamp, no duration, no chat-vs-UI source, no upgrade from→to versions. Yet **all of this already exists per record** (`createdAt`/`updatedAt` are store bookkeeping, `meta.on` has been recorded with every toggle since 0.4.0, `meta.session` is the pump pickup marker) — a pure presentation gap, not missing data. Existing records in browser localStorage (`dshm-operations`) become readable right after upgrade, zero migration.
package/lib/client.js CHANGED
@@ -1665,7 +1665,6 @@ function opRowVm(r) {
1665
1665
  full: ts === null ? "" : fmtOpFull(ts),
1666
1666
  durText: durMs === null ? "" : fmtOpDuration(durMs),
1667
1667
  dir: isToggle && typeof meta.on === "boolean" ? meta.on ? "on" : "off" : null,
1668
- session: meta.session === true,
1669
1668
  version,
1670
1669
  target: typeof rec.target === "string" ? rec.target : ""
1671
1670
  };
@@ -1905,8 +1904,6 @@ var ZH = {
1905
1904
  "sub.snapshot": "v{v}\uFF08\u76EE\u5F55\u5FEB\u7167\uFF09",
1906
1905
  "badge.verified": "\u5DF2\u5B9E\u6D4B",
1907
1906
  "badge.internal": "\u4F5C\u8005\u81EA\u7528",
1908
- "badge.decoupled": "\u7248\u672C\u65E0\u5173",
1909
- "badge.decoupled.tip": "DSH \u5347\u7EA7\u65E0\u9700\u8DDF\u968F\u9002\u914D",
1910
1907
  "modal.category": "\u5206\u7C7B",
1911
1908
  "modal.added": "\u6536\u5F55\u65E5\u671F",
1912
1909
  "modal.dlwindow": "\u4E0B\u8F7D\u91CF\uFF0830 \u5929\u7A97\u53E3\uFF09",
@@ -1945,8 +1942,6 @@ var ZH = {
1945
1942
  "op.status.superseded": "\u5DF2\u8DF3\u8FC7",
1946
1943
  "op.day.today": "\u4ECA\u5929",
1947
1944
  "op.day.yesterday": "\u6628\u5929",
1948
- "op.session": "\u5BF9\u8BDD",
1949
- "op.session.tip": "\u5BF9\u8BDD\u533A\u53D1\u8D77\uFF08\u975E\u754C\u9762\u70B9\u51FB\uFF09",
1950
1945
  "settings.ops.group.done.n": "\u5DF2\u7ED3\u675F\uFF08{n}\uFF09",
1951
1946
  "favorites.hint": "\u8FD8\u6CA1\u6709\u6536\u85CF\u2014\u2014\u53BB\u793E\u533A/\u7CBE\u9009\u9875\u70B9\u63D2\u4EF6\u5361\u7247\u53F3\u4E0A\u89D2\u7684 \u2606 \u6536\u85CF",
1952
1947
  "favorites.stale": "{n} \u6761\u6536\u85CF\u5DF2\u4ECE\u76EE\u5F55\u4E0B\u67B6",
@@ -2200,8 +2195,6 @@ var EN = {
2200
2195
  "sub.snapshot": "v{v} (catalog snapshot)",
2201
2196
  "badge.verified": "Verified",
2202
2197
  "badge.internal": "Author's own",
2203
- "badge.decoupled": "Version-independent",
2204
- "badge.decoupled.tip": "Survives DSH upgrades without per-release adaptation",
2205
2198
  "modal.category": "Category",
2206
2199
  "modal.added": "Added",
2207
2200
  "modal.dlwindow": "Downloads (30-day window)",
@@ -2240,8 +2233,6 @@ var EN = {
2240
2233
  "op.status.superseded": "Skipped",
2241
2234
  "op.day.today": "Today",
2242
2235
  "op.day.yesterday": "Yesterday",
2243
- "op.session": "Chat",
2244
- "op.session.tip": "Initiated from chat (not a UI click)",
2245
2236
  "settings.ops.group.done.n": "Ended ({n})",
2246
2237
  "favorites.hint": "No favorites yet \u2014 tap \u2606 on a plugin card in Community/Curated to bookmark it",
2247
2238
  "favorites.stale": "{n} favorites no longer in the catalog",
@@ -2546,7 +2537,14 @@ var CSS = `
2546
2537
  .dshm-seg .dshm-count{font-size:11px;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-caption,#9ca3af);margin:0}
2547
2538
  .dshm-seg button.on .dshm-count{color:var(--dsw-alias-state-business-primary,#4d6bfe)}
2548
2539
  .dshm-spacer{flex:1}
2549
- .dshm-body{flex:1;overflow:auto;padding:14px;display:flex;flex-direction:column;gap:12px}
2540
+ /* 0.9.76 \u5206\u7C7B\u884C\u5438\u9876\u9AD8\u9891\u8DF3\u52A8\u6839\u6CBB\uFF1AChrome \u6EDA\u52A8\u951A\u5B9A\uFF08scroll anchoring\uFF09\u628A\u300C\u5438\u9876\u6536\u5C55\u7684
2541
+ \u9AD8\u5EA6\u53D8\u5316\u300D\u7FFB\u8BD1\u6210 scrollTop \u8865\u507F\uFF08\u2248\u4E00\u4E2A\u884C\u9AD8\uFF09\uFF0C\u54E8\u5175\uFF08wrap \u5185 top:-5px\uFF09\u56E0\u6B64\u88AB\u6765\u56DE\u9001\u8FDB/
2542
+ \u9001\u51FA\u89C6\u53E3 \u2192 IO stuck \u6BCF\u5E27\u7FFB\u8F6C \u2192 chips \u884C\u9AD8\u9891\u8E66\u8DF3\u3002\u89E6\u53D1\u6761\u4EF6\uFF1Atab \u6761\u4EF6\u6E32\u67D3\u91CD\u6302\u56DE\u5230\u5E02\u573A
2543
+ \uFF08stuck=false + IO \u91CD\u65B0\u6B66\u88C5\uFF09\u4E14 .dshm-body \u4FDD\u7559\u7684 scrollTop \u6070\u843D\u5728\u54E8\u5175\u8FB9\u754C \xB130px \u5E26\u5185
2544
+ \uFF08\u7FFB\u9875 scrollIntoView \u4F1A\u628A scrollTop \u7CBE\u786E\u9001\u5230 bar \u8FB9\u7F18\uFF0C\u547D\u4E2D\u6982\u7387\u5927\u589E\uFF09\u3002\u951A\u5B9A\u5728\u672C\u6EDA\u52A8
2545
+ \u5BB9\u5668\u505C\u7528\u540E\uFF0Cstuck \u7FFB\u8F6C\u4E0D\u518D\u79FB\u52A8\u54E8\u5175\uFF0C\u5FAA\u73AF\u5728\u9A71\u52A8\u5668\u5904\u65AD\u5F00\uFF1B\u9762\u677F\u5185\u5BB9\u53EA\u5411\u4E0B\u5206\u9875\u8FFD\u52A0\u3001
2546
+ \u65E0\u4E0A\u65B9\u61D2\u52A0\u8F7D\u5E03\u5C40\uFF0C\u951A\u5B9A\u635F\u5931\u8D8B\u96F6\u3002 */
2547
+ .dshm-body{flex:1;overflow:auto;padding:14px;display:flex;flex-direction:column;gap:12px;overflow-anchor:none}
2550
2548
  .dshm-hint{color:var(--dsw-alias-label-caption,#6b7280);font-size:12px;line-height:18px;margin:0}
2551
2549
  .dshm-err{color:var(--dsw-alias-state-error-primary,#b91c1c);font-size:12px;line-height:18px}
2552
2550
  .dshm-ok{color:var(--dsw-alias-state-success-primary,#047857);font-size:12px;line-height:18px;word-break:break-word}
@@ -2705,15 +2703,16 @@ var CSS = `
2705
2703
  .dsvm-opkind{color:var(--dsw-alias-label-secondary,#4b5563)}
2706
2704
  .dsvm-optarget{font-weight:500;overflow-wrap:anywhere}
2707
2705
  .dsvm-opnote{color:var(--dsw-alias-label-caption,#6b7280);font-size:11px;overflow-wrap:anywhere}
2708
- /* 0.9.75 \u64CD\u4F5C\u8BB0\u5F55\u4FE1\u606F\u589E\u5F3A\uFF1A\u884C\u5185\u65F6\u95F4/\u8017\u65F6\uFF08tabular-nums \u5BF9\u9F50\uFF09\u3001\u6309\u65E5\u5206\u7EC4\u5934\u3001\u5F00\u5173\u65B9\u5411\u4E0E
2709
- \u5BF9\u8BDD\u6765\u6E90\u5FBD\u7AE0\u3001\u5347\u7EA7\u7248\u672C\u53D8\u8FC1\u3002\u5B57\u53F7\u5B88 0.9.67 \u7684 12px \u5BB6\u65CF\uFF08\u6B21\u7EA7 11px\uFF09\uFF0C\u989C\u8272\u6CBF\u7528\u65E2\u6709\u8BED\u4E49\uFF1A
2710
- \u65B9\u5411\u300C\u5F00\u300D\u7528 ok \u540C\u6B3E\u7EFF\uFF0C\u300C\u5173\u300D\u7528\u6B21\u7EA7\u7070\uFF1B\u5FBD\u7AE0 currentColor \u63CF\u8FB9\u81EA\u9002\u5E94\u6DF1\u6D45\u4E3B\u9898\u3002 */
2706
+ /* 0.9.75 \u64CD\u4F5C\u8BB0\u5F55\u4FE1\u606F\u589E\u5F3A\uFF1A\u884C\u5185\u65F6\u95F4/\u8017\u65F6\uFF08tabular-nums \u5BF9\u9F50\uFF09\u3001\u6309\u65E5\u5206\u7EC4\u5934\u3001\u5F00\u5173\u65B9\u5411\u5FBD\u7AE0\u3001
2707
+ \u5347\u7EA7\u7248\u672C\u53D8\u8FC1\u3002\u5B57\u53F7\u5B88 0.9.67 \u7684 12px \u5BB6\u65CF\uFF08\u6B21\u7EA7 11px\uFF09\uFF0C\u989C\u8272\u6CBF\u7528\u65E2\u6709\u8BED\u4E49\uFF1A
2708
+ \u65B9\u5411\u300C\u5F00\u300D\u7528 ok \u540C\u6B3E\u7EFF\uFF0C\u300C\u5173\u300D\u7528\u6B21\u7EA7\u7070\uFF1B\u5FBD\u7AE0 currentColor \u63CF\u8FB9\u81EA\u9002\u5E94\u6DF1\u6D45\u4E3B\u9898\u3002
2709
+ \uFF080.9.76\uFF1A\u300C\u5BF9\u8BDD\u300D\u6765\u6E90\u5FBD\u7AE0\u968F\u5176 CSS \u9000\u5F79\u2014\u2014meta.session \u662F\u6CF5\u6240\u6709\u6743\u6807\u8BB0\u975E\u6765\u6E90\u8BED\u4E49\u3002\uFF09 */
2711
2710
  .dsvm-optime,.dsvm-opdur{font-size:11px;color:var(--dsw-alias-label-caption,#9ca3af);font-variant-numeric:tabular-nums}
2712
2711
  .dsvm-opday{font-size:11px;font-weight:600;color:var(--dsw-alias-label-caption,#9ca3af);margin:6px 0 0}
2713
2712
  .dsvm-opgroup.done .dsvm-opday:first-child{margin-top:0}
2714
- .dsvm-opdir,.dsvm-opsession{font-size:11px;line-height:16px;padding:0 6px;border-radius:8px;border:1px solid currentColor}
2713
+ .dsvm-opdir{font-size:11px;line-height:16px;padding:0 6px;border-radius:8px;border:1px solid currentColor}
2715
2714
  .dsvm-opdir.on{color:#15803d}
2716
- .dsvm-opdir.off,.dsvm-opsession{color:var(--dsw-alias-label-secondary,#4b5563)}
2715
+ .dsvm-opdir.off{color:var(--dsw-alias-label-secondary,#4b5563)}
2717
2716
  .dsvm-opver{font-size:11px;color:var(--dsw-alias-label-secondary,#4b5563);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
2718
2717
  .dsvm-favbtn{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-caption,#9ca3af);font-size:15px;line-height:1;cursor:pointer;padding:0 2px;margin-left:auto}
2719
2718
  .dsvm-favbtn:hover{color:var(--dsw-alias-state-business-primary,#4d6bfe)}
@@ -3657,7 +3656,6 @@ function DetailModal({ it, labels, busy, onClose, onInstall, onUpgrade, upgradeB
3657
3656
  it.deprecated === true ? h("span", { className: "dshm-badge warn" }, lookup("badge.deprecated")) : null,
3658
3657
  it.community !== true && Array.isArray(it.verified) && it.verified.length ? h("span", { className: "dshm-badge", title: it.verified.join("\u3001") }, lookup("badge.verified")) : null,
3659
3658
  it.audience === "internal" ? h("span", { className: "dshm-badge" }, lookup("badge.internal")) : null,
3660
- it.decoupled === true ? h("span", { className: "dshm-badge", title: lookup("badge.decoupled.tip") }, lookup("badge.decoupled")) : null,
3661
3659
  it.installed ? h("span", { className: "dshm-badge" }, lookup("badge.installed")) : null,
3662
3660
  it.community === true ? h("span", { className: "dshm-badge info" }, lookup("badge.community")) : null,
3663
3661
  h("span", { className: "dshm-badge info" }, it.source === "npm" ? "npm" : "github"),
@@ -4055,7 +4053,6 @@ function MarketTab({ notify, markets, onMutation, ops, favorites, profileKind, o
4055
4053
  it.deprecated === true ? h("span", { className: "dshm-badge warn", key: "dep" }, lookup("badge.deprecated")) : null,
4056
4054
  it.community !== true && Array.isArray(it.verified) && it.verified.length ? h("span", { className: "dshm-badge", key: "v", title: it.verified.join("\u3001") }, lookup("badge.verified")) : null,
4057
4055
  it.audience === "internal" ? h("span", { className: "dshm-badge dshm-badge-internal", key: "internal" }, lookup("badge.internal")) : null,
4058
- it.decoupled === true ? h("span", { className: "dshm-badge", key: "decoupled", title: lookup("badge.decoupled.tip") }, lookup("badge.decoupled")) : null,
4059
4056
  it.outdated ? h("span", { className: "dshm-badge warn", key: "u" }, lookup("badge.update")) : null,
4060
4057
  it.installed ? h("span", { className: "dshm-badge", key: "i" }, lookup("badge.installed")) : null,
4061
4058
  it.community === true ? h("span", { className: "dshm-badge info", key: "c" }, lookup("badge.community")) : null,
@@ -4856,7 +4853,6 @@ function OperationsCard({ records, onClearFinished, onRemove }) {
4856
4853
  h("span", { className: "dsvm-opstatus" }, lookup("op.status." + r.status)),
4857
4854
  h("span", { className: "dsvm-opkind" }, lookup("op.kind." + r.kind)),
4858
4855
  vm.dir ? h("span", { className: `dsvm-opdir ${vm.dir}` }, lookup(vm.dir === "on" ? "op.state.on" : "op.state.off")) : null,
4859
- vm.session ? h("span", { className: "dsvm-opsession", title: lookup("op.session.tip") }, lookup("op.session")) : null,
4860
4856
  h("span", { className: "dsvm-optarget", title: tip || void 0 }, vm.target),
4861
4857
  vm.version ? h("span", { className: "dsvm-opver", title: tip || void 0 }, vm.version) : null,
4862
4858
  vm.durText ? h("span", { className: "dsvm-opdur" }, vm.durText) : null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-m",
3
- "version": "0.9.75",
3
+ "version": "0.9.76",
4
4
  "description": "可自定义收录清单的 DSH 插件市场:收录、安装、卸载、升级一站完成,附 agent 工具与 dshm CLI。",
5
5
  "license": "MIT",
6
6
  "type": "module",