关于 bubbletea-code-review
bubbletea-code-review 是面向 Bubble Tea Go 应用的代码审查技能,检查架构、更新处理、渲染和组件。它要求报告问题前提供证据并完成验证。
主要功能
- 01检查 Update 中的阻塞 I/O
- 02审查模型和消息处理
- 03检查渲染与 Lipgloss 样式
- 04检查组件组合与尺寸
- 05依据参考资料验证问题
适用场景
- 01审查 Bubble Tea 拉取请求
- 02检查 Update 逻辑中的阻塞操作
- 03审计组件更新和布局
- 04减少误报的审查问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ existential-birds/ beagle --skill bubbletea-code-review安装后在 Claude Code 中输入/bubbletea-code-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/bubbles-components.mdcomposition.mdelm-architecture.mdmodel-update.mdview-styling.md详细介绍
BubbleTea 代码审查
严格门槛(按顺序)
只有在每项通过条件均客观成立后才能继续(减少针对 tea.Cmd 的误报和缺乏依据的阻塞声明):
| 门槛 | 通过条件 |
|---|---|
| G1 — 防止误报 | 在记录有关 tea.Cmd 返回值、Update 上的值接收者或嵌套子组件 Update 的问题之前,你已略读下方的非问题部分,或已阅读 references/elm-architecture.md。 |
| G2 — 阻塞/可疑 I/O 的证据 | 每条严重/主要问题都注明文件路径 + 行号(或简短引用片段),以证明存在阻塞调用、在错误位置调用 huh.Form.Run 或其他所指称的反模式,而非假设。 |
| G3 — 验证 | 发布审查结果前,你已对每条拟议的问题应用 review-verification-protocol。 |
快速参考
| 问题类型 | 参考资料 |
|---|---|
| Elm 架构、作为数据的 tea.Cmd | references/elm-architecture.md |
| 模型状态、消息处理 | references/model-update.md |
| 视图渲染、Lipgloss 样式 | references/view-styling.md |
| 组件组合、Huh 表单 | references/composition.md |
| Bubbles 组件(列表、表格等) | references/bubbles-components.md |
重要:避免误报
请先阅读 elm-architecture.md! 最常见的审查错误是把正确模式标记为 bug。
非问题(不要标记)
| 模式 | 正确原因 |
|---|---|
return m, m.loadData() | tea.Cmd 会立即返回;运行时会异步执行 |
Update() 上的值接收者 | 标准 BubbleTea 模式;模型按值返回 |
m.child, cmd = m.child.Update(msg) | 正常的组件组合 |
返回 tea.Cmd 的辅助函数 | 创建命令描述符,不会在 Update 中执行 I/O |
tea.Batch(cmd1, cmd2) | 运行时会并发执行命令 |
实际问题(需要标记)
| 模式 | 错误原因 |
|---|---|
在 Update 中调用 os.ReadFile() | 会阻塞 UI 线程 |
在 Update 中调用 http.Get() | 网络 I/O 会造成阻塞 |
在 Update 中调用 time.Sleep() | 会冻结 UI |
在 Update 中执行 <-channel(阻塞) | 可能会无限期阻塞 |
在 Update 中调用 huh.Form.Run() | 阻塞调用 |
审查清单
架构
- Update() 中没有阻塞 I/O(文件、网络、休眠)
- 不得将返回
tea.Cmd的辅助函数误判为阻塞 - 所有异步操作都使用命令
模型与 Update
- 模型不可变(Update 返回新模型,而不是修改模型)
- Init 返回合适的初始命令(或 nil)
- Update 处理所有预期的消息类型
- 处理 WindowSizeMsg,以支持响应式布局
- 使用 tea.Batch 执行多个命令
- 正确使用 tea.Quit 退出
视图与样式
- View 是纯函数(无副作用)
- Lipgloss 样式只定义一次,而不是在 View 中定义
- 键绑定使用 key.Matches 和 help.KeyMap
组件
- 正确传递子组件更新
- Bubbles 组件在初始化时设置尺寸
- Huh 表单通过 Update 循环嵌入(而非调用 Run())
关键模式
模型必须不可变
// BAD - mutates model
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.items = append(m.items, newItem) // mutation!
return m, nil
}
// GOOD - returns new model
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newItems := make([]Item, len(m.items)+1)
copy(newItems, m.items)
newItems[len(m.items)] = newItem
m.items = newItems
return m, nil
}
用于异步操作/I/O 的命令
// BAD - blocking in Update
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
data, _ := os.ReadFile("config.json") // blocks UI!
m.config = parse(data)
return m, nil
}
// GOOD - use commands
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, loadConfigCmd()
}
func loadConfigCmd() tea.Cmd {
return func() tea.Msg {
data, err := os.ReadFile("config.json")
if err != nil {
return errMsg{err}
}
return configLoadedMsg{parse(data)}
}
}
样式只定义一次
// BAD - creates new style each render
func (m Model) View() string {
style := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("205"))
return style.Render("Hello")
}
// GOOD - define styles at package level or in model
var titleStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("205"))
func (m Model) View() string {
return titleStyle.Render("Hello")
}
何时加载参考资料
- 首次审查 BubbleTea → elm-architecture.md(避免误报)
- 审查 Update 函数逻辑 → model-update.md
- 审查 View 函数和样式 → view-styling.md
- 审查组件层级 → composition.md
- 使用 Bubbles 组件 → bubbles-components.md
审查问题
- Update() 是否没有阻塞式 I/O?(而不是:“cmd 辅助函数是否会阻塞?”)
- Update 中的模型是否不可变?
- Lipgloss 样式是否只定义一次,而非在 View 中定义?
- 是否处理了用于调整大小的 WindowSizeMsg?
- 是否使用 help.KeyMap 记录了键绑定?
- Bubbles 组件的尺寸是否正确?
评论
支持 Markdown