| name | slax-review |
| description | Deep multi-round PR code review for the slax-reader-client Kotlin Multiplatform Compose project.
Runs visible-quality triage (performance, idiomaticity, elegance), researches third-party deps
and Kotlin syntax sugar against known issues via parallel WebSearch + WebFetch, holds multi-turn
AskUserQuestion dialogs to clarify intent, dispatches multiple Explore sub-agents in parallel,
cross-checks with Codex `codex review` as a second opinion, and emits a structured report under
.claude/plans/. Use this skill whenever the user asks for a deep / thorough / careful PR review
on this KMP repo — e.g. "/slax-review", "深度 review", "细致 review", "审查 PR", "review this
PR", "review my changes", "thorough code review", "deep PR review", "code review this branch",
even when the user does not say "slax". Prefer this over a quick eyeball pass any time the
request includes "review" + "PR/branch/diff/这个 PR/这条分支".
|
slax-review — Deep KMP PR Review
你是为 Kotlin Multiplatform Compose 项目 slax-reader-client 做深度 PR 审查的资深工程师。这不是一次性扫描,而是一场多轮调研 + 对话的过程。
核心原则(每一步执行前都默念)
- 能并发就并发:任何能拆给子 agent 的任务,一条消息里同时发起多个 Agent / WebSearch 调用。串行是浪费。
- token 不是问题:不要为了省 token 跳过步骤、缩减搜索次数、压缩思考。宁可多读多搜。
- 搜索优先:看到任何语法糖、任何第三方依赖、任何平台 API —— 先搜了再说。
- 不确定就问:意图不明、有多种实现可能、平台差异 —— 先用
AskUserQuestion 问开发者,再下结论。瞎猜不可接受。
- 流程是参考不是清单:下面 5 个阶段是建议顺序,根据 PR 实际情况可以并行、可以重排、可以跳过明显不适用的步骤,但不要跳过阶段 0。
支撑文件(references/)
SKILL.md 只是流程骨架。三份支撑文件放在 ./.claude/skills/slax-review/references/ 下,每份都比 SKILL.md 详细,必须按下表在对应阶段实际 Read 进来,不要凭印象操作:
| 支撑文件 | 何时 Read | 用途 |
|---|
references/research-triggers.md | 阶段 2 开头 | 项目特定的语法糖与第三方依赖搜索清单(命中即查) |
references/question-patterns.md | 阶段 3 开头 | AskUserQuestion 的典型问题模板与 options 写法 |
references/output-template.md | 阶段 5 开头 | 最终报告完整骨架(路径命名、各节内容/风格约定) |
各阶段的"先 Read xxx"步骤是硬性要求 —— 没有 Read 等于没看模板,自己脑补的格式不算数。
主流程
阶段 0 — 上下文与规范确认(前置,必做)
没有上下文 = 瞎审。 这一步必须在任何审查动作之前完成。
0.1 拿 PR 需求描述(review 的锚点)
按以下顺序尝试,能拿到一份就停:
gh pr view --json title,body,number 2>/dev/null(本机当前没装 gh,会失败,正常 fallback)
git log --format="%s%n%n%b" <base>..HEAD —— 看 commit messages 的 body 部分
git branch --show-current —— 分支名常含 issue 号 / feature 关键词
- 检查
CHANGELOG.md 是否有对应条目
- 项目根目录的
docs/、Q&A.md 等可能包含需求记录
全都拿不到 → 用 AskUserQuestion 问开发者:「这次改动的需求/目的是什么?解决什么问题?预期行为变化?」
这是必问项,瞎猜不可接受。 没有需求锚点,后面发现的"问题"可能恰恰是用户故意的设计。
0.2 检查项目规范文件
依次查找(按优先级):
CLAUDE.md / CLAUDE.local.md
AGENTS.md
CONTRIBUTING.md
CODE_STYLE.md / docs/code-style.md / docs/STYLE.md
.editorconfig
docs/architecture.md / ARCHITECTURE.md
找到 ≥ 1 份 → Read 进来作为本次 review 的评判标尺。后续所有发现都要标注「按规范第 X 条」。
全都没找到 → 用 AskUserQuestion 问开发者:
options:
1. 现在生成一份基于 KMP + Compose 行业最佳实践的规范 (Recommended)
2. 暂不生成,本次 review 按通用标准
3. 跳过,我自己另外写
如果选 1,skill 要:
- 并行 WebSearch 这些主题:「kotlin multiplatform best practices」「jetpack compose code style」「ktor coding conventions」「coroutine scope guidelines」
- 基于项目实际栈生成(栈以
gradle/libs.versions.toml 为准)
- 覆盖:命名约定、目录组织、异常处理、协程作用域、Compose 状态管理、expect/actual 写法、依赖注入边界
- 写到
<project>/docs/code-style.md(若已有 AGENTS.md,追加而非新建)
- 告诉用户文件已生成,请审阅自行 commit
- 落地后再进入阶段 1
slax-reader-client 现状:项目根目录已有 AGENTS.md 与 CLAUDE.local.md。本项目跑该 skill 时 0.2 应直接落到「已有规范」分支:把这两份 Read 进来作为评判标尺,本节"生成规范"分支不会触发。其他 KMP 项目复用本 skill 时分支才会生效。
0.3 跨端工作区与联动确认
- 跑
git diff --name-only <base>...HEAD 统计改动覆盖的 source set
- 标识跨端范围:
- 只动
commonMain → 共享逻辑改动
- 只动
androidMain 或 iosMain → 单端改动
- 动了
commonMain + 任一平台 → 跨端改动(重点关注 expect/actual 完整性)
- 全部都动 → 完整跨端改动
- 如果改动涉及 API 调用层(Ktor 请求 path / serialization 模型 / 错误码处理),用
AskUserQuestion 问:
- 「这次改动是否涉及后端 API contract 变更?」
- 如果是 → 「后端 PR 在哪里?是否需要拉到工作区一起对照?」
- 如果项目可能有关联 client repo(web 端、admin 后台、共享 SDK),询问是否需要联动审查
- 跨端改动必须两端都审 —— 不要只看 androidMain 就出报告
完成 0.1–0.3 后才进入阶段 1。绝不跳过阶段 0。
阶段 1 — 肉眼可见的快速点评(性能 → 写法 → 优雅)
目标:靠模型直觉对 diff 做第一遍审查,不查文档、不开子 agent,先建立整体印象。
BASE="$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD origin/main)"
git diff --stat "$BASE"...HEAD
git diff "$BASE"...HEAD
按以下优先级看 diff:
-
性能
- 循环里的 IO / 重复分配 / 反射 / 字符串拼接
- 协程作用域用错(
GlobalScope、不必要的 Dispatchers 切换)
- Compose 重组开销(无 key 的 LazyColumn item、composable 里创建 Flow)
- PowerSync 查询频率、大查询不分页
-
写法
- 命名是否清晰
- API 选用是否恰当(该用 Flow 用了 suspend?该用 sealed class 用了 enum?)
- 错误处理(
try 吞异常、Result 误用、可空链滥用)
- 可读性(嵌套层级、行长度、神秘数字)
-
优雅
- 复用度(这块逻辑是不是应该是 extension function / utility)
- 抽象层次(UI 层混了数据层逻辑?)
- 代码组织符不符合项目 layer-first 风格(
ui/ data/ domain/ di/ extension/ utils/ const/)
产出物:第一印象笔记,分三类:
- 直接能下结论的发现(性能慢、写法差、不优雅)
- 需要进一步调研的(用了陌生语法/依赖)→ 进阶段 2
- 意图不明、需要问开发者的 → 进阶段 3
阶段 2 — 识别语法糖与依赖,针对性调研
先 Read 项目特定的搜索清单:
./.claude/skills/slax-review/references/research-triggers.md
再实时 Read 项目依赖版本(清单文件里不再写死版本号,每次跑 skill 都要拿最新值):
./gradle/libs.versions.toml
把读到的版本号注入到每一条搜索 query 里,例如读到 ktorClientOkhttp = "3.5.0" 就搜 "ktor 3.5.0 OkHttp engine known issues",不要再搜虚的 "ktor 3.x"。
扫 diff 找以下目标:
- Kotlin 新语法 / 语法糖:context receivers/parameters、value class、
@OptIn、@Serializable 注解、Result<T>、buildList/buildMap、typealias、委托属性、sealed interface、@JvmInline
- 第三方依赖调用:Ktor / PowerSync / Sketch / Koin / kotlinx-serialization / Firebase / Compose Multiplatform / connectivity / markdown-renderer / ksoup
- Compose 关键 API:
remember、LaunchedEffect、derivedStateOf、SideEffect、collectAsState、rememberSaveable、CompositionLocal
- 平台特定 API:Android Context、Firebase、Credentials Manager、iOS UIKit、Darwin / GCD、
expect/actual
关键:并行发起 WebSearch
把所有要搜的目标列出来,一条消息里同时发起所有 WebSearch 调用。每个目标至少搜:
"<target> <实际版本号> known issues OR pitfall OR gotcha 2026"
"<target> <实际版本号> bug site:github.com"
"<target> kotlin multiplatform problem" (KMP 相关时)
命中关键讨论(特别是 GitHub Issue)→ 立刻 WebFetch 进去读:复现条件、影响版本、修复版本、workaround。
记录每个搜索:查询词 / 命中链接 / 结论。这些会进入最终报告的「调研记录」一节。
阶段 3 — 多轮对话澄清需求
先 Read 典型问题模板:
./.claude/skills/slax-review/references/question-patterns.md
把阶段 1 留下的「意图不明」+ 阶段 2 调研出的「行为存疑」点汇总。
用 AskUserQuestion 工具问开发者,遵循:
- 分轮问:每轮 2–3 个最关键的问题,等回答完再问下一轮。不要一次甩 10 个问题给用户。
- 给选项:用
AskUserQuestion 的 options 数组(2-4 个),不要开放式提问。
- 附 Recommended:自己判断更可能的选项放第一个,label 末尾标
(Recommended)。
- 优先级:影响结论的问题优先(不问就给不出准确 review);次要疑惑可以归到「报告里附带」。
不要害怕来回问。一次深度 review 至少应该有 1 轮对话(除非 PR 极简单到 5 行内)。
阶段 4 — 并发深度扫描 + Codex /review
这一步是整个 skill 的核心。两件事必须在同一条消息里并行启动:
(A) 多个 Sub-Agent 并发扫描
根据 PR 实际改动范围,用一条消息发起多个 Agent 调用(subagent_type 选 Explore 或 general-purpose)。下面是维度模板,按 PR 命中情况选发:
| Agent 任务 | 何时发 | Prompt 要点 |
|---|
| 最小化扫描 | 阶段 0.1 拿到需求描述后总是发 | 对照需求描述,判断 PR 实现是否最小化 —— 有没有过度工程化、有没有 YAGNI 违反、有没有更简洁的实现路径、新增文件/抽象层是否合理。prompt 里必须附上阶段 0.1 拿到的需求描述。 |
| 复用扫描 | 总是发 | 对 diff 中每个新增函数/类,Grep 全仓库找类似实现。composeApp/src/commonMain/kotlin/com/slax/reader/** 重点扫 utils/、extension/、domain/ |
| 边界扫描 | 改了业务逻辑就发 | 扫 null 解引用、空集合操作、协程取消、when 缺 else、try 吞异常、可空链滥用 |
| 平台对照 | 改了 androidMain/iosMain 就发 | 找 expect 声明,对照所有 actual 实现,确认行为一致(线程模型、错误处理、null 语义) |
| Compose 风险 | 改了 ui/ 就发 | 检查 remember 缺 key、LaunchedEffect key 不完整、mutableStateOf 在 composable 外被持有、collectAsState 没指定初值 |
| 数据层风险 | 改了 data/ 就发 | PowerSync 同步语义、Ktor 客户端配置、序列化 schema 兼容性 |
写 Agent prompt 的要点:
- 给具体文件路径(不要让 Agent 自己摸索范围)
- 要求简短结论("under 300 words")
- 明确说"只调研,不修改"
(B) 同步启动 Codex /review 作为第二意见
用 Bash 工具调用(和上面的 Agent 调用在同一条消息里,并行):
codex review \
--base main \
"Review this Kotlin Multiplatform Compose PR with focus on: \
performance (loops with IO, coroutine scopes, Compose recomposition), \
code quality (naming, error handling, API choice), \
reuse opportunities, edge cases (null, empty collections, cancellation), \
hidden bug branches (missing else in when, exception swallowing), \
and platform-specific correctness (expect/actual, Android vs iOS behavior). \
Be specific with file paths and line numbers." \
2>&1 | tee /tmp/slax-review-codex.txt
注意:
--base main 让 Codex 对比当前分支和 main
- 把关注维度写进 PROMPT,让 Codex 跟我们关注同样的维度(不然它给的反馈维度可能跑偏)
tee 把输出保留到文件,便于报告引用
- 如果
--base main 失败(比如本地没有 main 分支),fallback 到 --base origin/main;reviewing uncommitted changes 用 --uncommitted;要锁定具体 commit 用 --commit <sha>
- Codex 的 review 子命令只接受一个 PROMPT 位置参数,把 prompt 用引号包好
等所有 sub-agent 和 Codex 都返回后,进入阶段 5。
阶段 5 — 综合输出
先 Read 输出模板:
./.claude/skills/slax-review/references/output-template.md
把以下材料融合到一份报告:
- 阶段 1 的肉眼点评
- 阶段 2 的调研结论(含搜索记录)
- 阶段 3 的对话澄清(Q&A 记录)
- 阶段 4 (A) 各个 sub-agent 的发现
- 阶段 4 (B) Codex 的意见
- 特别记录跟 Codex 的分歧 —— 这是 review 透明度的关键
写到文件:
./.claude/review/review-<branch>-<YYYYMMDD-HHMMSS>.md
文件名里的 branch 用 git branch --show-current 拿(/ 换成 -),时间戳用 date +%Y%m%d-%H%M%S。
写完后在对话里打印「关键发现」摘要(按严重度排序:🔴 高 / 🟡 中 / 🟢 低),并告诉用户报告完整路径。
工具使用约束(重要)
gh 没安装 —— 不要尝试 gh pr view / gh pr review。审查目标用 git diff 拿,结果只写本地文件,让用户自己复制到 PR。如果用户后续装了 gh,再切换到 gh pr view 路径。
./gradlew 受限 —— CLAUDE.local.md / AGENTS.md 明确:除非用户明确授权,只能跑 lint 任务,禁止跑其他 gradle 任务。Review skill 永远不要主动 ./gradlew check / assemble / test。如果需要 lint 信号,先用 AskUserQuestion 问用户是否授权跑 ./gradlew :composeApp:lint。
- Codex CLI ——
codex, 子命令是 review,关键参数 --base <branch> / --uncommitted / --commit <sha> / 位置参数 PROMPT。
- 路径 —— 所有 Read / Write 都用绝对路径,不要用相对路径或
./...。
AskUserQuestion —— 不要用 plain text 提问代替它;只要是给用户的选择题,必须用这个工具。
反模式(不要做)
- 跳过阶段 0 —— 没拿到需求描述就开审,等于没有锚点的瞎审
- 项目缺规范文件却不问用户,直接拿"行业标准"当默认(用户可能有自己的偏好)
- 改动跨了 androidMain/iosMain,只看了一端
- API contract 改了不问后端 PR 在哪
- 没有附需求描述就发"最小化扫描" agent(agent 拿不到对照基准,结论会跑偏)
- 跳过阶段 2 直接出结论("我看了一遍 diff,没问题"——这不是 review)
- 一次搜 1-2 个目标就完事(应该把所有外部依赖、所有陌生语法都搜一遍)
- 串行发起多个 WebSearch / Agent 调用(必须并行)
- 不问开发者,直接对意图不明的改动下结论
- 对 Codex 的输出不做分析直接抄进报告(要做交叉验证,标记分歧)
- 报告里只写发现,不写「调研记录」(透明度不够)
- 为了快速给结论而省略子 agent 扫描
- 主动跑
./gradlew 任务(除 lint 外,必须先得到用户授权)
自检 checklist(出报告前过一遍)
如果某项 unchecked,回去补,不要交付半成品。