206 lines
7.1 KiB
Markdown
206 lines
7.1 KiB
Markdown
# 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<br/>project, branch, model, tokens, connection"]
|
|
conversation["Conversation Area<br/>user + assistant messages,<br/>tool output, status"]
|
|
input["Input Bar<br/>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<br/>ratatui, 50ms poll]
|
|
end
|
|
|
|
subgraph "Tokio Runtime"
|
|
agent[Agent Loop<br/>chat processing,<br/>tool execution]
|
|
heartbeat[Heartbeat<br/>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.
|