Help us shape the future of Go! Take the 2026 Go Developer Survey

tui

package
v0.1.0-alpha.4 Latest Latest
Warning

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

Go to latest
Published: May 8, 2026 License: Apache-2.0 Imports: 38 Imported by: 0

Documentation

Overview

Package tui provides terminal UI components for OpenScholar. This file implements VimMode: a pure-logic vim normal mode handler for the chat viewport. It is consumed by key_handlers.go (Stage 3 integration).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearTerminalSequence

func ClearTerminalSequence(mode MainScreenResetMode) string

func FullscreenEnabled

func FullscreenEnabled() bool

FullscreenEnabled controls whether the interactive TUI should use the alternate screen buffer. Default is main-screen; fullscreen is opt-in via OS_TUI_FULLSCREEN truthy values: 1/true/on/fullscreen (trimmed, case-insensitive). Falsy values 0/false/off/no and empty/unset keep main-screen mode.

Product contract: main-screen keeps native terminal scrollback and does not promise retroactive reflow of already flushed native rows after resize. Fullscreen/alt-screen is the supported full-history reflow path.

Types

type ChatFeature

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

ChatFeature groups all chat viewport, message, and selection state.

func NewChatFeature

func NewChatFeature() ChatFeature

NewChatFeature creates a ChatFeature with initialized maps.

func (*ChatFeature) GetExpandState

func (c *ChatFeature) GetExpandState(id string) components.ExpandState

GetExpandState returns the ExpandState for a node. expandedNodes is the single source of truth; transcriptExpanded provides global override.

func (*ChatFeature) IsExpanded

func (c *ChatFeature) IsExpanded(id string) bool

IsExpanded returns whether a node is expanded (either legacy bool or Wave 2 ExpandState).

func (*ChatFeature) Reset

func (c *ChatFeature) Reset()

Reset clears all chat state.

type ChatRegion

type ChatRegion struct{}

ChatRegion fills all remaining vertical space. MinHeight is 0 so very small terminals keep prompt/overlay rows visible.

func (ChatRegion) MinHeight

func (ChatRegion) MinHeight() int

func (ChatRegion) PreferredHeight

func (ChatRegion) PreferredHeight(_ int) int

func (ChatRegion) View

func (ChatRegion) View(_, _ int) string

type CheckpointChoice

type CheckpointChoice struct {
	Event    tools.CheckpointEvent
	Response tools.CheckpointResponse
}

CheckpointChoice represents the user's checkpoint decision.

type CheckpointOverlay

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

CheckpointOverlay implements Overlay for the research pipeline checkpoint dialog.

func NewCheckpointOverlay

func NewCheckpointOverlay(event *tools.CheckpointEvent) *CheckpointOverlay

NewCheckpointOverlay creates a new checkpoint overlay.

func (*CheckpointOverlay) BlocksInput

func (o *CheckpointOverlay) BlocksInput() bool

func (*CheckpointOverlay) ID

func (o *CheckpointOverlay) ID() string

func (*CheckpointOverlay) Kind

func (o *CheckpointOverlay) Kind() OverlayKind

func (*CheckpointOverlay) Update

func (o *CheckpointOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*CheckpointOverlay) View

func (o *CheckpointOverlay) View(width, height int) string

type CheckpointState

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

CheckpointState holds checkpoint confirmation dialog state.

func (*CheckpointState) Reset

func (s *CheckpointState) Reset()

type ClarificationChoice

type ClarificationChoice struct {
	Event    tools.ClarificationEvent
	Response tools.ClarificationResponse
}

ClarificationChoice represents the user's clarification response.

type ClarificationOverlay

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

ClarificationOverlay implements Overlay for the AskUser clarification dialog.

func NewClarificationOverlay

func NewClarificationOverlay(event *tools.ClarificationEvent) *ClarificationOverlay

NewClarificationOverlay creates a new ClarificationOverlay for the given event.

func (*ClarificationOverlay) BlocksInput

func (o *ClarificationOverlay) BlocksInput() bool

func (*ClarificationOverlay) ID

func (o *ClarificationOverlay) ID() string

func (*ClarificationOverlay) Kind

func (*ClarificationOverlay) Update

func (o *ClarificationOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*ClarificationOverlay) View

func (o *ClarificationOverlay) View(width, height int) string

type ClarificationState

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

ClarificationState holds AskUser clarification dialog state.

func (*ClarificationState) Reset

func (s *ClarificationState) Reset()

type CodeBlock

type CodeBlock struct {
	Language string
	Content  string
}

CodeBlock represents a fenced code block extracted from markdown.

type CommandActivityState

type CommandActivityState struct {
	Invocation string
}

type CommandDialogState

type CommandDialogState struct {
	Visible         bool
	Invocation      string
	Title           string
	Body            string
	DismissText     string
	RecordOnDismiss bool
}

type ComposerFeature

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

ComposerFeature groups input, command picker, and file picker state.

func NewComposerFeature

func NewComposerFeature() ComposerFeature

NewComposerFeature creates a ComposerFeature with initialized state.

type ComposerRegion

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

ComposerRegion wraps the composer feature and estimates the height of the input area plus any active picker (command picker or file picker).

It holds a reference to the Model so it can inspect live picker state without coupling layout.go to every individual field.

func (ComposerRegion) MinHeight

func (r ComposerRegion) MinHeight() int

func (ComposerRegion) PreferredHeight

func (r ComposerRegion) PreferredHeight(width int) int

PreferredHeight returns the number of lines the composer section currently needs.

It always delegates to buildBottomSection() and counts the rendered lines. This keeps LayoutRegion height accounting aligned with the rendered prompt area (search chrome, input, picker, footer) without measuring a full string.

func (ComposerRegion) View

func (r ComposerRegion) View(_, _ int) string

type ConfigWizardChoice

type ConfigWizardChoice struct {
	Wizard *config.ConfigWizard
	Saved  bool
}

ConfigWizardChoice represents the config wizard completion.

type ConfigWizardOverlay

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

ConfigWizardOverlay implements Overlay for the multi-step config wizard.

func NewConfigWizardOverlay

func NewConfigWizardOverlay(cfg *config.Config) *ConfigWizardOverlay

NewConfigWizardOverlay creates a new config wizard overlay.

func (*ConfigWizardOverlay) BlocksInput

func (o *ConfigWizardOverlay) BlocksInput() bool

func (*ConfigWizardOverlay) ID

func (o *ConfigWizardOverlay) ID() string

func (*ConfigWizardOverlay) Kind

func (o *ConfigWizardOverlay) Kind() OverlayKind

func (*ConfigWizardOverlay) Update

func (o *ConfigWizardOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*ConfigWizardOverlay) View

func (o *ConfigWizardOverlay) View(width, height int) string

type ConfigWizardState

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

ConfigWizardState holds config wizard dialog state.

func (*ConfigWizardState) Reset

func (s *ConfigWizardState) Reset()

type CopyModeOverlay

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

CopyModeOverlay presents numbered code blocks for clipboard selection.

func NewCopyModeOverlay

func NewCopyModeOverlay(blocks []CodeBlock) *CopyModeOverlay

NewCopyModeOverlay creates a CopyModeOverlay with the given code blocks.

func (*CopyModeOverlay) BlocksInput

func (o *CopyModeOverlay) BlocksInput() bool

func (*CopyModeOverlay) ID

func (o *CopyModeOverlay) ID() string

func (*CopyModeOverlay) Kind

func (o *CopyModeOverlay) Kind() OverlayKind

func (*CopyModeOverlay) Update

func (o *CopyModeOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*CopyModeOverlay) View

func (o *CopyModeOverlay) View(width, height int) string

type DialogStates

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

DialogStates is the container for all dialog sub-states.

type ExpandState

type ExpandState uint8

ExpandState represents the expand/collapse state of a tool call or thinking block.

const (
	ExpandCollapsed ExpandState = iota // Single-line summary (default)
	ExpandInline    ExpandState = 1    // Inline expand: params + first N lines of result
	ExpandOverlay   ExpandState = 2    // Overlay full view (future extension)
)

type GeometryState

type GeometryState struct {
	Width  int
	Height int
	Source geometrySource
	Epoch  int
	Valid  bool
}

GeometryState records the sanitized terminal geometry used by layout and rendering. Width/height remain mirrored on Model for existing call sites.

type HeaderRegion

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

HeaderRegion is the top header bar.

func (HeaderRegion) MinHeight

func (HeaderRegion) MinHeight() int

func (HeaderRegion) PreferredHeight

func (r HeaderRegion) PreferredHeight(_ int) int

func (HeaderRegion) View

func (HeaderRegion) View(_, _ int) string

type HelpOverlay

type HelpOverlay struct{}

HelpOverlay displays keyboard shortcuts. Any key press dismisses it.

func NewHelpOverlay

func NewHelpOverlay() *HelpOverlay

NewHelpOverlay creates a new HelpOverlay.

func (*HelpOverlay) BlocksInput

func (o *HelpOverlay) BlocksInput() bool

func (*HelpOverlay) ID

func (o *HelpOverlay) ID() string

func (*HelpOverlay) Kind

func (o *HelpOverlay) Kind() OverlayKind

func (*HelpOverlay) Update

func (o *HelpOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*HelpOverlay) View

func (o *HelpOverlay) View(width, height int) string

type InitRequiredChoice

type InitRequiredChoice struct {
	StartInit bool // true = start wizard, false = skip
}

InitRequiredChoice represents the init required dialog result.

type InitRequiredOverlay

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

InitRequiredOverlay implements Overlay for the init required confirmation.

func NewInitRequiredOverlay

func NewInitRequiredOverlay() *InitRequiredOverlay

NewInitRequiredOverlay creates a new init required overlay.

func (*InitRequiredOverlay) BlocksInput

func (o *InitRequiredOverlay) BlocksInput() bool

func (*InitRequiredOverlay) ID

func (o *InitRequiredOverlay) ID() string

func (*InitRequiredOverlay) Kind

func (o *InitRequiredOverlay) Kind() OverlayKind

func (*InitRequiredOverlay) Update

func (o *InitRequiredOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*InitRequiredOverlay) View

func (o *InitRequiredOverlay) View(width, height int) string

type InitWizardChoice

type InitWizardChoice struct {
	Wizard *initwizard.Wizard // carries all answers; caller should Save()
}

InitWizardChoice represents the init wizard completion.

type InitWizardOverlay

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

InitWizardOverlay implements Overlay for the multi-step init wizard.

func NewInitWizardOverlay

func NewInitWizardOverlay() *InitWizardOverlay

NewInitWizardOverlay creates a new init wizard overlay.

func (*InitWizardOverlay) BlocksInput

func (o *InitWizardOverlay) BlocksInput() bool

func (*InitWizardOverlay) ID

func (o *InitWizardOverlay) ID() string

func (*InitWizardOverlay) Kind

func (o *InitWizardOverlay) Kind() OverlayKind

func (*InitWizardOverlay) Update

func (o *InitWizardOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*InitWizardOverlay) View

func (o *InitWizardOverlay) View(width, height int) string

type InitWizardState

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

InitWizardState holds init wizard dialog state.

func (*InitWizardState) Reset

func (s *InitWizardState) Reset()

type LayoutManager

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

LayoutManager computes how to distribute terminal height among the four regions: chat viewport, overlay, composer (input + pickers), and status bar.

Usage (as a temporary local variable in recalcLayout):

lm := LayoutManager{chat: chatR, overlay: overlayR, composer: composerR, status: statusR}
result := lm.Layout(m.width, m.height)

func (*LayoutManager) Layout

func (lm *LayoutManager) Layout(totalWidth, totalHeight int) LayoutResult

Layout distributes totalHeight among the four regions. It keeps backward compatibility with existing call sites that consume chat/composer/overlay/status heights.

func (*LayoutManager) Snapshot

func (lm *LayoutManager) Snapshot(totalWidth, totalHeight int) LayoutSnapshot

Snapshot resolves a full-screen layout in one pass and returns a stable region contract (header/transcript/bottom/status).

type LayoutResult

type LayoutResult struct {
	HeaderHeight   int
	StatusHeight   int
	ComposerHeight int
	OverlayHeight  int
	ChatHeight     int
}

LayoutResult holds the calculated heights for each region after a Layout() call.

type LayoutSnapshot

type LayoutSnapshot struct {
	Width            int
	Height           int
	Epoch            int
	HeaderHeight     int
	TranscriptHeight int
	BottomHeight     int
	StatusHeight     int
	ComposerHeight   int
	OverlayHeight    int
}

LayoutSnapshot captures the resolved geometry for one layout pass. It is an internal contract between layout planning and rendering paths.

type MainScreenFrameInput

type MainScreenFrameInput struct {
	Frame          string
	Width          int
	Height         int
	ViewportHeight int
	ResizeEpoch    int
	SliceAnchor    string
	Reason         string
}

type MainScreenOutputController

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

func NewMainScreenOutputController

func NewMainScreenOutputController(mode MainScreenResetMode) *MainScreenOutputController

func (*MainScreenOutputController) StageFrame

func (*MainScreenOutputController) Stats

func (*MainScreenOutputController) WrapOutput

func (c *MainScreenOutputController) WrapOutput(dst io.Writer) io.Writer

type MainScreenOutputStats

type MainScreenOutputStats struct {
	FrameSeq         int64
	ConsumedFrameSeq int64
	FullReset        bool
	ResetReason      string
	PrevLines        int
	NextLines        int
	ViewportHeight   int
	OffscreenReset   bool
}

type MainScreenRenderResult

type MainScreenRenderResult struct {
	Output         string
	FullReset      bool
	ResetReason    string
	PrevLines      int
	NextLines      int
	ViewportHeight int
	OffscreenReset bool
	FrameUpdated   mainScreenFrameStateLite
}

type MainScreenRenderer

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

func NewMainScreenRenderer

func NewMainScreenRenderer(mode MainScreenResetMode) *MainScreenRenderer

func (*MainScreenRenderer) Render

type MainScreenResetMode

type MainScreenResetMode string
const (
	MainScreenResetModeFull    MainScreenResetMode = "full"
	MainScreenResetModeVisible MainScreenResetMode = "visible"
)

func MainScreenResetModeFromEnv

func MainScreenResetModeFromEnv() MainScreenResetMode

type MemoryFileEntry

type MemoryFileEntry struct {
	RelPath   string // e.g. "user_preferences.md"
	Type      string // "user", "feedback", "project", "reference"
	UpdatedAt time.Time
	IsActive  bool // whether this file is injected into current prompt
}

MemoryFileEntry represents a memory file in the selector.

type MemorySelectorChoice

type MemorySelectorChoice struct {
	Action   string // "view", "delete"
	FilePath string
}

MemorySelectorChoice is the result data from the overlay.

type MemorySelectorOverlay

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

MemorySelectorOverlay implements Overlay for memory file browsing.

func NewMemorySelectorOverlay

func NewMemorySelectorOverlay(entries []MemoryFileEntry) *MemorySelectorOverlay

NewMemorySelectorOverlay creates a new memory selector overlay.

func (*MemorySelectorOverlay) BlocksInput

func (o *MemorySelectorOverlay) BlocksInput() bool

func (*MemorySelectorOverlay) ID

func (o *MemorySelectorOverlay) ID() string

func (*MemorySelectorOverlay) Kind

func (*MemorySelectorOverlay) Update

func (*MemorySelectorOverlay) View

func (o *MemorySelectorOverlay) View(width, height int) string

type Model

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

func New

func New(ctx context.Context, a *app.App, resume bool, dispatcher *command.Dispatcher, opts ...Option) Model

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (Model) View

func (m Model) View() (rendered string)

type ModelSelectChoice

type ModelSelectChoice struct {
	Provider models.ModelProvider
	ModelID  models.ModelID
}

ModelSelectChoice represents the selected model.

type ModelSelectOverlay

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

ModelSelectOverlay implements Overlay for the model selection dialog.

func NewModelSelectOverlay

func NewModelSelectOverlay(currentProvider models.ModelProvider, currentModelID models.ModelID) *ModelSelectOverlay

NewModelSelectOverlay creates a new model selection overlay, pre-populated with provider/model lists based on the current model.

func (*ModelSelectOverlay) BlocksInput

func (o *ModelSelectOverlay) BlocksInput() bool

func (*ModelSelectOverlay) ID

func (o *ModelSelectOverlay) ID() string

func (*ModelSelectOverlay) Kind

func (o *ModelSelectOverlay) Kind() OverlayKind

func (*ModelSelectOverlay) Update

func (o *ModelSelectOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*ModelSelectOverlay) View

func (o *ModelSelectOverlay) View(width, height int) string

type ModelSelectState

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

ModelSelectState holds model selection dialog state.

func (*ModelSelectState) Reset

func (s *ModelSelectState) Reset()

type Option

type Option func(*Model)

Option configures the TUI model.

func WithCWDExplicit

func WithCWDExplicit() Option

WithCWDExplicit marks that --cwd was explicitly provided, skipping workspace dialog.

func WithDebugTrace

func WithDebugTrace(trace *debug.TUITrace) Option

WithDebugTrace wires optional TUI trace logging.

func WithFullscreen

func WithFullscreen(enabled bool) Option

WithFullscreen overrides the fullscreen/alt-screen rendering mode.

func WithMainScreenRenderer

func WithMainScreenRenderer(controller *MainScreenOutputController) Option

func WithResumeFlags

func WithResumeFlags(latest bool, query string) Option

func WithScreenMode

func WithScreenMode(mode ScreenMode) Option

WithScreenMode overrides the initial screen mode.

type Overlay

type Overlay interface {
	// ID returns a unique identifier for this overlay type (e.g. "permission").
	ID() string
	// Kind returns whether this overlay blocks input.
	Kind() OverlayKind
	// BlocksInput returns true if this overlay should consume all key events.
	BlocksInput() bool
	// Update processes a tea.Msg and returns the (possibly replaced) overlay,
	// an optional result (non-nil means the overlay is done), and a tea.Cmd.
	Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)
	// View renders the overlay content for the given terminal dimensions.
	View(width, height int) string
}

Overlay is the common interface for all dialog overlays.

type OverlayKind

type OverlayKind int

OverlayKind categorizes overlay behavior.

const (
	// OverlayBlocking blocks all input to the layer beneath.
	OverlayBlocking OverlayKind = iota
	// OverlayNonBlocking allows chat interaction to coexist (e.g. help, copy-mode).
	OverlayNonBlocking
)

type OverlayManager

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

OverlayManager manages a stack of active overlays with a pending queue for blocking overlays.

func NewOverlayManager

func NewOverlayManager() *OverlayManager

NewOverlayManager creates an empty OverlayManager.

func (*OverlayManager) Depth

func (om *OverlayManager) Depth() int

Depth returns the number of active overlays (not counting pending).

func (*OverlayManager) FindByID

func (om *OverlayManager) FindByID(id string) Overlay

FindByID returns the overlay with the given ID, or nil.

func (*OverlayManager) HasBlocking

func (om *OverlayManager) HasBlocking() bool

HasBlocking returns true if any active overlay is blocking.

func (*OverlayManager) IsEmpty

func (om *OverlayManager) IsEmpty() bool

IsEmpty returns true if there are no active overlays.

func (*OverlayManager) PendingCount

func (om *OverlayManager) PendingCount() int

PendingCount returns the number of queued blocking overlays.

func (*OverlayManager) Pop

func (om *OverlayManager) Pop() *OverlayResult

Pop removes and returns the top overlay's result. If a pending blocking overlay exists, it is promoted to the stack.

func (*OverlayManager) PopByID

func (om *OverlayManager) PopByID(id string) *OverlayResult

PopByID removes the overlay with the given ID (if present) and returns its result.

func (*OverlayManager) Push

func (om *OverlayManager) Push(o Overlay)

Push adds an overlay to the stack. If it is blocking and there is already a blocking overlay active, it is queued.

func (*OverlayManager) ReplaceTop

func (om *OverlayManager) ReplaceTop(o Overlay)

ReplaceTop replaces the top overlay in-place (used after Update returns a new Overlay).

func (*OverlayManager) RouteKey

func (om *OverlayManager) RouteKey(msg tea.KeyMsg) (tea.Cmd, bool)

RouteKey sends a tea.KeyMsg to the top overlay. Returns (cmd, consumed). consumed=true means the overlay handled the key.

func (*OverlayManager) RouteMsg

func (om *OverlayManager) RouteMsg(msg tea.Msg) (tea.Cmd, bool)

RouteMsg sends a non-key tea.Msg to the top overlay (e.g. tick, window resize). Returns (cmd, consumed).

func (*OverlayManager) Top

func (om *OverlayManager) Top() Overlay

Top returns the top-most overlay, or nil if the stack is empty.

type OverlayRegion

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

OverlayRegion wraps the OverlayManager and reports the height of the topmost overlay. It uses the pre-rendered overlay string (measured via line count) to avoid the estimation errors that arise from calling View() with a provisional height value.

func (OverlayRegion) MinHeight

func (r OverlayRegion) MinHeight() int

func (OverlayRegion) PreferredHeight

func (r OverlayRegion) PreferredHeight(_ int) int

func (OverlayRegion) View

func (r OverlayRegion) View(_, _ int) string

type OverlayResult

type OverlayResult struct {
	Action string // "accept" | "reject" | "dismiss"
	Data   any    // optional payload
}

OverlayResult is returned when an overlay completes.

type PermissionChoice

type PermissionChoice struct {
	Request   permission.PermissionRequest
	OptionIdx int // 0=Yes, 1=No, 2=Always
}

PermissionChoice represents the user's permission decision.

type PermissionOverlay

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

PermissionOverlay implements Overlay for the permission confirmation dialog.

func NewPermissionOverlay

func NewPermissionOverlay(req *permission.PermissionRequest) *PermissionOverlay

NewPermissionOverlay creates a new PermissionOverlay for the given request.

func (*PermissionOverlay) BlocksInput

func (o *PermissionOverlay) BlocksInput() bool

func (*PermissionOverlay) ID

func (o *PermissionOverlay) ID() string

func (*PermissionOverlay) Kind

func (o *PermissionOverlay) Kind() OverlayKind

func (*PermissionOverlay) Update

func (o *PermissionOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*PermissionOverlay) View

func (o *PermissionOverlay) View(width, height int) string

type PermissionState

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

PermissionState holds pending permission dialog state.

func (*PermissionState) Reset

func (s *PermissionState) Reset()

type PlanApprovalChoice

type PlanApprovalChoice struct {
	Event    tools.PlanApprovalEvent
	Response tools.PlanApprovalResponse
}

type PlanApprovalOverlay

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

func NewPlanApprovalOverlay

func NewPlanApprovalOverlay(event *tools.PlanApprovalEvent) *PlanApprovalOverlay

func (*PlanApprovalOverlay) BlocksInput

func (o *PlanApprovalOverlay) BlocksInput() bool

func (*PlanApprovalOverlay) ID

func (o *PlanApprovalOverlay) ID() string

func (*PlanApprovalOverlay) Kind

func (o *PlanApprovalOverlay) Kind() OverlayKind

func (*PlanApprovalOverlay) Update

func (o *PlanApprovalOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*PlanApprovalOverlay) View

func (o *PlanApprovalOverlay) View(width, height int) string

type PlanApprovalState

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

PlanApprovalState holds the dedicated ExitPlanMode approval dialog state.

func (*PlanApprovalState) Reset

func (s *PlanApprovalState) Reset()

type ProcessingPhase

type ProcessingPhase uint8

ProcessingPhase represents the current phase of agent processing.

const (
	PhaseIdle        ProcessingPhase = iota // No processing
	PhaseThinking                           // Waiting for first token (0-1s: silent, >1s: active)
	PhaseToolQueued                         // Tools known but none started yet
	PhaseToolRunning                        // Tool execution in progress
	PhaseStreaming                          // Receiving assistant content tokens
	PhaseCompacting                         // Context compaction in progress
)

type ProcessingState

type ProcessingState struct {
	Phase        ProcessingPhase
	Label        string    // "reasoning", "running Bash", etc.
	ActiveTool   string    // Current tool name (Phase=ToolRunning)
	StartedAt    time.Time // When this phase started
	SpinnerFrame int       // Mirrors StatusFeature.spinnerFrame for convenience
	QueuedCount  int       // Number of tools in queued state
	TotalTools   int       // Total tools in current batch
}

ProcessingState is the unified processing state driven by agent events. Both the chat area and status bar read from this single source of truth.

func (ProcessingState) ElapsedSeconds

func (ps ProcessingState) ElapsedSeconds() int

ElapsedSeconds returns seconds since the current phase started.

func (ProcessingState) IsActiveWaiting

func (ps ProcessingState) IsActiveWaiting() bool

IsActiveWaiting returns true when thinking phase has lasted >1s.

type ProgressTelemetry

type ProgressTelemetry struct {
	LastTokenAt         time.Time // last time a streaming token arrived
	LastTokenCount      int       // actual token/char count from streaming
	DisplayedTokenCount int       // smoothly animated display value
	ActiveToolStartedAt time.Time // when the current tool started
	StalledIntensity    float64   // 0.0-1.0, smoothed stalled severity
}

ProgressTelemetry tracks timing and count facts for the progress presentation layer.

type Region

type Region interface {
	// PreferredHeight returns the desired number of terminal lines for this region
	// at the given terminal width.
	PreferredHeight(width int) int
	// MinHeight returns the smallest acceptable height for this region.
	MinHeight() int
	// View renders the region content for the given dimensions.
	View(width, height int) string
}

Region represents a rectangular area in the TUI layout. Each region can declare its preferred and minimum heights, and render itself. This enables declarative height calculation without full pre-rendering.

type ResearchSuggestionOverlay

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

ResearchSuggestionOverlay prompts the user to choose between research mode and normal chat for a detected research-intent message.

func NewResearchSuggestionOverlay

func NewResearchSuggestionOverlay(text string) *ResearchSuggestionOverlay

NewResearchSuggestionOverlay creates a ResearchSuggestionOverlay with the original user text that triggered the suggestion.

func (*ResearchSuggestionOverlay) BlocksInput

func (o *ResearchSuggestionOverlay) BlocksInput() bool

func (*ResearchSuggestionOverlay) ID

func (*ResearchSuggestionOverlay) Kind

func (*ResearchSuggestionOverlay) Update

func (*ResearchSuggestionOverlay) View

func (o *ResearchSuggestionOverlay) View(width, height int) string

type ResearchSuggestionState

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

ResearchSuggestionState holds research suggestion dialog state.

func (*ResearchSuggestionState) Reset

func (s *ResearchSuggestionState) Reset()

type RuntimeErrorState

type RuntimeErrorState struct {
	Summary  string
	Detail   string
	Expanded bool
}

type ScreenMode

type ScreenMode string
const (
	ScreenModeFullscreen ScreenMode = "fullscreen"
	ScreenModeMain       ScreenMode = "main"
)

func ParseScreenMode

func ParseScreenMode(raw string) (ScreenMode, bool)

func ScreenModeFromEnv

func ScreenModeFromEnv() ScreenMode

func (ScreenMode) IsFullscreen

func (m ScreenMode) IsFullscreen() bool

type ScrollMode

type ScrollMode int

ScrollMode controls auto-scroll behavior.

const (
	// ScrollAutoFollow scrolls to bottom on new content.
	ScrollAutoFollow ScrollMode = iota
	// ScrollManualLocked keeps viewport at current position when user is browsing history.
	ScrollManualLocked
)

type SearchFeature

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

SearchFeature groups history search and text search state.

func NewSearchFeature

func NewSearchFeature() SearchFeature

NewSearchFeature creates a SearchFeature with initialized models.

func (*SearchFeature) AnyVisible

func (s *SearchFeature) AnyVisible() bool

AnyVisible returns true if any search UI is visible.

type SessionBrowserChoice

type SessionBrowserChoice struct {
	Action    string // "select" | "new" | "delete"
	SessionID string
}

SessionBrowserChoice represents the user's session browser action.

type SessionBrowserOverlay

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

SessionBrowserOverlay implements Overlay for the session browser dialog.

func NewSessionBrowserOverlay

func NewSessionBrowserOverlay(sessions []session.Session) *SessionBrowserOverlay

NewSessionBrowserOverlay creates a new session browser overlay.

func (*SessionBrowserOverlay) BlocksInput

func (o *SessionBrowserOverlay) BlocksInput() bool

func (*SessionBrowserOverlay) ID

func (o *SessionBrowserOverlay) ID() string

func (*SessionBrowserOverlay) Kind

func (*SessionBrowserOverlay) Update

func (*SessionBrowserOverlay) View

func (o *SessionBrowserOverlay) View(width, height int) string

type SessionBrowserState

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

SessionBrowserState holds session browser dialog state.

func (*SessionBrowserState) Reset

func (s *SessionBrowserState) Reset()

type StatusFeature

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

StatusFeature groups processing state, mode, and spinner.

type StatusRegion

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

StatusRegion is the bottom status bar.

func (StatusRegion) MinHeight

func (StatusRegion) MinHeight() int

func (StatusRegion) PreferredHeight

func (r StatusRegion) PreferredHeight(_ int) int

func (StatusRegion) View

func (StatusRegion) View(_, _ int) string

type TUIFeatures

type TUIFeatures struct {
	BlockRenderer bool // Always true — block-based rendering is the only path
	VirtualScroll bool // TODO(phase2): wire into viewport update logic
	OverlayStack  bool // TODO(phase3): wire into dialogs.go state machine
	LayoutRegion  bool // TODO(phase5): declarative height calculation via Region interface
	VimMode       bool // Phase 6: vim normal mode for chat viewport navigation
	VisualV2      bool // Always true — V2 visual style is the only path
	StatusV2      bool // Wave 1: three-segment status bar
	ToolGroups    bool // Wave 3: consecutive same-type tool calls auto-grouped
	MemoryUI      bool // Wave 3: memory status pill + toast + selector overlay
}

TUIFeatures controls experimental TUI features via environment variables. These flags are consumed by the rendering/scrolling/overlay code paths in later refactoring phases. Phase 0 only establishes the mechanism; actual branching is wired in Phase 1+ (see docs/重构/tui-重构/).

func DefaultFeatures

func DefaultFeatures() TUIFeatures

DefaultFeatures returns features with all core rendering paths enabled.

func FeaturesFromEnv

func FeaturesFromEnv() TUIFeatures

FeaturesFromEnv reads feature flags from environment variables. Set OS_TUI_BLOCK_RENDERER=1, OS_TUI_VIRTUAL_SCROLL=1, OS_TUI_OVERLAY_STACK=1, OS_TUI_LAYOUT_REGION=1 to enable respective features.

func (TUIFeatures) Sanitize

func (f TUIFeatures) Sanitize() TUIFeatures

Sanitize disables flags whose dependencies are not met, ensuring a valid combination without failing. Logs a warning when flags are auto-disabled. Returns the corrected features.

func (TUIFeatures) Validate

func (f TUIFeatures) Validate() error

Validate checks feature flag dependencies and returns an error describing any invalid combinations.

type TemplateChoice

type TemplateChoice struct {
	Template    string // "empirical" | "aris_empirical" | "survey" | "theoretical"
	FolderName  string
	PendingText string // stashed user input to resume
}

TemplateChoice represents the completed template selection.

type TemplateOverlay

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

TemplateOverlay implements Overlay for the research template selection dialog.

func NewTemplateOverlay

func NewTemplateOverlay(options []string, pendingText string) *TemplateOverlay

NewTemplateOverlay creates a new template selection overlay.

func (*TemplateOverlay) BlocksInput

func (o *TemplateOverlay) BlocksInput() bool

func (*TemplateOverlay) ID

func (o *TemplateOverlay) ID() string

func (*TemplateOverlay) Kind

func (o *TemplateOverlay) Kind() OverlayKind

func (*TemplateOverlay) Update

func (o *TemplateOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*TemplateOverlay) View

func (o *TemplateOverlay) View(width, height int) string

type TemplateState

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

TemplateState holds template selection dialog state.

func (*TemplateState) Reset

func (s *TemplateState) Reset()

type TerminalState

type TerminalState struct {
	AltScreen bool
	Mouse     bool
}

type TextSelection

type TextSelection struct {
	Active     bool // drag in progress
	HasRange   bool // selection completed (show highlight until cleared)
	StartRow   int  // cached content line index (start)
	StartCol   int  // visual column (start)
	EndRow     int  // cached content line index (end)
	EndCol     int  // visual column (end)
	StartCoord TranscriptCoord
	EndCoord   TranscriptCoord
	PlainText  string
}

TextSelection tracks mouse text selection state.

type ToolRuntimeState

type ToolRuntimeState struct {
	ToolName      string
	BatchID       string
	Input         string
	State         message.ToolCallState
	Order         int
	Total         int
	DurationMs    int64
	ResultSummary string
}

ToolRuntimeState is the latest observed lifecycle state for a tool call.

type TranscriptCoord

type TranscriptCoord struct {
	Valid          bool
	ContentRow     int
	AbsLine        int
	Column         int
	PlainOffset    int
	LineStart      bool
	BlockID        string
	MsgID          string
	BlockIdx       int
	LineInBlock    int
	BoundaryBefore bool
}

TranscriptCoord is a semantic transcript position. ContentRow remains local to the currently mounted contentLines slice; AbsLine is the global transcript display line used by virtual scrolling and block anchors.

type VimAction

type VimAction string

VimAction identifies a viewport action triggered by a vim key binding.

const (
	// Single-key actions
	VimActionScrollDown   VimAction = "vim.scroll_down"    // j
	VimActionScrollUp     VimAction = "vim.scroll_up"      // k
	VimActionGotoBottom   VimAction = "vim.goto_bottom"    // G
	VimActionSearch       VimAction = "vim.search"         // /
	VimActionNextMatch    VimAction = "vim.next_match"     // n
	VimActionPrevMatch    VimAction = "vim.prev_match"     // N
	VimActionToggleFold   VimAction = "vim.toggle_fold"    // o
	VimActionHalfPageDown VimAction = "vim.half_page_down" // ctrl+d
	VimActionHalfPageUp   VimAction = "vim.half_page_up"   // ctrl+u

	// Mode transition
	VimActionInsertMode VimAction = "vim.insert_mode" // i or a

	// Compound-key actions (resolved via pending buffer)
	VimActionGotoTop   VimAction = "vim.goto_top"   // gg
	VimActionYankBlock VimAction = "vim.yank_block" // yy
)

type VimMode

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

VimMode is a pure-logic vim normal mode handler. It does not hold any reference to the TUI Model; callers are responsible for applying the returned VimAction to the viewport.

Lifecycle:

enabled=false → HandleKey always returns ("", false); behaves as passthrough.
enabled=true, mode=VimInsert → same passthrough; Esc transitions to VimNormal.
enabled=true, mode=VimNormal → intercepts navigation keys, returns VimAction.

func NewVimMode

func NewVimMode() *VimMode

NewVimMode creates a disabled VimMode in insert state.

func (*VimMode) Enabled

func (v *VimMode) Enabled() bool

Enabled reports whether vim mode is enabled.

func (*VimMode) EnterInsert

func (v *VimMode) EnterInsert()

EnterInsert switches back to VimInsert mode. Called by key_handlers.go when a VimActionInsertMode is returned, so it can re-focus the textarea.

func (*VimMode) EnterNormal

func (v *VimMode) EnterNormal()

EnterNormal switches to VimNormal mode. This is the handler for Esc when vim is enabled and the input area is not processing. Callers (key_handlers.go) call this method and then re-focus the viewport instead of the textarea.

func (*VimMode) HandleKey

func (v *VimMode) HandleKey(msg tea.KeyMsg) (VimAction, bool)

HandleKey processes a key message and returns the corresponding VimAction.

Returns (action, true) when the key is consumed by vim normal mode. Returns ("", false) when:

  • vim mode is disabled,
  • current state is VimInsert,
  • the key starts a compound sequence (pending is set; caller should not pass the key to the textarea),
  • the key does not match any known vim binding.

The second return value (consumed bool) is true whenever the key should NOT be forwarded to the underlying input component. This includes both the case where an action was produced and the case where a partial compound key was buffered.

func (*VimMode) IsNormalMode

func (v *VimMode) IsNormalMode() bool

IsNormalMode reports whether vim normal mode is currently active. Convenience helper for view rendering (e.g. status bar indicator).

func (*VimMode) Mode

func (v *VimMode) Mode() VimModeState

Mode returns the current VimModeState.

func (*VimMode) SetEnabled

func (v *VimMode) SetEnabled(enabled bool)

SetEnabled enables or disables vim mode. When disabled, HandleKey always returns ("", false) and the state is reset to VimInsert.

type VimModeState

type VimModeState int

VimModeState represents whether vim mode is in normal or insert mode.

const (
	// VimInsert is the default state. In this state all keys pass through to the
	// underlying input component unchanged, exactly as if vim mode were disabled.
	VimInsert VimModeState = iota

	// VimNormal intercepts navigation keys and routes them to viewport actions.
	VimNormal
)

type WorkspaceChoice

type WorkspaceChoice struct {
	Action string // "confirm" | "change"
	Path   string // resolved absolute path when Action="change"
}

WorkspaceChoice represents the workspace selection result.

type WorkspaceOverlay

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

WorkspaceOverlay implements Overlay for the workspace selection dialog.

func NewWorkspaceOverlay

func NewWorkspaceOverlay(cwd string) *WorkspaceOverlay

NewWorkspaceOverlay creates a new workspace selection overlay.

func (*WorkspaceOverlay) BlocksInput

func (o *WorkspaceOverlay) BlocksInput() bool

func (*WorkspaceOverlay) ID

func (o *WorkspaceOverlay) ID() string

func (*WorkspaceOverlay) Kind

func (o *WorkspaceOverlay) Kind() OverlayKind

func (*WorkspaceOverlay) Update

func (o *WorkspaceOverlay) Update(msg tea.Msg) (Overlay, *OverlayResult, tea.Cmd)

func (*WorkspaceOverlay) View

func (o *WorkspaceOverlay) View(width, height int) string

type WorkspaceState

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

WorkspaceState holds workspace selection dialog state.

func (*WorkspaceState) Reset

func (s *WorkspaceState) Reset()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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