bubbletea-code-review について
bubbletea-code-reviewは、Bubble Teaを使ったGoアプリ向けのコードレビュー用スキルです。アーキテクチャ、更新処理、描画、コンポーネントを確認し、指摘前に根拠と検証を求めます。
主な機能
- 01Update内のブロッキングI/O確認
- 02モデルとメッセージ処理のレビュー
- 03描画とLipglossスタイルの点検
- 04コンポーネント構成とサイズの確認
- 05リファレンスに基づく指摘の検証
活用シーン
- 01Bubble Teaのプルリクエストレビュー
- 02Updateロジックのブロッキング処理確認
- 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 の根拠 | 重大度が Critical/Major の各指摘には、ブロッキング呼び出し、誤った場所での 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を読んでください! レビューで最もよくある誤りは、正しいパターンをバグとして指摘することです。
問題ではないもの(指摘しないでください)
| パターン | 正しい理由 |
|---|---|
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 内ではなく、一度だけ定義される
- キーバインドでは help.KeyMap とともに key.Matches を使用する
コンポーネント
- サブコンポーネントの更新が正しく伝播される
- 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 対応