在 kimi-code 仓库里创建或更新 PR 时使用:如何写出让 reviewer 只读描述就能从逻辑和架构上理解改动的 PR 描述,包括核心思路与结构图、"行为变化与受影响人群"表、可视化大纲,以及 UI/UX 变化的截图和录屏。
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
为当前分支创建或更新 PR。目标是 reviewer 只读描述,就能从逻辑和架构上理解这个改动:为什么存在、核心思路是什么、改完后系统长什么样、现有用户会失去什么,以及该从哪里开始看代码。
读 PR 模板:
Read(.github/pull_request_template.md)
找到或创建 PR:
gh pr view --json url,number,title,state 2>/dev/null。git status --short --branch 和当前分支上的提交。gh pr create 创建 PR。收集解释改动所需的上下文:
git diff main...HEAD)和足够的周边代码,理解行为与归属。gh pr view 拿元数据和改动文件列表。按模板各节写描述。描述用用户当前使用的语言,行为变化表也一样;只有三样固定:PR 标题保持英文 Conventional Commit,changeset 保持英文(见 gen-changesets skill),节标题沿用模板原文。
Resolve #<number>,再补一句背景。解决办法留给 Code Changes。N/A。步骤已在 issue 里的写 See linked issue。N/A。说明根因,以及这是根本修复还是绕过。机制要靠时序或状态才说得清的,用图,见"代码变更的可视化大纲"。发布描述:
gh pr edit <number> --body-file <path> 或 gh pr create --body-file <path>。这一节回答一个问题:合入之后,现有用户会失去什么。这个仓库过去的回归大多来自没人回答这个问题,而不是逻辑错误。
判据:改动前能工作的任何输入(配置键、环境变量、命令行参数、provider 响应形态、旧版本写的会话数据、客户端请求、hook 载荷)改动后必须行为不变,除非这里明确声明了变化并给出退路。
写法:
列出 diff 改变的每一个可观测行为,一行一个。包括你认为"不变"但分支条件挪动了的:新增的条件会不会先于旧条件命中既有输入;删除或收窄的分支改动前谁在走。内部包会打进 CLI 发布包,"内部"不等于用户无感。表格用 PR 描述的语言,下面的示例用英文只是示意形状:
| Behavior | Before | After | Who relies on the old behavior | Escape hatch |
|---|---|---|---|---|
reasoning parsing when reasoning_details is an array | string reasoning also read | string ignored | OpenAI-compatible gateways that send both (OpenRouter dialect) | none |
人群要具名,不要写"部分用户"。从 .agents/skills/review-pr/surfaces.md 里取:客户端(TUI、print 模式、desktop 与 web、VS Code、ACP、SDK)、provider 方言、平台、配置状态、数据年代、外部脚本。
改了 prompt 文本(system prompt、工具描述、提醒)的,每一句单独成行,写清这句改动前约束了什么行为、谁依赖、现在由什么来约束。"没有测试引用这句"不是无影响的证据。
替换或绕过旧路径的(移植、runtime binding、协议替换),额外列出旧路径的功能清单:它认哪些环境变量、有哪些兜底、接受哪些输入,以及每一项在新路径里的位置。
确实没有可观测变化的,写 None,并说明证据:哪些分支、默认值、契约文件没动。
表后面列受影响模块与每一行对应的测试覆盖。默认翻转或删除行为的,必须有一条测试把未被改动的人群的旧行为钉住,并且 changeset 要写明用户失去了什么,见 gen-changesets skill;没有退路的,在 PR 里请维护者显式拍板。
Code Changes 要让 reviewer 不看 diff 也能从逻辑和架构上理解这个 PR。先判断要不要先建立整体理解:
需要时按下面的顺序写,没有内容的部分省略:
概念 | 回答什么问题 | 本 PR 之后。决策 | 选择 | 没选 | 理由。只列 reviewer 可能会问"为什么不……"的决策。理由要来自作者的真实考虑;对话和 issue 里没提过、只是你从代码推断出来的理由,先和用户确认再写。sequenceDiagram 沿新路径讲一遍。结构图已经讲清流程时省略。之后再用可视化大纲讲具体变化。有了阅读指南,文件树 diff 通常可以省掉。
不论 PR 大小都遵守:
<details><summary>标题</summary>…</details> 折叠块;</summary> 后空一行,里面的 Markdown 才会渲染。讲具体变化时用结构化视图,并配一两句话说明因果。用能说清实现的最小组合,没变的类别不要列。
逻辑或算法变化用伪代码 diff:
on(save)
- write content
+ if content is unchanged
+ return cached result
+ write new content
+ invalidate cache运行时控制流用调用树 diff:
submitForm
createSession
persistPrompt
+ expandSkillMention
launchAgent
- navigateToSession
+ navigateToSession
+ subscribeToEvents文件职责变化用浅层文件树 diff:
src/
├── commands/
+│ └── show-me.ts # expands the slash command
├── sessions/
-└── transport.ts
+└── transport/
+ ├── client.ts
+ └── stream.ts组件或 UI 结构变化用树 diff:
<SessionPage>
useSessionEvents()
<SessionToolbar>
+ <RunSkillButton />
<SessionTimeline>
+ <SkillResultCard />组件之间的交互和时序用 Mermaid sequenceDiagram,解释 bug 机制时尤其有用:
sequenceDiagram
participant User
participant UI
participant Daemon
User->>UI: choose command
UI->>Daemon: send expanded prompt
Daemon-->>UI: stream result分支判断用 flowchart,状态迁移用 stateDiagram-v2:
flowchart TD
A[tool output arrives] --> B{hides 2+ lines?}
B -- yes --> C[collapse with hint line]
B -- no --> D[show all lines]关键数据结构或类型变化用对应语言的代码块:
interface SessionEvents {
onTurnStart(cb: (turn: Turn) => void): void;
onTurnEnd(cb: (turn: Turn) => void): void;
}可视化大纲的规则:
diff 块。text 块给出完整目标形状。用户看到的东西变了,就让 reviewer 直接看到改动前后的样子,不要只用文字描述。涉及范围:TUI(apps/kimi-code/src/tui、packages/pi-tui)、apps/vis/web、apps/vscode/webview-ui、dist-web 同步,以及用户可见的文本输出(print 模式输出、报错文案、命令行帮助)。
选能说清变化的最低成本形式:
| 形式 | 适用 | 怎么得到 |
|---|---|---|
终端文本快照(text 代码块) | TUI 的布局、文案、对齐、折叠截断 | 用 packages/pi-tui/test/virtual-terminal.ts 渲染,或真实运行后复制屏幕内容 |
| 截图 | 颜色、主题、web 和 webview 界面 | 真实运行后截屏 |
| GIF | 只用于交互和时序:按键、展开折叠、流式输出、动画 | 本机有录屏工具就录;没有就退回关键帧截图或文本快照,不为此装工具 |
写法:
## Screenshots / Recordings。.tmp/pr-media/,不提交进 PR 分支。上传:gh 不能把图片传成 GitHub 附件,所以把素材推到 origin 上专门放图的孤立分支 pr-assets/<number>。在仓库根目录执行:
url=$(git remote get-url origin)
dir=$(mktemp -d) && cp .tmp/pr-media/<files> "$dir"/ && cd "$dir" && git init -q
git fetch -q "$url" pr-assets/<number> 2>/dev/null && git reset -q --soft FETCH_HEAD # 分支已存在就接在后面
git add -A && git commit -qm "chore: add screenshots for #<number>"
git push -q "$url" HEAD:refs/heads/pr-assets/<number>
git rev-parse HEAD # 链接里的 <sha>引用写成 。
<sha>,不要用分支名:追加的提交只含新文件,按分支名引用会让旧图失效。pr-assets/ 分支,不建 release。CI 只在 main 和 release/* 的 push 上触发,这类分支不会跑 CI。MoonshotAI/kimi-code
a2afdbc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.