Skip to content

Releases: FeatherHunter/dsh-plugin-update

v0.18.39

Choose a tag to compare

@FeatherHunter FeatherHunter released this 23 Oct 16:56

Fixed

  • #245 失败账本不因「目标版事后装好」结案:已装/运行/最新版全一致时单品面板仍常驻「更新失败」红字(真机 2026-10-23 20:21 desktop profile):dsh-im-companion 0.2.22 → 0.2.23 在 desktop-manager 路上 EPERM 失败后,用户照失败账本里的手工命令装好同一版本并重启;此后面板版本三格全是 0.2.23,却仍常驻「更新失败(install-failed)」红字、「最后手段 · 自动恢复不可用」与手工命令,点「已知晓」也不消失(同帧 render() 按盘上 job.state === 'failed' 重画,下一个 1s 轮询还会重建锁存),只能等未来 latest > target 触发 #100 让位。根因:盘上任务账本是历史证据,但快照把它原样带出,面板、入口徽标、日志面板态、复制诊断、安装按钮五处消费方各自把它当「当前失败」。现在:①新增 src/shared/failure-settled.ts——failureSettledOf(snapshot) 是唯一判据(任务 failed/interrupted、目标版本合法、磁盘已装、注册在册、磁盘与运行版本同版且都不低于目标版本 ⇒ 上次尝试已了结;任一未知/不满足都按真失败,installed/registered/运行版未知不冒充事实),settledClearsLatch 统一「了结后哪些旧锁存该清」(按装侧/查侧判定、不比对 jobId:目标版确实在跑时装侧旧失败一律让位,查侧失败仍等一次成功查询);②五个消费方只问这一处、不再各写版本比较:了结态不出失败横幅/最后手段/为那次失败的手工命令/04 章失败卷宗,只留一行中性历史(失败码 + 目标版本,非错误样式,新增双语 key panel.history.failure-settled),复制诊断按当前状态给快照、不再把旧码当当前码;本回包的新鲜 errorKind/lastError 仍照常显示;③盘上账本、healJob 与批量对账不改写——不伪造「修复成功」(#58 口径),也不把历史账本当当前失败。

Tests

  • 新增 tests/issue-245-failed-ledger-settled.test.mjs 19 例(判据:目标版被更高版取代也结案、任一未知/不满足不结案、判定只读不改写快照与 job;展示:首帧/成功轮询/知晓后/卸载重挂都无失败面、运行未知或低于目标或磁盘与运行不同版或未登记时失败帧照旧、更高新版出现时报可更新而非旧失败、只留一条中性历史行、新鲜失败不被历史行吞掉;贯通:复制诊断、入口徽标、安装槽视图、日志面板态同口径(非法态不记 error、真失败仍记 error);锁存:成功轮询清旧失败、恢复的安装锁存被结算快照解除且后续轮询不重建、真失败不被洗掉)。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1989 例:1988 过 / 0 失败 / 1 跳过;npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(89 个源文件、416 个 key、17 错误码、20 diag 键,违规 0);npm publish --dry-run 185 文件(dsh-plugin-update@0.18.38,523.8 kB 压缩 / 1.8 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(416 个 key 仍全是 draft: true)。

v0.18.38

Choose a tag to compare

@FeatherHunter FeatherHunter released this 20 Oct 16:00

Changed

  • #243 自动续跑改成「保留行为 + 必须可见」,删除失效的会话年龄门限(真机 2026-10-20 23:17、23:34 web profile 两次「只打开面板就自己把卡路里/备忘录装完」):0.18.37 按「会话超过 10 分钟不自动续跑」修过一版,但真实宿主里这个门限永远不触发——面板挂载前的检查对账会写会话账本(markBatchEntry 会刷新 session.updatedAt),客户端读到的年龄永远是「刚活动过」。产品拍板:自动续跑本身是合理的(用户不必在「检查更新」和「安装」之间反复点),但必须让用户看见它。现在:src/panel/batch/mount.ts 发起 batchResume 前先 say「正在继续上次未完成的更新…」并立即渲染(不静默开工);续跑结束如果还剩未完成行,报「已自动继续上次未完成的更新(剩余 N 个)」;全部收尾则报「上次未完成的更新已全部完成」;续跑失败时清掉临时回执、保留最后一条错误并按原错误路径收尾。删除 AUTO_RESUME_MAX_AGE_MS、autoResumeAgeMsOf() 与 batch.notice.resume-stale(不变量从「够新才自动跑」改为「跑就必须看得见」)。

Fixed

  • #244 批量检查不纠正「已安装完成,重启宿主后生效」行:磁盘被外部改回旧版后仍宣称已装好(真机 2026-10-20 22:59 web profile「饼干记账」:磁盘 0.3.81,会话账本却是 done + restartRequired 目标 0.3.82):src/host/batch/fan-out.ts 的 checkPhone 对账循环把 restartRequired 行整行跳过,检查学到的新版本永远写不进这条会话行,面板便按会话相位继续渲染「已安装完成,重启后生效」——可重启只会加载旧版,等于静默降级 + 假待重启。现在:对账不再整行跳过,按检查结论分派——update ⇒ 退回 ready、目标置最新、清 restartRequired(磁盘真相优先,重启救不回来只能重装);done 且版本一致 ⇒ 保持 done + restartRequired(还在等重启,不动);current ⇒ 收敛 current 并清目标与标记;检查失败的结论照旧不改动画像。

Tests

  • 新增 tests/issue-244-restart-row-reconcile.test.mjs 3 例(update ⇒ 退 ready 清标记;done 同版本 ⇒ 保持待重启;current ⇒ 收敛当前);tests/issue-152-check-reconcile.test.mjs 的「restartRequired 行不碰」旧断言按 #244 新口径改写;tests/issue-243-auto-resume-stale.test.mjs 删除(年龄门限语义取消),新增 tests/issue-243-auto-resume-visible.test.mjs 5 例(旧会话照跑但先落可见回执、剩余>0 报已自动继续、全部收尾报已完成、无未完成行不动作)。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1970 例:1969 过 / 0 失败 / 1 跳过;npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(88 个源文件、415 个 key、17 错误码、20 diag 键,违规 0);npm publish --dry-run 183 文件(dsh-plugin-update@0.18.38,520.3 kB 压缩 / 1.8 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(415 个 key 仍全是 draft: true)。

v0.18.37

Choose a tag to compare

@FeatherHunter FeatherHunter released this 20 Oct 09:28

Added

  • 开发工具:一键发版脚本 + 布局探针进仓(#208 复盘:编排税 / 复现税):scripts/release.mjs(npm run release)把「门禁 → CHANGELOG 定格 → 版本号 → commit/tag/push → token 发布 → 可见性轮询 → GitHub Release」固化成一条命令,默认计划模式只读、--yes 才执行、--verify <版本> 做发布后自检(npm 可见 / latest / tag 指向 / GitHub Release / tarball 布局);scripts/panel-layout-probe.mjs(npm run probe:layout)用系统 Chrome 渲染真面板量盒子,断言 #93 单面板布局契约与 #240 批量盘弹窗契约(横幅不被压扁、复制按钮不越框、内容超高时自身可滚且末行可达)。口径写进 docs/maintainers.md,docs/agents/architecture.md 门径表同步指路。

Fixed

  • #242 批量入口按钮卡「正在安装…」:弹窗关掉后台继续跑完后,入口件没人再刷(真机 2026-10-20 16:41 web profile,宿主 16:41:53 已收尾、按钮到 16:44 仍 disabled):入口件只在挂载/点击/关弹窗时各刷一次,关弹窗时批量还在跑就停在 installing 相位,之后无人跟进。现在:src/panel/batch/entry-batch.ts 在「有未终态行 + 面板没开 + 未卸载」时排后台跟进刷新(间隔取入口件 pollMs(缺省批量面板缺省值)且不小于全局下限),最多跟 10 分钟;弹窗打开、卸载、收尾即停,跟进只打只读 batchStatus,绝不再触发安装。
  • #243 打开批量面板静默续跑两小时前的旧会话(autoResume 无新鲜度门限,用户以为只是「检查更新」;真机 2026-10-20 16:41 web profile 自动执行 14:17 旧会话 7 家):runAutoOnce 自动续跑只看「账本里有没有未完成行」,不看会话多旧。现在:src/panel/batch/mount.ts 增 AUTO_RESUME_MAX_AGE_MS = 10 分钟 新鲜度门限——超龄会话不自动跑,落 batch.notice.resume-stale(「上次更新未完成,点『继续上次未完成的更新』继续」)并把决定权交给用户(底部 resume 按钮本来就在);updatedAt 读不到的旧形状保持原行为(照旧自动续跑),autoResume:false 与显式续跑/丢弃语义不变。

Tests

  • 新增 tests/issue-242-entry-background-watch.test.mjs 4 例(后台收尾后按钮自己刷回、卸载即停、收尾不空转、跟进只打只读电话);tests/issue-243-auto-resume-stale.test.mjs 4 例(超龄不自动续跑且留按钮与提示、点继续才续跑、新鲜会话照旧打开即续、缺 updatedAt 保持旧行为、无未完成行不动作)。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1966 例:1965 过 / 0 失败 / 1 跳过;npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(88 个源文件、414 个 key、17 错误码、20 diag 键,违规 0);npm run docs:log:check 过(6 条缺行警告是既有缺行,只警告不失败);npm publish --dry-run 183 文件(dsh-plugin-update@0.18.37,518.9 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(414 个 key 仍全是 draft: true)。

v0.18.36

Choose a tag to compare

@FeatherHunter FeatherHunter released this 20 Oct 07:32

Fixed

  • #241 recovery-required 死锁:宿主插件未加载(运行版 0.0.0)≠ 盘上版时,安装/重试全被同一拦截拒绝,只能重启宿主(真机 2026-10-20 14:23 爱生活面板「饼干记账」升级卡死):集成方拿不到宿主半区运行版时会注入占位版号 0.0.0(#216 只挡了显示层)。核心把它当真实版本判「运行版 ≠ 盘上版」,于是任务中断后派生 recovery-required;同一个拦截又拒绝 canInstall,形成「想恢复必须重试、重试被恢复态挡住」的自锁。现在:①src/shared/version.ts(新)提供 normalizeRunningVersion,读取器与核心把非字符串/空串/占位 0.0.0 一律归一为「未知」(null);②buildSnapshot 增恢复豁免——任务已中断/失败、运行版未知、盘上版本比目标旧时允许发起重试安装(这一次重试就是恢复动作),但仍不宣称「有更新」(#182 的 unknown 状态判定照旧);已知运行版时豁免不生效,#179/#215 判定不回归。异动文件:src/shared/version.ts、src/core/reader.ts、src/core/service.ts。
  • #238 单品面板进入时先渲染上一次失败账本:首次安装前先弹「更新失败」误导帧(真机 2026-10-20 14:11 web profile 首装「饼干记账」一进页签就吃 13:19 的旧失败横幅):目标从未装过(磁盘没有)时,盘上残留的 failed/interrupted 任务只是历史账本;面板把任务态直接当「当前失败」渲染,还把它铺进 mount 的 job-failed 锁存。现在:①src/panel/view-model.ts 区分「新鲜失败」(本回包 errorKind/lastError、会话锁存)与 historicalJobFailure(未装 + 盘上旧任务),后者不再进失败页;②src/panel/mount.ts 的 job-failed 锁存对「未装 + 无新鲜锁存」让位,等首装/未装视图。
  • #239 队列整写瞬时 EPERM 被误判成「上次安装异常中断」(真机 2026-10-20 14:16 web profile「卡路里」首装与 CLI 并发写同一份队列账本):writeQueue 整写队列账本(写临时文件 + rename),Windows 上句柄短占会偶发 EPERM/EACCES/EBUSY/ENOTEMPTY/EMFILE;写入被拒即抛,上层把「没写进去」落成 interrupted + recovery-required。现在:src/core/queue/ports.ts 对可判定的瞬时写错误做小步重试(瞬时错误码集合、最多 3 次、25ms 间隔、重试前清残留临时文件),非瞬时错误照旧立即失败;createUpdateQueuePorts 增 writeFileImpl/renameImpl 注入缝(只给测试用)。
  • #240 批量面板失败横幅被压扁:「复制诊断/复制手工命令」越出红框(真机 2026-10-20 14:17 web profile「更新档案·总账」8 行批量面板,窗口 CSS 高约 542):批量弹窗根没有 .dsh-upd-body 滚动区,内核 #93 弹窗契约(:has(>.dsh-upd-body))刻意不覆盖它;内容高过 85vh 时纵向 flex 按比例压子项,横排且显式 min-height:3.4em 的失败横幅先被压到地板,名单行与按钮越框。现在:src/panel/batch/styles.ts 增批量弹窗高度契约——.dsh-upd-overlay .dsh-upd.dsh-upd-batch 自己滚(overflow-y:auto)、child 一律 flex:none;契约只挂 overlay 作用域且只认批量根,内核面板与 embedded 形态零影响。

Tests

  • 新增 tests/issue-241-recovery-deadlock.test.mjs 4 例(占位 0.0.0 归一未知、中断任务可恢复重试、未知运行版不伪造 pending-restart、已知运行版时豁免不生效);tests/issue-238-first-install-stale-failure.test.mjs 8 例(首帧不渲染旧失败账本、新鲜失败仍显示、锁存让位、历史帧让位后新失败照常回归);tests/issue-239-queue-transient-write.test.mjs 4 例(瞬时 EPERM 重试成功、非瞬时立即失败、重试耗尽如实失败、只读队列不受影响);tests/issue-240-batch-dialog-height-contract.test.mjs 7 例(两条契约存在、只挂 overlay+batch 根、内核 #93 契约不扩到批量、dialog/embedded DOM 形状不回归、失败横幅与复制按钮组形状不变)。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1958 例:1957 过 / 0 失败 / 1 跳过;npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(88 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm run docs:log:check 过(6 条缺行警告是既有缺行,只警告不失败);npm publish --dry-run 183 文件(dsh-plugin-update@0.18.36,517.3 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true(合入条件未满足))。

v0.18.35

Choose a tag to compare

@FeatherHunter FeatherHunter released this 20 Oct 05:54

Fixed

  • #237 CLI 路:官方桌面运行时里的 dsh web / CLI 模式使用范围,安装第一步就 spawn-failed(真机 2026-10-20 13:19 爱生活面板「首次安装」点下去 2ms 失败):普通 DSH 宿主这条路由靠反查 process.argv[1] 找 CLI 的 JS 入口,旧实现只认 npm 布局(包名 @deepseek-ai/dsh + 清单声明 bin.dsh/bin)。而官方桌面运行时里 dsh web 的 CLI 入口是运行时自带的 …\app.asar\dsh\node_modules\@deepseek-ai\dsh-desktop-host\lib\cli.js——该包没有 bin 字段、包名也不同,反查永远返回 null,执行器 2ms 内如实失败 spawn-failed(面板显示「安装执行失败」),web profile 里爱生活对单品的「安装 / 升级」全部走不通。现在:反查同时认官方桌面运行时布局——向上找到包名 @deepseek-ai/dsh-desktop-host 时,入口必须正好是该包的 lib/cli.js;npm 布局、无关包、入口对不上返回 null 的既有语义不变,仍不猜 PATH 上的 dsh 命令名。桌面使用范围走管理器路,行为不变。
  • 测试:新增 tests/issue-237-cli-entry-desktop-runtime.test.mjs 4 例(桌面运行时布局返回入口;同包但入口不是 lib/cli.js 返回 null;npm 布局不回归;无关包仍 null)。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1935 例:1934 过 / 0 失败 / 1 跳过;npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(87 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm run docs:log:check 过(6 条缺行警告是既有缺行,只警告不失败);npm publish --dry-run 181 文件(dsh-plugin-update@0.18.35,513.1 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true)。

v0.18.34

Choose a tag to compare

@FeatherHunter FeatherHunter released this 20 Oct 04:39

Fixed

  • #236 管理器路:宿主在移除步失败时把在册的插件从 dsh.profile.bundles 摘掉却不回滚,更新后插件页显示「关闭」,只能用户手动启用(真机 2026-10-20 04:12 六个 life- 批量更新全部 bundle-in-use):宿主 removeBundle 对在册的 bundle 是「先 selectBundle(false)(立即写盘)再重载卸载」,活 fiber 没卸掉就抛 bundle-in-use;change() 只把结果标 failed,那次取消在册没有任何回滚——本包看到「移除失败」时,插件已经装着、却不在 dsh.profile.bundles 里(词义见 CONTEXT.md 的「在册」),重启也不会加载。现在:①#201 的拓扑探测顺带留下「移除前是否在册」快照;移除前探到在册的包在移除失败/超时(含 removeBundle 同步抛错)后先带时限复探一次,确认已被移出才用宿主 setBundleEnabled(name, true) 尽力恢复,恢复后再带时限复探一次,只有明确回到在册才说「已恢复在册」;恢复被拒说「恢复在册未成功」;前置结论不明、恢复调用超时或宿主没有 setBundleEnabled 时说「无法确认」——绝不把「可能」写成事实,也不宣称一次没发起的尝试;②装前本来未在册(#201 先恢复在册再移除)的失败不恢复*,回到用户原本状态,不擅自改拓扑;③老宿主没有 listBundles / setBundleEnabled、或探测抛错时一律不猜拓扑、行为与从前一致,只把 bundle-in-use 的误导提示(「请先在宿主插件页停用后再更新」——方向反了)换成可操作的两步(重启 DSH 后重试、插件页显示关闭就重新启用);④原失败码、reason/hostCode 与详情语义不变,尾部追加 ≤300 字的事实(已恢复在册 / 恢复在册未成功 / 无法确认三档);原文超预算时按上限截断原文、优先保住这条事实;更新本身仍是失败,绝不自动重试 remove→install、也不把补偿成功当成更新成功。⑤移除失败路径多一发 setBundleEnabled 与至多三次 listBundles(两次复探各 ≤5s);恢复调用额度取 max(剩余配方额度, 终止宽限) 再给一次终止宽限,成功路径的调用次数与总上界不变。
  • 测试:新增 tests/issue-236-manager-remove-failure-restore.test.mjs 11 例(在册失败后恢复并复探、恢复被拒如实报、恢复后复探仍关闭不谎报、装前未在册不二次改拓扑、老宿主无探测不猜、探测抛错不猜、移除超时仍补偿、无 setBundleEnabled 不宣称尝试、复探失效说无法确认不写事实、removeBundle 同步抛错仍补偿、长原话截断仍保住事实并守 300 字);双语基线随 bundle-in-use 提示与新事实句更新。

门禁(发版定格):npm run check 全绿——node --test tests/*.test.mjs 1931 例:1930 过 / 0 失败 / 1 跳过(主树 41f7454 + 本批发版文件上实测;一次并发全量下 tests/batch-e2e.test.mjs 的 E3b 曾红,单跑与重跑即绿,属已知负载敏感,已在两轮全量中复现并确认与本次改动无关);npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(87 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm run docs:log:check 过(6 条缺行警告是既有缺行,只警告不失败);npm publish --dry-run 181 文件(dsh-plugin-update@0.18.34,512.9 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true)。

v0.18.33

Choose a tag to compare

@FeatherHunter FeatherHunter released this 19 Oct 16:44

Changed

  • 发布线(0.18.26~0.18.32)整体并入 master,本版第一次「合体发版」(#234):这一线修的 #215~#232(缺席目标不再被旧失败任务判 recovery-required、批量面板三处显示缺陷、批次停下清自家排队占位、批次续跑换号重提、在装按钮动效、旧账本误导帧、忙时队列行文案、本体排第一)原先只活在发布分支,master 上没有——现已并入 master,master 成为唯一可信基线。合并以 master 的目录拆分重构(src/ 拆进 core/ host/ panel/ shared/ 域目录)为底座,把发布线的行为改动逐条移植进拆分后的文件;公开面(导出名字与形状)零变。本版与 0.18.32 的差别只有一处:npm 上此前最新的 0.18.32 只含发布线、不含重构,0.18.33 两者都有,运行时行为与 0.18.32 相同。
  • 内部目录拆分(#220/#221/#222/#225~#230)首次随包发出:src/ 从平铺目录拆进四个域目录——core/(服务、账本、队列、批运行)、host/(宿主电话、批量宿主、环境与能力)、panel/(单面板、批量面板、主题与视图模型)、shared/(哈希等共用件);旧路径保留兼容壳(如 src/host.ts、src/panel.ts、src/host-batch.ts、src/panel-batch.ts),包出口的 11 个子路径与导出名一字未改。事件契约、日志行字段、诊断键均未变;域目录与壳的对应关系见 docs/adr/。

Fixed

  • #233 CHANGELOG 在 master 线上缺 0.18.26~0.18.28 三节:这一线的正文曾只留在 GitHub Release;现按票拆回各自版本节(0.18.26=#215/#214/#213、0.18.27=#216、0.18.28=#217、0.18.29=#209/#208/#211/#218),正文一字未改,只做整行搬移。0.18.26 一节的原发版全量例数未逐字留存,故该节门禁行如实写「不编数字」。

门禁(发版定格):npm test 1920 例:1919 过 / 0 失败 / 1 跳过(主树 84e4aeb + 本批发版文件上实测);npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(87 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm run docs:log:check 过(6 条缺行警告是既有缺行,只警告不失败);npm publish --dry-run 181 文件(dsh-plugin-update@0.18.33,510.4 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true)。

v0.18.32

Choose a tag to compare

@FeatherHunter FeatherHunter released this 19 Oct 15:35

Changed

  • 版本号推进,供集成方(爱生活 / OpenCode 调色板 / IM 机器人 / dsh-prompt)统一跟随:代码与 0.18.31 相同,无行为变化;本版只把「当前已验收的修复线」作为一个明确的依赖版本发出来,避免各集成仓继续钉在旧引擎上(旧仓里还有钉 0.18.25 的)。

门禁(发版定格):npm test 1904 例:1903 过 / 0 失败 / 1 跳过(主树 c564ccd + 本批发版文件上实测);npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(52 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm publish --dry-run 111 文件(dsh-plugin-update@0.18.32,482.0 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true)。

v0.18.31

Choose a tag to compare

@FeatherHunter FeatherHunter released this 19 Oct 15:35

Fixed

  • #232 批量面板在「有安装在跑」时把已在批次队列里的行说成「加入队列」,还挂「(上次未完成)」,像要手动逐个入池:真机(2026-10-19 17:53 desktop,爱生活 0.3.74 + 更新器 0.18.30)一次「全部更新」里六家其实早已全部进批次账本(batch.json,单消费者逐个装),但未轮到行的按钮在忙时退化成「加入队列」、状态词带「(上次未完成)」,顶部还写「另有 N 个可选择『加入队列』等待」——看起来像生产者-消费者池要人手逐个投递;更早还同屏出现过「已自动继续上次未完成的更新(剩余 0 个)」与「继续上次未完成的更新(剩余 0 个)」。现在:①忙时轮次中未轮到行不再给行内按钮(本来就在队列里、会自动轮到),状态词改「已在队列 · 会自动依次安装」;②原「加入队列」动作更名「优先安装」,只在失败重试等真属于本行的场景出现;③「(上次未完成)」只保留给失败重试行,pending / ready / skipped 不再加尾注;④顶部提示按队列事实写「正在安装 N 个;队列里还有 M 个,会自动依次安装。」;⑤「继续上次未完成的更新(剩余 N)」只在真有未完成行时渲染,剩余 0 不再出现。事件契约无变化。
  • #231 重启后首帧先渲染上一轮旧账本,「已安装完成」「N 个已是最新」挂在屏幕上,几秒后自动检查才改口:真机(2026-10-19 重启后)看到六家写「已安装完成,无需操作」、页脚「1 个待重启 · 6 个已是最新」,但磁盘其实已是新版本、只差重启且仍在自动复查中——旧快照先上屏、新结论后到,用户读到的是过期事实。现在:自动检查在飞且尚无结论时,旧账本不再摆作结果——已完成 / 已最新行显示「正在查询版本信息」,总账改「正在按最新版本重新检查…」;仅在没有未完成行时进入这个复查帧(有未完成批次照旧走执行态),检查成功或失败落地后立即恢复原渲染。事件契约无变化。
  • 测试:新增 tests/issue-232-batch-queue-copy.test.mjs 4 例(忙时轮次中行无按钮且文案为「已在队列」、忙时全屏不出现「加入队列」、旧账本复查帧与「剩余 0」不渲染、「优先安装」只在批量外场景出现);tests/panel-batch.test.mjs / tests/issue-71-batch-rows.test.mjs / tests/batch-detail-dialog-108.test.mjs 同步更新期望;双语字典新增两个键(batch.row.batch-queued / batch.ledger.checking,全表 413 个 key 仍全 draft: true);全量 node --test tests/*.test.mjs 1904 例:1903 过 / 0 失败 / 1 跳过(一次全量并行下状态采样竞态曾红 1 例,单跑与重跑即绿,属已知负载敏感);npm run typecheck 与 npm run gate:bilingual 三道硬门禁过。

门禁(发版定格):npm test 1904 例:1903 过 / 0 失败 / 1 跳过(主树 c0ce71f + 本批发版文件上实测);npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(52 个源文件、413 个 key、17 错误码、20 diag 键,违规 0);npm publish --dry-run 111 文件(dsh-plugin-update@0.18.31,482.0 kB 压缩 / 1.7 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(413 个 key 仍全是 draft: true)。

v0.18.30

Choose a tag to compare

@FeatherHunter FeatherHunter released this 19 Oct 15:35

Fixed

  • #219 批量「正在安装…」按钮出现两枚转圈;爱生活本体被强制排在批量面板最后一行:真机(2026-10-19 desktop,爱生活 0.3.73 + 更新器 0.18.29)看到在装按钮左右各一枚旋转指示——单面板主题对任何 [aria-busy="true"] 按钮自带一枚 ::after 转圈,批量在装按钮自己还有一枚 ::before 转圈,两枚叠在同一按钮里;同时用户要求「爱生活本体」作为批量面板第一行,而 orderTargets 一直强制 selfKey 排最后(自更新安全口径),本体只能出现在最后一行。现在:①批量 CSS 对在装按钮显式关掉主题那枚 ::after(content:none;display:none),整屏只保留一枚 ::before 转圈(aria-busy 语义保留,prefers-reduced-motion 照旧关动效);②orderTargets / createBatchSession 新增 selfOrder?: 'last' | 'first'(默认 'last',自更新安全行为不变),createMultiHostUpdate 新增 selfOrder 选项透传到会话创建与追加目标,集成方传 'first' 后本体占第一行。事件契约无变化。
  • 测试:新增 tests/issue-219-self-order-first.test.mjs 4 例(orderTargets 默认最后 / first 第一 / 未知 selfKey 不影响顺序 / 去重;createBatchSession 的 order 与 entries 首行;批量宿主 selfOrder:'first' 时第一行是本体、缺省仍最后;批量 CSS 关停 ::after 且 ::before 转圈只一条);全量 node --test tests/*.test.mjs 1900 例:1899 过 / 0 失败 / 1 跳过;npm run typecheck 与 npm run gate:bilingual 三道硬门禁过。

门禁(发版定格):npm test 1900 例:1899 过 / 0 失败 / 1 跳过(主树 1ef7a47 + 本批发版文件上实测);npm run typecheck 过;npm run gate:bilingual 三道硬门禁过(52 个源文件、411 个 key、17 错误码、20 diag 键,违规 0);npm publish --dry-run 111 文件(dsh-plugin-update@0.18.30,480.2 kB 压缩 / 1.6 MB 解包);gate:bilingual:release 的第四道照旧如实红、非阻断(411 个 key 仍全是 draft: true)。