# ellie — Emacs front-end for ollie ellie talks to an ollie session through the `ollie-9p` CLI tool, which speaks the 9P protocol directly over a Unix socket. No FUSE mount required. The ollie-9p filesystem is the entire API surface — ellie uses nothing but plain file I/O. ## Prerequisites [olliesrv](../README.md) must be running: ```sh olliesrv ``` ## Installation Add `ellie.el` to your load path: ```elisp (add-to-list 'load-path "/path/to/ellie/contrib/elisp") (require 'ellie) ``` Or with `use-package`: ```elisp (use-package ellie :load-path "/path/to/ellie/contrib/elisp") ``` Optionally set default session options: ```elisp (setq ellie-default-session-opts '(("backend" . "ollama") ("model" . "qwen3:8b"))) ``` ## Quick start ``` M-x ellie ``` Opens the session tree (`*ellie-sessions*`), attached to the last-known session for your working directory if it still exists.

ellie Emacs interface showing the Ollie session tree and chat window

## Session tree The tree shows all sessions organized by active/inactive state: ``` ▼ Active ▼ myproject (2) default [idle] reviewer [idle] ▼ scratch (1) 0 [calling: file_read] ▶ Inactive ``` | Key | Action | |-----|--------| | `RET` | Expand/collapse header or session; select agent | | `e` | Toggle expand/collapse | | `n` | New session | | `N` | New agent (prompts for profile, cwd) | | `c` | Open chat buffer for selected agent | | `g` | Refresh tree | | `C-c C-c` | Send prompt to selected agent | | `C-c C-q` | Queue prompt for selected agent | | `C-c C-s` | Stop running agent | | `C-c C-k` | Kill session or agent at point | | `C-c C-p` | Show system prompt | | `q` | Quit tree | Sessions are addressed by name (`session/{sname}`). Agents within a session are addressed by their auto-generated ID (`session/{sname}/agent/{aname}`). The tree discovers both automatically. ## Chat buffer Once an agent is selected, `c` opens the chat buffer (`*ellie*`): | Key | Action | |-----|--------| | `RET` / `SPC` | Open input window to compose a prompt | | `C-c C-q` | Open input window to compose a queued prompt | | `C-c C-c` | Interrupt the running turn | | `C-c C-s` | Stop agent | | `C-c C-k` | Kill the current session | | `C-c C-n` / `n` | New session | | `C-c C-a` | Attach to a different session | | `C-c C-p` | Show the rendered system prompt | | `g` | Force-refresh the chat log | | `q` | Close chat (stop stream, bury buffer) | The input window (`*ellie-input*`): | Key | Action | |-----|--------| | `C-c C-c` | Submit prompt | | `C-c C-k` | Cancel | Queued prompts are held until the current turn finishes. The mode line shows `ellie:session/agent` and the current state. ## Creating sessions and agents Sessions are created by writing `key=value` pairs to `session/new`. The `ellie-new-session` command does this for you, injecting `cwd` from `default-directory`. Agents are created by writing to `session/{sname}/agent/new`. The `ellie-new-agent` command prompts for an agent profile and working directory. You can also create sessions and agents directly from dired — navigate to `session/` (or use `C-c C-d` if you have a mount), open `new`, write `key=value` lines, and save. ## Architecture The chat log is append-only. ellie polls it on a half-second timer, comparing file sizes. New content is appended to the buffer and ANSI color codes are rendered. State is read from `session/{sname}/agent/{aname}/state`. Everything goes through `ollie-9p` — there is no emacs-specific daemon, no IPC protocol, no external processes beyond the CLI tool. ## Reference - README: [/README.md](../README.md) - Usage guide: [/doc/usage.md](usage.md) - Technical whitepaper: [/doc/whitepaper.md](whitepaper.md)