tui

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: AGPL-3.0 Imports: 53 Imported by: 0

Documentation

Overview

Package tui implements the terminal user interface for the jungi chat application. It composes the message history, text input, and command palette into a three-panel layout and drives interaction through a vim-inspired modal editing model.

Index

Constants

View Source
const (
	// NormalMode suspends text entry and allows scrolling the message history
	// with standard vim motion keys. Press "i" to enter InsertMode, or "/"
	// to open the command palette (CommandMode). This is the default state on
	// startup and after executing a command.
	NormalMode = iota

	// InsertMode routes keystrokes to the text input field. Escape returns to
	// NormalMode. The user must explicitly enter this mode by pressing "i".
	InsertMode

	// CommandMode overlays the command palette on the history panel. All
	// keystrokes are forwarded to the palette until the user confirms a
	// selection (Enter) or cancels (Escape), both of which return to NormalMode.
	CommandMode

	// OverlayMode is active while a slash-command-triggered overlay (the
	// directory picker, the session list) holds focus. Dispatch is keyed on
	// the overlayKind field rather than another mode constant because the two
	// overlays share the same lifecycle: forward keys until they emit a select
	// or cancel message.
	OverlayMode
)

Editing mode constants govern which component receives keyboard input and which visual indicators are displayed in the divider bar. The zero value (NormalMode) is the navigation state so that a freshly created Model awaits an explicit "i" keypress before accepting text input.

Global key bindings (active in all modes):

  • Ctrl-C: quit the application.
  • Ctrl-K: interrupt any in-flight model execution.

Variables

This section is empty.

Functions

This section is empty.

Types

type ApprovalRequestMsg

type ApprovalRequestMsg struct {
	Descriptor approval.Descriptor
	Command    string
	Reason     string

	SessionID string
	// contains filtered or unexported fields
}

ApprovalRequestMsg carries a tool approval request from the tool-use loop into the Bubble Tea update loop. The TUI suspends the loop, shows the approval overlay, and writes a response to ResponseCh when the user decides.

type ApprovalResponseMsg

type ApprovalResponseMsg = session.ApprovalResponseMsg

ApprovalResponseMsg is re-exported from the session package so tui.Update can type-switch on it directly. It is sent via program.Send when the jungi control websocket connection receives a remote decision on a forwarded tool approval request.

type AssistantTextMsg added in v0.2.0

type AssistantTextMsg struct {
	Text string

	SessionID string
	// contains filtered or unexported fields
}

AssistantTextMsg carries one non-empty assistant-text block as it arrives, before any tools from the same response run. The channel fields allow chaining back to wait for the next event.

type AutoApproveResultMsg

type AutoApproveResultMsg struct {
	Descriptor approval.Descriptor
	Approved   bool
	Rationale  string
	Err        error

	SessionID string
	// contains filtered or unexported fields
}

AutoApproveResultMsg carries the AI evaluator's decision back into the Bubble Tea update loop. It is emitted by the tea.Cmd spawned in handleApprovalRequest when auto-approve is enabled, and handled in handleAutoApproveResult.

type CacheCompactionDoneMsg

type CacheCompactionDoneMsg struct {
	Summary   string
	SessionID string
}

CacheCompactionDoneMsg carries the summary text produced by the compaction API call back into the TUI update loop.

type CacheCompactionErrorMsg

type CacheCompactionErrorMsg struct {
	Err       error
	SessionID string
}

CacheCompactionErrorMsg signals that the compaction API call failed. The session history is left intact so the next idle timer cycle can retry.

type CacheCompactionTriggerMsg

type CacheCompactionTriggerMsg = session.CacheCompactionTriggerMsg

CacheCompactionTriggerMsg is re-exported from the session package so tui.Update can type-switch on it directly. The idle timer sends this via program.Send when 50 minutes of idle time elapses.

type ChannelMessageMsg

type ChannelMessageMsg = session.ChannelMessageMsg

ChannelMessageMsg is re-exported from the session package so tui.Update can type-switch on it directly. It is sent via program.Send when the jungi control websocket connection receives an inbound message.

type CompactErrorMsg

type CompactErrorMsg struct {
	Err       error
	SessionID string
}

CompactErrorMsg signals that the summary API call initiated by /compact failed. The old session is left intact so the user can retry.

type CompactSummaryMsg

type CompactSummaryMsg struct {
	Summary      string
	WorkDir      string
	OldSessionID string
}

CompactSummaryMsg carries the summary text produced by the old session's model, along with the old session ID and working directory needed to wire the carry-over message into the new session. It is emitted by waitForCompactEvent once the summary API call completes successfully.

type Deps added in v0.2.0

type Deps struct {
	// ScaffoldResult reports which paths scaffold.EnsureUserConfig created
	// on this startup, used to show a first-run notice on the idle screen.
	ScaffoldResult scaffold.Result
	// StartupFeatures reports which model slots are configured in the
	// settings merged at process startup (user settings plus any project
	// settings found at the working directory's repo root). Used to gate
	// the idle command palette before any session — and therefore no
	// per-session Settings — exists.
	StartupFeatures settings.FeatureSet
	// StartupModels reports the model identifier configured for each
	// session-creating command ("new", "plan", "execute", "review") in the
	// settings merged at process startup. Paired with the manager's
	// CredentialAvailable to resolve, per command, whether its own
	// configured model's provider has a stored credential.
	StartupModels map[string]model.ID
}

Deps bundles the process-level values New needs beyond the session manager itself.

type Model

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

Model is the root Bubble Tea model for the application. It owns the visible UI components (history, input, command palette, overlays) and holds a reference to the session manager; per-session runtime state (executor, logger, etc.) is read through manager.Active() at the point of use rather than being copied onto the TUI struct, so future multi-session navigation can swap the active session without rebuilding the TUI.

func New

func New(manager *session.Manager, deps ...Deps) Model

New constructs the root TUI model wired to the given session manager. The model starts in NormalMode; the user must press "i" to begin typing. The input widget is constructed blurred; Focus is issued only when transitioning to InsertMode. deps is optional; omit it in tests that don't care about process-level startup values such as the scaffolding result — omitting it also defaults StartupFeatures to "everything configured" so such tests don't need to opt in to see session-creating idle commands.

func (Model) Init

func (m Model) Init() tea.Cmd

Init satisfies the tea.Model interface. Because the model starts in NormalMode, no cursor-blink command is needed; the blink is started when the user presses "i" to enter InsertMode.

func (Model) InputFocused

func (m Model) InputFocused() bool

InputFocused reports whether the text input currently has keyboard focus. Used by tests to assert that Blur was called after message handler events.

func (Model) Mode

func (m Model) Mode() int

Mode returns the current editing mode (InsertMode, NormalMode, or CommandMode). Primarily used by tests and external status renderers.

func (Model) SessionUsage

func (m Model) SessionUsage() usage.SessionUsage

SessionUsage returns a snapshot of the accumulated token and cost totals for the active session. The snapshot is safe to read after any Update call. Returns the zero value when no active session exists.

func (Model) Update

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

Update is the central event dispatcher: it routes each message to a handler method by type. The handlers are grouped by concern across update_input.go (terminal events), update_exec.go (the tool-use loop), update_orchestration.go (multi-agent orchestration), update_compact.go (history compaction), and update_overlays.go (overlay / picker / command results).

Key routing within handleKey follows the active mode (Normal/Insert/Command/ Overlay); Ctrl-C quits and Ctrl-K interrupts from any mode. Unmatched message types fall through to a no-op.

func (Model) View

func (m Model) View() string

View renders the full terminal frame. Layout from top to bottom:

  1. History viewport (or command palette overlaid on top of it)
  2. Divider bar — horizontal rule with inline usage stats on the left and the active mode indicator flush-right
  3. Text input prompt

The divider is assembled by measuring the rendered widths of the mode tag and usage string, then filling the remaining columns with box-drawing characters so the bar always spans the full terminal width.

The command palette is composited as a floating overlay rather than splitting the layout so that the history context remains visible behind it.

func (Model) Waiting

func (m Model) Waiting() bool

Waiting reports whether the active session has an API request in flight. While true, new submissions to the active session are silently dropped and the divider shows "WAITING". Returns false when no session is active.

type ModelErrorMsg

type ModelErrorMsg struct {
	Err       error
	SessionID string
}

ModelErrorMsg signals that the API call failed. The error is written to the logger and surfaced to the user as a harness-role message in the history so the session can continue without restarting.

type ModelResponseMsg

type ModelResponseMsg struct {
	Result    toolexec.Result
	SessionID string
}

ModelResponseMsg carries the final API response back into the Bubble Tea update loop after all tool invocations are complete.

type OrchestrationResultMsg

type OrchestrationResultMsg struct {
	Result    orchestrator.Result
	Source    string // identifies which command initiated this
	SessionID string
}

OrchestrationResultMsg carries the aggregated result of a multi-agent orchestration back into the Bubble Tea update loop once every reviewer agent finishes. Started by cmdReviewAdHoc via Session.StartOrchestration; per-agent progress leading up to this arrives separately as SubagentProgressMsg (async injection), not as part of this message.

type SessionTitleMsg added in v0.3.0

type SessionTitleMsg struct {
	SessionID string
	Title     string
	Err       error
}

SessionTitleMsg is returned when asynchronous session title generation finishes.

type SubagentProgressMsg

type SubagentProgressMsg = session.SubagentProgressMsg

SubagentProgressMsg is re-exported from the session package so tui.Update can type-switch on it directly. It is the single message type for reviewer/research subagent progress: Session.StartOrchestration (ad-hoc /review) and planAgentRunner.ReviewDiff (plan-driven review_ticket) both send it via program.Send as each subagent starts, finishes, or errors.

type ToolEventMsg

type ToolEventMsg struct {
	Event toolexec.ToolEvent

	SessionID string
	// contains filtered or unexported fields
}

ToolEventMsg carries a single tool execution event to the TUI as it happens, allowing progressive display of command output during the agentic loop. The channel fields allow chaining back to wait for the next event.

type UsageUpdateMsg

type UsageUpdateMsg struct {
	Usage usage.RequestUsage

	SessionID string
	// contains filtered or unexported fields
}

UsageUpdateMsg carries a single API round-trip's RequestUsage into the TUI as it happens (before the turn as a whole completes), allowing the status bar's cost/context indicators to update live during a long tool-use loop. The channel fields allow chaining back to wait for the next event. handleModelResponse still performs the authoritative end-of-turn fold from Result.Usages, skipping whatever prefix was already folded live (tracked via Session.LiveFoldedCount), so a live update here is a progressive preview, not a substitute for that reconciliation.

Source Files

  • cmd_clear.go
  • cmd_close.go
  • cmd_compact.go
  • cmd_credentials.go
  • cmd_dispatch.go
  • cmd_editor.go
  • cmd_execute.go
  • cmd_export.go
  • cmd_model.go
  • cmd_new.go
  • cmd_options.go
  • cmd_plan.go
  • cmd_prompt.go
  • cmd_reasoning.go
  • cmd_review.go
  • cmd_sessions.go
  • cmd_terminal.go
  • exec.go
  • keys.go
  • newsession.go
  • session.go
  • tool_history.go
  • tui.go
  • update.go
  • update_compact.go
  • update_exec.go
  • update_input.go
  • update_orchestration.go
  • update_overlays.go
  • view.go

Directories

Path Synopsis
Package approvalview implements the tool confirmation overlay.
Package approvalview implements the tool confirmation overlay.
Package closeconfirmview implements the dirty-worktree confirmation overlay shown when /close or /clear would destroy uncommitted or unpushed work.
Package closeconfirmview implements the dirty-worktree confirmation overlay shown when /close or /clear would destroy uncommitted or unpushed work.
Package cmdpalette implements the slash-command palette overlay.
Package cmdpalette implements the slash-command palette overlay.
Package credpicker implements a radio-button style overlay for selecting which provider credential to set.
Package credpicker implements a radio-button style overlay for selecting which provider credential to set.
Package history provides a scrollable transcript of the conversation.
Package history provides a scrollable transcript of the conversation.
Package input provides the multi-line text entry component used at the bottom of the chat UI.
Package input provides the multi-line text entry component used at the bottom of the chat UI.
Package modelpicker implements the overlay that lists locally cached models so the user can switch the active session's model.
Package modelpicker implements the overlay that lists locally cached models so the user can switch the active session's model.
Package modelresults implements the overlay that lists OpenRouter models returned by a modelsearch query.
Package modelresults implements the overlay that lists OpenRouter models returned by a modelsearch query.
Package modelsearch implements the /model overlay shown when the user picks the OpenRouter provider: a small editable form of search filters that gets translated into a catalog.Query and handed off to the OpenRouter models API.
Package modelsearch implements the /model overlay shown when the user picks the OpenRouter provider: a small editable form of search filters that gets translated into a catalog.Query and handed off to the OpenRouter models API.
Package newsessionconfirmview implements the confirmation overlay shown when the user starts a new session (via /new, /plan, /execute, /review, or the /sessions list "New session" item) while a session is already active.
Package newsessionconfirmview implements the confirmation overlay shown when the user starts a new session (via /new, /plan, /execute, /review, or the /sessions list "New session" item) while a session is already active.
Package optionspicker implements the /options overlay.
Package optionspicker implements the /options overlay.
Package overlay composites a foreground widget centred over a background terminal grid.
Package overlay composites a foreground widget centred over a background terminal grid.
Package planpicker implements the overlay shown when the user runs /execute without a slug argument.
Package planpicker implements the overlay shown when the user runs /execute without a slug argument.
Package promptpicker implements the overlay shown when the user runs /prompt.
Package promptpicker implements the overlay shown when the user runs /prompt.
Package reasoningpicker implements the /reasoning overlay.
Package reasoningpicker implements the /reasoning overlay.
Package sessionlist implements the overlay shown when the user runs /sessions.
Package sessionlist implements the overlay shown when the user runs /sessions.
Package styles defines the lipgloss color and layout constants shared across the TUI.
Package styles defines the lipgloss color and layout constants shared across the TUI.
Package ticketpicker implements the overlay shown after the user selects a plan from the plan picker during /execute.
Package ticketpicker implements the overlay shown after the user selects a plan from the plan picker during /execute.

Jump to

Keyboard shortcuts

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