docs: update README and usage for current architecture

This commit is contained in:
Levi Neely 2026-08-12 18:06:22 +02:00
parent 23f3a6092b
commit 31d550a94b
2 changed files with 131 additions and 90 deletions

View File

@ -53,15 +53,15 @@ Everything lives under `$XDG_CONFIG_HOME/ollie/` (default: `~/.config/ollie/`)
| Capability | How | | Capability | How |
|---|---| |---|---|
| **CLI** | `o` — unified namespace CLI: `read`, `write`, `ls`, `ctl`, `prompt`, `tui`, `env`, `generate` | | **CLI** | `o` — unified namespace CLI: `read`, `write`, `ls`, `new`, `ctl`, `prompt`, `tui`, `env`, `generate` |
| **Terminal TUI** | `o tui` — tmux layout, no widgets | | **Terminal TUI** | `o tui` — tmux layout, no widgets |
| **One-shot LLM** | `o generate "explain monads"` or `echo "prompt" \| o generate` | | **One-shot LLM** | `o generate "explain monads"` or `echo "prompt" \| o generate` |
| **Run an agent** | Create a session + agent via 9P — then connect with any frontend ([ellie](doc/ellie.md), KDE (GUI/KRunner/Kate), `o tui`) | | **Run an agent** | Create a session + agent via 9P — then connect with any frontend ([ellie](doc/ellie.md), KDE (GUI/KRunner/Kate), acme, `o tui`) |
| **Remote execution** | Set `remote=user@host` in session config | | **Remote execution** | Set `remote=user@host` in session config |
| **Background processes** | Pass `"background": true` to any tool — runs with no timeout, output pushed to agent prompt on completion | | **Background processes** | Pass `"background": true` to any tool — runs with no timeout, output pushed to agent prompt on completion |
| **Parallel execution** | Non-conflicting tool calls within a turn run in parallel (scope-based conflict scheduling) | | **Parallel execution** | Non-conflicting tool calls within a turn run in parallel (scope-based conflict scheduling) |
| **Agents** | Write a JSON config in `data/agents/` with agent prompt in `data/prompts/` | | **Agents** | Write a JSON config in `~/.config/ollie/agents/` with agent prompt in `~/.config/ollie/prompts/` |
| **Tools** | Drop an executable + `.meta` in `~/.config/ollie/tools/` — load at runtime via `/tool_load` | | **Tools** | Drop an executable + `.meta` in `~/.config/ollie/tools/` — load at runtime via `tool_load` |
| **Domain skills** | Load markdown skill modules at runtime | | **Domain skills** | Load markdown skill modules at runtime |
## Repository layout ## Repository layout
@ -70,28 +70,42 @@ Single Go module with one Git submodule (kde).
| Directory | Language | Description | | Directory | Language | Description |
|-----------|----------|-------------| |-----------|----------|-------------|
| `agent/` | Go | Agent loop, history, prompt resolution, context compaction |
| `backend/` | Go | LLM providers (Anthropic, OpenAI, Ollama, Gemini, Copilot, CodeWhisperer) |
| `toolsrv/` | Go | Tool server client library (9P client for toolsrv) |
| `cmd/toolsrv/` | Go | Tool execution server (separate 9P server, sandboxed execution) |
| `tools/lsp/` | Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
| `session/` | Go | Session lifecycle, config, persistence |
| `fs/` | Go | 9P filesystem tree (EDSL-declared namespace, ctl dispatch) |
| `fsedsl/` | Go | Filesystem declaration EDSL (generic, reusable) |
| `bypass/` | Go | Bypass broker (sandbox escape approval) |
| `sandbox/` | Go | Landlock sandbox config |
| `lib9p/` | Go | 9P protocol library + native C client |
| `cmd/olliesrv/` | Go | The main server binary (session/agent 9P namespace) | | `cmd/olliesrv/` | Go | The main server binary (session/agent 9P namespace) |
| `cmd/toolsrv/` | Go | Tool execution server (spawned by olliesrv, separate 9P server) | | `cmd/toolsrv/` | Go | Tool execution server (separate 9P server, sandboxed execution) |
| `cmd/ollie-9p/` | Go | 9P client CLI | | `cmd/ollie-9p/` | Go | 9P client CLI |
| `cmd/ollie-remote/` | Go | Remote execution binary | | `toolsrv/` | Go | Tool server client library + tool discovery (9P client for toolsrv) |
| `virtfs/` | Go | Filesystem declaration EDSL (generic, reusable) |
| `lib9p/` | Go | 9P protocol library + native C client |
| `tools/lsp/` | Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
| `env/` | Go | Environment variable defaults |
| `format/` | Go | Output formatting |
| `log/` | Go | Structured logging |
| `paths/` | Go | XDG path resolution |
| `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner *(submodule)* | | `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner *(submodule)* |
| `data/agents/` | JSON | Agent configs | | `contrib/elisp/` | Emacs Lisp | ellie.el — Emacs frontend |
| `data/agents/` | JSON | Agent configs (installed to `~/.config/ollie/agents/`) |
| `data/prompts/` | Markdown | System prompt templates | | `data/prompts/` | Markdown | System prompt templates |
| `data/tools/` | Mixed | Tool executables (scripts + compiled) + `.meta` sidecar files | | `data/tools/` | Mixed | Tool executables (scripts + compiled) + `.meta` sidecar files |
| `data/skills/` | Markdown | Domain knowledge modules | | `data/skills/` | Markdown | Domain knowledge modules |
| `data/scripts/` | Shell | CLI scripts (`o`, `ollie-remount`, acme helpers) |
| `doc/` | Markdown | Architecture docs, usage guide | | `doc/` | Markdown | Architecture docs, usage guide |
### Internal packages (not importable outside their command)
| Package | Parent | Description |
|---------|--------|-------------|
| `agent` | `cmd/olliesrv` | Agent loop, history, prompt resolution, context compaction |
| `backend` | `cmd/olliesrv` | LLM providers (Anthropic, OpenAI/OpenRouter, Ollama, Gemini, Copilot, Kiro) |
| `session` | `cmd/olliesrv` | Session lifecycle, config, persistence |
| `fs` | `cmd/olliesrv` | 9P filesystem tree (virtfs-declared namespace, ctl dispatch) |
| `bypass` | `cmd/olliesrv` | Bypass broker (sandbox escape approval) |
| `toolclient` | `cmd/olliesrv` | Spawns and connects to toolsrv |
| `prompts` | `cmd/olliesrv` | Prompt template resolution |
| `registry` | `cmd/toolsrv` | Per-agent tool registry |
| `exec` | `cmd/toolsrv` | Sandboxed tool execution |
| `sandbox` | `cmd/toolsrv` | Landlock sandbox config and wrapper |
| `server` | `cmd/toolsrv` | 9P filesystem + proc management |
## Architecture ## Architecture
```mermaid ```mermaid
@ -126,6 +140,7 @@ graph TB
ANT[Anthropic] ANT[Anthropic]
COP[Copilot] COP[Copilot]
KIRO[Kiro] KIRO[Kiro]
GEM[Gemini]
end end
TUI & SCRIPTS & ACME --> O TUI & SCRIPTS & ACME --> O
@ -135,7 +150,7 @@ graph TB
SESS --> AG SESS --> AG
SESS -->|9P over Unix socket| TOOLS SESS -->|9P over Unix socket| TOOLS
AG -->|streaming| OLL & OAI & ANT & COP & KIRO AG -->|streaming| OLL & OAI & ANT & COP & KIRO & GEM
TOOLS --> EXEC TOOLS --> EXEC
``` ```
@ -156,4 +171,4 @@ filesystem, see [`doc/9p.md`](doc/9p.md).
## License ## License
GPLv3 GPLv3

View File

@ -32,20 +32,21 @@ Valid levels: `debug`, `info`, `warn`, `error`.
## `o` — Terminal CLI ## `o` — Terminal CLI
`o` is a multi-call shell script that wraps the 9P namespace into a human-friendly interface. `o` is a multi-call shell script that wraps the 9P namespace into a human-friendly interface.
Installed to `~/bin/o` by `just install-data`. Installed to `~/.local/bin/o` by `just install-data`.
### Quick start ### Quick start
```sh ```sh
eval $(o env myproject default) # set session + agent context o new myproject # create a session
o prompt # interactive prompt REPL o myproject new default # create an agent in that session
o myproject/default tui # launch the tmux TUI
``` ```
In another terminal: Or without the TUI:
```sh ```sh
eval $(o env myproject default) o myproject/default prompt # interactive prompt REPL (one terminal)
o read chat # stream chat output o myproject/default read chat # stream chat output (another terminal)
``` ```
<table align="center" width="90%"> <table align="center" width="90%">
@ -61,59 +62,70 @@ o read chat # stream chat output
</tr> </tr>
</table> </table>
### Context model
Context is determined by the first argument — not by environment variables:
```
o <cmd> Root level (no context)
o <session> <cmd> Session level
o <session>/<agent> <cmd> Agent level
```
The slash in `<session>/<agent>` disambiguates session-only from session+agent.
If no command follows the context, `o` defaults to `ls`.
### Commands ### Commands
| Command | Description | | Command | Context | Description |
|---|---| |---|---|---|
| `o prompt` | Interactive multi-line prompt REPL | | `o ls` | root | List sessions, models, backends |
| `o read [-l] <path>` | Read a file (-l: loop, re-read after each return) | | `o new <session> [cwd]` | root | Create a new session |
| `o write <path> [data]` | Write to any file | | `o generate <prompt>` | root | One-shot generation (no session needed) |
| `o ls [path]` | List namespace entries | | `o <sess> ls` | session | List session contents |
| `o ctl <cmd> [args]` | Send control command (rdwr: gets response) | | `o <sess> new <agent> [cwd]` | session | Create a new agent |
| `o generate <prompt>` | One-shot generation (no session needed) | | `o <sess> ctl <cmd>` | session | Session control |
| `o tui` | Launch tmux TUI | | `o <sess>/<agent> prompt` | agent | Interactive multi-line prompt REPL |
| `o env [session] [agent]` | Print export statements for context | | `o <sess>/<agent> tui` | agent | Launch tmux TUI |
| `o <sess>/<agent> ctl <cmd>` | agent | Agent control (stop, compact, model, etc.) |
### Context | `o <sess>/<agent> log [-n N]` | agent | Show last N lines of agent log |
| `o read [-l] <path>` | any | Read a file (-l: loop) |
Context is set via `$session` and `$agent` environment variables: | `o write <path> [data]` | any | Write to a file (args or stdin) |
| `o env` | any | Print export statements for current context |
```sh | `o help` | any | Show help |
eval $(o env myproject default) # export session=myproject agent=default
# Now every o command addresses the right agent automatically:
o ctl model # → shows current model
o read -l statewait
```
### Path resolution ### Path resolution
Paths are slash-delimited 9P namespace paths. The `o` CLI resolves them based When you supply a context, `o` sets a **prefix**:
on context: - Session: `session/<sess>`
- Agent: `session/<sess>/agent/<agent>`
| Path type | Example | Resolves to | Paths given to `read`, `write`, and `ls` are resolved relative to this prefix.
|---|---|---| A leading `/` escapes the prefix and addresses the root namespace directly:
| Root-level | `o read models` | `models` (no context needed) |
| Agent file | `o read state` | `session/$session/agent/$agent/state` |
| Session file | `o read env` | `session/$session/env` |
| Full path | `o read session/foo/agent/bar/chat` | Used as-is |
Root-level paths (`session/`, `agents`, `models`, `help`, `ctl`, `tools`) and | Invocation | Resolves to |
absolute paths (starting with `session/`) bypass context resolution entirely. |---|---|
Agent-level files (`chat`, `state`, `prompt`, `statewait`, `cfg`, `plan`, | `o myproj/coding read chat` | `session/myproj/agent/coding/chat` |
`log`, `cost`, `offset`, `context`, `systemprompt`) require both `$session` | `o myproj/coding read cfg` | `session/myproj/agent/coding/cfg` |
and `$agent`. Session-level files (`env`, `ctl`, `id`, `name`, `paused`) | `o myproj read env` | `session/myproj/env` |
require only `$session`. | `o myproj/coding read /models` | `models` (root) |
| `o myproj/coding ls /bypass` | `bypass` (root) |
| `o read models` | `models` (no context, no prefix) |
The leading slash is necessary when you want to access root-level paths
(like `models`, `backends`, `bypass/`) while in session or agent context.
Without it, the path is concatenated with the context prefix.
### Prompt REPL ### Prompt REPL
`o prompt` is an interactive multi-line REPL with readline editing: `o <session>/<agent> prompt` is an interactive multi-line REPL:
``` ```
$ o prompt $ o myproj/coding prompt
[myproject/default] [myproj/coding]
Type . on a blank line to send, Ctrl+D to exit. Type . on a blank line to send, Ctrl+D to exit.
Slash commands: /stop /compact /kill /clear /model /backend /cwd /help / prefix runs ctl: /stop, /compact, /model X, /inject X
!q exits the TUI.
> write a fibonacci function in python > write a fibonacci function in python
and include a test case and include a test case
@ -127,13 +139,16 @@ Slash commands control the agent without sending a prompt:
|---|---| |---|---|
| `/stop` | Interrupt running agent | | `/stop` | Interrupt running agent |
| `/compact` | Compact context window | | `/compact` | Compact context window |
| `/kill` | Kill the session (exits REPL) |
| `/clear` | Clear history |
| `/model X` | Switch model | | `/model X` | Switch model |
| `/backend X` | Switch backend |
| `/cwd X` | Change working directory | | `/cwd X` | Change working directory |
| `/quit` or `/q` | Kill the tmux TUI | | `!q` | Kill the tmux TUI session and exit |
| `/help` | List commands |
Piped input is also supported:
```sh
echo "explain this error" | o myproj/coding prompt
cat file.go | o myproj/coding write prompt
```
### One-shot generation ### One-shot generation
@ -145,18 +160,13 @@ cat error.log | o generate # pipe content as the prompt
echo "write a haiku about filesystems" | o generate | wc -w echo "write a haiku about filesystems" | o generate | wc -w
``` ```
Chain multiple steps:
```sh
echo "list 5 blog post ideas" | o generate | head -3 | o generate
```
--- ---
## `o tui` — tmux Terminal UI ## `o tui` — tmux Terminal UI
`o tui` composes `o read chat` and `o prompt` into a single tmux layout — two shell `o <session>/<agent> tui` composes `o read chat` and `o prompt` into a single
commands in two panes, with agent state in the tmux status bar: tmux layout — two shell commands in two panes, with agent state in the tmux
status bar:
<p align="center"> <p align="center">
<a href="img/ollie-tui.png"><img src="img/ollie-tui.png" alt="Screenshot of the o tui tmux layout: chat pane on top, prompt REPL on bottom, agent state in status bar" width="75%"></a> <a href="img/ollie-tui.png"><img src="img/ollie-tui.png" alt="Screenshot of the o tui tmux layout: chat pane on top, prompt REPL on bottom, agent state in status bar" width="75%"></a>
@ -165,17 +175,15 @@ commands in two panes, with agent state in the tmux status bar:
### Usage ### Usage
```sh ```sh
eval $(o env myproject default) o myproj/coding tui
o tui
``` ```
1. Requires `$session` and `$agent` to be set. 1. Creates a tmux session named `o-<session>`.
2. Creates a tmux session named `o-<session>`. 2. Two panes:
3. Two panes: - **Pane 0** (top, 80%): streams chat output (log tail + live `read chat`).
- **Pane 0** (top, 80%): `o read chat` — streams filtered chat output (markers stripped server-side).
- **Pane 1** (bottom, 20%): `o prompt` — multi-line REPL (`/` prefix runs ctl commands). - **Pane 1** (bottom, 20%): `o prompt` — multi-line REPL (`/` prefix runs ctl commands).
4. A background loop reads `statewait` and updates the tmux status bar instantly. 3. A background loop reads `statewait` and updates the tmux status bar on each state transition.
5. Focuses the prompt pane and attaches. 4. Focuses the prompt pane and attaches.
No polling. Each read blocks until data arrives. The status bar updates on every No polling. Each read blocks until data arrives. The status bar updates on every
state transition via `statewait` — zero CPU when idle. state transition via `statewait` — zero CPU when idle.
@ -189,10 +197,28 @@ state transition via `statewait` — zero CPU when idle.
--- ---
## `o env` — Context export
`o env` prints export statements for the current context. This is useful for
other tools (raw `ollie-9p` commands, scripts) that need to know which session
and agent are being addressed:
```sh
eval $(o myproj/coding env)
# exports OLLIE_SESSION=myproj OLLIE_AGENT=coding
ollie-9p read session/$OLLIE_SESSION/agent/$OLLIE_AGENT/stats
```
Note: `o` itself does not read these environment variables — it determines
context purely from its positional arguments.
---
## Other front-ends ## Other front-ends
- **[ellie](ellie.md)** — Emacs session tree, chat, multi-agent - **[ellie](ellie.md)** — Emacs session tree, chat, multi-agent
- **KDE** — plasmoid, standalone GUI, Kate plugin, KRunner - **[KDE](kde-gui.md)** — plasmoid, standalone GUI, Kate plugin, KRunner
- **acme** — Plan 9 editor (scripts in `data/scripts/acme/`)
For technical details (generation parameters, sandboxing, multi-agent workflows, For technical details on the raw 9P filesystem, see [`doc/9p.md`](9p.md).
tool discovery, and the raw 9P filesystem), see [doc/whitepaper.md](whitepaper.md). For tool authoring, see [`doc/writing-tools.md`](writing-tools.md).