Releases: Yara2090/dsh-update-center
Releases · Yara2090/dsh-update-center
Release list
v1.6.4
- 新增文档一致性检查(
test/docs.test.js,用例数 95 → 100)。这一轮里「文档里的数字过期」
是反复出现的问题——光「用例数」一项就手工改过四次(84 → 87 → 89 → 91 → 95)。现在四条
不变量由用例守着:目录里每条锚点都要跳到真实标题且文案一致、每个章节(除目录自身)都要
写进目录且顺序一致、「目录结构」树与实际文件双向对齐、文中写的用例数与实际数量一致。- 写完当场抓到一处真漏:新加的
docs.test.js自己忘了写进 README 的目录结构树。
- 写完当场抓到一处真漏:新加的
- 修正「亮点」里一处说得太满的话:「下载字节与速率」只在 npm 下提供;pnpm 的缓存布局
不同,代码刻意不显示(宁可不给,也不给一个错的数字)。原文没写这个限定。 - 接口表下面补了一句:只有「无错误」槽位始终以
null出现,其余字段在尚未发生时会整个
不出现在 JSON 里(latestVersion要检测过一次才有),取值前要先判断。
v1.6.3
- 改掉一处用词错误:中文把 npm「注册表」写成了「仓库」。 插件查的是 npm 注册表
(registry),不是代码仓库;英文侧一直写的是registry,中文侧却在 5 个文件里混用了
「仓库」,其中两处是页面上能看见的:设置页副标题「检查仓库中的新版本」、检查失败
时的提示「无法读取版本仓库」。README 开头那句「自动检测仓库上的新版本」同样错。
现在统一成「注册表」。 - 保留了三处正确的「仓库」:
.gitattributes的「仓库内存 LF」、README 与 integrity
用例里「只能重新克隆仓库」——那三处指的确实是代码仓库。 - 纯文案改动,行为零变化;用例仍为 95。
v1.6.2
- 新增前后端接口一致性检查(
test/endpoints.test.js,用例 91 → 95)。做法学自同类插件
dsh-whale-widget的tools/ci-audit.mjs——它给的理由是「前端与后端是两个各 1.5 万行的
单文件,各改一半就会在运行时静默 404,用户只看到『点了没反应』」。本插件是同样的架构、
同样的风险。三条不变量:前端调的每个动作后端都认、后端认的每个动作前端都在用、
两边路由前缀是同一个字符串。- 第二条正是冲着 1.6.0 那件事去的:那条「半撤」的重启路由如果早有这样的检查,第一天就
会被标红。验证方式是把它故意加回后端(if (action === 'stop' || action === 'restart')),
检查确实报后端有路由但前端从不调用:restart —— 半撤的残留就是这样来的。 - 检查自身带非空断言,防止「门禁腐烂」:一个什么都抽不到、于是永远通过的检查比没有更糟。
- 第二条正是冲着 1.6.0 那件事去的:那条「半撤」的重启路由如果早有这样的检查,第一天就
package.json补上标准字段:repository/homepage/bugs/main。两个同类插件
都有前三个,本插件此前一个都没有。- 没有加
peerDependencies: { react }(同类插件那样写了):本插件的浏览器半边是从
Harness 的浏览器模块表取 react(require('react')),并不从 npm 解析它,而宿主用的
是哪个版本在本机也查不到——签一个版本范围只会换来装插件时的告警,所以不签。
v1.6.1
- 修掉 1.6.0 删重启时留下的一处显示错误。 旧偏好文件里可能还躺着一条
lastLifecycle.action === "restart"的记录,它的字段形状和停止完全一样(同样有
ok/pid),照单全收会让「运行控制」卡片把一次重启说成一次停止——而
界面上的名字已经写死成「停止 Harness」了。现在读偏好时只收没有action的记录
(1.6.0 之后写的)或action === "stop"的(更早的停止记录),其余丢掉;同一份
文件里其它偏好照常读入,不会因为一条坏记录把整份设置丢了。 - 这是被问「删掉重启有没有影响别的功能」时查出来的,查法是把 v1.5.2 与 v1.6.0
放在一起做 A/B:状态快照只有lifecycle的键不同(canRestart/launcher
消失),12 条路由请求只有/restart不同(旧版 200 / 409 → 新版 404),
其余全部逐字一致——包括「脚本齐全时/stop仍返回 200 scheduled」。 - 用例 89 → 91(新增「旧的重启记录不显示」「旧的停止记录仍读入」)。
v1.6.0
- 删掉「重启」的全部残留。 1.5.0 只把界面上的按钮撤了,实现、
POST /restart路由
和一组用例都还留着——于是它成了一条谁都不走、也从没被真跑过的路径。实测触发它
(走的就是那条还活着的路由)会让服务停掉、却拉不起来:启动器每次启动前会清日志,
所以连失败现场都没留下,只能靠「服务没自己回来」这件事反推。lib/lifecycle.js只剩停止:planLifecycle/scheduleLifecycle→planStop/scheduleStop,
去掉 action 参数、-ForceRestart、-Workspace与LAUNCH_SCRIPT。resolveLifecycle不再返回canRestart/launcher;状态快照里的lifecycle
从{canStop, canRestart, stopper, launcher}收窄为{canStop, stopper}。- 路由表里没有
/restart了,访问它会得到404(这条有专门的用例守着,防止它
悄悄长回来)。 - 界面(
client.js)本来就没在用这些字段,只是清掉了三句提到「重启」的过时注释。
- 这一版真正想记下的教训不是「重启坏了」,而是「半撤」的代价。 入口撤掉之后,
剩下那半看起来是活的(有路由、有实现、有绿色用例),实际却从没被端到端验证过;
而它的失败方式是把服务停掉。要撤就撤干净,或者留一条真的有测试走通的路径。 - 用例数不变(89):删掉一条重启用例,补上一条「
/restart必须 404」的守门用例。
v1.5.2
- 修复「一键修复」可能删掉一个真实目录(数据安全)。判据
looksLikeLink此前拿
realpath(target)和target直接比字符串,而 realpath 会把整条路径规范化——
Windows 上包括大小写与 8.3 短名,任何平台都包括路径中间的任何一层链接。于是只要
target 的前缀写法不唯一,一个货真价实的普通目录就会被判成「指向别处的链接」,
而 profile-link 的修复分支正是据此决定要不要删掉它重建。现在基准改成父目录解析后的
写法:两边前缀一致,剩下的差异只可能来自 target 自己这一层,那才是「它是不是链接」
的定义。实测(空目录,前缀用别名路径):修复前repairedCount为 1、目录被换成链接;
修复后为 0、目录原样保留。 - 修复 profile 判定在同类情形下退化成「无法确定」:
discoverProfileDir里最硬的那份
证据(磁盘上的链接确实指向本插件,score 3)同样在拿一个 realpath 结果比一个未规范化的
写法,因此永远拿不到,只能退回清单去猜——而清单恰恰是坏掉时才需要自检的那部分。
现在两边都先 realpath 再比。 - 这两个问题不是新代码引入的,而是加上 CI 之后第一次在 GitHub 的 Windows runner 上
跑就暴露出来的:那里的临时目录带 8.3 短名,正好命中「路径写法不唯一」。7 条用例因此
变红,其中遇到真实目录时不硬来,如实报失败期望「不产生任何修复动作」却得到了 1——
那就是上面那次删除。 - 新增两条回归用例:用「中间层是链接」的别名路径让同一个目录拥有第二种写法,从而在任何
机器上都能确定地复现这两种情形;其中一条会真的跑一次修复,并断言那个目录还在。 - 用例 87 → 89。
v1.5.1
- 安全:版本号必须真的是版本号,才会进安装命令。
npm install --global在 Windows 上
要经 shell 执行(npm/pnpm 是.cmd包装脚本,shell: true的参数不会被转义),而注册表
返回的 dist-tag 此前只检查「是不是字符串」就被拼进了参数。现在有两道闸:读取注册表时
(applyDistTags)和安装出口本身(runUpdate)。第二道才是贴着危险动作的那道——
安全闸不能只建在调用方,而此前唯一挡住它的是浏览器半边把按钮置灰。 - 顺带收窄同一条路上的另一个入口:配置里的
registry也会以--registry=<地址>进入
命令行,现在只接受能被 URL 解析、且协议为http/https的地址,其余退回官方源。 - 新增 GitHub Actions:Ubuntu(Node 20 / 22)与 Windows(Node 22)跑同一套用例。
Windows 那一条会让test/lifecycle.test.js里的 PowerShell 冒烟测试真的执行,
其余平台上它自动跳过——那条用例正是「detached 让 PowerShell 静默退出」的产物,
只在 Windows 上跑才有意义。 - 用例 84 → 87:新增「注册表返回非版本号」「安装出口拒绝非法版本号」「注册表地址回退」。
- 拆出本文件,README 从 478 行压到 360 行;README 顶部补徽章与截图位。
v1.5.0
- 只保留「停止」,去掉「重启」。两个按钮带来的是持续困惑(「我点的是哪个、接下来会发生
什么、为什么页面回不来」),而「停止 + 用桌面快捷方式启动」本来就是同一条路径。现在界面上
只有一个动作,少一个概念就少一处误解。重启的 Host 路由保留在 API 里,界面不再暴露。 - 停止后自动尝试关闭标签页,关不掉就如实说。页面会盖一层浮层说明「服务即将关闭、这个
标签页可以关掉了」,并调用window.close();随后等一小段时间,如果代码还在跑就说明浏览器
拒绝了,于是提示按 Ctrl+W。实测 Chromium 拒绝的理由是:history.length = 2且
window.opener = false,即外部打开的标签页不允许被脚本关闭——这件事做不到就不能假装做到。 - 移除整套「旧页面自动恢复」机制(
resumeAt/loginUrl/ 轮询 / 手动重开按钮)。
它成立的前提是「服务会自己回来」,而那个前提只属于已经去掉的「重启」;连同一起移除的还有
给页面暴露带令牌地址的那条路径。 - 安装卡片上的「需要重启才生效」改为明确指引:点「停止 Harness」,再用桌面快捷方式启动。
- README 的安装说明按要求压成两种方式:纯手动(下载 → 装依赖 → 写 bundle 列表 → 重启),
或把 GitHub 地址交给 DSH 让它装。原先那种「先下载、再分两种装法、最后重启」的三段式里,
其实只有这两条路。 - 用例相应调整(84 个,去掉两个只服务于已删机制的用例)。
v1.4.1
- 修复「闪一下刷新,然后照样卡在重新连接中」。上一版让旧页面自己恢复,但排定动作的
那个进程也会立刻交出它自己的登录地址——而它几秒后就被杀掉,那个令牌已经作废。页面拿到
就跳过去,于是表现为:先有一次刷新感,接着又回到「重新连接中」,而且新页面里没有待办动作,
轮询不会再启动,只能手动开着。
现在排定动作的进程绝不交出自己的地址,只有从磁盘读到待恢复窗口的新进程才发;页面因此
会一直等到真正可用的那一刻才跳。 - 浮层上新增「立即重新打开」按钮:自动恢复之外的第二条路,用户点一下才发请求,不受任何
定时器或浏览器策略影响;服务还没起来时如实说「还没起来」,而不是装作在忙。 - 新增用例专门守住这条:排定动作的进程返回
loginUrl: undefined,后来起来的进程才返回地址
(用例总数 84 → 85)。
v1.4.0
- 停止/重启之后,旧标签页会自己恢复。此前它只会永远停在「重新连接中」:重启换了进程,
旧页面的登录凭证随之失效,而页面自己没有任何办法回来——用户既看不到新标签页,也只好手动
关掉旧页面。现在 Host 在动作排定后的 10 分钟窗口内,会在状态里带上由connection服务
签发的带令牌地址(启动时打印dsh web: …?token=…用的就是它),旧页面每 2 秒问一次,
拿到就自己跳过去完成重新登录。不需要新标签页,也不需要手动关闭。 - 带令牌的地址只在那个时间窗内提供;
connection取不到时退回手动提示,因此本插件在不带
Web 连接服务的组合里照常工作。 - 新增用例覆盖「排定动作后把恢复地址交给页面」(用例总数 83 → 84)。