- Move user-preferences.md from data/prompts/ to data/agents/.
- Remove it from prompt arrays in all agent JSON configs.
- Add userPrompts field referencing the file via $XDG_CONFIG_HOME path.
- Update justfile install target accordingly.
Removed the named sandbox concept. One config file: sandbox.yaml
(installed to ~/.config/ollie/sandbox.yaml). Removed sandbox-remote.yaml,
moved restricted.yaml to doc/ as a sample. Removed the 'sandbox' arg
from tool dispatch.
Add /session/{sid}/agent/{aid}/tools file:
- Read: list loaded tools for this agent
- Write: load a tool by name
Also add missing tool_load to justfile install.
Add acme-ollie-ensure helper that:
- Creates 'acme' session if it doesn't exist
- Creates agent named by cwd hash (like kate's approach)
- Updates agent cwd if it already exists
All acme commands now call acme-ollie-ensure before sending
prompts, so they work without manual session setup.
Add acme scripts for interacting with ollie:
- AskFile: describe the current file
- Explain: explain selected code
- Document: add documentation comments
- Fix: fix selected code
- Refactor: refactor selected code
- AddTests: write unit tests for selection
- SendVerbatim: send selection as-is
Scripts use the acme 9P filesystem to read selections and pipe
prompts to ollie via 'o prompt'.
Also update justfile to install/uninstall the acme scripts.
The ctl file is now a Request handler: write a command, read the
response. Commands with no args return current state:
/model → prints current model
/agent → prints current profile
/cwd → prints working directory
/name → prints agent name
/model X → switches model, returns new model
/compact → compacts, returns 'ok'
o ctl now uses 'ollie-9p rdwr' to get the response.
This enables /model (no args) to show the current model from
any frontend.
Previously, Go binaries and scripts installed to ~/bin while cmake
(KDE) installed to ~/.local/bin. This caused stale binaries in ~/bin
to shadow fresh builds since ~/bin comes first on PATH.
- Change bin variable from ~/bin to ~/.local/bin
- Add migrate-bin target to clean stale ~/bin copies
- Run migrate-bin automatically during install
Each backend is now configured via ~/.config/ollie/backends.conf:
[openrouter]
key = sk-or-v1-...
model = qwen/qwen3-235b-a22b
[anthropic]
key = sk-ant-...
Each backend knows its own default URL (openrouter → openrouter.ai/api,
anthropic → api.anthropic.com, etc). Only key and optional model needed.
Env vars (OLLIE_OPENAI_KEY, OLLIE_ANTHROPIC_KEY, etc) still work as
fallback for backward compatibility, but backends.conf is the canonical
config path going forward.
- Delete openAIName() (URL no longer determines backend identity)
- Delete geminiKey() (config handles fallback)
- Install template with mode 600 (contains API keys)
- Only install template if user hasn't created their own
Go shared library (c-shared buildmode) that wraps 9fans.net/go/plan9/client.
Provides C API for persistent 9P connections, eliminating process spawn
overhead for GUI operations.
Exports: ollie9p_connect, ollie9p_read, ollie9p_write, ollie9p_rdwr,
ollie9p_ls, ollie9p_stat, ollie9p_remove, ollie9p_create, ollie9p_mkdir,
ollie9p_rename, ollie9p_close, ollie9p_last_error, ollie9p_free
Build: go build -buildmode=c-shared -o libollie9p.so
Install: just lib9p (installs to ~/.local/lib and ~/.local/include)
Nodes in the 9P namespace can now declare alternate names (Aliases)
that resolve during Twalk but are invisible in directory listings.
Session dirs alias their immutable RunnableID(), agent dirs alias
their ID(). Clients can use session/{uuid}/agent/{uuid}/... paths
that remain valid across renames.
Changes:
- fs/fsnode.go: Add Aliases []string field, Alias() NodeOption
- fs/builder.go: findChild checks aliases via matchAlias helper
- fs/sessionfiles.go: Session dirs get Alias(s.RunnableID())
- fs/agentfiles.go: Agent dirs get Alias(a.ID())
- fs/spec.go: Add /aliases file (read-only alias→path table)
- fs/rootfiles.go: readAliases handler
- fs/lifecycle.go: buildIndex includes immutable ID in session/idx
- doc/edsl.md: Document Aliases field and behavior
- prompts: Update session/idx format documentation
The KDE GUI submodule now uses immutable IDs in all 9P paths,
fixing disconnected indicators after session rename.
Each lsp_*.meta now lives in tools/lsp/cmd/<name>/ alongside
main.go, rather than in data/tools/. The lsp-tools just target
was updated to install both the binary and its .meta sidecar.
AGENTS.md updated to document the pattern for compiled tools.
With the zero-tools transition complete, the tools/builtin/ package
served no purpose — Builtins() returned nil. Removed:
- tools/builtin/builtins.go and the directory
- builtins field, WithBuiltins, Dispatch from toolsrv.Server
- Handler type from toolsrv (only used by builtins)
- OnPreDispatch/WithOnPreDispatch (dead code)
- Strict field and WithStrict (dead code, never read)
- CallTool simplified — no fallback to Dispatch
- builtin import and WithBuiltins/WithStrict calls from ollie-remote
- tools/builtin from justfile build/test targets
Updated AGENTS.md, ARCHITECTURE.md, README.md, EVOLUTION.md
The old fs/session/ package (14 files) and cmd/olliesrv/elevate_tree.go
(imperative FileTree implementations) are gone. Replaced by a single
declarative EDSL in fs/spec.go that declares the entire 9P namespace.
cmd/olliesrv/server.go simplified from 1430 to 825 lines:
- Deleted pathType() (110 lines) — tree.Stat() now handles all path resolution
- Deleted isSessionFile(), dirMode(), filePerm() — all from tree's info
- Deleted fsRoute/routes/route/routeDir — single rootTree, no route table
- Deleted elevateTree — EDSL handles /elevate/ in spec.go
- Deleted handleWrite(), readDNS(), helpPath() — dead code
- Deleted all 5 per-fid result fields — EDSL Request handlers manage state
- Deleted all path-based intercepts in read()/write() — entry.RequestRespMode()
- Deleted all path-depth hacks in makeStat() — custom Stat() closures in EDSL
- Deleted all content-length compute logic — info.Size() from tree
- Removed imports: agent, backend, elevate, paths, toolsrv, json
New fs/ package:
- spec.go — single EDSL declaration of the entire namespace
- builder.go — BuildTree() validates and compiles spec into *Tree
- tree.go — configurable FileTree implementation
- fsnode.go — Dir(), Leaf(), TemplateDir(), NodeOption constructors
- agentfiles.go / sessionfiles.go / rootfiles.go / elevatefiles.go
— handler implementations wired by the EDSL
- lifecycle.go — Create, Kill, Rename, Shutdown, InterruptAll
- persist.go, procfiles.go
- edsl.md — documentation of the EDSL
skill_list and skill_load are now simple shell scripts that read
SKILL.md files from OLLIE_SKILLS_PATH. No built-in registry needed.
skill_load returns the file body as tool result (tier:hot, survives compaction).
skill_active dropped — model uses skill_list instead.
- Embed the full sandbox/default.yaml instead of sandbox-remote.yaml
so local ollie-remote subprocesses get proper sandbox permissions
(DNS, git config, etc.)
- justfile copies sandbox/default.yaml temporarily during build
- Register builtins + ToolRegistry + SkillsRegistry on ollie-remote
- Pdeathsig: kernel auto-SIGTERMs children when parent dies
- Cleanup: SIGTERM → 3s grace → SIGKILL (guaranteed kill)
- Atomic counter for unique socket paths (no collisions)
Execution is now identical for local and remote:
- Session calls Spawn()/SpawnRemote() → owns *Process with socket
- Clients call Dial(LocalAddr(socket)) → *Conn over Unix socket
- ollie-remote serves --listen mode with multi-client accept loop
- Builtins (shell, tool_load, skill_load) run in subprocess with registries
Lifecycle:
- Pdeathsig ensures children die with parent (no orphans)
- Cleanup: SIGTERM → 3s grace → SIGKILL (guaranteed)
- Socket paths use atomic counter for uniqueness
- Session Kill() closes Process
Protocol:
- Extended RPC: set_env, set_cwd, detach, list_detached, etc.
- Shell goes through builtin dispatch (parses 'cmd' field correctly)
- Streaming output via JSON-RPC notifications
- Fix for loop: just doesn't need $$ escaping (that produces PID)
- Remove empty install-scripts and install-contrib targets
- Fold script installs into install-data