跳转至

[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 compile 0 错
  • pnpm build 8.47s
  • pnpm scan:protocol 0 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。