dsh-m 0.10.1 → 0.10.3

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,18 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
8
8
 
9
9
  ## 中文
10
10
 
11
+ ### 0.10.3 修复:操作泵恢复记账对账(挂账 1)+ D3 applied core 直钉(挂账 3)
12
+
13
+ - **需求(2026-10-18,0.10.2 dogfood 收尾盘点挂账)**:面板随宿主换装重载会打断泵的最后落账,残留的 running 记录被恢复流程一律标「进程重启中断」——0.10.2 自升级事件中升级实际成功(intent ledger resolved ok + 三面账写穿)却被记为失败,审计误导;另:D3 `applied → needsRestart=false` 缺 core 层直接钉(此前仅 client 层间接覆盖,评审挂账 3)。
14
+ - **方案**:① `restoreRecords` 增第三参 `installedVersionOf`(账实复读缝,main.jsx 以 `api("installed")` 实读实现,与 stillApplies 同款实读纪律)——升级类 running 残留若账面已到 `meta.toVersion` → 改判 done(`meta.reconciledAfterRestart` 留痕);未到目标保持中断原语义;不传第三参行为不变(既有调用方零迁移)。② 三处升级站点 enqueue meta 携带 `toVersion`(chip=state.latest、已装列表=it.latestVersion、市场卡=it.latest)——中断恢复对账的比对依据。
15
+ - **验证**:typecheck 零错误;全量测试(新增 6:T-D3 applied core 直钉 + 恢复对账改判/未到/向后兼容三形态 + 三站点 meta 单行锚;18 例既有失败 028 本机环境清单零新增)。
16
+
17
+ ### 0.10.2 修复:D3 自升级 post-write 伪失败账实改判 + 静默自升级(0.10.0→0.10.1 dogfood 实证轮)
18
+
19
+ - **需求(2026-10-18 凌晨,首次 D3 真机 dogfood——0.10.0→0.10.1 自升级事件)**:自升级报失败(`application=failed、error=already-installed`)但三面账(manifest/node_modules/lock)均已写入 0.10.1——宿主对自身 bundle 换装存在 **post-write 伪失败**:installBundle 写穿后 manifest 含该名,宿主完成路径自触守卫(自指操作伪影;守卫源码 `specPackageName` 对 tarball URL 同样可解析包名)。另:0.10.1 引入的自升级确认框破坏既有「点击即升级」体验(主人裁决撤除)。
20
+ - **方案**:① **D3 终态失败一律账实复读改判**——实读 listInstalled:目标版已写入 = 升级事实成立,按成功改判(needsRestart=true 提示重启激活,output 留改判痕);未到目标 = 真失败原语义;profileDir 自 host-api/两处缝透传。② **静默自升级**——确认框整体撤除(受控态/Modal/文案键/SSR 钉),角标点击直接升级,结局由成功/失败横幅如实报告。ADR-0022 增补决议 7(spike 推断修正 + 改判 + UX 裁决入册)。
21
+ - **验证**:typecheck 零错误;全量测试(新增 2 钉 T-D1 改判成功/T-D2 真失败双形态,静默结构钉替换确认框钉;18 例既有失败 028 本机环境清单零新增);真机事件本身即第一份 dogfood 数据:0.10.1 经「重启激活」到位,重启后守卫锚点干净。
22
+
11
23
  ### 0.10.1 修复:0.10.0 真机 E2E 实证缺陷三连——enable 竞速重试普适化 + 回装失败账实复读 + 守卫命中一律两步化
12
24
 
13
25
  - **需求(2026-10-17,0.10.0 装机当日 E2E 实证,真机 skip-auth@0.4.1 与卸载→重装两个事件)**:①插件树重载窗口的 enable 阶段激活竞速(`pending (waiting for service: webRuntime)`)会让两步升级的第二腿、兜底回装腿与 D3 自升级通道直接终态失败——0.9.94 时代的「enable 失败自动重试一次(重试即愈)」本地增强只覆盖了首腿;②回装腿报失败 ≠ 真缺席——pnpm 可能已写入账面(激活阶段失败),此时建议「手动重装旧版」会误导用户降级;③卸载后同会话重装:宿主活跃态/manifest 字面仍视其在装(守卫命中),而 previousVersion 探测口径为「未安装」,0.10.0 的 previousVersion 前置门使守卫命中原样透传 already-installed。
@@ -673,6 +685,18 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
673
685
 
674
686
  ## English
675
687
 
688
+ ### Fixes in 0.10.3 — operation-pump restore ledger reconciliation (pending item 1) + D3 applied core-level pin (pending item 3)
689
+
690
+ - **Need (2026-10-18, pending items from the 0.10.2 dogfood wrap-up)**: a panel reload during the host's own bundle swap interrupts the pump's final ledger write, and the leftover running record is unconditionally labeled「进程重启中断」(process-restart interrupted) by the restore flow — in the 0.10.2 self-upgrade event the upgrade had actually succeeded (intent ledger resolved ok + all three ledgers written through) yet was recorded as failed, misleading the audit trail. Separately: D3 `applied → needsRestart=false` lacked a core-level pin (previously covered only indirectly at the client layer; review pending item 3).
691
+ - **Approach**: ① `restoreRecords` gains a third parameter `installedVersionOf` (an account-reality re-read seam implemented in main.jsx via `api("installed")`, same live-read discipline as stillApplies) — an upgrade-kind running leftover whose ledger has reached `meta.toVersion` is re-judged as done (`meta.reconciledAfterRestart` recorded); anything else keeps the interrupted semantics; omitting the third parameter preserves the old behavior (zero migration for existing callers). ② the three upgrade sites now carry `toVersion` in the enqueue meta (chip=state.latest, installed list=it.latestVersion, market card=it.latest) — the comparison basis for the restore reconciliation.
692
+ - **Verification**: typecheck clean; full suite (6 new: T-D3 applied core-level pin + three restore-reconciliation shapes + three site meta anchors; 18 pre-existing failures are the 028 machine-environment set, zero new).
693
+
694
+ ### Fixes in 0.10.2 — account-reality reconciliation for D3 self-upgrade post-write pseudo-failure + silent self-upgrade (first D3 dogfood round)
695
+
696
+ - **Need (2026-10-18 early morning, first real-machine D3 dogfood — the 0.10.0→0.10.1 self-upgrade event)**: the self-upgrade reported failure (`application=failed、error=already-installed`) while all three ledgers (manifest/node_modules/lock) had already been written to 0.10.1 — the host has a **post-write pseudo-failure** for its own bundle swap: installBundle writes through, the manifest then contains the name, and the host's completion path trips its own guard (self-referential artifact; the guard's `specPackageName` resolves package names from tarball URLs too). Separately: the 0.10.1 self-upgrade confirmation dialog broke the existing "click to upgrade" experience (owner ordered its removal).
697
+ - **Approach**: ① **reconcile on any D3 terminal failure** — re-read listInstalled: if the target version is already written, the upgrade factually happened and the result is re-judged as success (needsRestart=true prompting the activating restart, with the reconciliation noted in output); if the target is absent, the genuine-failure semantics stand; profileDir is threaded from host-api and both seams. ② **silent self-upgrade** — the confirmation dialog is removed wholesale (controlled state / modal / copy keys / SSR pin); the chip click upgrades directly and outcomes are still reported truthfully via banners. ADR-0022 decision 7 records the spike-inference correction, the reconciliation, and the UX ruling.
698
+ - **Verification**: typecheck clean; full suite (2 new pins T-D1 reconciled-success / T-D2 genuine-failure, silent structure pins replacing the confirmation pins; 18 pre-existing failures are the 028 machine-environment set, zero new); the real-machine event itself is the first dogfood datum: 0.10.1 landed via "restart to activate", guard journal anchors clean after restart.
699
+
676
700
  ### Fixes in 0.10.1 — three defects proven by same-day real-machine E2E of 0.10.0: enable-race retry universalized + account-reality re-read on rollback failure + guard hit always two-steps
677
701
 
678
702
  - **Need (2026-10-17, proven during the same-day real-machine E2E of 0.10.0 — the skip-auth@0.4.1 upgrade event and the uninstall→reinstall event)**: ① the enable-stage activation race during plugin-tree reload windows (`pending (waiting for service: webRuntime)`) made the two-step upgrade's second leg, the rollback reinstall leg, and the D3 self-upgrade channel fail terminally — the 0.9.94-era "retry enable failures once (retry heals)" local enhancement covered only the first leg; ② a failed reinstall leg ≠ true absence — pnpm may have already written the package (activation failed afterwards), where advising "manually reinstall the old version" would mislead the user into a downgrade; ③ uninstall followed by a same-session reinstall: the host's live state / literal manifest still considers the package installed (guard fires) while the previousVersion probe reports "not installed", so 0.10.0's previousVersion precondition let the raw already-installed error surface.
package/lib/client.js CHANGED
@@ -1562,7 +1562,7 @@ function createOperationsStore(storage) {
1562
1562
  }
1563
1563
  };
1564
1564
  }
1565
- async function restoreRecords(records, stillApplies) {
1565
+ async function restoreRecords(records, stillApplies, installedVersionOf) {
1566
1566
  const list = Array.isArray(records) ? records : [];
1567
1567
  const out = [];
1568
1568
  for (const rec of list) {
@@ -1584,6 +1584,24 @@ async function restoreRecords(records, stillApplies) {
1584
1584
  } else if (rec.status === "input") {
1585
1585
  out.push({ ...rec, status: "failed", error: "\u5F85\u51B3\u786E\u8BA4\u4E0D\u53EF\u6062\u590D\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77", updatedAt: Date.now() });
1586
1586
  } else if (rec.status === "running") {
1587
+ if (rec.kind === "upgrade" && rec.meta && typeof rec.meta.toVersion === "string" && rec.meta.toVersion !== "" && typeof installedVersionOf === "function") {
1588
+ let installed;
1589
+ try {
1590
+ installed = await installedVersionOf(rec);
1591
+ } catch {
1592
+ installed = void 0;
1593
+ }
1594
+ if (installed === rec.meta.toVersion) {
1595
+ out.push({
1596
+ ...rec,
1597
+ status: "done",
1598
+ error: void 0,
1599
+ meta: { ...rec.meta, reconciledAfterRestart: true },
1600
+ updatedAt: Date.now()
1601
+ });
1602
+ continue;
1603
+ }
1604
+ }
1587
1605
  out.push({ ...rec, status: "failed", error: "\u8FDB\u7A0B\u91CD\u542F\u4E2D\u65AD", updatedAt: Date.now() });
1588
1606
  } else {
1589
1607
  out.push({ ...rec });
@@ -2351,9 +2369,6 @@ var ZH = {
2351
2369
  "op.degraded": "\u5347\u7EA7\u5931\u8D25\uFF1A\u65B0\u7248\u5B89\u88C5\u672A\u6210\u529F\uFF0C\u5DF2\u81EA\u52A8\u6062\u590D\u65E7\u7248 {restoredTo}\u2014\u2014\u63D2\u4EF6\u5F53\u524D\u53EF\u7528\uFF0C\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",
2352
2370
  "notify.selfupgraded": "dsh-m \u5DF2\u5347\u7EA7\uFF08v{from} \u2192 v{to}\uFF09",
2353
2371
  "notify.selfupgraded.failed": "dsh-m \u5347\u7EA7\u5931\u8D25\uFF1A{err}",
2354
- "selfupgrade.confirm": "\u5C06\u901A\u8FC7 tarball \u76F4\u88C5\u901A\u9053\u628A dsh-m \u5347\u7EA7\u5230 {version}\uFF1A\u4E0D\u7ECF\u8FC7\u5378\u8F7D\uFF0C\u5931\u8D25\u65F6\u5F53\u524D\u7248\u672C\u4E0D\u53D7\u5F71\u54CD\uFF1B\u5B8C\u6210\u540E\u9700\u91CD\u542F Desktop \u751F\u6548\u3002",
2355
- "selfupgrade.confirm.noversion": "\u5C06\u901A\u8FC7 tarball \u76F4\u88C5\u901A\u9053\u5347\u7EA7 dsh-m\uFF1A\u4E0D\u7ECF\u8FC7\u5378\u8F7D\uFF0C\u5931\u8D25\u65F6\u5F53\u524D\u7248\u672C\u4E0D\u53D7\u5F71\u54CD\uFF1B\u5B8C\u6210\u540E\u9700\u91CD\u542F Desktop \u751F\u6548\u3002",
2356
- "selfupgrade.go": "\u5347\u7EA7",
2357
2372
  "failed.install": "\u5B89\u88C5\u5931\u8D25\uFF1A{err}",
2358
2373
  "failed.uninstall": "\u5378\u8F7D\u5931\u8D25\uFF1A{err}",
2359
2374
  "failed.upgrade": "\u5347\u7EA7\u5931\u8D25\uFF1A{err}",
@@ -2655,9 +2670,6 @@ var EN = {
2655
2670
  "op.degraded": "Upgrade failed: the new version did not install \u2014 rolled back to {restoredTo}. The plugin still works; you can retry later.",
2656
2671
  "notify.selfupgraded": "dsh-m upgraded (v{from} \u2192 v{to})",
2657
2672
  "notify.selfupgraded.failed": "dsh-m upgrade failed: {err}",
2658
- "selfupgrade.confirm": "Upgrade dsh-m to {version} via the tarball direct-install channel: no uninstall involved, the current version stays intact on failure; a Desktop restart is needed afterwards.",
2659
- "selfupgrade.confirm.noversion": "Upgrade dsh-m via the tarball direct-install channel: no uninstall involved, the current version stays intact on failure; a Desktop restart is needed afterwards.",
2660
- "selfupgrade.go": "Upgrade",
2661
2673
  "failed.install": "Install failed: {err}",
2662
2674
  "failed.uninstall": "Uninstall failed: {err}",
2663
2675
  "failed.upgrade": "Upgrade failed: {err}",
@@ -4174,7 +4186,7 @@ function MarketTab({ notify, markets, onMutation, ops, favorites, profileKind, o
4174
4186
  const r = await api("upgrade", { pkg: it.installedPkg });
4175
4187
  const m = opUpgradeMeta2(r);
4176
4188
  return m ? { ...r, opMeta: m } : r;
4177
- });
4189
+ }, { toVersion: it.latest });
4178
4190
  const degraded = oc.degradedOutcome(res);
4179
4191
  if (degraded) {
4180
4192
  notify({ kind: "warn", text: degraded.text });
@@ -4576,7 +4588,7 @@ function InstalledTab({ notify, installed, updates, onMutation, ops }) {
4576
4588
  const r = await api("upgrade", { pkg: it.pkg });
4577
4589
  const m = opUpgradeMeta2(r);
4578
4590
  return m ? { ...r, opMeta: m } : r;
4579
- });
4591
+ }, { toVersion: it.latestVersion });
4580
4592
  const degraded = oc.degradedOutcome(res);
4581
4593
  if (degraded) {
4582
4594
  notify({ kind: "warn", text: degraded.text });
@@ -5191,12 +5203,11 @@ var TABS = [
5191
5203
  ["installed", "tab.installed", "installed"],
5192
5204
  ["settings", "tab.settings", null]
5193
5205
  ];
5194
- function DshmVersionChip({ version, notify, initialCheck, ops, initialConfirm }) {
5206
+ function DshmVersionChip({ version, notify, initialCheck, ops }) {
5195
5207
  const [check, setCheck] = useState(
5196
5208
  () => initialCheck !== void 0 ? initialCheck : typeof window !== "undefined" && window.localStorage ? readSelfCheckCache2(window.localStorage, { version }) : null
5197
5209
  );
5198
5210
  const [busy, setBusy] = useState(false);
5199
- const [confirming, setConfirming] = useState(initialConfirm === true);
5200
5211
  useEffect(() => {
5201
5212
  if (initialCheck !== void 0) return;
5202
5213
  let live = true;
@@ -5214,17 +5225,16 @@ function DshmVersionChip({ version, notify, initialCheck, ops, initialConfirm })
5214
5225
  }, [initialCheck]);
5215
5226
  const doUpgrade = async () => {
5216
5227
  if (busy) return;
5217
- setConfirming(true);
5228
+ return performUpgrade();
5218
5229
  };
5219
5230
  const performUpgrade = async () => {
5220
5231
  if (busy) return;
5221
- setConfirming(false);
5222
5232
  setBusy(true);
5223
5233
  try {
5224
5234
  const res = await (ops ? ops.runOp("upgrade", "dsh-m", async () => {
5225
5235
  const r = await api("self-upgrade");
5226
5236
  return { ...r, opMeta: { from: version, to: r.version || "latest" } };
5227
- }, { npm: "dsh-m" }) : api("self-upgrade"));
5237
+ }, { npm: "dsh-m", toVersion: state.latest }) : api("self-upgrade"));
5228
5238
  clearSelfCheckCache2(typeof window !== "undefined" && window.localStorage ? window.localStorage : null);
5229
5239
  setCheck({ current: version, latest: null, outdated: false, ahead: false });
5230
5240
  notify({
@@ -5247,36 +5257,6 @@ function DshmVersionChip({ version, notify, initialCheck, ops, initialConfirm })
5247
5257
  };
5248
5258
  const state = deriveChipState2(check, version);
5249
5259
  if (state.kind === "outdated") {
5250
- if (confirming) {
5251
- return h(
5252
- "div",
5253
- { className: "dshm-compat-overlay", ...backdropCloseHandlers2(() => setConfirming(false)) },
5254
- h(
5255
- "div",
5256
- { className: "dshm-compat-dialog", onClick: (e) => e.stopPropagation() },
5257
- h("div", { className: "dshm-compat-title" }, lookup("selfupdate.available", { v: state.latest || "?" })),
5258
- h(
5259
- "div",
5260
- { className: "dshm-compat-body" },
5261
- state.latest ? lookup("selfupgrade.confirm", { version: `v${state.latest}` }) : lookup("selfupgrade.confirm.noversion")
5262
- ),
5263
- h(
5264
- "div",
5265
- { className: "dshm-actions" },
5266
- h(
5267
- "button",
5268
- { className: "dshm-btn", onClick: () => setConfirming(false) },
5269
- lookup("common.later")
5270
- ),
5271
- h(
5272
- "button",
5273
- { className: "dshm-btn primary", onClick: performUpgrade, disabled: busy },
5274
- lookup("selfupgrade.go")
5275
- )
5276
- )
5277
- )
5278
- );
5279
- }
5280
5260
  return h(
5281
5261
  "button",
5282
5262
  {
@@ -5770,19 +5750,29 @@ function MarketPanel({ onClose }) {
5770
5750
  if (opsPumpCtx && opsPumpCtx.syncOps === syncOps) opsPumpCtx = null;
5771
5751
  };
5772
5752
  }, [stillApplies, dispatchRestored, syncOps, refreshViews]);
5753
+ const installedVersionOf = useCallback(async (r) => {
5754
+ try {
5755
+ const fresh = await api("installed", { probe: false });
5756
+ const items = fresh && Array.isArray(fresh.items) ? fresh.items : [];
5757
+ const row = items.find((it) => it && it.pkg === r.target);
5758
+ return row && typeof row.version === "string" ? row.version : void 0;
5759
+ } catch {
5760
+ return void 0;
5761
+ }
5762
+ }, []);
5773
5763
  const restoredRef = useRef(false);
5774
5764
  useEffect(() => {
5775
5765
  if (restoredRef.current || !installed.data) return;
5776
5766
  restoredRef.current = true;
5777
5767
  void (async () => {
5778
- const restored = await restoreRecords2(opsStore.list(), stillApplies);
5768
+ const restored = await restoreRecords2(opsStore.list(), stillApplies, installedVersionOf);
5779
5769
  opsStore.replaceAll(restored);
5780
5770
  syncOps();
5781
5771
  if (restored.some((r) => r.status === "queued")) {
5782
5772
  void opsPump.kick();
5783
5773
  }
5784
5774
  })();
5785
- }, [installed.data, stillApplies, syncOps]);
5775
+ }, [installed.data, stillApplies, installedVersionOf, syncOps]);
5786
5776
  const counts = {
5787
5777
  market: marketCommunity.data ? marketCommunity.data.total : null,
5788
5778
  installed: installed.data ? installed.data.items.length : null
@@ -302,14 +302,16 @@ export function createApiDispatcher(ctx) {
302
302
  }
303
303
  case 'self-upgrade': {
304
304
  assertWriteAllowed(profile, 'self-upgrade');
305
- // 0.10.0 D3 自升级专用通道(desktop):tarball 直覆盖。desktopInstall 的 registry spec 在
306
- // 0.2.1 宿主必撞 already-installed 守卫,而 remove+add 对调用者自身是破坏性路径(R6:自升级
307
- // 绝不落入通用两步——改道唯一执行点在 core 缝,此处调 D3 入口即语义同源);tarball spec
308
- // 不受守卫约束(spike 实证)。恒 panel 语义零外部日志(ADR-0018),intent 预写/收口在 core 层。
305
+ // 0.10.0 D3 自升级专用通道(desktop):tarball 直装。0.10.2 实证修订:0.2.1 守卫经
306
+ // specPackageName 对 tarball URL 同样解析包名(自升级写穿后宿主完成路径自触守卫 = post-write
307
+ // 伪失败),由 D3 的账实复读改判兜住;通道分治不变——remove+registry-spec 通用两步仍不达自升级。
308
+ // 恒 panel 语义零外部日志(ADR-0018),intent 预写/收口在 core 层。
309
309
  if (profile.kind !== 'web') {
310
310
  const managed = await d.desktopSelfUpgradeViaTarball(ctx.pkg.name, ctx.pkg.version, {
311
311
  timeoutMs: cfg().timeoutMs,
312
312
  signal,
313
+ // 0.10.2:账实复读(post-write 伪失败改判)需要 profile 目录
314
+ profileDir: profile.dir,
313
315
  }, {
314
316
  getService: d.getService,
315
317
  ensureService: d.ensureService,
@@ -194,7 +194,7 @@ async function desktopInstallLocked(id, cfg, opts, deps) {
194
194
  // 0.10.0 R6(install 臂):dsh-m 已装态下的 install 调用实为升级(守卫必拦)→ 改道 D3;
195
195
  // 全新安装(未装)走既有单步——守卫不触发,R1「新装路径不动」。
196
196
  if (pkg === SELF_PKG && previousVersion !== undefined) {
197
- return desktopSelfUpgradeViaTarballLocked(pkg, previousVersion, { timeoutMs, signal: opts.signal }, {
197
+ return desktopSelfUpgradeViaTarballLocked(pkg, previousVersion, { timeoutMs, signal: opts.signal, profileDir: opts.profileDir }, {
198
198
  getService: () => service,
199
199
  npmLatest: deps.npmLatest,
200
200
  npmTarballUrl: deps.npmTarballUrl,
@@ -671,6 +671,34 @@ async function desktopSelfUpgradeViaTarballLocked(pkgName, currentVersion, opts,
671
671
  change = changeOf(await service.installBundle(spec, { enabled: true }));
672
672
  }
673
673
  if (isTerminalFailure(change)) {
674
+ // 0.10.2(D3 dogfood 实证,0.10.0→0.10.1 真机事件):宿主对自身 bundle 换装存在 post-write 伪失败——
675
+ // installBundle 已写穿三面账(manifest/node_modules/lock 均为目标版)却回传 failed/already-installed
676
+ // (自指操作伪影:写完后 manifest 含该名,宿主完成路径自触守卫)。终态失败一律实读账面:
677
+ // 目标版已写入 = 升级事实成立,按成功改判(needsRestart=true,重启激活);否则真失败(原语义)。
678
+ let installedVersion;
679
+ if (opts.profileDir && deps.listInstalled) {
680
+ try {
681
+ const row = (await deps.listInstalled(opts.profileDir)).items.find((it) => it.pkg === pkgName);
682
+ installedVersion = row?.version;
683
+ }
684
+ catch {
685
+ // 复读失败按真失败处理
686
+ }
687
+ }
688
+ if (installedVersion === latest.version) {
689
+ await resolveIntent({ ok: true, installedVersion: latest.version });
690
+ return {
691
+ id: pkgName,
692
+ pkg: pkgName,
693
+ spec,
694
+ version: latest.version,
695
+ buildApprovals: Array.isArray(change.approvedBuilds) ? change.approvedBuilds : [],
696
+ fallbackAllBuilds: false,
697
+ needsRestart: true,
698
+ output: `official pluginManager (self-upgrade via tarball): application=${change.application ?? 'failed'}、error=${change.error?.code ?? 'terminal-failure'} 经账实复读改判成功——目标版 ${latest.version} 已写入(宿主自升级 post-write 伪失败),重启 Desktop 激活`,
699
+ via: 'desktop-manager',
700
+ };
701
+ }
674
702
  const pending = pendingOf(change);
675
703
  if (change.application === 'cancelled') {
676
704
  throw new DesktopOpsError('install-refused', `自升级已被取消(${pkgName}):当前版本 ${currentVersion} 不受影响`);
@@ -729,7 +757,7 @@ async function desktopUpgradeLocked(pkg, cfg, opts, deps) {
729
757
  const selfTarget = items.find((it) => it.pkg === pkg);
730
758
  if (!selfTarget)
731
759
  throw new DesktopOpsError('install-refused', `desktop profile 未安装该插件: ${pkg}(升级目标必须是已装插件)`);
732
- return desktopSelfUpgradeViaTarballLocked(pkg, selfTarget.version, { timeoutMs, signal: opts.signal }, {
760
+ return desktopSelfUpgradeViaTarballLocked(pkg, selfTarget.version, { timeoutMs, signal: opts.signal, profileDir: opts.profileDir }, {
733
761
  getService: () => service,
734
762
  npmLatest: deps.npmLatest,
735
763
  npmTarballUrl: deps.npmTarballUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-m",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "description": "可自定义收录清单的 DSH 插件市场:收录、安装、卸载、升级一站完成,附 agent 工具与 dshm CLI。",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/registry.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "category": "essentials",
9
9
  "alsoCategories": ["self-dev"],
10
10
  "tags": ["市场", "插件管理"],
11
- "verified": ["0.1.2-rc.1", "0.1.5-rc.1", "0.1.5-rc.2", "0.1.7-rc.1", "0.1.7-rc.2", "0.2.0-rc.1", "0.2.0-rc.2"],
11
+ "verified": ["0.1.2-rc.1", "0.1.5-rc.1", "0.1.5-rc.2", "0.1.7-rc.1", "0.1.7-rc.2", "0.2.0-rc.1", "0.2.0-rc.2", "0.2.1-rc.2"],
12
12
  "source": "npm",
13
13
  "npm": "dsh-m",
14
14
  "github": "iasiv5/dsh-m",
@@ -91,7 +91,7 @@
91
91
  "description": "替换官方 Connection 跳过 BrowserAuth,免 Token;已适配七个已审计精确版本对,详见仓库。仅支持 web profile;desktop 宿主一律自动休眠(多进程树判别),desktop 用户请保持最新版。",
92
92
  "category": "self-dev",
93
93
  "tags": ["BrowserAuth", "连接", "安全", "工具"],
94
- "verified": ["0.1.2-rc.1", "0.1.5-rc.1", "0.1.5-rc.2", "0.1.7-rc.1", "0.1.7-rc.2", "0.2.0-rc.1", "0.2.0-rc.2"],
94
+ "verified": ["0.1.2-rc.1", "0.1.5-rc.1", "0.1.5-rc.2", "0.1.7-rc.1", "0.1.7-rc.2", "0.2.0-rc.1", "0.2.0-rc.2", "0.2.1-rc.2"],
95
95
  "source": "npm",
96
96
  "npm": "@iasiv5/dsh-skip-browser-auth",
97
97
  "github": "iasiv5/dsh-skip-browser-auth",