/00. Claude Plugins
A Claude Code plugin is a folder of skills, agents, hooks, and slash commands that Claude installs per project. 28 plugins, 68 skills here.
/plugin marketplace add aiocean/claude-plugins
/plugin install <plugin-name>@aiocean-plugins
Skills load when their description matches your message, hooks fire on
tool-call events, agents spawn on the Agent tool. Idle plugins cost
nothing — browse plugins or read the guides.
Folders
Articles
- Send books to your BOOX from the terminal01
- Patching Claude Code: rebalance the built-in prompts (and more)02
- Install Claude Code plugins in two commands03
- My CLAUDE.md04
- Three Claude Code primitives, three different jobs05
- Writing CLAUDE.md: the sections that actually help06
- aio-architect-advisor07
- aio-architect-reference08
- aio-atlassian09
- aio-boox10
- aio-browser-cookie11
- aio-bun-fullstack-setup12
- aio-catch-me-up13
- aio-code-review14
- aio-dashboard-design15
- aio-debug16
- aio-discover17
- aio-doc-writer18
- aio-dream19
- aio-epub-analyze20
/02. aio-tui
/plugin install aio-tui@aiocean-plugins
aio-tui
The Bubbletea v2 reference you need before the compiler tells you what you did wrong.
Building a terminal UI with Bubbletea is not hard once you understand the Elm Architecture. The problem is that the framework's rules are strict and silent: return a new model from Update, never mutate state, never build heavy clients in Init, never double-wrap a Cmd. Violating these rules produces compile errors that point at the wrong line, or runtime behavior that makes no sense until you understand the underlying model.
This plugin encodes those rules — and the non-obvious production patterns that follow from them — against the v2 API (charm.land/bubbletea/v2, charm.land/lipgloss/v2), so Claude applies them correctly the first time rather than iterating through the common mistakes.
Install
/plugin install aio-tui@aiocean-plugins
Requirements
- Go (any recent version)
The architecture
Every Bubbletea app is three functions and a state struct:
Model (state) → Update (handle messages) → Model → View (render) ...
Init() returns a command to run at startup. Update() receives messages and returns a new model plus an optional next command. View() is a pure function of model state — it returns a tea.View struct (v2: the frame string lives in .Content, and alt-screen/mouse modes are fields on that struct). The skill includes a complete, runnable v2 skeleton that demonstrates all three correctly, including async data fetching, auto-refresh via tick, and keyboard handling.
What the skill covers
v2 API differences — the changes that bite: View() returns a tea.View struct (not a string); alt-screen and mouse mode are fields on that struct, not tea.NewProgram options; key messages are tea.KeyPressMsg with printable input in .Text and named keys via .String(); mouse is an interface whose concrete type is the action (tea.MouseClickMsg, tea.MouseReleaseMsg, tea.MouseWheelMsg, tea.MouseMotionMsg).
Architecture rules — the invariants that prevent the most common Bubbletea mistakes: where to initialize heavy clients (in main(), not Init()), how to build text input by appending msg.Text, the correct func() tea.Msg signature for Cmds, and why tea.Batch is the right way to fan out multiple commands.
Restrained styling — one accent color reused for active borders, cursor rows, focus glows, and spinners. Everything else is a small fixed set: dim for muted/inactive, danger/warn for destructive vs cautionary. A status-code-to-color mapping keeps this discipline even for multi-state badges.
Layout gotchas — .Width(n) is the outer width (border + padding included, not content width); floating boxes need no Background fill because canvas layers are opaque at the cell level; color-profile detection must happen in main() before tea.NewProgram takes over the terminal to avoid race conditions.
Mouse hit-testing — click location is geometry, not line-counting. The skill teaches the layout() reverse-mapping approach: derive a layout struct from terminal size and scroll offset, render into it, then reverse-map click coordinates through the same struct. Counting \n characters to find a click's row drifts the moment chrome changes and is explicitly the anti-pattern the skill warns against.
Testing — four layers, cheapest first — unit-testing Update/View without a terminal; golden snapshots of View().Content for layout regression; teatest/v2 (the v2-correct import path) for multi-step interaction tests; and render-to-image + agent verdict for visual assertions that string comparisons cannot make.
Deep patterns reference — for full generalized v2 code, the skill points to references/patterns.md (async render with a gen-counter stale guard, layout geometry as a single source of truth, per-row performance caching, column alignment with Unicode/emoji, filter/search mode) and references/gold-monitor.md with the complete examples/gold-monitor/ working example.
The gotchas section
The skill contains a dedicated section of named, explained mistakes with working and broken code side by side:
- Heavy client initialization in
main(), notInit() tea.KeyPressMsgwith.Textfor printable input — not the v1tea.KeyMsg{Runes}func() tea.Msgvs double-wrapping a Cmd- Mouse location via geometry, not
\n-counting - Color-profile detection before
tea.NewProgramto avoid races teatest/v2import path (not the v1 path, which compiles against the wrongtea.Model/Viewshapes)
Trigger phrases
"build a TUI", "Bubbletea", "Bubbletea v2", "terminal UI", "lipgloss", "lipgloss v2", "Elm architecture", "Go terminal app", "interactive CLI", "charmbracelet", "charm.land", "TUI dashboard", "two-pane layout", "terminal mouse", "async render"
Skills (1)
- aio-tui — Build interactive terminal UIs with Go + the charmbracelet v2 stack (charm.land/bubbletea/v2, charm.land/lipgloss/v2) — Elm architecture, restrained styling, an…