一键导入
add-component
Scaffold a new Bubble Tea TUI component following lstk's UI patterns. Use when adding a new reusable UI element.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Scaffold a new Bubble Tea TUI component following lstk's UI patterns. Use when adding a new reusable UI element.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Create a GitHub pull request following lstk conventions with proper title, description, and ticket references.
Scaffold a new CLI subcommand following lstk patterns. Use when adding a new command to the CLI.
Add a new output event type to the event/sink system. Use when adding a new kind of event for domain-to-UI communication.
Review a PR against lstk architectural patterns and coding conventions. Use when asked to review a pull request.
基于 SOC 职业分类
| name | add-component |
| description | Scaffold a new Bubble Tea TUI component following lstk's UI patterns. Use when adding a new reusable UI element. |
| argument-hint | <component-name> |
| allowed-tools | Read, Write, Edit, Glob, Grep |
Scaffold a new Bubble Tea component named $ARGUMENTS.
Read these files first — they are the source of truth:
internal/ui/components/spinner.go — stateful component with Update/View patterninternal/ui/components/error_display.go — simple show/hide component driven by eventsinternal/ui/components/header.go — pure presentational component (View only)internal/ui/styles/styles.go — all style definitionsinternal/ui/app.go — how components are composed in the main App modelCreate internal/ui/components/<name>.go with:
A struct holding component state:
type <Name> struct {
// Private fields for internal state
visible bool
}
A constructor:
func New<Name>() <Name> {
return <Name>{}
}
State mutation methods that return a new copy (value receiver pattern, like Spinner):
func (c <Name>) Show(...) <Name> {
c.visible = true
// set fields
return c
}
A View method:
func (c <Name>) View() string {
if !c.visible {
return ""
}
// Render using styles from internal/ui/styles
}
An Update method (only if the component handles tea.Msg internally, like Spinner):
func (c <Name>) Update(msg tea.Msg) (<Name>, tea.Cmd) {
// Must be non-blocking
}
In internal/ui/styles/styles.go, add new style variables with semantic names:
var (
<Name>Style = lipgloss.NewStyle().
Foreground(lipgloss.Color("..."))
)
Use existing palette constants (NimboDarkColor, NimboMidColor, NimboLightColor) or standard ANSI color codes. Name styles after what they represent, not how they look.
In internal/ui/app.go:
App structNewApp()Update() to drive the componentView() at the appropriate positionCreate internal/ui/components/<name>_test.go with tests covering:
Follow the existing test patterns in spinner_test.go or error_display_test.go.
If the component is driven by a new domain event, use /add-event to create the event type first. The component should consume the event — not define it. Events live in internal/output/, not in internal/ui/components/.
If the component needs messages that are purely UI concerns (not domain events), define them in the component file with the ...Msg suffix:
type <Name>DoneMsg struct{}
These are for internal component coordination only and should not appear in internal/output/.
Update() blocking — no network calls, no file I/O, no channel waitsinternal/output/events.gointernal/output for event types and internal/ui/styles for styling)