# sunbeam code — Terminal Coding Agent `sunbeam code` is a terminal-based coding agent powered by Sol. It connects to Sol's gRPC `CodeAgent` service and provides an interactive TUI for writing code, asking questions, and executing tools — with Sol handling the AI reasoning and the CLI handling local file operations. ## Quick Start ```bash sunbeam code # start a session (auto-detects project) sunbeam code start --model devstral-small # override the model sunbeam code start --endpoint http://sol:50051 # custom Sol endpoint sunbeam code demo # demo the TUI without Sol ``` ## How It Works ```mermaid sequenceDiagram participant User participant TUI as sunbeam code TUI participant Agent as Background Agent participant Sol as Sol gRPC User->>TUI: sunbeam code TUI->>TUI: Discover project context TUI->>Agent: Spawn background tasks Agent->>Sol: StartSession (project, capabilities) Agent->>Sol: IndexSymbols (tree-sitter symbols) Sol-->>Agent: SessionReady (session_id, model) Agent-->>TUI: Connected User->>TUI: Type message, press Enter TUI->>Agent: Chat request Agent->>Sol: UserInput (text) loop Tool calls Sol-->>Agent: ToolCall (is_local=true) Agent->>Agent: Check permissions alt needs approval Agent-->>TUI: Show approval prompt User->>TUI: yes / always / no TUI->>Agent: Decision end Agent->>Agent: Execute tool locally Agent->>Sol: ToolResult end Sol-->>Agent: TextDone (response + tokens) Agent-->>TUI: Display response ``` ## Project Discovery On startup, the CLI discovers project context from the current working directory: - **Project name** — directory basename - **Custom instructions** — `.sunbeam/prompt.md` (injected into Sol's system prompt) - **Tool configuration** — `.sunbeam/config.toml` (model + tool permissions) - **Git state** — current branch + `git status --short` - **File tree** — recursive scan (max depth 2, skips `target/`, `node_modules/`, hidden dirs) All of this is sent to Sol in the `StartSession` message so it has full project context. ## Symbol Indexing After connecting, the CLI extracts code symbols from the project using tree-sitter and sends them to Sol via `IndexSymbols`. Sol indexes these in OpenSearch for code search during the session. Supported languages: - **Rust** — functions, structs, enums, traits - **TypeScript/JavaScript** — functions, classes, interfaces, types - **Python** — functions, classes, methods Each symbol includes name, kind, signature, docstring, line numbers, and a preview of the body. ## Tool Execution Sol decides which tools to call. Tools marked `is_local=true` execute on your machine; everything else runs on the server. ### Client-Side Tools | Tool | Default Permission | Description | |------|-------------------|-------------| | `file_read` | always | Read file contents (with optional line ranges) | | `file_write` | ask | Write or create files | | `search_replace` | ask | Apply SEARCH/REPLACE diffs to files | | `grep` | always | Search files with ripgrep or grep | | `bash` | ask | Execute shell commands | | `list_directory` | always | List directory tree (with depth limit) | ### LSP Tools Auto-detected based on project files: | Project File | Server | |-------------|--------| | `Cargo.toml` | `rust-analyzer` | | `package.json` or `tsconfig.json` | `typescript-language-server` | | `pyproject.toml`, `setup.py`, `requirements.txt` | `pyright-langserver` | | `go.mod` | `gopls` | LSP tools: `lsp_definition`, `lsp_references`, `lsp_hover`, `lsp_diagnostics`, `lsp_symbols`. These are advertised as client capabilities in `StartSession` — Sol only registers tools for LSP servers the client can actually spawn. ### Server-Side Tools Sol can also call its own server-side tools during coding sessions: `search_code`, `search_archive`, `search_web`, `research`, and others. These execute on Sol's side — no local action needed. ## Tool Permissions Configure in `.sunbeam/config.toml`: ```toml [model] name = "devstral-2" # override default model [tools] file_read = "always" # always, ask, never file_write = "ask" bash = "never" # block shell commands entirely search_replace = "ask" grep = "always" list_directory = "always" ``` Permissions: - **`always`** — execute immediately, no prompt - **`ask`** — show approval prompt with three choices: *yes*, *yes, always allow*, *no* - **`never`** — deny silently, Sol gets an error response Choosing "yes, always allow" upgrades the permission to `always` for the rest of the session (in-memory only). ## TUI ```mermaid flowchart TD subgraph Layout title[Title Bar
project | branch | model | tokens | connection] conversation[Conversation Area
user + assistant messages,
tool output, status] input[Input Bar
current line] end title --> conversation conversation --> input ``` **Key bindings:** | Key | Action | |-----|--------| | Enter | Send message | | Ctrl+C | Quit | | Alt+L | Toggle debug log view | | Up/Down | Navigate input history | | Page Up/Down | Scroll conversation | The TUI shows real-time status updates as Sol thinks and executes tools. Approval prompts appear inline when a tool needs permission. ## Session Resumption Sessions are tied to a project path + git branch. If a session already exists for the current context, Sol resumes it — the TUI loads conversation history and you can continue where you left off. ## Code Reindexing Separately from coding sessions, you can trigger repo indexing into Sol's code search: ```bash sunbeam reindex-code # all repos sunbeam reindex-code --org studio # specific org sunbeam reindex-code --repo studio/sol --branch main # specific repo + branch ``` This calls Sol's `ReindexCode` gRPC endpoint, which walks Gitea repos, extracts symbols via tree-sitter, and indexes them to OpenSearch. ## Architecture The `sunbeam code` command is structured as three concurrent layers: ```mermaid flowchart TD subgraph "Main Thread" tui[TUI Event Loop
ratatui, 50ms poll] end subgraph "Tokio Runtime" agent[Agent Loop
chat processing,
tool execution] heartbeat[Heartbeat
1s ping to Sol] end subgraph "Sol (remote)" grpc_service[gRPC CodeAgent] orchestrator[Orchestrator] mistral[Mistral AI] end tui <--> |crossbeam channels| agent agent <--> |gRPC stream| grpc_service heartbeat --> |health check| grpc_service grpc_service --> orchestrator orchestrator --> mistral ``` - **TUI** (main thread) — Ratatui event loop, renders conversation, handles input, shows tool approval prompts - **Agent** (tokio task) — Manages the gRPC session, executes client-side tools, bridges between TUI and Sol via crossbeam channels - **Heartbeat** (tokio task) — Pings Sol every second, updates the connection indicator in the title bar The TUI never blocks on network calls. All gRPC communication happens in the agent task, with events flowing back via bounded channels.