-
-
Notifications
You must be signed in to change notification settings - Fork 0
Terminal UI
M31 Autonomous's (M31A) terminal interface is built with Bubble Tea, following the Elm architecture with a single-threaded Update() loop. The TUI provides 31 distinct screens, 40+ reusable components, and 5+ themes.
cmd/m31a/main.go
│
▼
tea.NewProgram(AppState)
├── Init() → startup commands
├── Update() → message routing, state transitions
└── View() → screen rendering
Source: internal/tui/app.go
Source: internal/tui/app_state.go
AppState is the root Bubble Tea model containing:
| Field | Type | Purpose |
|---|---|---|
screen |
Screen enum |
Active screen identifier |
config |
*config.Config |
Runtime configuration |
registry |
*provider.Registry |
LLM provider registry |
dispatcher |
*tools.Dispatcher |
Tool dispatcher |
sessionManager |
*session.Manager |
Session lifecycle |
workflowEngine |
*workflow.Engine |
Workflow orchestration |
replModel |
*ReplModel |
REPL screen model |
sidebarModel |
*SidebarModel |
Sidebar panel |
themeManager |
*theme.Manager |
Theme management |
| Various screen models | Model selector, settings, plan, diff, etc. |
| Screen | Source | Description |
|---|---|---|
ScreenREPL |
repl_model.go |
Main chat interface |
ScreenFirstRun |
firstrun_model.go |
Initial API key setup |
ScreenModelSelector |
modelselector_model.go |
Fuzzy model search |
ScreenSettings |
settings_model.go |
Config editor with tabs |
ScreenConfig |
config_model.go |
Full config.toml editor |
ScreenPlan |
plan_model.go |
Plan viewer and refiner |
ScreenExecute |
execute_model.go |
Task execution view |
ScreenVerify |
verify_model.go |
Verification results |
ScreenShip |
ship_model.go |
Ship phase view |
ScreenDiff |
diff_model.go |
Git diff viewer |
ScreenRollback |
rollback_model.go |
Commit rollback browser |
ScreenResume |
resume_model.go |
Session resume picker |
ScreenDashboard |
dashboard_model.go |
Workflow dashboard |
ScreenMetrics |
metrics_model.go |
Session analytics |
ScreenLedger |
ledger_model.go |
Learning ledger |
ScreenFileExplorer |
fileexplorer_model.go |
File tree browser |
ScreenChatHistory |
chathistory_model.go |
Message history browser |
ScreenBisect |
bisect_model.go |
Model response comparison |
ScreenDiscuss |
discuss_model.go |
Discuss Q&A interface |
ScreenHelp |
help_model.go |
Keybinding help |
ScreenThemePicker |
themepicker_model.go |
Theme selection |
ScreenToolDetail |
tooldetail_model.go |
Tool detail view |
ScreenSessionDetail |
sessiondetail_model.go |
Session detail view |
ScreenConfirmQuit |
confirmquit_model.go |
Quit confirmation |
ScreenNotification |
notification_model.go |
Notification center |
ScreenGhostPicker |
ghostpicker_model.go |
Ghost write file picker |
ScreenGhostOutput |
ghostoutput_model.go |
Ghost write output |
ScreenSubagents |
subagents_model.go |
Subagent manager |
ScreenPhaseModelPicker |
phasemodelpicker.go |
Per-phase model assignment |
ScreenCommandPalette |
commandpalette_model.go |
Full-screen searchable command browser with split-panel layout |
Source: internal/tui/components/
40+ reusable UI components:
| Component | Purpose |
|---|---|
badge.go |
Status badges with color coding |
bash_renderer.go |
Syntax-highlighted bash command output |
breadcrumb.go |
Navigation breadcrumbs |
card.go |
Content cards with borders |
codeblock.go |
Code blocks with syntax highlighting |
confirm.go |
Confirmation dialogs |
datatable.go |
Tabular data display |
divider.go |
Visual dividers |
dropdown.go |
Dropdown menus |
file_renderers.go |
File content renderers |
filetree.go |
File tree with expand/collapse |
filterchips.go |
Filter chip selectors |
logo.go |
Application logo rendering |
message.go |
Chat message rendering (markdown) |
metriccard.go |
Metric display cards |
notification_list.go |
Notification list with auto-expiry |
permission.go |
Permission modal |
progress.go |
Progress bars |
question.go |
Question/option picker |
search.go |
Search input |
sparkline.go |
Sparkline charts |
special_renderers.go |
Special content renderers |
spinner.go |
Loading spinners (multiple styles) |
splitpane.go |
Split pane layout |
starfield.go |
Animated starfield background |
statrow.go |
Statistics row display |
syntax.go |
Syntax highlighting (Chroma-based) |
tabbar.go |
Tab bar navigation |
taskgraph.go |
Task dependency graph visualization |
thinking.go |
Thinking/reasoning block display |
timeline.go |
Event timeline |
toolcard.go |
Tool execution cards |
toolrenderers.go |
Tool-specific renderers |
truncate.go |
Text truncation helpers |
workflow_phasebar.go |
Workflow phase progress bar |
Source: internal/tui/theme/
| File | Purpose |
|---|---|
theme.go |
Theme struct with all color/style definitions |
registry.go |
Theme registry with named themes |
colors.go |
Color palette definitions |
borders.go |
Border style definitions |
shadow.go |
Shadow effect rendering |
tabs.go |
Tab styling |
unicode.go |
Unicode character constants |
| Mode | Description |
|---|---|
ModeDark |
Dark theme (default) |
ModeLight |
Light theme |
ModeAuto |
Auto-detect from terminal |
Built with Lip Gloss for declarative styling.
Source: internal/tui/layout/
| File | Purpose |
|---|---|
responsive.go |
Responsive breakpoints and sizing |
page.go |
Page layout helper |
minscreen.go |
Minimum screen size handling |
Source: internal/tui/streaming/
| File | Purpose |
|---|---|
agent_loop.go |
Agent loop streaming with tool execution |
streaming.go |
Core streaming response rendering |
The streaming system:
- Receives
StreamChunkfrom the provider - Renders text deltas incrementally
- Accumulates tool_call chunks
- Updates thinking duration display
- Handles usage tracking
The REPL is the primary interaction surface. It supports:
Source: internal/tui/repl.go and related files
| Feature | Source |
|---|---|
| Message history | repl_model.go |
| Streaming display | repl_stream.go |
| Thinking blocks | repl_thinking.go |
| Mouse support | repl_mouse.go |
| Scrollbar | repl_scrollbar.go |
| Quick actions | repl_quickactions.go |
| Welcome screen | repl_welcome.go |
| Footer | repl_footer.go |
| Clipboard | repl_clipboard.go |
| State management | repl_state.go |
| Slash commands | repl_commands.go |
Source: internal/tui/cmdpalette.go, internal/tui/commandpalette_model.go
Press Ctrl+P to open. All registered slash commands appear with fuzzy search. Features a split-panel layout with searchable command list on the left and detail panel on the right.
Source: internal/tui/repl_mouse.go
Full mouse interaction is supported across all viewport-based screens:
| Event | Action |
|---|---|
| Scroll wheel | Scroll viewport content (REPL, plan, execute, verify, ship, ledger, chat history) |
| Left-click on viewport | Focus textarea + mark user-scrolled |
| Left-click on overlay | Select slash-suggestion or mention-suggestion item |
| Scrollbar drag | Drag-scroll the viewport via scrollbar thumb |
Mouse support is enabled via tea.MouseAll in the program options. The REPL model dispatches mouse events to the appropriate handler based on coordinates and UI state.
The TUI drives the workflow engine via RunPhaseCmd():
User types "/workflow"
│
▼
AppState.initWorkflowEngine()
│
▼
RunPhaseCmd(PhaseInitialize) → engine.RunPhase() in goroutine
│
▼
PhaseResultMsg arrives via Bubble Tea message
│
▼
AppState transitions to next phase
│
▼
RunPhaseCmd(PhaseDiscuss) → ... → RunPhaseCmd(PhaseShip)
Messages from the engine reach the TUI through a channelEmitter that writes to a buffered channel, drained by drainEmitterCmd().