Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TUICommander — Complete Feature Reference

Canonical feature inventory. Update this file when adding, changing, or removing features. See AGENTS.md for the maintenance requirement.

Version: 1.1.0 | Last verified: 2026-05-04


1. Terminal Management

1.1 PTY Sessions

  • Up to 50 concurrent PTY sessions (configurable in Rust MAX_SESSIONS)
  • Each tab runs an independent pseudo-terminal with the user’s shell
  • Terminals are never unmounted — hidden tabs stay alive with full scroll history
  • Session persistence across app restarts (lazy restore on branch click); only agent tabs are restored — plain shell tabs are discarded and a fresh terminal is spawned instead
  • Agent session restore shows a clickable banner (“Agent session was active — click to resume”) instead of auto-injecting the resume command; Space/Enter resumes, other keys dismiss
  • Foreground process detection (macOS: libproc, Windows: CreateToolhelp32Snapshot)
  • PTY environment: TERM=xterm-256color, COLORTERM=truecolor, LANG=en_US.UTF-8
  • Pause/resume PTY output (pause_pty / resume_pty Tauri commands) — suspends reader thread without killing the session

1.2 Tab Bar

  • Create: Cmd+T, + button (click = new tab, right-click = split options)
  • Close: Cmd+W, middle-click, context menu
  • Reopen last closed: Cmd+Shift+T (remembers last 10 closed tabs)
  • Switch: Cmd+1 through Cmd+9, Ctrl+Tab / Ctrl+Shift+Tab
  • Rename: double-click tab name (inline editing)
  • Reorder: drag-and-drop with visual drop indicators (works for all tab types: terminal, diff, editor, markdown, plugin panels)
  • Tab status dot (left of name): grey=idle, blue-pulse=busy, green=done, purple=unseen (completed while not viewed), orange-pulse=question (needs input), red-pulse=error
  • Tab type colors: red gradient=diff, blue gradient=editor, teal gradient=markdown, purple gradient=panel, amber gradient=remote PTY session
  • Remote PTY sessions (created via HTTP/MCP) show “PTY:” prefix and amber styling
  • Progress bar (OSC 9;4)
  • Context menu (right-click): Close Tab, Close Other Tabs, Close Tabs to the Right, Detach to Window, Copy Path (on diff/editor/markdown file tabs)
  • Detach to Window: right-click a tab to open it in a floating OS window
    • PTY session stays alive in Rust — floating window reconnects to the same session
    • Closing the floating window automatically returns the tab to the main window
    • Requires an active PTY session (disabled for tabs without a session)
  • Overflow menu on scroll arrows (right-click) shows clipped tabs; the + button always stays visible regardless of scroll position
  • Tab pinning: pinned tabs are visible across all branches (not scoped to branch key)

1.3 Split Panes

  • Vertical split: Cmd+\ (side by side)
  • Horizontal split: Cmd+Alt+\ (stacked)
  • Navigate: Alt+←/→ (vertical), Alt+↑/↓ (horizontal)
  • Close active pane: Cmd+W
  • Drag-resize divider between panes
  • Up to 6 panes in same direction (N-way split)
  • Split layout persists per branch

1.4 Zoom (Per-Terminal)

  • Zoom in: Cmd+= (+2px)
  • Zoom out: Cmd+- (-2px)
  • Reset: Cmd+0
  • Range: 8px to 32px
  • Current zoom shown in status bar

1.5 Copy & Paste

  • Copy selection: Cmd+C
  • Paste to terminal: Cmd+V
  • Trailing whitespace trimmed — All copy paths (Cmd+C, Ctrl+C, copy-on-select) strip trailing spaces from terminal rows
  • Copy on Select — When enabled (Settings > General > Terminal or Settings > Appearance), selecting text in the terminal automatically copies it to the clipboard. A brief “Copied to clipboard” confirmation appears in the status bar.
  • Copy feedback (Cmd+C) — Copying via Cmd+C shows “Copied to clipboard” in the status bar, consistent with copy-on-select and Ctrl+C paths.

1.6 Clear Terminal

  • Cmd+L — clears display, running processes unaffected

1.7 Clickable File Paths

  • File paths in terminal output are auto-detected and become clickable links
  • Paths validated against filesystem before activation (Rust resolve_terminal_path)
  • .md/.mdx → opens in Markdown panel; preview-capable files (HTML, PDF, images, video, audio, plain text/data) → open in the Preview tab (section 3.15); all other code files → open in the built-in code editor
  • file:// URLs are recognized in addition to plain paths — the prefix is stripped and the path resolved like any other
  • OSC 8 hyperlinks: programs that emit hyperlink escape sequences (e.g. Claude Code, modern ls) produce clickable links; hover underline spans the full link text (via terminal_hyperlink_span backend API)
  • Supports :line and :line:col suffixes for precise navigation
  • Recognized extensions: rs, ts, tsx, js, jsx, py, go, java, kt, swift, c, cpp, cs, rb, php, lua, zig, css, scss, html, vue, svelte, json, yaml, toml, sql, graphql, tf, sh, dockerfile, and more

1.8 Find in Content

  • Cmd+F opens search overlay — context-aware: routes to terminal, markdown tab, or diff tab based on active view
  • Terminal: incremental search with highlight decorations
  • Markdown viewer: DOM-based search with cross-element matching (finds text spanning inline tags)
  • Diff viewer: DOM-based search via SearchBar + DomSearchEngine (same engine as markdown viewer)
  • Yellow highlight for matches, orange for active match
  • Navigate matches: Enter / Cmd+G (next), Shift+Enter / Cmd+Shift+G (previous)
  • Toggle options: case sensitive, whole word, regex
  • Match counter shows “N of M” results
  • Escape closes search and refocuses content

1.9 International Keyboard Support

  • Terminal handles international keyboard input correctly
  • Rate-limit false positives reduced for non-ASCII input

1.10 Move Terminal to Worktree

  • Right-click a terminal tab → “Move to Worktree” submenu lists available worktrees (excluding the current one)
  • Selecting a worktree sends cd to the PTY; OSC 7 auto-reassigns the terminal to the target branch
  • Also available via Command Palette: dynamic “Move to worktree: <branch>” entries appear when the active terminal belongs to a repo with multiple worktrees
  • Only shown when the repo has more than one worktree

1.11 OSC 7 CWD Tracking

  • Terminals report their current working directory via OSC 7 escape sequences
  • Parsed in the Rust backend from PTY output and stored per-session as session_cwd
  • When a terminal’s CWD falls inside a known worktree path, the session is automatically reassigned to the correct branch in the sidebar
  • Enables accurate branch association even when the user cds into a different worktree from a single terminal

1.12 Kitty Keyboard Protocol

  • Supports Kitty keyboard protocol flag 1 (disambiguate escape codes)
  • Per-session flag tracking via get_kitty_flags Tauri command
  • Enables correct handling of Shift+Enter (multi-line input), Ctrl+Backspace, and modifier key combinations in agents that request the protocol (e.g. Claude Code)

1.13 File Drag & Drop

  • Drag files from Finder/Explorer onto the terminal area or any panel
  • Uses Tauri’s native onDragDropEvent API (not HTML5 File API — Tauri webviews do not expose file paths via HTML5)
  • Active PTY session: dropped file paths are forwarded directly to the terminal as text (enables Claude Code image drops and similar workflows)
  • No active PTY session: .md/.mdx files open in Markdown viewer, preview-capable files open in the Preview tab (section 3.15), all other files open in Code Editor
  • Multiple files can be dropped at once
  • Visual overlay with dashed border appears during drag hover
  • Global dragover/drop preventDefault prevents the Tauri webview from treating drops as browser navigation (which would replace the UI with a white screen)
  • macOS file association: .md/.mdx files registered with TUICommander — double-click in Finder opens them directly
  • Drag to external apps: Drag files from the File Browser to external applications (Finder, email clients, etc.) using native OS-level drag via tauri-plugin-drag. Works alongside internal drag & drop (tab reorder, split panes)
  • Type ~ in the command palette (Cmd+P) to search text across all open terminal buffers
  • Results show terminal name, line number, and highlighted match text
  • Selecting a result switches to the correct terminal tab/pane and scrolls to the matched line (centered in viewport)
  • Minimum 3 characters after prefix
  • Also accessible via the explicit “Search Terminals” command in the palette

1.15 Refresh Terminal (Cmd+Shift+L)

  • Rebuilds the terminal renderer to fix corrupted glyphs (WebGL atlas issues, font rendering artifacts)
  • Does not clear content or affect the PTY session — purely a visual refresh
  • Action name: refresh-terminal

1.16 Terminal Bell

  • Terminal Bell — Configurable bell behavior when the terminal receives a BEL character (\x07). Four modes: none (silent), visual (screen flash animation), sound (plays the Info notification sound), both (flash + sound). Configure in Settings > Appearance.

1.17 Scrollback History Overlay (Experimental)

  • Read-only overlay for viewing full terminal scrollback beyond the visible buffer
  • Gated behind scrollHistoryEnabled settings flag (Settings > General > Experimental Features)
  • Content reconstructed from VtLogBuffer via LogSpan ANSI reconstruction — preserves colors, bold, underline, and other SGR attributes
  • Built as a read-only terminal overlay using ANSI reconstruction from VtLogBuffer
  • Selection & copy: select text in the overlay; auto-copies to clipboard with ::selection highlight
  • Search (Cmd+F): incremental search with match highlighting via SearchAddon, “N of M” counter, Enter/Shift+Enter navigation
  • Theme-synced: ANSI CSS variables follow the active terminal theme
  • Grid-aligned positioning matches the underlying terminal metrics

1.18 Command Blocks

Terminal output is segmented into command blocks — one per prompt+output cycle. Blocks are detected via OSC 133 shell integration markers (A/C/D sequences) or OSC 7770;block= agent-emitted markers. For Claude Code, heuristic detection synthesizes blocks from tool call headers (⏺ ToolName(args)).

  • Scrollbar marks — Color-coded indicators on the scrollbar for each command block boundary. Provides a visual map of command history at a glance
  • Timestamp overlay — Hold Ctrl+Cmd to reveal timestamps showing when each block started, displayed as relative time (e.g. “2m ago”)
  • Gutter click — Click the gutter area to select the entire block output for easy copying
  • Block folding — Collapse/expand block output with Cmd+Shift+. toggle. Folded blocks show a summary line. Backend stores fold state per session via set_block_fold Tauri command
  • Block-scoped search — Toggle with Cmd+Shift+B to restrict terminal search to the current block only
  • Block navigationCmd+Shift+Up/Down jumps between block boundaries
  • Block cap — Sessions are capped at 500 command blocks; oldest blocks are evicted when the cap is reached
  • Settings — Configure block features at Settings > Terminal > Blocks: show/hide timestamps, enable/disable folding

2. Sidebar

2.1 Repository List

  • Add repository via + button or folder dialog
  • Click repo header to expand/collapse branch list
  • Click again to toggle icon-only mode (shows initials)
  • button: Repo Settings, Switch Branch (via context menu on main worktree), Create Worktree, Move to Group, Park Repository, Remove
  • macOS TCC access dialog: when the OS denies access to a repository directory (e.g. Desktop, Documents), a dialog explains the issue and guides the user to grant Full Disk Access in System Settings

2.2 Repository Groups

  • Named, colored groups for organizing repositories
  • Create: repo → Move to Group → New Group…
  • Move repo: drag onto group header, or repo → Move to Group → select group
  • Remove from group: repo → Move to Group → Ungrouped
  • Group context menu (right-click header): Rename, Change Color, Delete
  • Collapse/expand: click group header
  • Reorder groups: drag-and-drop
  • Color inheritance: repo color > group color > none

2.2.1 Switch Branch

Right-click the main worktree row → Switch Branch submenu to checkout a different branch. The submenu shows all local branches with a checkmark on the current one. If the working tree is dirty, prompts to stash changes first. Blocks switching when a terminal has a running process.

2.3 Branch Items

  • Click: switch to branch (shows its terminals, creates worktree if needed)
  • Double-click branch name: rename branch
  • Right-click context menu: Copy Path, Add Terminal, Create Worktree, Merge & Archive, Delete Worktree, Open in IDE, Rename Branch
  • CI ring: proportional arc segments (green=passed, red=failed, yellow=pending)
  • PR badge: colored by state (green=open, purple=merged, red=closed, gray=draft) — click for detail popover
  • Diff stats: +N / -N additions/deletions
  • Merged badge: branches merged into main show a “Merged” badge
  • Question indicator: ? icon (orange, pulsing) when agent asks a question
  • Idle indicator: branch icons turn grey when the repo has no active terminals
  • Quick switcher badge: numbered index shown when Cmd+Ctrl held
  • Remote-only branches with open PRs: shown in sidebar with PR badge and inline accordion actions (Checkout, Create Worktree). Additional actions when PR popover is open: Merge, View Diff, Approve, Dismiss
  • Dismiss/Show Dismissed: remote-only PRs can be dismissed from the sidebar; a “Show Dismissed” toggle reveals them again
  • Branch sorting: main/master/develop always first, then alphabetical; merged PR branches sorted last

2.4 Git Quick Actions

  • Bottom of sidebar when a repo is active
  • Pull, Push, Fetch, Stash buttons — execute in active terminal

2.5 Sidebar Resize

  • Drag right edge to resize (200-500px range)
  • Toggle visibility: Cmd+[
  • Width persists across sessions

2.6 Quick Branch Switcher

  • Hold Cmd+Ctrl (macOS) or Ctrl+Alt (Win/Linux): show numbered overlay
  • Cmd+Ctrl+1-9: switch to branch by index

2.7 Park Repos

  • Right-click any repo in the sidebar to park or unpark it
  • Group park/unpark: right-click a group header or use the command palette to park or unpark all repos in a group at once
  • Parked repos are hidden from the main repository list
  • Sidebar footer button opens a popover showing all parked repos
  • Unpark a repo from the popover to restore it to the main list

3. Panels

3.1 Panel System

  • File Browser, Markdown, Diff, and Plan panels are mutually exclusive — opening one closes the others
  • Ideas panel is independent (can be open alongside any of the above)
  • Subtle fade transition when closing side panels (opacity + transform animation)
  • All panels have drag-resize handles on their left edge (200-800px)
  • Min-width constraints prevent panels from collapsing (Markdown: 300px, File Browser: 200px)
  • Toggle buttons in status bar with hotkey hints visible during quick switcher

3.2 Diff Panel (Removed in 0.9.0)

Replaced by the Git Panel’s Changes tab (section 3.8). Cmd+Shift+D now opens the Git Panel

3.3 Markdown Panel (Cmd+Shift+M)

  • Renders .md and .mdx files with syntax-highlighted code blocks
  • File list from repository’s markdown files
  • Clickable file paths in terminal open .md files here
  • Auto-show: adding any markdown tab automatically opens the Markdown panel if it’s closed
  • Header bar shows file path (or title for virtual tabs) with Edit button (pencil icon) to open in CodeEditor
  • Cmd+F search: find text in rendered markdown with highlight navigation (shared SearchBar component)
  • Interactive GFM checkboxes: - [ ], - [x], and - [~] task-list items render as clickable checkboxes. Clicking cycles through unchecked → checked → in-progress → unchecked. Changes are written back to the source .md file on disk. The [~] state renders as an indeterminate (half-filled) checkbox — non-standard GFM extension for tracking in-progress items
  • Mermaid diagrams: fenced code blocks with ```mermaid are rendered as interactive SVG diagrams. Mermaid.js is lazy-loaded on first use with dark theme
  • Inline review comments (tweaks): select text in rendered markdown, add a comment — stored as HTML comment markers invisible to standard renderers but readable by humans and LLMs

3.4 File Browser Panel (Cmd+E)

  • Directory tree of active repository
  • Auto-refresh: directory watcher detects external file changes (create/delete/rename) and refreshes automatically within ~1s, preserving selection
  • Navigation: ↑/↓ (navigate), Enter (open/enter dir), Backspace (parent dir)
  • Breadcrumb toolbar: always-visible path bar with click-to-navigate segments + inline sort dropdown (funnel icon)
  • Search filter: text input with * and ** glob wildcard support
  • Git status indicators: orange (modified), green (staged), blue (untracked)
  • Context menu (right-click): Copy (Cmd+C), Cut (Cmd+X), Paste (Cmd+V), Rename, Delete, Add to .gitignore
  • Keyboard shortcuts work when panel is focused (copy/cut/paste)
  • Sort dropdown: Name (alphabetical, directories first) or Date (newest first, directories first)
  • View modes: flat list (default) and tree view — toggle via toolbar buttons. Tree view shows a collapsible hierarchy with lazy-loaded subdirectories on expand. Switching to tree resets to repo root. Search always uses flat results
  • Click file to open in code editor tab

3.4.1 Content Search (Cmd+Shift+F)

  • Full-text search across file contents — toggle from filename search via the C button in the search bar
  • Options: case-sensitive, regex, whole-word
  • Results stream progressively and are grouped by file with match count per file
  • Each result row shows file path, line number, and highlighted match context
  • Click a result to open the file in the code editor at the matched line
  • Binary files and files larger than 1 MB are automatically skipped
  • Backed by search_content Tauri command; results delivered via content-search-batch events

3.5 Code Editor (CodeMirror 6)

  • Opens in main tab area when clicking a file in file browser
  • Syntax highlighting auto-detected from extension (disabled for files > 500 KB)
  • Line numbers, bracket matching, active line highlight, Tab-to-indent
  • Find/Replace: Cmd+F (find), Cmd+G / Cmd+Shift+G (next/prev), Cmd+H (replace), selection match highlighting
  • Save: Cmd+S (when editor tab is focused)
  • Read-only toggle: padlock icon in editor header
  • Unsaved changes: dot indicator in tab bar and header
  • Disk conflict detection: banner with “Reload” (discard local) or “Keep mine” options
  • Auto-reloads silently when file changes on disk and editor is clean
  • Undo/Redo: Cmd+Z / Cmd+Shift+Z with full history
  • Code folding: collapse/expand blocks via gutter arrows or Cmd+Shift+[/]
  • Auto-close brackets: typing (, [, {, ", ' inserts matching pair
  • Scroll past end: last line can scroll to the top of the viewport
  • Block selection: Alt+drag for rectangular/column selection with crosshair cursor
  • Drop cursor: ghost cursor shown when dragging text over the editor
  • Special character highlighting: invisible chars (zero-width spaces, control chars) rendered as placeholders
  • CSS color preview: inline color swatches next to hex/rgb/rgba/hsl values

3.6 Ideas Panel (Cmd+Alt+N)

  • Quick notes / idea capture with send-to-terminal
  • Enter submits idea, Shift+Enter inserts newline
  • Per-idea actions: Edit (copies back to input), Send to Terminal (sends + return), Delete
  • Mark as used: notes sent to terminal are timestamped (usedAt) for tracking
  • Badge count: status bar toggle shows count of notes visible for the active repo
  • Per-repo filtering: notes can be tagged to a repository; untagged notes visible everywhere
  • Image paste: Ctrl+V / Cmd+V pastes clipboard images as thumbnails attached to the note
    • Images saved to config_dir()/note-images/<note-id>/ on disk
    • Thumbnails displayed inline below note text and in the input area before submit
    • Image-only notes (no text) are supported
    • Images removed from disk when the note is deleted
    • Send to terminal appends absolute image paths so AI agents can read them
    • Max 10 MB per image; accepted formats: PNG, JPEG, WebP, GIF
  • Edit preserves note identity (in-place update, no ID change)
  • Escape cancels edit mode
  • Data persisted to Rust config backend

3.7 Help Panel (Cmd+?)

  • Shows app info and links (About, GitHub, docs)
  • Keyboard shortcuts are now in Settings > Keyboard Shortcuts tab (auto-generated from actionRegistry.ts)

3.8 Git Panel (Cmd+Shift+D)

Tabbed side panel with four tabs: Changes, Log, Stashes, Branches. Replaces the former Git Operations Panel floating overlay and the standalone Diff Panel.

Changes tab:

  • Porcelain v2 working tree status via get_working_tree_status (branch, upstream, ahead/behind, stash count, staged/unstaged/untracked files)
  • Sync row: Pull, Push, Fetch buttons (background execution via run_git_command)
  • Stage / unstage individual files or stage all / unstage all
  • Discard unstaged changes (with confirmation dialog)
  • Inline commit form with message input and Amend toggle
  • Click a file row to open its diff in the diff panel
  • Status icons per file: Modified, Added, Deleted, Renamed, Untracked
  • Per-file diff counts (additions/deletions) shown inline
  • Glob filter to narrow the file list
  • Path-traversal validation on all stage/unstage/discard operations
  • History sub-panel (collapsible): per-file commit history via get_file_history (follows renames), paginated with virtual scroll
  • Blame sub-panel (collapsible): per-line blame via get_file_blame (porcelain format), age heatmap (green=recent, fading to neutral), commit metadata per line

Log tab:

  • Paginated commit log via get_commit_log (default 50, max 500)
  • Virtual scroll via @tanstack/solid-virtual for large histories
  • Canvas-based commit graph via get_commit_graph: lane assignment, Bezier curve connections, 8-color palette, ref badges (branch, tag, HEAD). Graph follows HEAD only
  • Click a commit row to expand and see its full commit message body (multi-line, untruncated) and changed files (via get_changed_files)
  • Click a file in an expanded commit to open its diff at that commit hash
  • Relative timestamps (e.g., “3h ago”)

Stashes tab:

  • List all stash entries via get_stash_list
  • Per-stash actions: Apply, Pop, Drop (via run_git_command)

Branches tab (Cmd+G — opens Git Panel directly on this tab):

  • Local and Remote branches in collapsible sections
  • Rich info per branch: ahead/behind counts (↑N ↓M), relative date, merged badge, stale dimming (branches with last commit > 30 days)
  • Prefix folding: groups branches by / separator (e.g. feature/, bugfix/), toggle to expand/collapse groups
  • Recent Branches section from git reflog
  • Inline search/filter to narrow branch list
  • Checkout (Enter / double-click): switches to the selected branch, with dirty worktree dialog (stash / force / cancel)
  • n — Create new branch (inline form, optional checkout)
  • d — Delete branch (safe + force options; refuses main branch and current branch)
  • R — Rename branch (inline edit)
  • M — Merge selected branch into current
  • r — Rebase current onto selected branch
  • P — Push branch (auto-detects missing upstream and sets tracking)
  • p — Pull current branch
  • f — Fetch all remotes
  • Context menu (right-click): Checkout, Create Branch from Here, Delete, Rename, Merge into Current, Rebase Current onto This, Push, Pull, Fetch, Compare (shows diff --name-status)
  • Backend: get_branches_detail, delete_branch, create_branch, get_recent_branches
  • Click on sidebar “GIT” vertical label also opens Git Panel on the Branches tab

Keyboard navigation:

  • Escape to close the panel
  • Ctrl/Cmd+1–4 to switch between tabs (1=Changes, 2=Log, 3=Stashes, 4=Branches)
  • Auto-refreshes via repo revision subscription

3.9 Quick Branch Switch (Cmd+B)

  • Fuzzy-search dialog to switch branches instantly
  • Shows all local and remote branches for the active repo
  • Badges: current, remote, main branch indicators
  • Keyboard navigation: Arrow keys, Enter to switch, Escape to close
  • Remote branches auto-checkout as local tracking branch
  • Fetches live branch list via get_git_branches

3.10 Task Queue Panel (Cmd+J)

  • Task management with status tracking (pending, running, completed, failed, cancelled)
  • Drag-and-drop task reordering

3.11 Command Palette (Cmd+P)

  • Fuzzy-search across all app actions by name
  • Recency-weighted ranking: recently used actions surface first
  • Each row shows action label, category badge, and keybinding hint
  • Keyboard-navigable: ↑/↓ to move, Enter to execute, Esc to close
  • Search modes: type ! to search files by name, ? to search file contents, ~ to search across all open terminal buffers. File/content results open in editor tab (content matches jump to the matched line). Terminal results navigate to the terminal tab/pane and scroll to the matched line. Leading spaces after prefix are ignored
  • Discoverable search commands: “Search Terminals”, “Search Files”, “Search in File Contents” appear as regular palette commands and pre-fill the corresponding prefix
  • Powered by actionRegistry.ts (ACTION_META map)

3.12 Activity Dashboard (Cmd+Shift+A)

  • Real-time view of all active terminal sessions in a compact list
  • Each row shows: terminal name, project name badge (last segment of CWD), agent type, status, last activity time
  • Sub-rows (up to one shown per terminal, in priority order):
    • currentTask (gear icon) — current agent task from status-line parsing (e.g. “Reading files”). Suppressed for Claude Code (spinner verbs are decorative)
    • agentIntent (crosshair icon) — LLM-declared intent via intent: token
    • lastPrompt (speech bubble icon) — last user prompt (>= 10 words). Shown only when no agentIntent is present
  • Status color codes: green=working, yellow=waiting, red=rate-limited, gray=idle
  • Rate limit indicators with countdown timers
  • Click any row to switch to that terminal and close the dashboard
  • Relative timestamps auto-refresh (“2s ago”, “1m ago”)

3.13 Error Log Panel (Cmd+Shift+E)

  • Centralized log of all errors, warnings, and info messages across the app
  • Sources: App, Plugin, Git, Network, Terminal, GitHub, Dictation, Store, Config
  • Level filter tabs: All, Error, Warn, Info, Debug
  • Source filter dropdown to narrow by subsystem
  • Text search across all log messages
  • Each entry shows timestamp, level badge (color-coded), source tag, and message
  • Copy individual entries or all visible entries to clipboard
  • Clear button to flush the log
  • Status bar badge shows unseen error/warning count (red, resets when panel opens)
  • Global error capture: uncaught exceptions and unhandled promise rejections are automatically logged
  • Ring buffer of 1000 entries (oldest dropped when full), Rust-backed — warn/error entries survive webview reloads via push_log/get_logs Tauri commands
  • Also accessible via Command Palette: “Error log”

3.14 Plan Detection

  • Plans are detected via structured plan-file events from the output parser and via plans/ directory watcher
  • Auto-open: restores the active plan from .claude/active-plan.json on startup; new plans opened as background markdown tabs on first detection (no focus change)
  • Repo-scoped: only processes plans belonging to the active repository

3.15 Preview Tab

  • Multi-format file previewer opened from clickable file paths, drag & drop, File Browser, or Command Palette
  • File routing handled by classifyFile() in src/utils/filePreview.ts
  • Supported formats:
    • HTML — rendered in sandboxed iframe with “Open in browser” button
    • PDF — rendered via asset protocol in embedded iframe
    • Images — PNG, JPG/JPEG, GIF, WebP, SVG, AVIF, ICO, BMP — rendered as <img> via asset protocol
    • Video — MP4, WebM, OGG, MOV — rendered as <video> with native controls
    • Audio — MP3, WAV, FLAC, AAC, M4A — rendered as <audio> with native controls
    • Text / data — TXT, JSON, CSV, LOG, XML, YAML, TOML, INI, CFG, CONF — raw text in a <pre> block
  • Header bar shows shortened file path with Edit button (pencil icon — opens file in code editor) and Open externally button
  • File content auto-refreshes on repository revision bumps (git change detection)
  • Uses Tauri’s convertFileSrc() asset protocol for binary files, read_external_file IPC for text content
  • CSP allows asset: and http://asset.localhost in frame-src and media-src

3.16 Focus Mode (Cmd+Alt+Enter)

  • Hides sidebar, tab bar, and all side panels to maximize the active tab’s content area
  • Toolbar and status bar remain visible for repo/branch state and mode exit
  • Session-only (not persisted across restarts)
  • Toggle again to restore the previous layout

3.17 Detachable Panels

  • Any panel (AI Chat, Activity Dashboard, Git Panel) can be detached into a separate OS window
  • Generic system via open_panel_window / close_panel_window Rust commands with per-panel adapters
  • Two-tier sync: self-sufficient panels (Git Panel) call Rust directly; projection panels (Activity Dashboard) receive state snapshots via emitTo at 1 Hz
  • Shared PanelWindowControls component provides consistent detach/reattach/close buttons across all panels
  • Closing a detached window automatically restores the panel to the main window
  • Tab bar “Detach to Window” context menu entry for per-tab detach (PTY session stays alive in Rust)
  • Generic lifecycle functions: togglePanel(), detachPanel(), reattachPanel() replace per-panel callsites
  • uiStore.detachedPanels map tracks all detached panels (replaces former aiChatDetached boolean)

4. Toolbar

4.1 Sidebar Toggle

  • button (left side) — same as Cmd+[
  • Hotkey hint visible during quick switcher

4.2 Branch Display

  • Center: shows repo / branch name
  • Click to open branch rename dialog

4.3 Plan File Button

  • Appears when an AI agent emits a plan file path (e.g., PLAN.md)
  • Click: .md/.mdx files open in Markdown panel; others open in IDE
  • Dismiss (×) button to hide without opening

4.4 Notification Bell

  • Bell icon with count badge when notifications are available
  • Click: opens popover listing all active notifications
  • Empty state: shows “No notifications” when nothing is pending
  • PR Updates section — types: Merged, Closed, Conflicts, CI Failed, CI Passed, Changes Requested, Ready
  • Git section — background git operation results (push, pull, fetch) with success/failure status
  • Worktrees section — worktree creation events (from MCP/agent)
  • Plugin activity sections — registered by plugins via activityStore
  • Click PR notification: opens full PR detail popover for that branch
  • Individual dismiss (×) per notification, section “Dismiss All”, auto-dismiss after 5min focused time

4.5 IDE Launcher

  • Button with current IDE icon — click to open repo/file in IDE
  • Dropdown: shows all detected installed IDEs, grouped by category
  • Categories: Code Editors, Terminals, Git Tools, System
  • File-capable editors open the focused file (from editor or MD tab); others open the repo
  • Run command button: Cmd+R (run), Cmd+Shift+R (edit & run)

5. Status Bar

5.1 Left Section

  • Zoom indicator: current font size (shown when != default)
  • Status info text (with pendulum ticker for overflow, pulse animation on new messages)
  • CWD path: shortened with ~/, click to copy to clipboard (shows “Copied!” feedback)
  • Unified agent badge with priority cascade:
    1. Rate limit warning (highest): count + countdown timer when sessions are rate-limited
    2. Claude Usage API ticker: live utilization from Anthropic API (click opens dashboard)
    3. PTY usage limit: weekly/session percentage from terminal output detection
    4. Agent name (lowest): icon + name of detected agent
    • Color coding: blue < 70%, yellow 70-89%, red pulsing >= 90%
    • Claude usage ticker absorbed into badge when active agent is Claude (avoids duplicate display)
  • Shared ticker area: multi-source rotating messages from plugins with source labels, counter badge (1/3 ▸), click-to-cycle, right-click popover, and priority tiers (low/normal/urgent)
  • Update badge: “Update vX.Y.Z” (click to download & install), progress percentage during download

5.2 GitHub Section (center)

  • Branch badge: name + ahead/behind counts — click for branch popover
  • PR badge: number + state color — click for PR detail popover
    • PR lifecycle filtering: CLOSED PRs hidden immediately; MERGED PRs hidden after 5 minutes of accumulated user activity
  • CI badge: ring indicator — click for PR detail popover

5.3 Right Section — Panel Toggles

  • Ideas (lightbulb icon) — Cmd+Alt+N
  • File Browser (folder icon) — Cmd+E
  • Markdown (MD icon) — Cmd+Shift+M
  • Git (diff icon) — Cmd+Shift+D (opens Git Panel)
  • Mic button (when dictation enabled): hold to record, release to transcribe

6. AI Agent Support

6.1 Supported Agents

AgentBinaryResume Command
Claude Codeclaudeclaude --resume <uuid> (session-aware) / claude --continue (fallback)
Gemini CLIgeminigemini --resume <uuid> (session-aware) / gemini --resume (fallback)
OpenCodeopencodeopencode -c
Aideraideraider --restore-chat-history
Codex CLIcodexcodex resume <uuid> (session-aware) / codex resume --last (fallback)
Ampampamp threads continue
Cursor Agentcursor-agentcursor-agent resume
Goosegoosegoose session --resume --name <uuid> (session-aware) / goose session --resume (fallback)
Droid (Factory)droid
Git (background)git

6.1.1 Session-Aware Resume

When an agent is detected running in a terminal, TUICommander automatically discovers its session ID from the filesystem and stores it per-terminal (agentSessionId). On restore, this enables session-specific resume instead of generic fallback commands.

  • Claude Code — Sessions stored as ~/.claude/projects/<slug>/<uuid>.jsonl; UUID from filename
  • Gemini CLI — Sessions stored in ~/.gemini/tmp/<hash>/chats/session-*.json; sessionId field from JSON
  • Codex CLI — Sessions stored in ~/.codex/sessions/YYYY/MM/DD/rollout-*-<UUID>.jsonl; UUID from filename
  • Goose — Sessions stored in SQLite (~/Library/Application Support/Block/goose/sessions/sessions.db); shell wrapper injects --name $TUIC_SESSION for deterministic binding, resume by name

Discovery runs once per terminal on null→agent transition. Multiple concurrent agents are handled via a claimed_ids deduplication list. On agent exit, the stored session ID is cleared to allow re-discovery on next launch.

6.1.2 TUIC_SESSION Environment Variable

Every terminal tab has a stable UUID (tuicSession) injected as the TUIC_SESSION environment variable in the PTY shell. This UUID persists across app restarts and enables:

  • Automatic session binding: Shell integration injects wrapper functions that transparently bind agent sessions to the current tab (zsh, bash, fish):
    • Claude Code: claude() adds --session-id $TUIC_SESSION; bypassed when --session-id, --resume, or --continue are explicit
    • Goose: goose() adds --name $TUIC_SESSION to session and run subcommands; bypassed when --name, -n, --resume, or -r are explicit
    • Session conflict handling: When an agent reports a session conflict (in-use or not-found), TUICommander creates a no-session-inject.$TUIC_SESSION flag file in the config directory. Shell wrappers check for this file and skip --session-id injection when it exists — avoiding PTY writes that could corrupt TUI output
  • Automatic resume: On restore, TUICommander verifies if the session file exists on disk (verify_agent_session) before using --resume $TUIC_SESSION
  • UI spawn coherence: When spawning agents via the context menu, TUIC_SESSION is used as --session-id automatically
  • Custom scripts: $TUIC_SESSION is available as a stable key for any tab-specific state

6.2 Agent Detection

  • Auto-detection from terminal output patterns
  • Multi-agent status line detection via regex patterns anchored to line start: Claude Code (*//· + task text + .../), [Running] Task format, Aider (Knight Rider scanner ░█ + token reports), Codex CLI (/ bullet spinner with time suffix), Goose (<message>... (Ctrl+C to interrupt)), Copilot CLI (// indicators), Gemini CLI (braille dots ⠋⠙⠹...)
  • Status lines rejected when they appear in diff output, code listings, or block comments
  • Brand SVG logos for each agent (fallback to capital letter)
  • Agent badge in status bar showing active agent
  • Binary detection: Rust probes well-known directories via resolve_cli() for reliable PATH resolution in desktop-launched apps
  • Foreground process detection: tcgetpgrp() on the PTY master fd, then proc_pidpath() to get the binary name. Handles versioned binary paths (e.g. Claude Code installs as ~/.local/share/claude/versions/2.1.87) by scanning parent directory names when the basename is not a known agent

6.3 Rate Limit Detection

  • Provider-specific regex patterns detect rate limit messages
  • Status bar warning with countdown timer
  • Per-session tracking: rate-limit events are only accepted for sessions where agent activity has been detected (prevents false warnings in plain shell sessions)
  • Auto-expire: rate limits are cleared automatically after retry_after_ms (or 120s default) without requiring agent output

6.4 Question Detection

  • Recognizes interactive prompts (yes/no, multiple choice, numbered options)
  • Tab dot turns orange (pulsing) when awaiting input; sidebar branch icon shows ? in orange
  • Prompt overlay: keyboard navigation (↑/↓, Enter, number keys 1-9, Escape)
  • Two detection strategies run in priority order:
    1. Screen-based (Strategy 1): reads the live terminal screen, finds the last chat line above the prompt box (delimited by separator lines), checks if it ends with ?. Works with Claude Code, Codex ( prompt), and Gemini (> prompt) layouts
    2. Silence-based (Strategy 2, fallback): if terminal output stops for 10s after a line ending with ?, the session is treated as awaiting input
  • Stale candidate clearing: candidates that fail screen verification are purged so the same question can re-fire in a future agent cycle
  • Echo suppression: user-typed input echoed by PTY is ignored for 500ms to prevent false question detection
  • extract_question_line() scans all changed rows (not just the last) for question text, applied in both normal and headless reader threads
  • Question state auto-clears when a status-line event fires (agent is actively working, so it’s no longer awaiting input)

6.5 Usage Limit Detection

  • Claude Code weekly and session usage percentage (from PTY output patterns)
  • Color-coded badge in status bar (blue < 70%, yellow 70-89%, red pulsing >= 90%)
  • Integrated into unified agent badge (see section 5.1)

6.6 Claude Usage Dashboard

  • Native SolidJS component (not a plugin panel — renders as a first-class tab)
  • Opens via status bar agent badge click or Cmd+Shift+A action
  • Rate Limits section: Live utilization bars from Anthropic OAuth usage API
    • 5-Hour, 7-Day, 7-Day Opus, 7-Day Sonnet, 7-Day Cowork buckets
    • Color-coded bars: green < 70%, yellow 70-89%, red >= 90%
    • Reset countdown per bucket
  • Usage Over Time chart: SVG line chart of token usage over 7 days
    • Input tokens (blue) and output tokens (red) stacked area
    • Interactive hover crosshair with tooltip
  • Insights: Session count, message totals, input/output tokens, cache stats, tokens-per-hour metric (based on real active hours from session timestamps)
  • Activity heatmap: 52-week GitHub-style contribution grid
    • Tooltip shows date, message count, and top 3 projects
  • Model Usage table: Per-model breakdown (messages, input, output, cache)
  • Projects breakdown: Per-project token usage with click to filter
  • Scope selector: Filter all analytics by project slug
  • Auto-refresh: API data polled every 5 minutes
  • Rust data layer: Incremental JSONL parsing of ~/.claude/projects/*/ transcripts
    • File-size-based cache (only new bytes parsed on each scan)
    • Cache persisted to disk as JSON for fast restarts

6.7 Intent Event Tracking

  • Agents declare work phases via intent: text (Title) tokens at column 0, colorized dim yellow in terminal output
  • Colorization is agent-gated (only applied in sessions with a detected agent) to prevent false positives
  • Structural tokens stripped from log lines served to PWA/REST consumers via LogLine::strip_structural_tokens()
  • Structured Intent events emitted for LLM-declared work phase tracking
  • Centralized debounced busy signal with completion notifications for accurate idle/active status

6.8 API Error Detection

  • Detects API errors (server errors, auth failures) from agent output and provider-level JSON error responses
  • Covers Claude Code, Aider, Codex CLI, Gemini CLI, Copilot, and raw API error JSON from providers (OpenAI, Anthropic, Google, OpenRouter, MiniMax)
  • Triggers error notification sound and logs to the Error Log Panel

6.9 Agent Configuration (Settings > Agents)

  • Agent list: All supported agents with availability status and version detection
  • Run configurations: Named command templates per agent (binary, args, env vars)
  • Default config: One run config per agent marked as default for quick launching
  • MCP bridge install: One-click install/remove of tui-mcp-bridge into agent’s native MCP config file
  • Supported MCP agents: Claude, Cursor, Windsurf, VS Code, Zed, Amp, Gemini
  • Edit agent config: Opens agent’s own configuration file in the user’s preferred IDE
  • Context menu integration: Right-click terminal > Agents submenu with per-agent run configurations
  • Busy detection: Agents submenu disabled when a process is already running in the active terminal
  • Environment Flags — Per-agent environment variables injected into every new terminal session. Configure in Settings > Agents > expand an agent > Environment Flags. Useful for setting feature flags like CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 without manual export.

6.10 Agent Teams

  • Purpose: Enables Claude Code’s Agent Teams feature to use TUIC tabs instead of tmux panes
  • Approach: Environment variable CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 injected into PTY sessions, which unlocks Claude Code’s TeamCreate/TaskCreate/SendMessage tools. Agent spawning uses direct MCP tool calls (agent spawn) instead of the deprecated it2 shim
  • Session lifecycle events: MCP-spawned sessions emit session-created and session-closed events so they automatically appear as tabs and clean up on exit
  • Settings toggle: Settings > Agents > Agent Teams
  • Suggest follow-ups: Agents can propose follow-up actions via suggest: A | B | C tokens, displayed as floating chip bar
  • Deprecated: The it2 shim approach (iTerm2 CLI emulation) is commented out — superseded by direct MCP tool spawning

6.11 Suggest Follow-up Actions

  • Protocol: Agents emit suggest: action1 | action2 | action3 at column 0 after completing a task
  • Token concealment: Suggest tokens are concealed in terminal output via line erasure or space replacement — the raw token never appears on screen. Concealment is agent-gated
  • Desktop: Floating chip bar (SuggestOverlay) above terminal with larger buttons and keyboard shortcut badges (19 to select, Esc to dismiss). Auto-dismiss after 30s, on typing, or on Esc
  • Mobile: Horizontal scrollable pill buttons above CommandInput in SessionDetailScreen
  • Action: Clicking a chip (or pressing its number key) sends the text to the PTY via write_pty
  • Settings: Configurable via Settings > Agents > Show suggested follow-up actions

6.12 Slash Menu Detection

  • When the user types / in a terminal, slash_mode activates and the output parser scans the bottom screen rows for slash command menus
  • Detection: 2+ consecutive rows starting with /command patterns, with highlight for the selected item
  • Produces ParsedEvent::SlashMenu { items } — used by mobile PWA to render a native bottom-sheet overlay
  • slash_mode cleared on user-input events and status-line events

6.13 Inter-Agent Messaging

  • New messaging MCP tool for agent-to-agent coordination when multiple agents are spawned in parallel
  • Identity: Each agent uses its $TUIC_SESSION env var (stable tab UUID) as its messaging identity
  • Actions: register (announce presence), list_peers (discover other agents), send (message a peer by tuic_session), inbox (poll for messages)
  • Dual delivery: Real-time push via MCP notifications/claude/channel over SSE when the client supports channels; polling fallback via inbox always available
  • Channel support: TUICommander declares experimental.claude/channel capability; spawned Claude Code agents automatically get --dangerously-load-development-channels server:tuicommander
  • Lifecycle: Peer registrations cleaned up on MCP session delete and TTL reap; PeerRegistered/PeerUnregistered events broadcast via event bus for frontend visibility
  • Limits: 64 KB max message size, 100 messages per inbox (FIFO eviction), optional project filtering for list_peers
  • TUICommander acts as the messaging hub — no external daemon needed

6.14 AI Chat Panel (Cmd+Alt+A)

  • Conversational AI companion docked on the right, streaming markdown with syntax-highlighted code blocks. Every code block has Run (sends to the attached terminal via sendCommand()), Copy, and Insert actions
  • Multi-provider: Ollama (local, auto-detected on localhost:11434 with live model list), Anthropic, OpenAI, OpenRouter, custom OpenAI-compatible endpoint. Provider abstraction via genai crate
  • Per-terminal state — each terminal tab maintains its own independent chat history, streaming state, and conversation ID (keyed by tuicSession). The header shows the active terminal’s name as a badge
  • Frozen state — when no terminal is focused (e.g. Git panel or settings active), a banner reads “No terminal focused — chat is read-only”, input is disabled, and the send button is greyed out
  • Per-turn terminal context: last context_lines rows from VtLogBuffer (ANSI-stripped, alt-screen suppressed), SessionState, recent ParsedEvents, git branch/diff. Terminal follows the focused tab automatically
  • API keys stored in OS keyring (service tuicommander-ai-chat, user api-key) — masked with eye-toggle in Settings
  • Streaming via Tauri Channel<ChatStreamEvent> (chunk/end/error); cancellable mid-stream
  • Conversation persistence: save / load / delete with in-memory cap of 100 messages per conversation. Files at <config_dir>/ai-chat-conversations/<id>.json
  • Conversation history panel — click the clock/history icon in the header to browse all saved conversations (title, terminal name, message count, date). Click a row to load it
  • Usage footer — live token counter at the bottom: prompt tokens (↑N), completion tokens (↓N), estimated cost ($X.XXXX), cache hit rate
  • Terminal context menu: Send selection to AI Chat, Explain this error. Toolbar toggle + hotkey
  • Detachable panel — click the detach icon in the header to pop the panel into a separate window (500×700). The main window shows a placeholder with “Bring back”. Cross-window sync via a Rust-side ChatRegistry using Channel<ChatEvent> fan-out — streaming chunks, messages, and errors are projected in real-time to all subscribers. Closing the detached window automatically restores the panel
  • Full user guide: docs/user-guide/ai-chat.md

6.15 AI Agent Loop (ReAct)

  • Autonomous loop that observes and acts in a terminal. Same panel as AI Chat, mode toggle in the header
  • Seven terminal tools: read_screen, send_input, send_key, wait_for (regex or stability), get_state, get_context + search_code (BM25 semantic search over repo files via content_index)
  • Safety gates via the SafetyChecker trait — three verdicts: Allow, NeedsApproval { reason }, Block { reason }. Destructive commands (rm -rf, git reset --hard, git push --force, DROP TABLE, dd of=, …) surface a pending-approval card; hard-coded blocks refuse patterns like rm -rf /
  • Pause / resume / cancel between iterations with clean state transitions. Tool-call cards collapse/expand in the panel. Conversation schema v2 persists tool-call records alongside messages
  • Session knowledge store (Level 3): command outcomes (exit code, duration, CWD, classification, output snippet), auto-correlated error→fix pairs, CWD history, tui_apps_seen, terminal mode. Injected into the agent system prompt as a compact markdown summary
  • OSC 133 semantic prompts feed exact exit codes when the shell supports them; a silence-timer fallback records Inferred outcomes otherwise. Persisted to <config_dir>/ai-sessions/<session_id>.json with a 2 s debounced flush
  • SessionKnowledgeBar — collapsible footer under the panel showing live command count, last 5 outcomes with kind badges, recent errors with inferred error_type, TUI mode indicator. A History button opens the knowledge history overlay (two-pane sessions/detail browser with full-text search, errors-only filter, and 24h/7d/30d date window)
  • Experimental AI block enrichment (opt-in, Settings > AI Chat) — after each completed OSC 133 D block, a bounded mpsc worker asks the active AI provider for a one-line semantic_intent and stamps it onto the CommandOutcome (identified by stable id: u64). Rate-limited ~10/min, silent drop on full queue, never blocks the PTY path
  • TUI app detection via alternate-screen tracking (ESC[?1049h/l). TerminalMode::FullscreenTui { app_hint, depth } is set when the terminal enters vim/htop/lazygit/less/tmux/…; the agent adapts (prefers send_key + wait_for over line-oriented send_input)
  • External MCP surface — eight tools exposed as ai_terminal_read_screen, ai_terminal_send_input, ai_terminal_send_key, ai_terminal_wait_for, ai_terminal_get_state, ai_terminal_get_context, ai_terminal_drive_agent, ai_terminal_search_code. Input operations always require user confirmation and are rejected while the internal agent loop is active on the target session
  • drive_agent — atomic send→wait→read tool. Sends a command, waits for idle/pattern, returns screen + shell state in one call. Replaces the common send_inputwait_forread_screen three-step pattern
  • Session aliases — Human-friendly aliases auto-assigned from repo directory name (e.g. tuicommandertc-1). Acronym derived from segment initials (split on -, _, ., camelCase), with collision resolution. All ai_terminal_* tools accept aliases in place of UUIDs. Visible in tab tooltips and list_sessions output. Counters reset on app restart
  • Delta cursorread_screen, drive_agent, and session action=output return a monotonic cursor field. Pass since_cursor on subsequent calls to receive only new scrollback lines since that position, avoiding full re-reads. Client-side tracking, zero server state
  • Unsafe mode — lock icon in the AI Chat header toggles unrestricted operation (TrustLevel::Unrestricted). Bypasses SafetyChecker approval and FileSandbox path jail. Confirmation dialog before activation; header turns red while active. Per-session, resets on loop end
  • Agent model overrides — per-task-phase model routing (agent_model_overrides in ai-chat-config.json). Four phases: plan, search, read, write. Each phase can use a different model to optimize cost/quality trade-offs
  • Cross-session memory injectionbuild_cross_session_section() scans all sessions whose CWD history overlaps the current session’s repo root and injects a summarised memory block into the agent system prompt. The agent inherits knowledge from prior sessions in the same repo without manual intervention
  • Cron scheduler — time-triggered agent tasks defined in Settings > AI Chat > Scheduler. Cron expressions with goals, persisted to <config_dir>/ai-cron.json. Scheduler ticks every 30 s. Tauri commands: load_scheduler_config, save_scheduler_config

6.16 Provider Registry

  • Centralized multi-provider configuration replacing per-feature provider settings
  • Supported provider types: Anthropic, OpenAI, OpenRouter, Ollama (local, auto-detected), custom OpenAI-compatible endpoints
  • Per-provider API keys stored in OS keyring via Credential::Provider variant
  • Per-provider model lists with add/remove/reorder
  • Slot resolver — logical slots (headless, chat, triage) map to concrete provider+model pairs with a configurable fallback chain
  • Legacy migration — existing ai-chat-config.json provider/model/API key settings auto-migrated to providers.json on first load
  • Settings > Providers tab — full CRUD UI: add/edit/remove providers, manage model lists, assign slots, test connections
  • All Rust consumers (ai_chat, ai_agent, headless, triage) resolve models via the registry instead of reading config directly
  • Config file: <config_dir>/providers.json

6.17 AI Diff Triage

  • LLM-powered code review panel for git diff changes
  • Progressive loading: diffs grouped by file with heuristic pre-classification (formatting-only, rename, test, config changes) before LLM analysis
  • Multi-turn conversation via TriageSession — ask follow-up questions about specific findings
  • “Diff” button on findings opens the relevant file diff in context
  • Refresh support: re-run triage when the diff changes
  • Backed by run_diff_triage Tauri command with classify_multi_turn for iterative refinement

6.18 ChoicePrompt Detection

  • New ParsedEvent::ChoicePrompt { title, options, dismiss_key, amend_key } recognises Claude-Code-style numbered confirmation menus (footer matches Esc to cancel · Tab to amend)
  • Options parsed by regex with optional cursor marker (, , >). Title heuristics require ? or a verb prefix (proceed, confirm, do you want, …) to avoid matching Markdown numbered lists. Minimum two options
  • Destructive labels (no, cancel, reject, abort, deny, don't) flagged for styling
  • Piped into SessionState.choice_prompt; dispatched to plugins via pluginRegistry.dispatchStructuredEvent("choice-prompt", …); rendered as PWA overlay
  • Single-key replies routed through sendPtyKey() (src/utils/sendCommand.ts) — never text + \r. Desktop listener plays a warning sound when the prompt arrives on an inactive tab

7. Git Integration

7.1 Repository Info

  • Branch name, remote URL, ahead/behind counts
  • Read directly from .git/ files (no subprocess for basic info)
  • Repo watcher: monitors .git/index, .git/refs/, .git/HEAD, .git/MERGE_HEAD for changes

7.2 Worktrees

  • Auto-creation on branch select (non-main branches)
  • Configurable storage strategies: sibling (__wt), app directory, inside-repo (.worktrees/), or Claude Code default (.claude/worktrees/)
  • Sci-fi themed auto-generated names
  • Three creation flows: dialog (with base ref dropdown), instant (auto-name), right-click branch (quick-clone with hybrid {branch}--{random} name)
  • Base ref selection: choose which branch to start from when creating new worktrees
  • Per-repo settings: storage strategy, prompt on create, delete branch on remove, auto-archive, orphan cleanup, PR merge strategy, after-merge behavior, PR visibility filters (hide drafts/conflicting/CI-failing)
  • Setup script: runs once after creation (e.g., npm install)
  • Archive script: runs before a worktree is archived or deleted; non-zero exit blocks the operation
  • Merge & Archive: right-click → merge branch into main, then archive or delete based on setting
  • External worktree detection: monitors .git/worktrees/ for changes from CLI or other tools
  • Remove via sidebar × button or context menu (with confirmation)
  • Worktree Manager panel (Cmd+Shift+W or Command Palette → “Worktree manager”):
    • Dedicated overlay listing all worktrees across all repos with metadata: branch name, repo badge, PR state (open/merged/closed), dirty stats, last commit timestamp
    • Orphan worktree detection with warning badge and Prune action
    • Repo filter pills and text search for branch names
    • Multi-select with checkboxes and select-all for batch operations
    • Batch delete and batch merge & archive
    • Single-row actions: Open Terminal, Merge & Archive, Delete (disabled on main worktrees)

7.3 Auto-Fetch

  • Per-repo configurable interval (5/15/30/60 minutes, default: disabled)
  • Background git fetch --all via non-interactive subprocess
  • Bumps revision counter to refresh branch stats and ahead/behind counts
  • Errors logged to appLogger, never blocking
  • Master-tick architecture: single 1-minute timer checks all repos

7.4 Unified Repo Watcher

  • Single watcher per repository monitoring the entire working tree recursively (replaces separate HEAD/index watchers)
  • Uses raw notify::RecommendedWatcher with manual per-category trailing debounce
  • Event categories: Git (HEAD, refs, index, MERGE_HEAD), WorkTree (source files), Config (app config changes)
  • Each category has its own debounce window — git metadata changes propagate faster than file edits
  • Respects .gitignore rules — ignored paths do not trigger refreshes
  • Gitignore hot-reload: editing .gitignore rebuilds the ignore filter without restarting the watcher
  • When a terminal runs git checkout -b new-branch in the main working directory (not a worktree), the sidebar renames the existing branch entry in-place (preserving all terminal state) instead of creating a duplicate

7.5 Diff

  • Working tree diff and per-commit diff via Git Panel Changes tab
  • Per-file diff counts (additions/deletions) shown inline in Changes tab
  • Click a file row to view its diff
  • Side-by-side (split), unified (inline), and scroll (all files) view modes — toggle in toolbar, preference persisted
  • Scroll mode (all-files diff) — shows every changed file (staged + unstaged) in a continuous scrollable view with collapsible file sections, per-file addition/deletion stats, sticky header with totals, and clickable filenames that open in the editor. Reactively reloads on git operations via revision tracking
  • Auto-unified for new/deleted files — split view is forced to unified when the diff is one-sided
  • Word-level diff highlighting via @git-diff-view/solid with virtualized rendering
  • Hunk-level restore — hover a hunk header to reveal a revert button (discard for working tree, unstage for staged)
  • Line-level restore — click individual addition/deletion lines to select them (shift+click for ranges), then restore only the selected lines via partial patch
  • Text selection and copy enabled in diff panels (user-select: text)
  • Cmd+F search in diff tabs via SearchBar + DomSearchEngine
  • Submodule entries are filtered from working tree status (not shown as regular files)
  • Standalone DiffPanel removed in v0.9.0 (see section 3.2)

8. GitHub Integration

8.1 PR Monitoring

  • GraphQL API (replaces gh CLI for data fetching)
  • PR badge colors: green (open), purple (merged), red (closed), gray (draft)
  • Merge state: Ready to merge, Checks failing, Has conflicts, Behind base, Blocked, Draft
  • Review state: Approved, Changes requested, Review required
  • PR lifecycle rules: CLOSED PRs hidden from sidebar and status bar; MERGED PRs shown for 5 minutes of accumulated user activity then hidden
  • Auto-show PR popover filters out CLOSED and MERGED PRs (configurable in Settings > General)

8.2 CI Checks

  • Ring indicator with proportional segments
  • Individual check names and status in PR detail popover
  • Labels with GitHub-matching colors

8.3 PR Detail Popover

  • Title, number, link to GitHub
  • Author, timestamps, state, merge readiness, review decision
  • CI check details, labels, line changes, commit count
  • View Diff button: opens PR diff as a dedicated panel tab with collapsible file sections, dual line numbers, and color-coded additions/deletions
  • Merge button: visible when PR is open, approved, CI green — merges via GitHub API. Merge method auto-detected from repo-allowed methods; auto-fallback to squash on HTTP 405 rejection
  • Approve button: submit an approving review via GitHub API (remote-only PRs)
  • Post-merge cleanup dialog: after merge, offers checkable steps (switch to base, pull, delete local/remote branch)
  • Review button: if the branch’s active agent has a run config named “review”, spawns a terminal running the interpolated command with {pr_number}, {branch}, {base_branch}, {repo}, {pr_url}. Hidden when no matching config exists
  • Triggered from: sidebar PR badge, status bar PR badge, status bar CI badge, toolbar notification bell

8.4 PR Visibility Filters

  • Global settings (Settings > GitHub): hide draft PRs, hide conflicting PRs, hide CI-failing PRs
  • Per-repo overrides (Settings > [Repo] > PR Visibility): tri-state toggle per filter (Show / Default / Hide)
  • Default = inherit from global setting, shown in parentheses (e.g. “Draft PRs (Show)”)
  • Resolution chain: per-repo override → global setting
  • TriStateToggle component: 3-position pill switch (left=hide, center=default, right=show) matching existing toggle style

8.5 CI Auto-Heal

  • When CI checks fail on a branch with an active agent terminal, auto-heal can fetch failure logs and inject them into the agent
  • Toggle per-branch via pill-switch toggle in PR detail popover (visible when CI checks are failing), styled consistently with CI check item rows
  • Fetches logs via gh run view --log-failed, truncated to ~4000 chars
  • Waits for agent to be idle/awaiting input before injecting
  • Max 3 attempts per failure cycle, then stops and logs a warning
  • Attempt counter visible in PR detail popover
  • Status tracked per-branch in BranchState.ciAutoHeal

8.6 PR Notifications

  • Types: Merged, Closed, Conflicts, CI Failed, Changes Requested, Ready
  • Toolbar bell with count badge
  • Individual dismiss or dismiss all
  • Click to open PR detail popover

8.7 Merge PR via GitHub API

  • Merge PRs directly from TUICommander without switching to GitHub web
  • Configurable merge strategy per repo: merge commit, squash, or rebase (Settings > Repository > Worktree tab)
  • Merge method auto-detected from repo’s allowed methods via GitHub API (get_repo_merge_methods); auto-fallback to squash on HTTP 405 rejection
  • Triggered from: PR detail popover (local branches), remote-only PR popover, Merge & Archive workflow (sidebar context menu)
  • Post-merge cleanup dialog: sequential steps executed via Rust backend (not PTY — terminal may be occupied by AI agent)
    • Switch to base branch (auto-stash if dirty — inline warning shown with “Unstash after switch” checkbox)
    • Pull base branch (ff-only)
    • Close terminals + delete local branch (safe delete, refuses default branch)
    • Delete remote branch (gracefully handles “already deleted”)
    • Steps are checkable — user can toggle which to execute
    • Per-step status reporting: pending → running → success/error
  • After-merge behavior setting for worktrees: archive (auto-archive), delete (remove), ask (show dialog)
  • When afterMerge=ask: unified cleanup dialog includes an archive/delete worktree step (with inline selector) alongside branch cleanup steps — replaces the old 3-button MergePostActionDialog

8.8 Auto-Delete Branch on PR Close

  • Per-repo setting: Off (default) / Ask / Auto
  • Triggered when GitHub polling detects PR merged or closed transition
  • If branch has a linked worktree, removes worktree first then deletes branch
  • Safety: never deletes default/main branch; dirty worktrees always escalate to ask mode
  • Uses safe git branch -d (refuses unmerged branches)
  • Deduplication prevents double-firing on the same PR

8.9 GitHub Issues Panel

  • Issues displayed in a collapsible section within the GitHub panel alongside PRs
  • Filter modes: Assigned (default), Created, Mentioned, All, Disabled
  • Filter persisted in app config (issue_filter field) and configurable in Settings > GitHub
  • Each issue shows: number, title, state (OPEN/CLOSED), author, labels, assignees, milestone, comment count, timestamps
  • Labels rendered with GitHub-matching colors (background opacity 0.7, contrast-aware text color)
  • Issue actions: Open in GitHub, Close/Reopen, Copy issue number
  • Expand accordion to see full details (milestone, assignees, labels, timestamps)
  • Skeleton loading rows shown during first fetch
  • Empty state message when no issues match the filter
  • MCP HTTP endpoint: GET /repo/issues?path=... returns issues JSON
  • MCP HTTP endpoint: POST /repo/issues/close closes an issue

8.10 Polling

  • Active window: every 30 seconds
  • Hidden window: every 2 minutes
  • API budget: ~2 calls/min/repo

8.11 Token Resolution

  • Priority: GH_TOKEN env → GITHUB_TOKEN env → OAuth keyring token → gh_token crate → gh auth token CLI
  • gh_token crate with empty-string bug workaround
  • Fallback to gh auth token CLI

8.12 OAuth Device Flow Login

  • One-click GitHub authentication from Settings > GitHub tab
  • Uses GitHub OAuth App Device Flow (no client secret, works on desktop)
  • Token stored in OS keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
  • Requested scope: repo
  • Shows user avatar, login name, and token source after authentication
  • Logout removes OAuth token, falls back to env/gh CLI
  • On 401: auto-clears invalid OAuth token and prompts re-auth

9. Voice Dictation

9.1 Whisper Inference

  • Local processing via whisper-rs (no cloud)
  • macOS: GPU-accelerated via Metal
  • Linux/Windows: CPU-only

9.2 Models

ModelSizeQuality
tiny~75 MBLow
base~140 MBFair
small~460 MBGood
medium~1.5 GBVery good
large-v3-turbo~1.6 GBBest (recommended)

9.3 Push-to-Talk

  • Default hotkey: F5 (configurable, registered globally)
  • Mic button in status bar: hold to record, release to transcribe
  • Transcribed text inserts into the focused input element (textarea, input, contenteditable); falls back to active terminal PTY when no text input has focus. Focus target captured at key-press time.

9.4 Streaming Transcription

  • Real-time partial results during push-to-talk via adaptive sliding windows
  • First partial within ~1.5s, subsequent windows grow to 3s for quality
  • VAD energy gate skips silence windows (prevents hallucination)
  • Floating toast shows partial text above status bar during recording
  • 200ms audio window overlap (keep_ms) carries context across windows for continuity
  • Final transcription pass on full captured audio at key release

9.5 Microphone Permission Detection (macOS)

  • On first use, checks microphone permission via macOS TCC (Transparency, Consent, and Control) framework
  • Permission states: NotDetermined (will prompt), Authorized, Denied, Restricted
  • If denied, shows a dialog guiding the user to System Settings > Privacy & Security > Microphone with an “Open Settings” button
  • Linux/Windows: always returns Authorized (no TCC framework)

9.6 Configuration

  • Enable/disable, hotkey, language (auto-detect or explicit), model download
  • Audio device selection
  • Text correction dictionary (e.g., “new line” → \n)
  • Auto-send — Enable in Settings > Services > Dictation to automatically submit (press Enter) after transcription completes.

10. Prompt Library

10.1 Access

  • Cmd+K to open drawer
  • Toolbar button

10.2 Prompts

  • Create, edit, delete saved prompts
  • Variable substitution: {{variable_name}}
  • Built-in variables: {{diff}}, {{changed_files}}, {{repo_name}}, {{branch}}, {{cwd}}
  • Custom variables prompt user for input
  • Categories: Custom, Recent, Favorites
  • Pin prompts to top
  • Search by name or content

10.3 Keyboard Navigation

  • ↑/↓: navigate, Enter: insert (restores terminal focus), Ctrl+N: new, Ctrl+E: edit, Ctrl+F: toggle favorite, Esc: close

10.4 Run Commands

  • Cmd+R: run saved command for active branch
  • Cmd+Shift+R: edit command before running
  • Configure per-repo in Settings → Repository → Scripts

10.5 Smart Prompts

AI automation layer with 24 built-in context-aware prompts. Each prompt includes a description explaining what it does. Prompts auto-resolve git context variables and execute via inject (PTY write), shell script (direct run), headless (one-shot subprocess), or API (direct LLM call) mode.

  • Open: Cmd+K or toolbar lightning bolt button
  • Drawer with category filtering (All/Custom/Recent/Favorites), search by name/description, and enable/disable toggles
  • Prompt rows show inline badges: execution mode (inject/shell/headless/api), built-in, placement tags
  • Prompts are context-aware: 31 variables auto-resolved from git, GitHub, and terminal state
  • Variable Input Dialog: unresolved variables show a compact form with variable name + description before execution
  • Edit Prompt dialog: full editor with name, description, content textarea, variable insertion dropdown (grouped by Git/GitHub/Terminal with descriptions), placement checkboxes, execution mode + auto-execute side-by-side, keyboard shortcut capture
  • Auto-execute: when enabled, inject-mode prompts send Enter immediately via agent-aware sendCommand; when disabled, text is pasted without Enter so the user can review before sending
  • API execution mode: calls LLM providers directly via HTTP API (genai crate) without terminal or agent CLI. Per-prompt system prompt field. Output routed via the same outputTarget options (clipboard, commit-message, toast, panel). Tauri-only (PWA shows “requires desktop app”)
  • LLM API config (Settings > Agents): global provider/model/API key for all API-mode prompts. Supports OpenAI, Anthropic, Gemini, OpenRouter, Ollama, and any OpenAI-compatible endpoint via custom base URL. API key stored in OS keyring. Test button validates connection

10.6 Built-in Prompts by Category

CategoryPrompts
Git & CommitSmart Commit, Commit & Push, Amend Commit, Generate Commit Message
Code ReviewReview Changes, Review Staged, Review PR, Address Review Comments
Pull RequestsCreate PR, Update PR Description, Generate PR Description
Merge & ConflictsResolve Conflicts, Merge Main Into Branch, Rebase on Main
CI & QualityFix CI Failures, Fix Lint Issues, Write Tests, Run & Fix Tests
InvestigationInvestigate Issue, What Changed?, Summarize Branch, Explain Changes
Code OperationsSuggest Refactoring, Security Audit

10.7 Context Variables

Variables are resolved from the Rust backend (resolve_context_variables) and frontend stores:

VariableSourceDescription
{branch}gitCurrent branch name
{base_branch}gitDetected default branch (main/master/develop)
{repo_name}gitRepository directory name
{repo_path}gitFull filesystem path to the repository root
{repo_owner}gitGitHub owner parsed from remote URL
{repo_slug}gitRepository name parsed from remote URL
{diff}gitFull working tree diff (truncated to 50KB)
{staged_diff}gitStaged changes diff (truncated to 50KB)
{changed_files}gitShort status output
{dirty_files_count}gitNumber of modified files (derived from changed_files)
{commit_log}gitLast 20 commits (oneline)
{last_commit}gitLast commit hash + message
{conflict_files}gitFiles with merge conflicts
{stash_list}gitStash entries
{branch_status}gitAhead/behind remote tracking branch
{remote_url}gitRemote origin URL
{current_user}gitGit config user.name
{pr_number}GitHub storePR number for current branch
{pr_title}GitHub storePR title
{pr_url}GitHub storePR URL
{pr_state}GitHub storePR state (OPEN, MERGED, CLOSED)
{pr_author}GitHub storePR author username
{pr_labels}GitHub storePR labels (comma-separated)
{pr_additions}GitHub storeLines added in PR
{pr_deletions}GitHub storeLines deleted in PR
{pr_checks}GitHub storeCI check summary (passed/failed/pending)
{merge_status}GitHub storePR mergeable status
{review_decision}GitHub storePR review decision
{agent_type}terminal storeActive agent type (claude, gemini, etc.)
{cwd}terminal storeActive terminal working directory
{issue_number}manualPrompted from user at execution time

10.8 Execution Modes

  • Inject (default): writes the resolved prompt text into the active terminal’s PTY. Checks agent idle state before sending (configurable via requiresIdle). Appends newline for auto-execution
  • Shell script: executes the prompt content directly as a shell script via execute_shell_script Tauri command. No agent involved — runs content as-is via sh -c (macOS/Linux) or cmd /C (Windows) in the repo directory. Output routed via outputTarget. 60-second timeout cap. No prerequisites (no terminal, agent, or API config needed)
  • Headless: runs a one-shot subprocess via execute_headless_prompt Tauri command. Requires a per-agent headless template configured in Settings → Agents (e.g. claude -p "{prompt}"). Output routed to clipboard or toast depending on outputTarget. Falls back to inject in PWA mode. 5-minute timeout cap

10.9 UI Integration Points

LocationPrompts shownTrigger
Toolbar dropdownAll enabled prompts with toolbar placementCmd+Shift+K or lightning bolt button
Git Panel — Changes tabSmartButtonStrip with git-changes placementInline buttons above changed files
PR Detail PopoverSmartButtonStrip with pr-popover placementInline buttons in PR detail view
Command PaletteAll prompts with Smart: prefixCmd+P then type “Smart”
Branch context menuPrompts with git-branches placementRight-click branch in Branches tab

10.10 Smart Prompts Management (Cmd+Shift+K Drawer)

  • All prompt management consolidated in the Cmd+Shift+K drawer (Settings tab removed)
  • Enable/disable individual prompts via toggle button on each row
  • Edit prompt: opens modal with name, description, content, variable dropdown, placement, execution mode, auto-execute, keyboard shortcut
  • Variable insertion dropdown below content textarea: grouped by Git/GitHub/Terminal, click to insert {variable} at cursor
  • Create custom smart prompts with + New Prompt button
  • Built-in prompts show a “Reset to Default” button when content is overridden

10.11 Headless Template Configuration

  • Settings → Agents → per-agent “Headless Command Template” field
  • Template uses {prompt} placeholder for the resolved prompt text
  • Example: claude -p "{prompt}", gemini -p "{prompt}"
  • Required for headless execution mode; without it, headless prompts fall back to inject

11. Settings

11.1 General

  • Language, Default IDE, Shell
  • Confirmations: quit, close tab (only when a process is running — agents or busy shell; idle shells close immediately)
  • Power management: prevent sleep when busy
  • Updates: auto-check, check now
  • Git integration: auto-show PR popover
  • Terminal: copy-on-select toggle (auto-copy selection to clipboard)
  • Experimental Features: master toggle + per-feature sub-flags (AI Chat, AI Triage, AI Watchers, Scrollback Reflow)
  • Repository defaults: base branch, file handling, setup/run scripts, worktree defaults (storage strategy, prompt on create, etc.)

11.2 Appearance

  • Terminal theme: multiple themes, color swatches
  • Terminal font: 11 bundled monospace fonts (JetBrains Mono default)
  • Default font size: 8-32px slider
  • Split tab mode: separate / unified
  • Tab ordering mode: grouped-by-type (default, tabs grouped by kind), terminals-first (terminals left, others freely interleaved), free (any tab anywhere)
  • Max tab name length: 10-60 slider
  • Repository groups: create, rename, delete, color-coded
  • Reset panel sizes: restore sidebar and panel widths to defaults

11.3 Services

  • HTTP API server: always active on IPC listener (Unix domain socket on macOS/Linux, named pipe \\.\pipe\tuicommander-mcp on Windows). TCP port only for remote access
  • MCP connection info: bridge sidecar auto-installs configs for supported agents (Claude Code, Cursor, etc.)
  • TUIC native tool toggles: enable/disable individual MCP tools (session, agent, repo, ui, plugin_dev_guide, config, debug) to restrict what AI agents can access
  • MCP Upstreams: add/edit/remove upstream MCP servers (HTTP or stdio with optional cwd), per-upstream enable/disable, reconnect, credential storage via OS keyring, live status dots, tool count and metrics. Saved upstreams auto-connect on boot
  • MCP Per-Repo Scoping: each repo can define which upstream MCP servers are relevant via an allowlist in repo settings (3-layer: per-repo > .tuic.json > defaults). Null/empty allowlist = all servers. Quick toggle via Cmd+Shift+M popup
  • Remote access: port, username, password (bcrypt hash), URL display, QR code, token duration, IPv6 dual-stack, LAN auth bypass
  • Voice dictation: full setup (see section 9)

11.4 Repository Settings (per-repo)

  • Display name
  • Worktree tab: storage strategy, prompt on create, delete branch on remove, auto-archive, orphan cleanup, PR merge strategy, after-merge action (each overridable from global defaults)
  • Scripts tab: setup script (post-worktree), run script (Cmd+R), archive script (pre-archive/delete hook)
  • Repo-local config: .tuic.json in repo root provides team-shared settings. Three-tier precedence: .tuic.json > per-repo app settings > global defaults. Scripts (setup, run, archive) are intentionally excluded from .tuic.json merging — arbitrary script execution by a checked-in file poses a security risk; scripts are always sourced from the local per-repo app settings only

11.5 Notifications

  • Master toggle, volume (0-100%)
  • Per-event: question, error, completed, warning, info
  • Test buttons per sound
  • Reset to defaults

11.6 Keyboard Shortcuts

  • Settings > Keyboard Shortcuts tab (Cmd+, to open Settings), also accessible from Help > Keyboard Shortcuts
  • All app actions listed with their current keybinding
  • Click the pencil icon to rebind — inline key recorder with pulsing accent border
  • Conflict detection: warns when the new combo is already bound to another action, with option to replace
  • Overridden shortcuts highlighted with accent color; per-shortcut reset icon to revert to default
  • “Reset all to defaults” button at the bottom
  • Custom bindings stored in keybindings.json in the platform config directory
  • Auto-populated from actionRegistry.ts (ACTION_META map) — new actions appear automatically
  • Global Hotkey: configurable OS-level shortcut to toggle window visibility from any application. Set in the “Global Hotkey” section at the top of the Keyboard Shortcuts tab. No default — user must configure. Toggle: hidden/minimized → show+focus, visible but unfocused → focus, focused → instant hide (no dock animation). Cmd and Ctrl are distinct modifiers. Uses tauri-plugin-global-shortcut (no Accessibility permission required on macOS). Hidden in browser/PWA mode.

11.7 Agents

  • See 6.9 Agent Configuration for full details
  • Claude Usage Dashboard enable/disable toggle (under Claude agent section)

11.8 Providers

  • Settings > Providers tab for centralized AI provider management
  • See 6.16 Provider Registry for full details

12. Persistence

12.1 Rust Config Backend

All data persisted to platform config directory via Rust:

  • app_config.json — general settings
  • notification_config.json — sound settings
  • ui_prefs.json — sidebar visibility/width
  • repo_settings.json — per-repo worktree/script settings
  • repositories.json — repository list, groups, branches
  • agents.json — per-agent run configurations
  • prompt_library.json — saved prompts
  • notes.json — ideas panel data
  • dictation_config.json — dictation settings
  • providers.json — provider registry (providers, models, slot assignments)
  • .tuic.json — repo-root team config (read-only from app, highest precedence for overridable fields)
  • claude-usage-cache.json — incremental session transcript parse cache

12.2 Hydration Safety

  • save() blocks before hydrate() completes to prevent data loss

13. Cross-Platform

13.1 Supported Platforms

  • macOS (primary), Windows, Linux

13.2 Platform Adaptations

  • CmdCtrl key abstraction
  • resolve_cli(): probes well-known directories when PATH unavailable (release builds)
  • Windows: cmd.exe shell escaping, CreateToolhelp32Snapshot for process detection
  • IDE detection: .app bundles (macOS), registry entries (Windows), PATH probing (Linux)

14. System Features

14.1 Auto-Update

  • Check for updates on startup via tauri-plugin-updater
  • Status bar badge with version
  • Download progress percentage
  • One-click install and relaunch
  • Menu: Check for Updates (app menu and Help menu)

14.2 Sleep Prevention

  • keepawake integration prevents system sleep while agents are working
  • Configurable in Settings

14.3 Splash Screen

  • Branded loading screen on app start

14.4 Confirmation Dialogs

  • In-app ConfirmDialog component replaces native Tauri ask() dialogs
  • Dark-themed to match the app (native macOS sheets render in light mode)
  • useConfirmDialog hook provides a confirm()Promise<boolean> API
  • Pre-built helpers: confirmRemoveWorktree(), confirmCloseTerminal(), confirmRemoveRepo()
  • Keyboard support: Enter to confirm, Escape to cancel

14.5 Error Handling

  • ErrorBoundary crash screen with recovery UI
  • WebGL canvas fallback (graceful degradation)
  • Error classification with backoff calculation

14.6 MCP & HTTP Server

  • REST API on localhost for external tool integration
  • Exposes terminal sessions, git operations, agent spawning
  • WebSocket streaming, Streamable HTTP transport
  • Used by Claude Code, Cursor, and other tools via MCP protocol
  • tuic-bridge ships as a Tauri sidecar; auto-installs MCP configs on first launch for Claude Code, Cursor, Windsurf, VS Code, Zed, Amp, Gemini
  • Local connections use Unix domain socket (<config_dir>/mcp.sock) on macOS/Linux or named pipe (\\.\pipe\tuicommander-mcp) on Windows; TCP port reserved for remote access only
  • Unix socket lifecycle is crash-safe: RAII guard removes the socket file on Drop; bind retries 3× (×100 ms) removing any stale file before each attempt; liveness check uses a real connect() probe so a dead socket from a crashed run never blocks MCP tool loading

14.7 Cross-Repo Knowledge Base

  • Knowledge base functionality is available via the mdkb MCP upstream server (configure in MCP Upstreams settings)
  • Provides hybrid BM25 + semantic search across docs, code, symbols, and memory
  • Call graph queries (calls, callers, impact analysis) via code_graph tool
  • Requires mdkb binary on PATH (installed separately)

14.8 Code Intelligence (MDKB integration)

  • Go-to-definition: Cmd+Click on symbols in the editor navigates to the definition via mdkb_goto_definition
  • Find references: Shift+F12 finds all callers of a symbol via mdkb_references (uses code_graph callers query)
  • Symbol outline: file-level symbol tree via mdkb_outline (functions, types, structs)
  • Install/uninstall managed from Settings → General → Code Intelligence
  • is_available() checks binary existence on disk (not cached path) — survives external uninstalls
  • Homebrew-managed installs show brew uninstall mdkb guidance instead of silent failure
  • Graceful fallback: all commands return empty results when mdkb is unavailable

14.9 macOS Dock Badge

  • Badge count for attention-requiring notifications (questions, errors)

14.9 Tailscale HTTPS

  • Auto-detects Tailscale daemon and FQDN via tailscale status --json (cross-platform)
  • Provisions TLS certificates from Tailscale Local API (Unix socket on macOS/Linux, CLI on Windows)
  • HTTP+HTTPS dual-protocol on same port via axum-server-dual-protocol
  • Graceful fallback: HTTP-only when Tailscale unavailable or HTTPS not enabled
  • QR code uses https:// scheme with Tailscale FQDN when TLS active
  • Background cert renewal every 24h with hot-reload via RustlsConfig::reload_from_pem()
  • Session cookie gets Secure flag on TLS connections
  • Settings panel shows Tailscale status with actionable guidance

15. Keyboard Shortcut Reference

Terminal

ShortcutAction
Cmd+TNew terminal tab
Cmd+WClose tab / close active split pane
Cmd+Shift+TReopen last closed tab
Cmd+1Cmd+9Switch to tab by number
Ctrl+Tab / Ctrl+Shift+TabNext / previous tab
Cmd+LClear terminal
Cmd+Shift+LRefresh terminal (fix glyphs)
Cmd+CCopy selection
Cmd+VPaste to terminal
Cmd+HomeScroll to top
Cmd+EndScroll to bottom
Shift+PageUpScroll one page up
Shift+PageDownScroll one page down
Cmd+RRun saved command
Cmd+Shift+REdit and run command
Cmd+Shift+.Toggle block folding
Cmd+Shift+UpJump to previous block
Cmd+Shift+DownJump to next block
Cmd+Shift+BToggle block-scoped search

Zoom

ShortcutAction
Cmd+=Zoom in (+2px)
Cmd+-Zoom out (-2px)
Cmd+0Reset zoom

Split Panes

ShortcutAction
Cmd+\Split vertically
Cmd+Alt+\Split horizontally
Alt+←/→Navigate vertical panes
Alt+↑/↓Navigate horizontal panes
Cmd+Shift+EnterMaximize / restore active pane
Cmd+Alt+EnterFocus mode (hide sidebar, tab bar, panels)

AI

ShortcutAction
Cmd+Alt+AToggle AI Chat panel (toggle-ai-chat)
Cmd+Enter (panel focused)Send message
Esc (panel focused)Cancel in-flight stream

Panels

ShortcutAction
Cmd+[Toggle sidebar
Cmd+Shift+DToggle Git Panel
Cmd+Shift+MToggle markdown panel
Cmd+Alt+NToggle Ideas panel
Cmd+EToggle file browser
Cmd+OOpen file… (picker)
Cmd+NNew file… (picker for name + location)
Cmd+PCommand palette
Cmd+,Open settings
Cmd+?Toggle help panel
Cmd+Shift+KPrompt library
Cmd+JTask queue
Cmd+Shift+EError log
Cmd+Shift+WWorktree manager
Cmd+Shift+AActivity dashboard
Cmd+Shift+MMCP servers popup (per-repo)

Git

ShortcutAction
Cmd+BQuick branch switch (fuzzy search)
Cmd+Shift+DGit Panel (opens on last active tab)
Cmd+GGit Panel — Branches tab

Branches Panel (when panel is focused)

ShortcutAction
/ Navigate branches
EnterCheckout selected branch
nCreate new branch
dDelete branch
RRename branch (inline edit)
MMerge selected into current
rRebase current onto selected
PPush branch
pPull current branch
fFetch all remotes

File Browser (when focused)

ShortcutAction
↑/↓Navigate files
EnterOpen file / enter directory
BackspaceGo to parent directory
Cmd+CCopy file
Cmd+XCut file
Cmd+VPaste file
Cmd+Shift+FOpen file browser and activate content search

Code Editor (when focused)

ShortcutAction
Cmd+FFind
Cmd+GFind next
Cmd+Shift+GFind previous
Cmd+HFind and replace
Cmd+SSave file

Ideas Panel (when textarea focused)

ShortcutAction
EnterSubmit idea
Shift+EnterInsert newline
Cmd+V / Ctrl+VPaste image from clipboard
EscapeCancel edit mode

Quick Switcher

ShortcutAction
Hold Cmd+CtrlShow quick switcher overlay
Cmd+Ctrl+1-9Switch to branch by index

Voice Dictation

ShortcutAction
Hold F5Push-to-talk (configurable)

Mouse Actions

ActionWhereEffect
ClickSidebar branchSwitch to branch
Double-clickSidebar branch nameRename branch
Double-clickTab nameRename tab
Right-clickTabTab context menu
Right-clickSidebar branchBranch context menu
Right-clickSidebar repo Repo context menu
Right-clickSidebar group headerGroup context menu
Right-clickFile browser entryFile context menu
Middle-clickTabClose tab
DragTabReorder tabs
DragSidebar right edgeResize sidebar
DragPanel left edgeResize panel
DragSplit pane dividerResize panes
DragRepo onto groupMove repo to group
ClickStatus bar CWD pathCopy to clipboard
ClickPR badge (sidebar/status)Open PR detail popover
ClickCI ringOpen PR detail popover
ClickToolbar bellOpen notifications popover
ClickStatus bar panel buttonsToggle panels
HoldMic button (status bar)Record dictation

16. Build & Release

16.1 Makefile Targets

TargetDescription
devStart development server
buildBuild production app
build-dmgBuild macOS DMG
signCode sign the app
notarizeNotarize with Apple
releaseBuild + sign + notarize
build-github-releaseBuild for GitHub release (CI)
publish-github-releasePublish GitHub release
github-releaseOne-command release
cleanClean build artifacts

16.2 CI/CD

  • GitHub Actions for cross-platform builds
  • macOS code signing and notarization
  • Linux: libasound2-dev dependency, -fPIC flags
  • Updater signing with dedicated keys

17. Plugin System

17.1 Architecture

  • Obsidian-style plugin API with 4 capability tiers
  • Built-in plugins (TypeScript, compiled with app) and external plugins (JS, loaded at runtime)
  • Hot-reload: file changes in plugin directories trigger automatic re-import
  • Per-plugin error logging with ring buffer (500 entries)
  • Capability-gated access: pty:write, pty:read, ui:markdown, ui:sound, ui:panel, ui:ticker, ui:context-menu, ui:sidebar, ui:file-icons, net:http, credentials:read, invoke:read_file, invoke:list_markdown_files, fs:read, fs:list, fs:watch, fs:write, fs:rename, exec:cli, git:read
  • CLI execution API: sandboxed execution of whitelisted CLI binaries (mdkb) with timeout and size limits
  • Filesystem API: sandboxed read, write, rename, list, tail-read, and watch operations restricted to $HOME
  • HTTP API: outbound requests scoped to manifest-declared URL patterns (SSRF prevention)
  • Credential API: cross-platform credential reading (macOS Keychain, Linux/Windows JSON file) with user consent
  • Panel API: rich HTML panels in sandboxed iframes (sandbox="allow-scripts") with structured message bridge (onMessage/send) and automatic CSS theme variable injection
  • Shared ticker system: setTicker/clearTicker API with source labels, priority tiers (low <10, normal 10-99, urgent >=100), counter badge, click-to-cycle, right-click popover
  • Agent-scoped plugins: agentTypes manifest field restricts output watchers and structured events to terminals running specific agents (e.g. ["claude"])
  • Plugin manifest fields use camelCase (minAppVersion, agentTypes, contentUri) — matches Rust serde serialization

17.2 Plugin Management (Settings > Plugins)

  • Installed tab: List all plugins with enable/disable toggle, logs viewer, uninstall button
  • Browse tab: Discover plugins from the community registry with one-click install/update
  • Enable/Disable: Persisted in AppConfig.disabled_plugin_ids
  • ZIP Installation: Install from local .zip file or HTTPS URL
  • Folder Installation: Install from a local folder (copies plugin directory into plugins dir)
  • Uninstall: Removes plugin directory (confirmation required)

17.3 Plugin Registry

  • Remote JSON registry hosted on GitHub (tuicommander-plugins repo)
  • Fetched on demand with 1-hour TTL cache
  • Version comparison for “Update available” detection
  • Install/update via download URL
  • tuic://install-plugin?url=https://... — Download and install plugin (HTTPS only, confirmation dialog)
  • tuic://open-repo?path=/path — Switch to repo (must be in sidebar)
  • tuic://settings?tab=plugins — Open Settings to specific tab
  • tuic://open/<path> — Open markdown file in tab (iframe SDK only, path validated against repos)
  • tuic://terminal?repo=<path> — Open terminal in repo (iframe SDK only)

17.4.1 TUIC SDK (window.tuic)

  • Injected automatically into every plugin iframe (inline and same-origin URL mode)
  • Feature detection: if (window.tuic)tuic.version reports SDK version
  • Files: tuic.open(path, {pinned?}), tuic.edit(path, {line?}), tuic.getFile(path): Promise<string>
  • Path resolution: relative paths resolve against active repo; absolute paths match longest repo prefix; ../ traversal outside repo root is blocked
  • Repository: tuic.activeRepo() returns active repo path; tuic.onRepoChange(cb) / tuic.offRepoChange(cb) for live updates
  • Terminal: tuic.terminal(repoPath) — open terminal in repository
  • UI feedback: tuic.toast(title, {message?, level?, sound?}) — native toast notifications with optional sound (info blip, warn double-beep, error descending sweep); tuic.clipboard(text) — copy to clipboard from sandboxed iframe
  • Messaging: tuic.send(data) / tuic.onMessage(cb) — bidirectional host↔plugin communication
  • Theme: tuic.theme — current theme as JS object (camelCase CSS vars); tuic.onThemeChange(cb) for live updates
  • <a href="tuic://open/..."> and <a href="tuic://terminal?repo=..."> links intercepted automatically
  • data-pinned attribute on links sets pinned flag
  • Interactive test page: docs/examples/sdk-test.html (see docs/tuic-sdk.md for launch instructions)

17.5 Built-in Plugins

  • Plan Tracker — Detects Claude Code plan files from structured events

Note: Claude Usage Dashboard was promoted from a plugin to a native SolidJS feature (see section 6.6). It is managed via Settings > Agents > Claude > Usage Dashboard toggle.

17.6 Example External Plugins

See examples/plugins/ for reference implementations:

  • hello-world — Minimal output watcher example
  • auto-confirm — Auto-respond to Y/N prompts
  • ci-notifier — Sound notifications and markdown panels
  • repo-dashboard — Read-only state and dynamic markdown
  • report-watcher — Generic report file watcher with markdown viewer
  • claude-status — Agent-scoped plugin (agentTypes: ["claude"]) tracking usage and rate limits
  • wiz-kanban — Wiz framework plugin: kanban board for managing the workflow of plans, stories, and reviews with drag-and-drop

17.7 Claude Wakeup Plugin

Agent-scoped plugin (agentTypes: ["claude"]) that wakes Claude Code when it stalls without asking a question. Ships in plugins/claude-wakeup/.

  • Idle detection: After 20 s of shell idle with no pending question, no active sub-tasks, and no choice prompt, sends a verification message to the agent
  • Typing suppression: Every busy→idle transition resets the idle clock, so keystroke-generated shell-state blips prevent false wakes
  • Done detection (primary): Watches the busy-cycle duration after a wake — short cycle (<8 s) = agent acknowledged (“done”), long cycle (≥8 s) = agent continued working
  • Done detection (secondary): OutputWatcher fast-path for agents that emit a clean done line
  • Disarm/re-arm: Disarms after confirmed done; re-arms only when the user gives new input after the disarm timestamp and the agent works >10 s
  • Limits: Max 3 wakes per stall, max 12 per session lifetime
  • Dashboard: Markdown stats panel with wake counts, done rate, active session state, and history
  • Pause/Resume: Via Activity Center toggle (transient, not persisted)
  • Configuration: data/config.jsonidleThresholdMs, maxWakes, maxWakesEver, doneMaxBusyMs, checkIntervalMs, minBusyDurationMs, questionStaleMs, pendingTimeoutMs
  • Capabilities: pty:write, pty:read, ui:ticker, ui:markdown

18. Mobile Companion UI

Phone-optimized progressive web app for monitoring AI agents remotely. Separate SolidJS entry point (src/mobile/) served by the existing HTTP server at /mobile.

18.1 Architecture

  • Separate Vite entry point (mobile.html + src/mobile/index.tsx)
  • Shares transport layer, stores, and notification manager with desktop
  • Server-side routing: /mobile/*mobile.html, everything else → index.html
  • Session state accumulator enriches GET /sessions with question/rate-limit/busy state
  • SSE endpoint (/events) and WebSocket JSON framing for real-time updates

18.2 Sessions Screen

  • Hero metrics header: active session count + awaiting input count with large tabular-nums display
  • Elevated session cards with agent icon, status badge, project/branch, relative time
  • Rich sub-rows per card: agent intent (crosshair icon) or last prompt (speech bubble), current task (gear icon) with inline progress bar, usage limit percentage
  • Question state highlighted via inset gold box-shadow
  • Pull-to-refresh spinner via touch events
  • Loading skeletons during initial data fetch
  • Empty state with instructional hint
  • Tap card to open session detail

18.3 Session Detail Screen

  • Live output via WebSocket with format=log (VT100-extracted clean lines, auto-scrolling, 500-line buffer)
  • Semantic colorization: log lines are color-coded by type (info, warning, error, diff +/-, file paths) via classifyLine() utility
  • Search/filter in output: text search bar filters visible log lines in real time
  • Rich header: agent intent line (italic), current task line, progress bar, usage percentage (red above 80%)
  • Error bar (red tint) when last_error is set
  • Rate-limit bar (orange tint) with live countdown timer (formatRetryCountdown)
  • Suggest follow-up chips: horizontal scrollable pills from suggested_actions, tap to send
  • Slash menu overlay: frosted glass bottom sheet showing detected /command entries; tap to send Ctrl-U + command + Enter
  • Quick-action chips: Yes, No, y, n, Enter, Ctrl-C
  • TerminalKeybar: context-aware row of special key buttons above the main input. Shows Ctrl+C, Ctrl+D, Tab, Esc, Enter, arrow keys for terminal operations. When the agent is awaiting input, adds Yes/No quick-reply buttons. Consolidated from the former separate QuickActions component
  • CLI command widget: agent-specific quick commands (e.g., /compact, /status for Claude Code) accessible via expandable button
  • Text command input with 16px font (prevents iOS auto-zoom), inputmode="text"
  • Offline retry queue: write_pty calls that fail due to network disconnection are queued and retried when connectivity resumes
  • Back navigation to session list

18.4 Question Banner

  • Persistent overlay when any session has awaiting_input state
  • Shows agent name, truncated question, Yes/No quick-reply buttons
  • Visible on all screens, between top bar and content
  • Stacks multiple questions

18.5 Activity Feed

  • Chronological event feed grouped by time (NOW, EARLIER, TODAY, OLDER)
  • Reads from shared activityStore
  • Throttled grouping: items snapshot every 10s to prevent constant reordering with multiple active sessions; new items/removals trigger immediate refresh
  • Sticky section headers, tap to navigate to session

18.6 Session Management

  • Session kill: swipe or long-press a session card to kill/close the PTY session
  • New session: create a new PTY session from the sessions screen (optional shell/cwd selection)

18.7 Settings

  • Connection status: connectivity indicator with real-time Connected/Disconnected state
  • Server URL display
  • Notification sound toggle (localStorage-persisted)
  • Open Desktop UI link

18.8 PWA Support

  • Web app manifest (mobile-manifest.json) with standalone display mode
  • iOS Safari and Android Chrome Add to Home Screen support
  • apple-mobile-web-app-capable meta tags
  • PNG icons (192x192, 512x512) for PWA installability

18.8.1 Push Notifications

  • Web Push from TUICommander directly to mobile PWA clients (no relay dependency)
  • VAPID ES256 key generation on first enable, persisted in config
  • Service worker (sw.js) handles push events and notification clicks
  • PushManager.subscribe() flow with user gesture (click handler) for iOS/Firefox
  • Push subscriptions stored in push_subscriptions.json, survive restarts
  • API endpoints: POST/DELETE /api/push/subscribe, GET /api/push/vapid-key, POST /api/push/test
  • Triggers: agent awaiting_input (question, orange dot) and PtyExit (session completed, purple/unseen dot)
  • Deep link: notification click navigates to /mobile/session/<id>, opening the specific session detail
  • Delivery gate: push is sent whenever the desktop window is not focused (minimized, hidden, or on another workspace). This prevents duplicate alerts while the user is at the desktop and still wakes the PWA service worker when the phone is locked
  • Rate limited: max 1 push per session per 30 seconds
  • Stale subscriptions cleaned on HTTP 410 Gone
  • iOS standalone detection: shows “Add to Home Screen” guidance when not installed
  • HTTP detection: shows “Push requires HTTPS (enable Tailscale)” when not on HTTPS

18.9 Notification Sounds

  • Audio playback via Rust rodio crate (Tauri command play_notification_sound), replacing the previous Web Audio API approach
  • Eliminates AudioContext suspend issues on WebKit and works in headless/remote modes
  • State transition detection: question, rate-limit, error, completion
  • Completion notifications deferred 10s and suppressed when active sub-tasks are running (detected via ⏵⏵/›› mode-line prefix)

18.10 Visual Polish

  • Frosted glass bottom tabs: backdrop-filter: blur(20px) saturate(1.8) with semi-transparent background
  • Elevated card design: border-radius: var(--radius-xl), background: var(--bg-secondary), margin spacing
  • Safe-area-inset padding for notched devices
  • font-variant-emoji: text on output view — forces Unicode symbols (●, ○, ◉) to render as monochrome text glyphs instead of colorful emoji

18.11 Standalone CSS

  • Mobile PWA uses its own standalone stylesheet (src/mobile/mobile.css), independent from the desktop global.css
  • Shares core color palette and border radius tokens; differs in font stacks, layout approach, and iOS-specific rules
  • WebSocket state deduplication: duplicate state pushes are filtered to reduce unnecessary re-renders

19. MCP Proxy Hub

TUICommander aggregates upstream MCP servers and exposes them through its own /mcp endpoint. Any MCP client (Claude Code, Cursor, VS Code) connecting to TUIC automatically gains access to all configured upstream tools.

19.1 Architecture

  • TUIC acts as both an MCP server (to downstream clients) and an MCP client (to upstream servers)
  • All upstream tools are exposed via the single POST /mcp Streamable HTTP endpoint
  • Native TUIC tools (session, git, agent, config, workspace, notify, plugin_dev_guide) coexist with upstream tools
  • Tool routing: names containing __ are routed to the upstream registry; all others handled natively

19.1.1 Lazy Tool Discovery (collapse_tools)

  • When collapse_tools: true (Settings > Services > TUIC Tools > “Collapse tools”), the full tool list is replaced with 3 meta-tools: search_tools, get_tool_schema, call_tool
  • Cuts MCP context from ~35k tokens to ~500 tokens per agent turn; agent fetches schemas on demand via BM25-ranked search
  • BM25 index backed by AppState::tool_search_index (rebuilds automatically when the tool set changes)
  • Safety filters (disabled_native_tools, upstream allow/deny) enforced at both discovery and dispatch time — agents cannot bypass filters by calling call_tool directly
  • Toggling fires notifications/tools/list_changed so connected clients refresh

19.2 Tool Namespace

  • Upstream tools are prefixed: {upstream_name}__{tool_name}
  • Double underscore (__) is the routing discriminator — native tool names never contain it
  • Tool descriptions are annotated with [via {upstream_name}] to identify origin
  • Clients always see the merged tool list in a single tools/list response

19.3 Supported Transports

  • HTTP (Streamable HTTP, spec 2025-03-26) — connects to any MCP server with an HTTP endpoint
  • Stdio — spawns local processes (npm packages, Python scripts, etc.) communicating via newline-delimited JSON-RPC

19.4 Circuit Breaker (per upstream)

  • 3 consecutive failures → circuit opens
  • Backoff: 1s → exponential growth → 60s cap
  • After 10 retry cycles without recovery → permanent Failed state
  • Recovery: successful tool call or health check resets the circuit breaker

19.5 Health Checks

  • Background task probes every Ready upstream every 60 seconds via tools/list (HTTP) or process liveness check (stdio)
  • CircuitOpen upstreams with expired backoff are also probed for recovery

19.6 Tool Filtering (per upstream)

  • Allow list: only matching tools are exposed
  • Deny list: all tools except matching ones are exposed
  • Pattern syntax: exact match or trailing-* prefix glob

19.6.1 Per-Repo Scoping

  • Each repository can define an allowlist of upstream server names in RepoSettings.mcpUpstreams
  • 3-layer merge: per-repo user settings > .tuic.json (team-shareable) > defaults (null = all servers)
  • Quick toggle via Cmd+Shift+M popup: shows all upstream servers with status, transport, tool count, and per-repo checkboxes
  • Toggling a checkbox immediately persists to repo settings (reactive, no refresh needed)

19.7 Hot-Reload

  • Adding, removing, or changing upstreams takes effect on save without restarting TUIC or AI clients
  • Config diff computed by stable id field; only changed entries are reconnected

19.8 Credential Management

  • Bearer tokens stored in OS keyring (Keychain / Credential Manager / Secret Service)
  • Keyring warm-up — resolved bearer token cached in memory after the first read. Health checks (every 60 s) and tool calls reuse the cache, invalidated on 401 and re-populated after token refresh. Eliminates repeated macOS Keychain permission prompts
  • Config file (mcp-upstreams.json) never contains secrets
  • Per-upstream credential lookup at call time
  • OAuth 2.1 token sets persisted as structured JSON in the keyring ({"type": "oauth2", "access_token", "refresh_token", "expires_at"})

19.8.1 OAuth 2.1 Upstream Authentication

  • Full RFC 9728 (Protected Resource Metadata) + RFC 8414 (Authorization Server Discovery) flow with PKCE S256
  • UpstreamAuth::OAuth2 { client_id, scopes, authorization_endpoint?, token_endpoint? } joins Bearer as a credential type; endpoints auto-discovered from the resource server’s WWW-Authenticate challenge when omitted
  • Completion via native deep link tuic://oauth-callback?code=…&state=… — callbacks never touch the WebView console
  • TokenManager shared across every HttpMcpClient refresh path with a per-upstream semaphore that defeats thundering-herd refresh. 60 s expiry margin; None expires_at treated as valid
  • UpstreamError::NeedsOAuth { www_authenticate } transitions the registry to needs_auth; Services tab shows an Authorize button
  • Auto-triggered OAuth is gated behind explicit user consent; the confirm dialog surfaces the Authorization Server origin to defend against AS mix-up
  • Status values extended: authenticating (“Awaiting authorization…”) + needs_auth
  • Tauri commands: start_mcp_upstream_oauth, mcp_oauth_callback, cancel_mcp_upstream_oauth

19.9 Environment Sanitization (stdio)

  • Parent environment is cleared before spawning to prevent credential leakage
  • Safe allowlist re-applied: PATH, HOME, USER, LANG, LC_ALL, TMPDIR, TEMP, TMP, SHELL, TERM
  • User-configured env overrides applied on top

19.10 SSE Events

  • upstream_status_changed events emitted on status transitions (connecting, ready, circuit_open, disabled, failed)
  • tools/list_changed notification emitted when upstream tool lists change, enabling live tool-list updates for connected MCP clients
  • Delivered via GET /events SSE stream

19.11 Metrics (per upstream, lock-free)

  • call_count — total tool calls routed
  • error_count — total failed calls
  • last_latency_ms — last observed round-trip time

19.12 Validation

  • Names: must match [a-z0-9_-]+, must be unique
  • HTTP URLs: must use http:// or https:// scheme only
  • Self-referential URL detection: rejects URLs pointing to TUIC’s own MCP port
  • Stdio: command must be non-empty
  • All errors collected (not just first) and returned to caller
  • Respects sound toggle from Settings screen

20. Performance

20.1 PTY Write Coalescing

  • Paint triggers coalesced per animation frame via requestAnimationFrame (~60 repaints/sec)
  • High-throughput agent output (hundreds of events/sec) batched into single grid frame updates
  • Reduces canvas render passes during burst output
  • Flow control (pause/resume at HIGH_WATERMARK) unchanged

20.2 Async Git Commands

  • All ~25 Tauri git commands run inside tokio::task::spawn_blocking
  • Prevents git subprocess calls from blocking Tokio worker threads
  • get_changed_files merged from 2 sequential subprocesses to 1

20.3 Watcher-Driven Git Cache

  • Unified repo_watcher (FSEvents/inotify) monitors entire working tree with per-category debounce
  • CategoryEmitter routes events to Git, WorkTree, or Config handlers with trailing debounce
  • .gitignore-aware filtering prevents unnecessary cache invalidations
  • Cache hit ~0.2ms vs git subprocess ~20-30ms
  • 60s TTL as safety net for missed watcher events

20.4 Process Name via Syscall

  • proc_pidpath (macOS) / /proc/pid/comm (Linux) replaces ps fork
  • Eliminates ~100 fork+exec/min with 5 terminals open

20.5 MCP Concurrent Tool Calls

  • HttpMcpClient uses RwLock instead of Mutex
  • Tool calls use read lock (concurrent); only reconnect takes write lock

20.6 Serialization

  • PTY parsed events serialized once with serde_json::to_value
  • Reused for both Tauri IPC emit and event bus broadcast (was serialized twice)

20.7 Frontend Bundle Splitting

  • Vite manualChunks: terminal, codemirror, diff-view, markdown as separate chunks
  • SettingsPanel, ActivityDashboard, HelpPanel lazy-loaded with lazy() + Suspense
  • PTY read buffer increased from 4KB to 64KB for natural batching

20.8 Conditional Timers

  • StatusBar 1s timer only active when merged PR countdown or rate limit is displayed
  • ActivityDashboard snapshot signal uses default equality check (no forced re-render every 10s)

20.9 Profiling Infrastructure

  • Scripts in scripts/perf/: IPC latency, PTY throughput, CPU recording, Tokio console, memory snapshots
  • tokio-console feature flag for async task inspection
  • See docs/guides/profiling.md

21. CLI Companion (tuic)

21.1 Overview

  • Standalone Rust binary embedded as a sidecar, installed to system PATH
  • Combines VS Code-style file opening, tmux-style session management, and agent orchestration
  • Cross-platform: macOS, Linux, Windows
  • Communicates via IPC (Unix socket / Windows named pipe) with the running TUICommander instance
  • Auto-launches TUICommander if not running

21.2 Editor Mode

  • tuic [path] — open file or directory (VS Code/Zed style)
  • tuic open --goto file:line:col — open at specific position
  • tuic open --wait — block until file closed ($EDITOR support)
  • tuic diff <a> <b> — diff view

21.3 Session Management (tmux-compatible)

  • tuic ls / tuic new / tuic kill / tuic send / tuic capture
  • tuic resize <id> WxH / tuic pause / tuic resume
  • Targets accept UUIDs, ID prefixes, or session names
  • tmux key name translation (Enter, C-c, Space, etc.)

21.4 Agent Orchestration

  • tuic agent spawn <type> [repo] — spawn AI agent
  • tuic agent ls — list running agents
  • tuic agent send <id> <message> — message an agent

21.5 tmux Compatibility Mode

  • tuic alias creates tmux → tuic symlink; argv[0] detection switches to compat mode
  • Supports: new-session, list-sessions, kill-session, kill-server, send-keys, capture-pane, resize-pane, attach-session, has-session
  • Tools expecting tmux (e.g. Claude Code --tmux) transparently use TUICommander

21.6 Installation

  • First-run prompt on app launch (one-time, dismissible)
  • Settings > General > Command Line Interface (install/uninstall button with status)
  • Auto-update on app startup (silent, no elevation prompt)
  • Paths: /usr/local/bin/tuic (macOS/Linux), %LOCALAPPDATA%\Microsoft\WindowsApps\tuic.exe (Windows)
  • tuic install-cli / tuic alias for self-service

22. Remote Daemon (tuic-remote) — Beta

22.1 Overview

  • Standalone headless binary for running TUICommander on servers without a desktop environment
  • Same HTTP/WebSocket API as the desktop app’s remote access feature
  • No Tauri dependency — pure Rust binary
  • Available as GitHub Release artifacts for Linux x64/ARM64, macOS ARM, and Windows x64

22.2 Configuration

  • Uses the same config file as the desktop app (~/.config/tuicommander/config.toml)
  • Default port: 9877 (overridable via TUIC_PORT env var)
  • --set-password flag for interactive password setup (bcrypt hashed)
  • LAN auth bypass always disabled in headless mode (security hardening)

22.3 TLS

  • Manual TLS via [services.tls] config section (cert + key PEM paths)
  • No TLS by default — use a reverse proxy or Tailscale for production

22.4 Lifecycle

  • Graceful shutdown on SIGINT/SIGTERM
  • Binds TCP, starts background tasks (MCP session reaper, upstream health checks)
  • Fails fast if port is already in use

23. SSH Tunnel Manager

23.1 Supervised Tunnels

  • Managed SSH processes with automatic lifecycle supervision
  • Tunnel states: Starting, Connected, Reconnecting, Stopped, Error
  • Health check: process must survive 500ms after spawn to be considered connected
  • Graceful shutdown: SIGTERM with 5s grace period, then SIGKILL escalation
  • SSH agent forwarding: auto-discovers SSH_AUTH_SOCK for key-based auth

23.2 Reconnection with Exponential Backoff

  • Automatic retry on retryable failures (network down, connection refused, timeout)
  • Exponential backoff: 1s base, doubling per attempt, capped at 30s
  • Jitter: +/-25% per delay to prevent thundering herd
  • Maximum 10 retries before stopping; counter resets on successful connection
  • Non-retryable failures (auth denied, host key mismatch, port in use) stop immediately

23.3 Exit Classification

  • Stderr-based pattern matching classifies SSH exit reasons (AuthFailed, HostKeyMismatch, PortInUse, ConnectionRefused, NetworkDown, Timeout, UserKilled)
  • Exit code used as fallback when stderr is empty
  • Classification drives retry decisions — only network-related failures are retried

23.4 Audit Logging

  • SQLite database with WAL mode for concurrent-safe, high-performance event logging
  • Event types: Started, Connected, Disconnected, Error, Retry, Stopped
  • Query by tunnel ID (most recent N events) or by time range
  • Automatic rotation: configurable retention period deletes old events
  • Indexed on tunnel_id and timestamp for fast lookups

23.5 Profile Configuration

  • TOML-based profiles with name, host, port, user, identity file, and port forwards
  • Global scope: <config_dir>/tunnels/*.toml — available across all repos
  • Per-repo scope: <repo>/.tuic/tunnels/*.toml — overrides global profiles with same ID
  • Forward types: Local (-L) and Remote (-R) port forwarding
  • Options: ServerAliveInterval (default 15s), ServerAliveCountMax (default 3), StrictHostKeyChecking (Yes/AcceptNew)
  • Validation: duplicate bind ports, empty fields, port range (1-65535)
  • Pre-spawn port availability check for local forwards

23.6 Tauri IPC Commands

  • All tunnel management exposed as native Tauri IPC commands (tunnels/tauri_commands.rs) — profile CRUD, start/stop, status, audit log, SSH config host parsing, SSH agent key listing
  • Desktop app uses IPC directly; browser mode falls back to HTTP endpoints

23.7 Auto-Connect

  • Profiles with auto_connect: true start automatically on app launch
  • Hydration runs once during startup, guarded against duplicate calls
  • Non-blocking: failures are logged but don’t prevent app startup

23.8 SSH Agent Detection

  • Auto-detects SSH agent type from SSH_AUTH_SOCK: 1Password, Secretive, GPG Agent, generic SSH Agent
  • Lists loaded keys via ssh-add -l (fingerprint, comment, key type)
  • Shown in the tunnel editor for identity verification

23.9 Orphan SSH Process Cleanup

  • check_local_port() distinguishes PermissionDenied (privileged ports) from AddrInUse
  • kill_ssh_on_port() finds SSH processes holding a port via lsof, verifies with ps, sends SIGTERM
  • Only kills confirmed ssh processes — never unrelated services

23.10 Statusbar Shield

  • Grey shield icon when tunnel profiles exist but none are connected
  • Green shield with count badge when tunnels are connected
  • Clicking the shield opens the Tunnels Panel

23.11 Shutdown on Exit

  • TunnelManager::shutdown_all() called on RunEvent::Exit
  • Stops all supervisors and clears the tunnel map — no orphaned SSH processes after app close

23.12 UI

  • TunnelsPanel — List of tunnel profiles with status badges and start/stop controls
  • TunnelEditorModal — Create and edit tunnel profiles with form validation; file browse dialog for identity file; remote host pre-populated from tunnel host when adding forwards; numeric input mode for port fields
  • TunnelStatusBadge — Color-coded status indicator (green=connected, blue=starting, orange=reconnecting, red=error, grey=stopped)
  • Command Palettetoggle-tunnels action registered for quick access

24. Remote Connection Manager

24.1 Connection Types

  • SSH — Connects via SSH tunnel to a remote tuic-remote daemon; auto-creates port forwarding
    • Fields: host, SSH port (default 22), SSH user, optional identity file, remote daemon port (default 9877)
  • Direct — Connects to a tuic-remote daemon URL directly (for Tailscale, LAN, or VPN scenarios)
    • Fields: URL, auth username

24.2 Storage

  • Connections persisted in <config_dir>/connections.json
  • Atomic writes via temp file + rename
  • Each connection has UUID, name, transport, auth username, and enabled flag

24.3 Remote Repositories and Terminals

  • Repos can be assigned to a remote connection; sidebar shows remote badge
  • Terminals on remote repos route WebSocket I/O through the connection’s base URL
  • transport.ts routes invoke() calls based on the active connection’s connectionId
  • canvasTerminalTransport.ts supports configurable baseUrl for remote WebSocket connections
  • Health polling for direct connections; SSH connections rely on tunnel supervisor status

24.4 SSE Event Bridge

  • remoteEventBridge.ts subscribes to server-sent events from remote daemons
  • Bridges remote events (repo changes, PTY output, agent status) into local stores
  • Automatic reconnection on connection loss

25. Generators

Secure value generators accessible from the command palette (open-generators action).

25.1 Available Generators

  • Password — Configurable length, character classes (uppercase, lowercase, digits, symbols)
  • UUID v4 — Standard random UUID (RFC 4122)
  • UUID v7 — Time-ordered UUID (RFC 9562)
  • ULID — Universally unique lexicographic identifier
  • CUID2 — Collision-resistant unique identifier
  • JWT Secret — 256-bit random hex key
  • TOTP Secret — RFC 4226 base32 secret (160-bit)
  • Nano ID — URL-friendly random ID with configurable length
  • Slug — adjective-noun-NNNN random slug
  • Ed25519 Key Pair — Public + private key pair

25.2 Architecture

  • All generation happens in the Rust backend (generators.rs) via the ring crate for cryptographic randomness
  • Frontend is a modal dialog with copy-to-clipboard and regenerate actions
  • Password and Nano ID have configurable options (length, character classes)