mcpField
B
building-glamorous-tuis

building-glamorous-tuis

github.com/dicklesworthstone设计与 UI20881 次安装2 天前更新
代码仓库

关于 building-glamorous-tuis

这是一份使用 Charmbracelet 库构建终端界面的参考技能,涵盖 Shell 脚本提示交互、Go TUI、SSH 托管界面及生产实践。

主要功能

  1. 01库的选型指南
  2. 02Gum Shell 脚本提示交互
  3. 03使用 Bubble Tea 和 Lip Gloss 构建 Go TUI
  4. 04SSH 托管 TUI 模式
  5. 05生产架构与性能优化
  6. 06布局、表单、动画和测试

适用场景

  1. 01为 Shell 脚本或 Go TUI 选择库
  2. 02为脚本添加交互式提示和选项
  3. 03构建响应式多视图终端界面
  4. 04提升 TUI 性能与可靠性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dicklesworthstone/meta_skill --skill building-glamorous-tuis

安装后在 Claude Code 中输入/building-glamorous-tuis确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
advanced-patterns.md
component-catalog.md
go-tui.md
infrastructure.md
production-architecture.md
PROMPTS.md
QUICK-REFERENCE.md
shell-scripts.md

详细介绍

使用 Charmbracelet 构建精美的 TUI

快速导航 — 从这里开始

我需要……使用参考
为 shell 脚本添加提示词/微调器Gum(无需 Go)Shell 脚本
构建 Go TUIBubble Tea + Lip GlossGo TUI
构建生产级 Go TUI以上内容 + 高级模式生产级架构
通过 SSH 提供 TUI 服务Wish + Bubble Tea基础设施
录制终端演示VHSShell 脚本
查找 Bubbles 组件list、table、viewport、spinner、progress……组件目录
获取可直接复制粘贴的模式布局、表单、动画、测试快速参考 / 高级模式

决策指南

Is it a shell script?
├─ Yes → Use Gum
│        Need recording? → VHS
│        Need AI? → Mods
│
└─ No (Go application)
   │
   ├─ Just styled output? → Lip Gloss only
   ├─ Simple prompts/forms? → Huh standalone
   ├─ Full interactive TUI? → Bubble Tea + Bubbles + Lip Gloss
   │  │
   │  └─ Production-grade?  → Also add elite patterns:
   │     (multi-view, data-    two-phase async, immutable snapshots,
   │      dense, must be       adaptive layout, focus state machine,
   │      fast & polished)     semantic theming, pre-computed styles
   │                           → See Production Architecture reference
   │
   └─ Need SSH access? → Wish + Bubble Tea

Shell 脚本(无需 Go)

brew install gum  # One-time install
# Input
NAME=$(gum input --placeholder "Your name")

# Selection
COLOR=$(gum choose "red" "green" "blue")

# Fuzzy filter from stdin
BRANCH=$(git branch | gum filter)

# Confirmation
gum confirm "Continue?" && echo "yes"

# Spinner
gum spin --title "Working..." -- long-command

# Styled output
gum style --border rounded --padding "1 2" "Hello"

Gum 完整参考 → VHS 录制 → Mods AI →


Go 应用

go get github.com/charmbracelet/bubbletea github.com/charmbracelet/lipgloss
最简 TUI(复制并运行)
package main

import (
    "fmt"
    tea "github.com/charmbracelet/bubbletea"
    "github.com/charmbracelet/lipgloss"
)

var highlight = lipgloss.NewStyle().Foreground(lipgloss.Color("212")).Bold(true)

type model struct {
    items  []string
    cursor int
}

func (m model) Init() tea.Cmd { return nil }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.KeyMsg:
        switch msg.String() {
        case "q", "ctrl+c":
            return m, tea.Quit
        case "up", "k":
            if m.cursor > 0 { m.cursor-- }
        case "down", "j":
            if m.cursor < len(m.items)-1 { m.cursor++ }
        case "enter":
            fmt.Printf("Selected: %s\n", m.items[m.cursor])
            return m, tea.Quit
        }
    }
    return m, nil
}

func (m model) View() string {
    s := ""
    for i, item := range m.items {
        if i == m.cursor {
            s += highlight.Render("▸ "+item) + "\n"
        } else {
            s += "  " + item + "\n"
        }
    }
    return s + "\n(↑/↓ move, enter select, q quit)"
}

func main() {
    m := model{items: []string{"Option A", "Option B", "Option C"}}
    tea.NewProgram(m).Run()
}
库速查表
需求库示例
TUI 框架bubbleteatea.NewProgram(model).Run()
组件bubbleslist.New()、textinput.New()
样式lipglossstyle.Foreground(lipgloss.Color("212"))
表单huhhuh.NewInput().Title("Name").Run()
Markdownglamourglamour.Render(md, "dark")
动画harmonicaharmonica.NewSpring()

Go TUI 完整指南 → 所有 Bubbles 组件 → 布局与动画模式 →


SSH 应用(基础设施)

s, _ := wish.NewServer(
    wish.WithAddress(":2222"),
    wish.WithHostKeyPath(".ssh/key"),
    wish.WithMiddleware(
        bubbletea.Middleware(handler),
        logging.Middleware(),
    ),
)
s.ListenAndServe()

连接:ssh localhost -p 2222

基础设施完整指南 →


生产级 TUI 架构(高级模式)

超越基础 Bubble Tea:让 TUI 感觉快速、精致且专业的模式。 每个链接都指向生产级架构中的完整代码示例。

我的 TUI 很慢或卡顿
症状模式解决方法
计算期间 UI 阻塞两阶段异步阶段 1 即时完成,阶段 2 使用后台 goroutine
渲染路径持有互斥锁不可变快照预先构建快照,通过原子指针交换
文件变更导致卡顿后台工作线程防抖监视器 + 合并处理
每帧分配数千次预计算样式在启动时一次性分配 delegate 样式
View() 中存在 O(n²) 字符串拼接strings.Builder使用预分配并调用 Grow() 的 Builder
Glamour 每帧都重新渲染缓存 Markdown按内容哈希缓存,宽度变化时失效
交互期间发生 GC 暂停空闲时间 GC在空闲期间触发 GC
数据集过大导致内存占用高对象池化使用带预分配切片的 sync.Pool
渲染屏幕外的项目视口虚拟化仅渲染可见行
我的布局在不同终端上显示异常
症状模式修复方案
硬编码宽度导致布局异常自适应布局设置 3-4 个响应式断点(80/100/140/180 列)
浅色终端上的颜色不正确语义化主题使用 lipgloss.AdaptiveColor + 符合 WCAG AA 标准的对比度
项目优先级相同 → 列表顺序变化确定性排序使用稳定排序,并通过次级键打破平局
排序模式不可见动态状态栏使用左右片段并填充间隙
我的 TUI 有多个视图,结构变得混乱
症状模式修复方案
按键路由混乱焦点状态机明确的焦点枚举 + 模态优先级层
用户在嵌套视图中迷失方向面包屑导航使用 Home > Board > Priority 路径指示器
关闭覆盖层后焦点位置丢失焦点恢复显示覆盖层前保存焦点,关闭时恢复
旧的异步结果覆盖新数据过期消息检测应用结果前比较数据哈希
每帧更新多个组件tea.Batch 累积将 cmd 收集到切片中,并返回 tea.Batch(cmds...)
后台 goroutine panic 导致 TUI 退出错误恢复为所有 goroutine 添加 defer/recover 包装器
我想添加数据丰富的可视化效果
需求模式代码
在列表列中显示条形图Unicode 迷你图使用 8 级块状字符 ▇▅▂
按强度着色感知热力图灰色 → 蓝色 → 紫色 → 粉色渐变
在终端中显示依赖关系图ASCII 图形渲染器画布 + 曼哈顿路径布线(╭─╮│╰╯)
一眼看出年龄年龄颜色编码新鲜=绿色,渐旧=黄色,陈旧=红色
让边框传达含义语义化边框红色=受阻,绿色=就绪,黄色=高影响
我希望 TUI 显得精致且专业
需求模式核心思路
Vim 风格的 gg/GVim 按键组合在按键之间跟踪 waitingForG 状态
搜索流畅不卡顿防抖搜索设置 150ms 计时器,仅在停止输入后触发
一次搜索所有字段复合 FilterValue将所有字段合并为一个字符串
带元数据的 4 行卡片丰富的委托项使用 Height()=4 的自定义委托项
行内展开详情行内展开按 d 切换,按 j/k 时自动折叠
复制到剪贴板剪贴板集成按 y 复制 ID,按 C 复制 Markdown,并显示 Toast 反馈
? / ` / ; 帮助多层级帮助快速参考 + 教程 + 持久侧边栏
支持模式切换的看板看板泳道预计算看板状态,以 O(1) 复杂度切换
使用 h/l 导航的可折叠树树形导航将树展平为可见列表,以便使用 j/k 导航
挂起 TUI 并用 vim 编辑编辑器调度终端使用 tea.ExecProcess,GUI 使用后台方式
记住展开/折叠状态持久化状态保存为 JSON,损坏时优雅降级
通过环境变量调整环境变量偏好设置NO_COLOR、主题、防抖时间、分栏比例
可选功能缺失怎么办?优雅降级启动时检测,并隐藏不可用的功能

完整的生产架构指南 →


启动前检查清单(每个 TUI)

  • 处理 tea.WindowSizeMsg — 调整所有组件的大小
  • 处理 ctrl+c — 执行清理并恢复终端状态
  • 检测通过管道传入的 stdin/stdout — 回退到纯文本
  • 在至少 80×24 的终端上测试
  • 提供 --no-tui / NO_TUI 退出方式
  • 在浅色和深色背景下都进行测试
  • 在设置 NO_COLOR=1 和 TERM=dumb 时进行测试

有关生产级 TUI,请参阅完整检查清单(16 项必备内容 + 20 项润色内容)。


何时不使用 Charm

  • 输出通过管道传递: mytool | grep → 纯文本
  • CI/CD: 没有终端 → 使用标志/环境变量
  • 只有一个简单提示: 也许用 fmt.Scanf 就够了

退出方式:

if !term.IsTerminal(os.Stdin.Fd()) || os.Getenv("NO_TUI") != "" {
    runPlainMode()
    return
}

所有参考资料

我需要……查看此文档
可复制粘贴的单行命令快速参考
提供给 Claude 的 TUI 任务提示词提示词
Gum / VHS / Mods / Freeze / GlowShell 脚本
Bubble Tea 架构、调试、反模式Go TUI
Bubbles 组件 API(列表、表格、视口……)组件目录
主题、布局、动画、Huh 表单、测试高级模式
专业模式:异步、快照、焦点状态机、自适应布局、迷你图、看板、树、缓存生产架构
Wish SSH 服务、Soft Serve、teatest基础设施

评论

支持 Markdown