[ISSUE-0032] scan:protocol 基础设施 + open-results lost message¶
v0.10.47 第三轮 agent 提了 3 个 meta-tool 建议,本 issue 实施 Tool 2(dead listener 检测)。 实施过程中扫到真孤儿协议
open-results,连带删除整个死 messager 模块。
工具:pnpm scan:protocol¶
pnpm scan:protocol # 完整扫
pnpm scan:protocol -- --save-baseline # 存基线
pnpm scan:protocol -- --diff # 仅显示新增(pre-commit 用)
pnpm scan:protocol -- --strict # CI 强制
扫的内容¶
- dead listener:注册了但全仓 0 发送方(孤儿 listener)
- lost message:发送了但全仓 0 注册方(黑洞消息)
设计决策(实测后)¶
只检测 webext-bridge 的显式 onMessage('name', ...) 模式。
不扫 background 的 if (type === 'name') —— 因为这种"router-dispatch"在项目里
也用于 page-log type 字段、payment status 等数据语义,false positive 太多
(实测 22/23 router-dispatch 命中都是 FP)。
代价:只能抓 webext-bridge 协议的孤儿。chrome.runtime 协议的 lost message (如本次的 open-results)当 lost 报,因为我们故意不扫 router-dispatch listener。
收益:ISSUE-0031 has-new-data 模式能稳定抓。
也排除 method call onMessage¶
# 要求前面是行首/空白/非 word.char(不能是 `.onMessage`)
(r"(?:^|[^a-zA-Z_.])onMessage\(\s*['\"]([^'\"]+)['\"]", ...),
排除 websiteMessager.onMessage(...) 等自定义 messager 的 method call
(那些发送方在 injected.js / page context,我们扫不到)。
工具首次跑发现 1 真 lost:open-results¶
🟡 lost message 'open-results'
📍 src/sections/content-search/index.tsx:98 (chrome-runtime)
📍 src/sections/content-search/index.tsx:257 (chrome-runtime)
验证:
- src/utils/messager-extension.ts:5 注册 schema
- src/entrypoints/background/ 0 个 handler 真处理它
- 历史遗留 — content-search 发送 fire-and-forget,无效 call
连带发现:整个 messager-extension.ts 是死代码¶
extensionMessager 唯一定义:
- setup-popup-toggle → 只有 schema + background:105 注释掉的发送
- open-results → 有发送但无 handler
全仓 grep extensionMessager 只 export 和注释 — 整个 module 0 实际用。
修法¶
| 文件 | 改了什么 |
|---|---|
src/utils/messager-extension.ts |
🗑️ 删整个文件(死 module) |
src/sections/content-search/index.tsx:98 |
删 sendMessage('open-results')(无 handler) |
src/sections/content-search/index.tsx:253-260 |
清掉已注释的"查看结果"按钮 |
pre-commit hook 第 4 路集成¶
# v0.10.48 pre-commit 现在四轨:
# 1. docs/ 改动 → docs:check
# 2. background/scrape-* 改动 → scan:mv3 --diff
# 3. src/sections/components/hooks 改动 → scan:react --diff
# 4. 含 onMessage/sendMessage/messager- 的 .ts(x) 改动 → scan:protocol --diff
改动文件¶
| 文件 | 改了什么 |
|---|---|
scripts/scan-protocol-orphan.py 🆕 |
新工具 |
package.json |
+ scan:protocol script + version 0.10.47 → 0.10.48 |
scripts/hooks/pre-commit |
+ 第 4 路 scan:protocol --diff |
src/utils/messager-extension.ts |
🗑️ 删 |
src/sections/content-search/index.tsx |
清 dead sendMessage + 注释代码 |
.protocol-orphan-baseline.json 🆕 |
基线(19 lost = 都是 chrome-runtime 协议,已知合规) |
验证¶
- ✅
pnpm compile0 错 - ✅
pnpm build8.47s - ✅
pnpm scan:protocol0 dead + 19 lost(已纳入基线) - ✅ pre-commit 现在四轨
触发流程¶
写代码涉及 onMessage / sendMessage
↓
pre-commit 自动跑 scan:protocol --diff
↓
新增 dead listener / lost message?
↓ 是 → 阻止 commit + 提示 3 选项(修/重存基线/--no-verify)
↓ 否 → 放行
历史价值¶
ISSUE-0031 Bug F1 (has-new-data dead listener) 是这套工具诞生的契机。
本工具上线后,类似的"架构漂移 / 协议失配"在 commit 阶段就能拦截。
累计基础设施¶
v0.10.25 pnpm docs:check / docs:rebuild 文档治理
v0.10.42 pnpm scan:mv3 MV3 持久化陷阱
v0.10.43 scan:mv3 + baseline diff + pre-commit
v0.10.46 pnpm scan:react React lifecycle 陷阱
v0.10.48 pnpm scan:protocol 协议失配(本 issue)
pre-commit 现在 4 轨自动校验:docs / mv3 / react / protocol。