Skip to content

v1.0.17 — 键盘双倍输入修复 + 批量关标签(每个 id 都有交代)

Latest

Choose a tag to compare

@caob23 caob23 released this 13 Oct 10:53

v1.0.17

三件事:browser_press 一次按键插入两次(表单被提交两遍)修好了、browser_tabs close 现在能一次关一批且每个 id 都有交代(合并 PR #11)、以及批量关闭的超时分类修正——合并进来之后我自己复审时发现的缺口。

这一版改了 extension/——扩展必须重装,只更新插件不够。

1. 键盘:一次按键只许插入一次(issue #14)

cmdPress 在 Input.dispatchKeyEvent 的 keyDown 已经带 text(Chrome 据此就已插入字符)之后,又补发一个独立的 char 事件——两处各插一次:

  • 输入框里按一下 x → 得到 xx
  • 按一下 Enter → 表单提交两次
  • browser_type 的 submit:true 走同一条通道,所以提交类操作会做两遍

同一个仓库里这个坑早就在 cmdInput 的 type 模式修过,注释就写着「an explicit char event duplicates the input」,CHANGELOG v1.0.2 也记了一笔——只有 cmdPress 没跟上,从 v0.2.0(be6c302)一路留到现在。取报告方(@wangyuncai2024)的方案 B:删掉 char 分支,与 cmdInput 一致(他的方案 A 改 rawKeyDown 保留 char,实测等价,但仓库里会同时存在两种写法)。

同一函数里另外两处也一并修了:

  • 组合键现在真能用:"Ctrl+A" / "Shift+ArrowRight",或 modifiers: ["ctrl"]。以前扩展层支持 modifiers 而工具层没暴露,写 "Shift+ArrowRight" 只是静默无效(不报错也不选中文本)。shift 单独存在时照常打字,ctrl/meta/alt 抑制插入。
  • 认不出的键名改为抛错,不再带着 undefined 的 keyCode/code 照样派发、再回一句 pressed:true 让调用方以为成功。

为什么以前测不出来:报告方的判断成立——verify/ 对 browser_press 只测过模型可见文本,整个仓库没有任何一条按键事件计数。新增 verify/verify_press_events.mjs(19 项)第一次按派发次数测:单字符 / Enter / 数字键 / type 模式逐字符都必须「插入型事件恰好一个、不得有 char」,外加组合键解析与未知键名零派发。这个台子可以传入另一份 background.js:对修复前的版本跑同一批断言红 12 项并如实报出 keyDown,char,keyUp,所以它不是跟着新代码写的空断言。

2. 批量关标签页(合并 PR #11,@long-arm-ape)

browser_tabs action:"close" 收 tabId(一个)或 tabIds(一批)。一批在链路上只发一条命令(扩展侧 tabs.closeMany → 一次 chrome.tabs.remove([ids])),不再 N 次往返中间掉线。结果统一为 {requested, closed, alreadyGone, failed:[{tabId,error}]},单数与批量同一个形状(cmdTabsClose 直接委托给 cmdTabsCloseMany)。以前的 for (id of ids) await tabs.close(id) 第一个失败就抛出,会把已经真的关掉的标签藏起来,模型以为什么都没发生于是重放整批。alreadyGone(早就没了)算幂等成功;并且不猜——remove 之后逐个复查,「还在」的才进 failed,被拒但其实已关掉的如实进 closed。

他们顺手挖出了我们自己的对账缺陷:verify_surface.mjs 的命令名正则 [a-z_.]+ 会把 tabs.closeMany 截成 tabs.close,新命令名进不了对账——已放宽。

3. 合并后的复审抓到的缺口:tabs.closeMany 没登记为写操作

effectState 是按命令名判写/读的。批量关闭是新命令名,没进写清单就会静默落到 not_started,于是超时报文会写着「effectState=not_started:这次调用没有动到页面,重试安全」——而实际可能已经关掉了一半标签。这正是本仓库这一路在修的那类不诚实,只不过这次出现在我刚合并进来的代码上。

修法:登记为写操作,并加一条对账护栏——从 extension/background.js 的 COMMANDS 表解析出全部 26 条命令,每条要么在写清单里,要么在测试侧显式登记为读/幂等并写理由;新增命令不做判断就直接红。护栏做过变异测试:临时摘掉 tabs.closeMany 的登记,两条断言立刻点名该命令并 FAIL。

关于 1.0.16

1.0.16 只存在于 npm(没有 tag、没有 Release、没有在任何地方推荐安装)。原因是发布流程走到一半——npm publish 之后、建 Release 之前——上面第 3 条缺口被发现,而 npm 的版本不可改写。为避免有人按确切版本号装到那个半修好的版本,已对 1.0.16 下 npm 弃用提示指向本版。请直接装 1.0.17。

测试台

npm run verify 331 → 350(键盘台)→ 381(PR #11 自带 31 项)→ 385 项断言,exit 0。CI 在合并提交上 ubuntu 与 windows-latest 两个 job 都 success。

还没验证的部分(说实话)

  • 键盘修复没有在真实 Chrome 上跑过。 断言来自「有状态假 chrome.debugger + 真实扩展代码」,测的是我们能控制的那一层(派发序列);「Chrome 收到带 text 的 keyDown 之后到底插几个字符」是浏览器的行为——报告方给了裸 CDP 三组对照支持方案 B,但那是他的环境。你重装扩展后请按一次 x 看是否只出一个字符、按一次 Enter 是否只提交一次;若仍翻倍,请在 #14 直接回我,我改按方案 A(rawKeyDown + char)。
  • 批量关闭的 closed / alreadyGone / failed 划分在假 chrome.tabs 上验过,真实 Chrome 里「remove 之后复查」的时序仍需一次实机确认。
  • 前面几版留下的:归组的视觉效果、AX 快照在真实页面上的表现与耗时(扩展升到本版后即可测 AX)。

资产校验和

不附 .sha256 文件,直接列在这里:

文件 大小 SHA-256 MD5
DSH-Browser-Control-v1.0.17.zip 50969 B bb117b0f0f8c597540eb21e64916062d8db5f4d8e9a40dbae011b19efeb708e9 bcd59b1f2bdf7ff40d06e8191f72782a
dsh-browser-control-plugin-v1.0.17.zip 172353 B b774702ee1e4cb8c0ccf0a24bb198ff7e6b2830cce1910c8c66d504165faf64f 6dc197519825d8ea04a68d40fedfcbac

两份都验过:文件头 504b0304、条目全用正斜杠、CRC 全过;插件包含 cordis.patch.yml(dsh.bundle.patch 指向它),扩展 manifest 版本 1.0.17、权限 debugger, tabs, tabGroups, storage, alarms。

安装(两步都要做)

  1. 扩展:下载 DSH-Browser-Control-v1.0.17.zip → 解压 → chrome://extensions → 开发者模式 → 先移除旧版再「加载未打包的扩展程序」,确认版本显示 1.0.17。不重装扩展,键盘修复不会生效。
  2. 插件:dsh plugin --profile <你的profile> add @caob23/dsh-browser-control@1.0.17。刚发布 24 小时内可能撞 dsh 自带的包龄闸门,报 ERR_PNPM_NO_MATURE_MATCHING_VERSION 等满即可;报 ERR_PNPM_NO_MATCHING_VERSION 才是源没同步,那一次加 --registry=https://registry.npmjs.org/,或用上面的离线插件包。
  3. 自检:http://127.0.0.1:9777/ 状态页应显示已连接;在输入框让 agent 按一次字母,页面里只应多出一个字符;browser_tabs close 传 tabIds:[a,b] 时结果会把每个 id 的去向写出来。