🧰 百宝箱审查报告

审查日期:2026-05-26 → 05-27 范围:toolbox/ 下全部 47 个项目(7 棋类 + 4 牌类 + 13 单人 + 3 派对 + 8 工作 + 10 生活 + suika 一款特例 + recipes 列表页) 模式:审查期间 AUDIT_MODE 开启,本报告由主对话整合 7 组并行 Explore agent 的发现 + 主对话亲自复核而成 处理建议:先看「🛑 必修」清单,再看「⚠️ 建议改」清单。误报已剔除并备注。


📌 2026-05-27 处理状态

状态 commit
P0① fruit-ninja 缺 games-shell 误报 — mount 在外部 fruit-ninja.js:3104-3146,后端排行榜已有真实玩家分数(curl 验证:进击的Jason 3171)
P0② blackjack/solitaire nick_taken alert 已修 — 24 文件统一改 NickPrompt.showError 2437307
P1 41 文件 / 201 处 :hover 未守卫 已修 — scripts/wrap-hover.py 一次性脚本批处理 838ccc6
P2 forest 计时器后台漂移 已修 — visibilitychange visible 时立即 tick() 对齐 wall-clock 9843ee8
audit 脚本三条误报启发式 已修 — bare_dollar 跳 $\d+/\d+$ 分数 / bare_url 跳整行含 [.] 钓鱼示例 / backend_pulse 分类 HTTP 错误码 a54ee7b
P3 drawing 房主转移 UI 不阻塞,后端早已支持,无投诉,延后
P3 citation alert/confirm → 内联 功能正常仅 UX,延后
P3 converter 扩展单位(体积/能量) 看用户需求,延后
P4 tax-bracket / countdown / goals / timemachine 边界 数据时效/边界,每年人工巡一次
P4 pitch 麦权失败引导 小 UX 优化,延后

关键教训(已写进 复核备注 末尾):Explore agent 遇到 HTML 引入外部 JS 必须主动跟读那个 JS,否则会把“看不见”误报为“缺失”——本轮 fruit-ninja / tiaoqi 都是同一类错。


⚡ TL;DR

类别 严重 🛑 建议 ⚠️ 误报已剔
棋类 7 0 4(chess/tiaoqi/feixingqi hover;chess auto-join 1 处) tiaoqi“无 auto-join”——其实逻辑在外部 JS,已确认有
牌类 4 1(blackjack/solitaire alert 阻塞;后述合并) 1 0
单人 A 7 0 7(2048/snake/minesweeper/runner/leap hover;2048/snake alert;suika DPR) suika“未统一”——故意独立架构
单人 B 7 1(fruit-ninja 完全缺 games-shell) 5 breakout“无续局”——tagline 本就没声称续局;typing“无 scoreAsc”——默认 false 就是它想要的
派对 3 0 3(dare/werewolf/drawing hover) dare innerHTML“XSS”——p.id 是自动生成的 P1..PN,不接受用户输入
工作 8 0 8(各类细节,无阻塞 bug) 0
生活 10 0 5(pitch 麦权 UX / countdown 节日到 2030 / goals localStorage 版本 / timemachine 闰年) 0
合计 2 33 5 条已澄清

整体很健康:全站无明显安全/功能阻塞 bug,问题集中在两类:

  1. CSS :hover 未守卫 — iOS/安卓触屏长按后样式卡在 hover 态。多款游戏受影响。
  2. fruit-ninja 漏接 games-shell — 排行榜/昵称/comments/settlement 全缺。

🛑 必修(2 项)

1. fruit-ninja 完全没接入 games-shell

file: toolbox/fruit-ninja/index.html:1

参照 toolbox/breakout/index.html:365-370 的引法和 toolbox/breakout/index.html:886-913 的 mount 代码补全即可。后端 api/lb.js GAMES 字典需要加 fruit-ninja 一行(scoreAsc: false,可考虑用 mode 分桶(经典/计时/禅模式三模式))。

2. 起昵称仍走阻塞 alert()(blackjack / solitaire)

memory [[project_games_batch_2026_05]] 记录“全站 wins-leaderboard 游戏已无 prompt() 阻塞”,但这两款 leaderboard 类游戏的 nick_taken 错误处理仍是 alert。应改成「NickPrompt 卡片错误提示」(参考 reversi/guandan 的 nick_taken 处理路径:clearNickNickPrompt.refresh().show() 内联红字提示)。


⚠️ 建议改(按类目)

A. CSS :hover 未用 @media (hover: hover) 守卫

iOS/安卓 tap 后 hover 样式会粘住,需要重新 tap 别处才消。审查脚本 hover_no_media.py 设计来抓这类,每天跑。当前命中:

文件 :hover
toolbox/chess/index.html:226 .ch-promotion-choice:hover
toolbox/tiaoqi/index.html:101 .tq-corner-chip:hover:not(:disabled)
toolbox/feixingqi/index.html:145 .fxq-corner-chip:hover
toolbox/feixingqi/index.html:167 .fxq-corner-chip.locked:hover
toolbox/2048/index.html:64-75 2 处
toolbox/snake/index.html:93-104 2 处
toolbox/minesweeper/index.html:115-126 2 处
toolbox/runner/index.html:120 .overlay-btn:hover(有 @media (hover: none) and (pointer: coarse) 反向覆盖,可接受)
toolbox/leap/index.html:120 同上
toolbox/breakout/index.html:93-104 2 处
toolbox/sudoku/index.html:87 .sudoku-btn:hover
toolbox/schulte/index.html:93-104 2 处
toolbox/memory/index.html:93-104 2 处
toolbox/dare/index.html:62 .player-count-chips button:hover
toolbox/dare/index.html:290-301 2 处
toolbox/werewolf/index.html:41-46 至少 10 处 (.ww-btn.*:hover / .preset-btn:hover / .counter-btn:hover 等)
toolbox/drawing/index.html:30-33 多处 .dg-btn.*:hover

推荐统一改法:每个文件 CSS 顶部加一个块:

@media (hover: hover) {
  /* 把所有 :hover 规则搬进这块 */
}

(或者按 runner/leap 的反向写法:保留 :hover,但在 @media (hover: none) and (pointer: coarse) { ... } 内把这些选择器的 hover 副作用重置回默认。两种都行。)

B. 棋类对战

C. 单人游戏 B 组

D. 工作 8 款

E. 生活 10 款


✅ 整体良好的项目

复核确认无重大问题:


📋 修复优先级建议

优先级 任务 估时
P0 fruit-ninja 补齐 games-shell(引脚本 + Leaderboard.mount + NickPrompt + Settlement + 后端注册 fruit-ninja gameId) 30-45 分钟
P0 blackjack / solitaire 起昵称 alert → NickPrompt 错误态 15 分钟
P1 17 个 :hover 未守卫文件统一加 @media (hover: hover) 包裹(或同等 (hover: none) and (pointer: coarse) 反向写法) 1 小时(可脚本化批量处理)
P2 forest 计时器换 performance.now() + Page Visibility API 防漂移 20 分钟
P3 drawing 补房主转移 UI(后端已支持) 30 分钟
P3 citation 阻塞 alert/confirm → 内联提示 15 分钟
P3 converter 扩展单位类别(体积/能量) 30 分钟
P4 tax-bracket / countdown / forest / vocab localStorage schema 升级路径 各 10-15 分钟
P4 pitch 麦权失败时引导用户去系统设置 10 分钟

🔍 复核备注(误报记录)

避免误导,记下首轮 agent 报告错的几条:

  1. tiaoqi 无 auto-join: 错。在 assets/js/games/tiaoqi.js:1556,agent 没读外部 JS。
  2. breakout 缺续局: 错。breakout tagline 本就没声称续局;agent 误读我的审查提示。
  3. typing 缺 scoreAsc: 错。默认 false 就是 WPM 排行所需。
  4. sudoku/tetris innerHTML XSS: 错。模板字符串拼的是难度标签 + 数字,无用户字符串。
  5. dare innerHTML XSS: 错。p.idtoolbox/dare/index.html:684 自动生成的 'P' + (i+1),不接受用户名。
  6. suika ”未统一“: 错。suika 是 memory 明确指定的独立架构,不套 games-shell 是设计上的对。
  7. picker XSS: 错。外部 JS 用 escapeHtml() 包了所有 innerHTML。

这些案例提醒:之后 Explore agent 审查时,遇到「外部 JS 引入」要主动跟读外部文件,否则容易把”看不见就是没有“误报为缺陷。