bubbletea
GoとBubbleteaフレームワークを使ったターミナルUIの構築に特化したスキルです。ElmアーキテクチャベースのTUIアプリ、デュアルペインレイアウト、アコーディオンモード、マウス/キーボード操作、Lipglossによるスタイリング、再利用可能なコンポーネントの実装に活用できます。実プロジェクトで検証済みのテンプレート、エフェクトライブラリ、レイアウトパターンを収録しています。
description の原文を見る
Build terminal user interfaces with Go and Bubbletea framework. Use for creating TUI apps with the Elm architecture, dual-pane layouts, accordion modes, mouse/keyboard handling, Lipgloss styling, and reusable components. Includes production-ready templates, effects library, and battle-tested layout patterns from real projects.
SKILL.md 本文
Bubbletea TUI開発
GoとBubbletea、Lipglossで美しいターミナルユーザーインターフェースを構築するための本番対応スキルです。
このスキルを使用する場合
このスキルは以下の場合に使用します:
- Goで新しいTUIアプリケーションを作成する
- 既存アプリにBubbleteatコンポーネントを追加する
- レイアウト/レンダリングの問題を修正する(境界線、配置、オーバーフロー)
- マウス/キーボード操作を実装する
- デュアルペインまたはマルチパネルレイアウトを構築する
- ビジュアルエフェクト(メタボール、波、虹色テキスト)を追加する
- TUIレンダリングの問題をトラブルシューティングする
コア原則
重要: レイアウト実装前にreferences/golden-rules.mdの4つのゴールデンルールを必ず確認してください。これらのルールはTUIレイアウトで最も一般的で煩雑なバグを防ぎます。
4つのゴールデンルール(概要)
- 常に境界線を考慮する - パネルレンダリング前に高さ計算から2を差し引く
- 境界線付きパネルで自動折り返しを使用しない - 常にテキストを明示的に切り詰める
- マウス検出をレイアウトに合わせる - 水平方向はX座標、垂直方向はY座標を使用
- ピクセルではなくウェイトを使用する - 比例レイアウトは完璧にスケーリングする
詳細と例はreferences/golden-rules.mdを参照してください。
新しいプロジェクトの作成
このプロジェクトには本番対応のテンプレートシステムが含まれています。このスキルが新しいプロジェクトにバンドルされる場合(new_project.sh経由)、既存のテンプレート構造を出発点として使用してください。
プロジェクト構造
すべての新しいプロジェクトは以下のアーキテクチャに従います:
your-app/
├── main.go # エントリーポイント(最小限、~21行)
├── types.go # 型定義、構造体、列挙型
├── model.go # モデル初期化とレイアウト計算
├── update.go # メッセージディスパッチャー
├── update_keyboard.go # キーボード操作
├── update_mouse.go # マウス操作
├── view.go # ビューレンダリングとレイアウト
├── styles.go # Lipglossスタイル定義
├── config.go # 設定管理
└── .claude/skills/bubbletea/ # このスキル(バンドル)
アーキテクチャガイドライン
main.goは最小限にしてください(エントリーポイントのみ、~21行)- すべての型を
types.goに記載します(構造体、列挙型、定数) - キーボードとマウス操作を専用ファイルに分ける
- 1ファイル、1つの責務
- 最大ファイルサイズ: 800行(理想は500行以下)
- YAMLで設定し、ホットリロード対応
利用可能なコンポーネント
references/components.mdの再利用可能なコンポーネント完全カタログを参照してください:
- パネルシステム: シングル、デュアルペイン、マルチパネル、タブレイアウト
- リスト: シンプルリスト、フィルター付きリスト、ツリービュー
- 入力: テキスト入力、複数行、フォーム、オートコンプリート
- ダイアログ: 確認、入力、進捗、モーダル
- メニュー: コンテキストメニュー、コマンドパレット、メニューバー
- ステータス: ステータスバー、タイトルバー、パンくず
- プレビュー: テキスト、Markdown、シンタックスハイライト、画像、16進数
- テーブル: シンプルテーブルとインタラクティブテーブル
エフェクトライブラリ
テンプレートで利用可能な物理ベースのアニメーション:
- 🔮 メタボール - ラバランプ風の浮遊ブロブ
- 🌊 波エフェクト - サイン波歪み
- 🌈 虹色サイクリング - アニメーション色グラデーション
- 🎭 レイヤーコンポジター - ANSI対応マルチレイヤーレンダリング
使用例と統合パターンについてはreferences/effects.mdを参照してください。
レイアウト実装パターン
レイアウト実装時は以下の順序に従ってください:
1. 利用可能なスペースを計算する
func (m model) calculateLayout() (int, int) {
contentWidth := m.width
contentHeight := m.height
// UI要素を差し引く
if m.config.UI.ShowTitle {
contentHeight -= 3 // タイトルバー(3行)
}
if m.config.UI.ShowStatus {
contentHeight -= 1 // ステータスバー
}
// 重要: パネル境界線を考慮する
contentHeight -= 2 // 上+下の境界線
return contentWidth, contentHeight
}
2. ウェイトベースのパネルサイジングを使用する
// フォーカス/アコーディオンモードに基づいてウェイトを計算
leftWeight, rightWeight := 1, 1
if m.accordionMode && m.focusedPanel == "left" {
leftWeight = 2 // フォーカスされたパネルは2倍のウェイト
}
// ウェイトから実際の幅を計算
totalWeight := leftWeight + rightWeight
leftWidth := (availableWidth * leftWeight) / totalWeight
rightWidth := availableWidth - leftWidth
3. テキストを切り詰めて折り返しを防ぐ
// 折り返しを防ぐための最大テキスト幅を計算
maxTextWidth := panelWidth - 4 // -2境界線、-2パディング
// レンダリング前にすべてのテキストを切り詰める
title = truncateString(title, maxTextWidth)
subtitle = truncateString(subtitle, maxTextWidth)
func truncateString(s string, maxLen int) string {
if len(s) <= maxLen {
return s
}
return s[:maxLen-1] + "…"
}
マウス操作パターン
マウスイベント処理前に常にレイアウトモードをチェックしてください:
func (m model) handleLeftClick(msg tea.MouseMsg) (tea.Model, tea.Cmd) {
if m.shouldUseVerticalStack() {
// 縦スタックモード: Y座標を使用
topHeight, _ := m.calculateVerticalStackLayout()
relY := msg.Y - contentStartY
if relY < topHeight {
m.focusedPanel = "left" // 上のパネル
} else {
m.focusedPanel = "right" // 下のパネル
}
} else {
// 横並びモード: X座標を使用
leftWidth, _ := m.calculateDualPaneLayout()
if msg.X < leftWidth {
m.focusedPanel = "left"
} else {
m.focusedPanel = "right"
}
}
return m, nil
}
避けるべき一般的な落とし穴
一般的な問題の詳細な解決策はreferences/troubleshooting.mdを参照してください:
❌ しない: 境界線付きパネルに明示的なHeight()を設定する
// 悪い例: 配置ずれの原因となる可能性がある
panelStyle := lipgloss.NewStyle().
Border(border).
Height(height) // これはしないでください!
✅ する: コンテンツを正確な高さに埋める
// 良い例: コンテンツ行を正確な高さに埋める
for len(lines) < innerHeight {
lines = append(lines, "")
}
panelStyle := lipgloss.NewStyle().Border(border)
テストとデバッグ
パネルが配置されていないか、正しくレンダリングされていない場合:
- 高さのアカウンティングを確認 - contentHeight計算がすべてのUI要素+境界線を差し引いているか確認
- テキストの折り返しを確認 - すべての文字列がmaxTextWidthに切り詰められているか確認
- マウス検出を確認 - X/Y座標の使用がレイアウト方向と一致しているか確認
- 境界線の一貫性を確認 - すべてのパネルで同じ境界線スタイルを使用しているか確認
完全なデバッグ決定木はreferences/troubleshooting.mdを参照してください。
設定システム
すべてのプロジェクトはYAMLの設定とホットリロードをサポートしています:
theme: "dark"
keybindings: "default"
layout:
type: "dual_pane"
split_ratio: 0.5
accordion_mode: true
ui:
show_title: true
show_status: true
mouse_enabled: true
show_icons: true
設定ファイルは以下から読み込まれます:
~/.config/your-app/config.yaml(ユーザー設定)./config.yaml(ローカルオーバーライド)
依存関係
必須:
github.com/charmbracelet/bubbletea
github.com/charmbracelet/lipgloss
github.com/charmbracelet/bubbles
gopkg.in/yaml.v3
オプション(必要に応じてgo.modのコメントを外す):
github.com/charmbracelet/glamour # Markdownレンダリング
github.com/charmbracelet/huh # フォーム
github.com/alecthomas/chroma/v2 # シンタックスハイライト
github.com/evertras/bubble-table # インタラクティブテーブル
github.com/koki-develop/go-fzf # ファジーファインダー
リファレンスドキュメント
すべてのリファレンスファイルは必要に応じて段階的に読み込まれます:
- golden-rules.md - クリティカルなレイアウトパターンとアンチパターン
- components.md - 再利用可能なコンポーネント完全カタログ
- troubleshooting.md - 一般的な問題とデバッグ決定木
- emoji-width-fix.md - 複数のターミナル(xterm、WezTerm、Termux、Windows Terminal)間での絵文字配置のための実証済みソリューション
外部リソース
ベストプラクティスの概要
- 常にレイアウト実装前にgolden-rules.mdを確認する
- 常に柔軟なレイアウトにウェイトベースのサイジングを使用する
- 常にテキストを明示的に切り詰める(自動折り返しに頼らない)
- 常にマウス検出をレイアウト方向に合わせる
- 常に高さ計算で境界線を考慮する
- 決して境界線付きLipglossスタイルに明示的なHeight()を設定しない
- 決してマウスハンドラーでレイアウト方向を想定しない
これらのパターンに従えば、TUIレイアウトバグの90%を回避できます。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- ggprompts
- リポジトリ
- ggprompts/tfe
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/ggprompts/tfe / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。