tui

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LabelContinue        = "可继续"
	LabelReadonly        = "仅浏览"
	LabelBlocked         = "不兼容"
	ReasonCompatible     = "同运行环境,可继续"
	ReasonAuthMismatch   = "认证方式不兼容,仅可浏览"
	ReasonProviderBlock  = "跨 provider,不可恢复"
	ReasonEndpointBlock  = "跨 endpoint,不可恢复"
	ReasonReadonlyNotice = "当前会话为只读浏览,运行环境不兼容,不能继续对话"
)

统一文案常量(selector / Enter 提示 / 输入区 共用)

View Source
const (
	SymThinking   = "∴"
	SymResponse   = "⎿"
	SymPause      = "⏸"
	SymUserPrompt = "❯"
)

CC 符号体系

Variables

View Source
var (
	// 品牌色
	ColorBrand    = lipgloss.Color("#D77757") // CC: rgb(215,119,87)
	ColorBrandDim = lipgloss.Color("#EB9F7F") // CC: rgb(235,159,127) 闪烁态

	// 语义色
	ColorSuccess = lipgloss.Color("#2CB74F")
	ColorError   = lipgloss.Color("#CC3333")
	ColorWarning = lipgloss.Color("#DCA032")
	ColorPerm    = lipgloss.Color("#B1B9F9") // CC: rgb(177,185,249) 权限蓝紫

	// 文本色
	ColorText    = lipgloss.Color("#FFFFFF")
	ColorTextDim = lipgloss.Color("#A0A0A0")
	ColorSubtle  = lipgloss.Color("#6E6E6E")

	// 边框色
	ColorInputBorder = lipgloss.Color("#888888") // CC: rgb(136,136,136)

	// Diff 色
	ColorDiffAdd = lipgloss.Color("#4ADE80")
	ColorDiffDel = lipgloss.Color("#FB7185")

	// 上下文进度条
	ColorCtxLow  = lipgloss.Color("#34D399")
	ColorCtxMid  = lipgloss.Color("#F59E0B")
	ColorCtxHigh = lipgloss.Color("#F87171")
)

颜色令牌(CC dark theme 精确 RGB)

View Source
var (
	// ⎿ 前缀及 assistant 响应区文本
	StyleMsgResponse = lipgloss.NewStyle().
						Foreground(ColorTextDim)

	// 用户输入文本
	StyleUserText = lipgloss.NewStyle().
					Foreground(ColorText).
					Bold(true)

	// ∴ 思考中文本
	StyleThinking = lipgloss.NewStyle().
					Foreground(ColorTextDim).
					Italic(true)

	// 工具名称
	StyleToolName = lipgloss.NewStyle().
					Bold(true)

	// 工具输出内容
	StyleToolOutput = lipgloss.NewStyle().
					Foreground(ColorTextDim)

	// 错误文本
	StyleError = lipgloss.NewStyle().
				Foreground(ColorError)

	// Spinner 动画
	StyleSpinner = lipgloss.NewStyle().
					Foreground(ColorBrand)

	// 通用 dim 文本
	StyleDim = lipgloss.NewStyle().
				Foreground(ColorTextDim)

	// 输入框提示符
	StyleInputPrompt = lipgloss.NewStyle().
						Foreground(ColorTextDim)

	// 权限请求标题
	StylePermTitle = lipgloss.NewStyle().
					Foreground(ColorPerm).
					Bold(true)

	// Diff 样式
	StyleDiffAdd = lipgloss.NewStyle().
					Foreground(ColorDiffAdd)

	StyleDiffDel = lipgloss.NewStyle().
					Foreground(ColorDiffDel)

	StyleDiffHeader = lipgloss.NewStyle().
					Foreground(ColorPerm).
					Bold(true)

	StyleDiffCtx = lipgloss.NewStyle().
					Foreground(ColorTextDim)

	// Footer 通用样式
	StyleFooter = lipgloss.NewStyle().
				Foreground(ColorTextDim)
)

组件样式

Functions

func BlackCircle

func BlackCircle() string

BlackCircle 返回平台对应的实心圆符号(macOS 用 Unicode 录制键符号)

func ContextColor

func ContextColor(percent float64) lipgloss.Color

ContextColor 根据上下文使用百分比返回对应颜色

func SetTheme

func SetTheme(mode ThemeMode)

SetTheme 切换主题并重建所有样式

func SpinnerTickCmd

func SpinnerTickCmd() tea.Cmd

SpinnerTickCmd 返回一个 80ms 间隔的 Tick 命令

Types

type App

type App struct {

	// 会话回调(由 main.go 注入)
	OnClear       func()
	OnCompact     func() string
	OnModelSwitch func(string)
	OnExport      func() string
	OnInterrupt   func()
	OnResume      func() ([]ResumeEntry, error)
	OnResumeLoad  func(sessionID string) error
	OnThemeSwitch func(string) string
	OnLogin       func() string
	OnLogout      func() string
	OnSkillsList  func() string
	OnPluginsList func() string
	OnHooksList   func() string

	// 会话信息
	SessionID    string
	SessionTurns int
	// contains filtered or unexported fields
}

App TUI 主 Model

func NewApp

func NewApp(cfg AppConfig) *App

NewApp 创建 TUI 应用

func (*App) Init

func (a *App) Init() tea.Cmd

func (*App) IsReadOnly

func (a *App) IsReadOnly() bool

IsReadOnly 返回当前是否处于只读浏览模式

func (*App) RestoreTranscript

func (a *App) RestoreTranscript(msgs []ChatMessage)

RestoreTranscript 从结构化消息恢复前台 transcript(/resume 后调用)

func (*App) Send

func (a *App) Send(msg tea.Msg)

Send 向终端界面发送消息(模型代理协程调用)

func (*App) SetModel

func (a *App) SetModel(model string)

SetModel 切换运行时模型(/resume 恢复后调用)

func (*App) SetProvider

func (a *App) SetProvider(provider string)

SetProvider 切换运行时 provider 名称(/resume 恢复后调用)

func (*App) SubmitCh

func (a *App) SubmitCh() <-chan string

SubmitCh 返回用户提交消息的通道(外部模型代理读取)

func (*App) Update

func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*App) View

func (a *App) View() string

type AppConfig

type AppConfig struct {
	Model      string
	Provider   string
	Tracker    *cost.Tracker
	MaxContext int
	Version    string
	ToolCount  int
	PermMode   string
	WorkDir    string
}

AppConfig TUI 初始化配置

type AppState

type AppState int

AppState TUI 状态机

const (
	StateInput        AppState = iota // 等待用户输入
	StateQuery                        // 等待模型响应
	StateToolExec                     // 工具执行中
	StatePermission                   // 等待权限确认
	StateDiffPreview                  // 等待差异确认
	StateAskUser                      // 询问工具等待用户输入
	StateResumeSelect                 // 会话恢复选择器
	StatePanel                        // 可滚动文本面板
)

type ChatMessage

type ChatMessage struct {
	ID        string // 稳定标识(递增 ID)
	Role      string // 用户 / 助手 / 工具 / 思考 / 错误 / 系统
	Content   string
	ToolName  string // 工具消息时使用
	ToolID    string // 工具调用标识(用于精确匹配同名工具)
	ToolInput string // 工具输入参数(原始 JSON)
	IsError   bool
	Folded    bool // 是否已折叠
}

ChatMessage 单条转录消息

type ChatView

type ChatView struct {
	// contains filtered or unexported fields
}

ChatView 转录区域组件

func NewChatView

func NewChatView(width, height int) ChatView

NewChatView 创建转录区域

func (*ChatView) AddSystemMessage

func (c *ChatView) AddSystemMessage(text string)

AddSystemMessage 添加系统消息

func (*ChatView) Clear

func (c *ChatView) Clear()

Clear 清空消息

func (ChatView) HasMessages

func (c ChatView) HasMessages() bool

HasMessages 返回是否有用户发起的消息(非 system 消息)

func (ChatView) Init

func (c ChatView) Init() tea.Cmd

func (*ChatView) InvalidateCache

func (c *ChatView) InvalidateCache()

InvalidateCache 清空 Markdown 渲染缓存并重建(主题切换后调用)

func (ChatView) IsToolOutputExpanded

func (c ChatView) IsToolOutputExpanded() bool

IsToolOutputExpanded 返回工具输出展开状态

func (*ChatView) LoadMessages

func (c *ChatView) LoadMessages(msgs []ChatMessage)

LoadMessages 从外部替换全部消息并刷新视图(用于 /resume 恢复 transcript)

func (*ChatView) SetToolOutputExpanded

func (c *ChatView) SetToolOutputExpanded(expanded bool)

SetToolOutputExpanded 设置工具输出展开状态

func (ChatView) Update

func (c ChatView) Update(msg tea.Msg) (ChatView, tea.Cmd)

func (ChatView) View

func (c ChatView) View() string

func (ChatView) ViewWithHint

func (c ChatView) ViewWithHint() string

View 渲染转录区(含底部"跳到最新"提示)

type CommandHint

type CommandHint struct {
	Name        string
	Description string
}

CommandHint 斜杠命令提示

type ComposerConfig

type ComposerConfig struct {
	Model        string
	PermMode     string
	MouseMode    MouseMode
	ReadOnly     bool
	ToolExpanded bool
	Tracker      *cost.Tracker
	MaxContext   int
	WorkDir      string
}

ComposerConfig 底部 Composer 渲染所需数据

type DiffDialog

type DiffDialog struct {
	// contains filtered or unexported fields
}

DiffDialog 差异预览弹层

func NewDiffDialog

func NewDiffDialog() DiffDialog

NewDiffDialog 创建差异预览弹层

func (*DiffDialog) Hide

func (d *DiffDialog) Hide()

Hide 隐藏差异预览弹层

func (DiffDialog) Init

func (d DiffDialog) Init() tea.Cmd

func (DiffDialog) IsVisible

func (d DiffDialog) IsVisible() bool

IsVisible 是否可见

func (*DiffDialog) Show

func (d *DiffDialog) Show(path string, diffText string, responseCh chan bool)

Show 显示差异预览弹层

func (DiffDialog) Update

func (d DiffDialog) Update(msg tea.Msg) (DiffDialog, tea.Cmd)

func (DiffDialog) View

func (d DiffDialog) View() string

View 渲染差异预览弹层(modal 层独占全屏)

type EventSender

type EventSender func(tea.Msg)

EventSender 模型代理向界面发送事件的回调接口

type InputBox

type InputBox struct {
	// contains filtered or unexported fields
}

InputBox 输入框组件

func NewInputBox

func NewInputBox(commands []CommandHint) InputBox

NewInputBox 创建输入框

func (*InputBox) Blur

func (i *InputBox) Blur()

Blur 失焦

func (*InputBox) Focus

func (i *InputBox) Focus() tea.Cmd

Focus 聚焦输入框

func (InputBox) GetPastedContent

func (i InputBox) GetPastedContent(id int) string

GetPastedContent 获取存储的粘贴内容

func (*InputBox) HandlePaste

func (i *InputBox) HandlePaste(content string) (display string, stored string)

HandlePaste 处理粘贴内容:短文本原样返回,长文本存储并返回引用标记

func (InputBox) Height

func (i InputBox) Height() int

Height 返回输入组件当前高度

func (InputBox) Init

func (i InputBox) Init() tea.Cmd

func (*InputBox) RecordMouseEvent

func (i *InputBox) RecordMouseEvent()

RecordMouseEvent 记录鼠标事件时间(由 app.go 调用)

func (*InputBox) Reset

func (i *InputBox) Reset()

Reset 清空输入框

func (InputBox) SearchHistory

func (i InputBox) SearchHistory(query string) []string

SearchHistory 按关键词过滤历史记录(倒序,最近的在前)

func (InputBox) Update

func (i InputBox) Update(msg tea.Msg) (InputBox, tea.Cmd)

func (InputBox) Value

func (i InputBox) Value() string

Value 获取当前值

func (InputBox) View

func (i InputBox) View() string

type LayerContent

type LayerContent struct {
	Main        string
	Bottom      string
	BottomFloat string
	Overlay     string
	Modal       string // 已含 lipgloss.Place 定位的完整帧
}

LayerContent 各层内容

type Layout

type Layout struct {
	// contains filtered or unexported fields
}

Layout 五层布局管理器 真 overlay 实现:主区不被 overlay/bottomFloat 挤压。

  1. Main — 主滚动区(transcript),占满剩余高度
  2. Bottom — 底部固定区(Composer)
  3. BottomFloat — 底部浮层(权限确认、spinner),覆盖在 Main 底部
  4. Overlay — 覆盖层(ResumeSelector 等),居中覆盖在 Main 上
  5. Modal — 模态层(diff/panel),居中覆盖全屏,保留背景感

func (*Layout) MainHeight

func (l *Layout) MainHeight(bottomContent string) int

MainHeight 返回主区域可用高度

func (*Layout) Render

func (l *Layout) Render(content LayerContent) string

Render 按层级合成最终视图

type MouseMode

type MouseMode int

MouseMode 鼠标模式

const (
	// MouseModeBrowse 浏览模式:启用鼠标报告,支持滚轮滚动和点击交互
	MouseModeBrowse MouseMode = iota
	// MouseModeSelect 复制模式:关闭鼠标报告,允许终端原生拖拽选择复制
	MouseModeSelect
)

func (MouseMode) Label

func (m MouseMode) Label() string

Label 返回模式的中文标签(状态栏显示用)

type MsgAgentDone

type MsgAgentDone struct {
	Err error
}

MsgAgentDone 模型代理循环完成(无更多工具调用)

type MsgAskUser

type MsgAskUser struct {
	Question string
	Response chan string
}

MsgAskUser 询问工具请求用户输入

type MsgClosePanel

type MsgClosePanel struct{}

MsgClosePanel 关闭文本面板

type MsgDiffPreview

type MsgDiffPreview struct {
	Path     string
	DiffText string
	Response chan bool
}

MsgDiffPreview 差异预览确认请求

type MsgError

type MsgError struct {
	Err error
}

MsgError 错误消息

type MsgOpenPanel

type MsgOpenPanel struct {
	Title   string
	Content string
}

MsgOpenPanel 打开可滚动文本面板

type MsgPermissionRequest

type MsgPermissionRequest struct {
	ID       string
	ToolName string
	Input    string
	Response chan PermissionResponse
}

MsgPermissionRequest 权限请求

type MsgResponseDone

type MsgResponseDone struct{}

MsgResponseDone 一轮 API 响应完成

type MsgResumeChosen

type MsgResumeChosen struct {
	SessionID string
}

MsgResumeChosen 用户选中了要恢复的会话

type MsgResumeEntries

type MsgResumeEntries struct {
	Entries []ResumeEntry
}

MsgResumeEntries 打开会话恢复选择器(携带结构化数据)

type MsgSpinnerTick

type MsgSpinnerTick struct{}

MsgSpinnerTick 是驱动 Spinner 帧推进的 Tick 消息

type MsgSubAgentDone

type MsgSubAgentDone struct {
	ID          string
	Description string
	Result      string // 摘要(截取前 200 字符)
}

MsgSubAgentDone 子 agent 执行完成

type MsgSubAgentStart

type MsgSubAgentStart struct {
	ID          string
	Description string
}

MsgSubAgentStart 子 agent 开始执行

type MsgSubmit

type MsgSubmit struct {
	Text string
}

MsgSubmit 用户提交消息

type MsgSystemNotice

type MsgSystemNotice struct {
	Text string
}

MsgSystemNotice 系统通知(如自动压缩提示)

type MsgTextDelta

type MsgTextDelta struct {
	Text string
}

MsgTextDelta 模型回复文本增量

type MsgThinking

type MsgThinking struct {
	Text string
}

MsgThinking 模型思考提示

type MsgToolDone

type MsgToolDone struct {
	ID      string
	Name    string
	Output  string
	IsError bool
}

MsgToolDone 工具执行完成

type MsgToolStart

type MsgToolStart struct {
	ID    string
	Name  string
	Input string
}

MsgToolStart 工具开始执行

type MsgUsage

type MsgUsage struct {
	Usage *provider.Usage
}

MsgUsage Token 使用量更新

type MsgWindowSize

type MsgWindowSize struct {
	Width  int
	Height int
}

MsgWindowSize 窗口大小变化

type Panel

type Panel struct {
	// contains filtered or unexported fields
}

Panel 可滚动文本面板(用于 /help /config /permissions 等长输出)

func NewPanel

func NewPanel() Panel

NewPanel 创建面板

func (*Panel) Hide

func (p *Panel) Hide()

Hide 隐藏面板

func (Panel) IsVisible

func (p Panel) IsVisible() bool

IsVisible 是否可见

func (*Panel) Show

func (p *Panel) Show(title, content string)

Show 显示面板

func (Panel) Update

func (p Panel) Update(msg tea.Msg) (Panel, tea.Cmd)

Update 处理事件

func (Panel) View

func (p Panel) View() string

View 渲染面板(居中 modal 风格)

type PermissionDialog

type PermissionDialog struct {
	// contains filtered or unexported fields
}

PermissionDialog 权限确认对话框

func NewPermissionDialog

func NewPermissionDialog() PermissionDialog

NewPermissionDialog 创建权限对话框

func (PermissionDialog) Card

func (p PermissionDialog) Card(width int) string

Card 渲染权限确认卡片(圆角边框 + 按键高亮反馈)

func (*PermissionDialog) Hide

func (p *PermissionDialog) Hide()

Hide 隐藏对话框

func (PermissionDialog) Init

func (p PermissionDialog) Init() tea.Cmd

func (PermissionDialog) IsVisible

func (p PermissionDialog) IsVisible() bool

IsVisible 是否可见

func (*PermissionDialog) Show

func (p *PermissionDialog) Show(toolName, input string, responseCh chan PermissionResponse)

Show 显示权限对话框

func (PermissionDialog) Update

func (p PermissionDialog) Update(msg tea.Msg) (PermissionDialog, tea.Cmd)

func (PermissionDialog) View

func (p PermissionDialog) View() string

type PermissionResponse

type PermissionResponse int

PermissionResponse 权限响应

const (
	PermAllow PermissionResponse = iota
	PermDeny
	PermAlways
	PermNever
)

type ResumeEntry

type ResumeEntry struct {
	ID         string
	Model      string
	Provider   string
	BaseURL    string
	AuthSource string
	Turns      int
	Cost       string
	Mode       ResumeMode // 恢复能力
	ModeReason string     // 原因文案
}

ResumeEntry 历史会话条目(含兼容性元数据)

type ResumeMode

type ResumeMode string

ResumeMode 恢复能力级别

const (
	ResumeContinue ResumeMode = "continue" // 完全兼容,可继续对话
	ResumeReadonly ResumeMode = "readonly" // 可浏览历史,不可续接
	ResumeBlocked  ResumeMode = "blocked"  // 不兼容,不可恢复
)

type ResumeSelector

type ResumeSelector struct {
	// contains filtered or unexported fields
}

ResumeSelector 会话恢复选择器(真正可滚动)

func NewResumeSelector

func NewResumeSelector() ResumeSelector

NewResumeSelector 创建会话恢复选择器

func (*ResumeSelector) Hide

func (r *ResumeSelector) Hide()

Hide 隐藏选择器

func (ResumeSelector) IsVisible

func (r ResumeSelector) IsVisible() bool

IsVisible 是否可见

func (ResumeSelector) SelectedEntry

func (r ResumeSelector) SelectedEntry() *ResumeEntry

SelectedEntry 返回当前选中的条目

func (*ResumeSelector) Show

func (r *ResumeSelector) Show(entries []ResumeEntry)

Show 显示选择器并填充条目

func (ResumeSelector) Update

func (r ResumeSelector) Update(msg tea.Msg) (ResumeSelector, tea.Cmd)

Update 处理键盘和鼠标事件

func (ResumeSelector) View

func (r ResumeSelector) View() string

View 渲染选择器列表(居中浮层)

type SpinnerState

type SpinnerState struct {
	// contains filtered or unexported fields
}

SpinnerState 保存 Spinner 的运行状态

func NewSpinnerState

func NewSpinnerState() SpinnerState

NewSpinnerState 初始化一个空闲状态的 Spinner

func (*SpinnerState) AddSubAgent

func (s *SpinnerState) AddSubAgent(id, description string)

AddSubAgent 注册一个正在运行的子 agent

func (*SpinnerState) ClearSubAgents

func (s *SpinnerState) ClearSubAgents()

ClearSubAgents 清空所有子 agent 状态

func (*SpinnerState) CompleteSubAgent

func (s *SpinnerState) CompleteSubAgent(id string)

CompleteSubAgent 标记指定子 agent 为已完成

func (*SpinnerState) Start

func (s *SpinnerState) Start()

Start 开始计时并随机选取动词

func (*SpinnerState) Stop

func (s *SpinnerState) Stop()

Stop 停止 Spinner

func (*SpinnerState) Tick

func (s *SpinnerState) Tick()

Tick 推进一帧

func (*SpinnerState) View

func (s *SpinnerState) View() string

View 渲染 Spinner 行,格式:` [glyph] [verb]… [elapsed]` glyph 使用品牌橙色,elapsed 使用 dim 色 如果有子 agent,在下方渲染树形列表

type SubAgentStatus

type SubAgentStatus struct {
	ID          string
	Description string
	Done        bool
}

SubAgentStatus 子 agent 状态

type ThemeMode

type ThemeMode string

ThemeMode 主题模式

const (
	ThemeDark  ThemeMode = "dark"
	ThemeLight ThemeMode = "light"
)

func CurrentTheme

func CurrentTheme() ThemeMode

CurrentTheme 返回当前主题模式

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL