An agent-driven desktop shell where the agent decides what you see.
Early development — not ready for production use. The API and protocol surface are still settling; expect breaking changes between commits.
Aethon embeds the pi coding agent inside a Tauri 2 desktop shell and renders its output as live, interactive UI via the A2UI protocol. The interface is not a fixed IDE layout — it's a canvas the agent populates dynamically. Skills bring their own components, themes control the look, the agent decides the layout.
The name comes from Greek mythology: Αἴθων, one of the horses that pulled Helios's sun chariot. The blazing one that shapes what you see.
- Multi-tab workspace — top-strip agent tabs (one pi conversation each) plus a bottom-panel terminal with sub-tabs: a read-only "Agent bash" stream and zero-or-more interactive PTY shells (xterm.js + WebGL, full TUI / 256-color / true-color). Focus-aware
⌘T,⌘1–⌘9jump,⌘Wclose,⌘⌥Treopen. - Native shell integration — system tray + macOS menu, auto-updater (
tauri-plugin-updateragainst GitHub Releases), persistent chat history / tabs / themes / projects /~/.aethon/config.toml, per-tab pi session continuity. - Agent-controlled UI — themes (
aethon.registerThemeor~/.aethon/themes/*.json) drive the whole palette including terminal ANSI; any A2UI built-in (composites or app-root overlays likecommand-palette,notification-stack,settings-panel,search-panel) is overridable viaaethon.registerComponent. One built-in layout (workstation); extensions register more viaaethon.registerLayout. - Agent ↔ shell sharing — four-value
shareMode(private/read/read-write/read-write-trusted) per shell, clickable badge to cycle. Bridge surfaceaethon.shells.{list, read, write}exposes scrollback (forward-only, privacy floor enforced Rust-side) and keystroke injection (Allow/Deny prompt per write unless trusted). - Extensibility — drop a
.tsinto~/.aethon/extensions/for hot-reload, ornpm install --prefix ~/.aethon/skills <pkg>for npm-distributed extensions (manifest viapackage.json#aethon); project-local extensions discovered from cwd up to its git root. Extensions register slash commands, keybindings, menu items, event routes, layouts, A2UI components, and themes — all reported back in the runtime snapshot. - Built-in slash commands —
/clear,/help,/theme,/model,/reset,/terminal,/extensions,/sidebar,/layout,/project. Unknown commands fall through to pi.
See SPEC.md for the full status checklist and CHANGELOG.md for release notes.
Requires Nix with flakes enabled. With direnv, the dev shell activates automatically when you cd into the directory.
nix develop # enter the dev shell (rust toolchain + bun + tauri CLI)
bun install # install JS deps
dev # launch the app with hot reloadBring your own LLM key — pi reads ANTHROPIC_API_KEY / OPENAI_API_KEY / equivalents from the environment. See pi's docs for the full multi-provider setup.
The flake also exposes a distribution package and overlay:
nix build .#aethon
nix run .#aethonDownstream flakes can consume overlays.default, which provides pkgs.aethon.
The package follows nixpkgs' Tauri pattern (cargo-tauri.hook +
fetchNpmDeps) and uses package-lock.json as the reproducible npm dependency
input for Nix builds.
| Command | What it does |
|---|---|
dev |
Launch the app with hot reload (auto-increments Vite + debug ports if 1420/19433 are busy) |
build-app |
Release bundle (.app / .dmg on macOS, .deb / .rpm on Linux, NSIS .exe on Windows) |
check |
Full CI gate: clippy + tsc + ESLint + cargo test + vitest |
lint |
ESLint frontend + agent (no auto-fix) |
test |
Run Rust + TS tests (cargo test --lib + vitest run) |
coverage |
TS coverage report under coverage/ (vitest v8) |
fmt |
Format Rust + Nix with treefmt |
graph TD
subgraph aethon["Aethon"]
TS["Tauri Shell (Rust)\nwindows · tray + menu · file watch · spawn agent"]
PA["Pi Agent (bun bin)\npi-ai · tools · skills · exts"]
subgraph react["React Frontend (Vite)"]
R["A2UI Renderer\n19 primitives + scoped templates"]
L["default-layout\nsidebar · canvas · terminal · …"]
end
TS -- "stdin JSON lines\nuser / UI events" --> PA
PA -- "stdout JSON lines\nA2UI components + responses" --> TS
TS <-- "Tauri IPC" --> react
end
| Layer | Owns | Doesn't own |
|---|---|---|
| Tauri shell (Rust) | OS surface — windows, tray, native menus, file watcher, spawning the agent subprocess | Any business logic, agent awareness, A2UI knowledge |
| Pi agent (Bun) | LLM interaction, tool execution, session management, extension loading, A2UI emission | OS resources |
| React frontend | Rendering A2UI payloads, dispatching events, persisting local state, hosting the chrome | The chrome is data — default-layout is itself an A2UI payload |
The default layout is a skill (src/skills/default-layout/). Replacing it requires no React changes — just register a different layout payload via aethon.setLayout(...).
aethon/
├── src/ # React frontend (entry: src/main.tsx)
├── src-tauri/ # Rust Tauri shell (lib + helpers + watcher)
├── agent/ # Pi agent bridge (run as a bun subprocess)
├── docs/aethon-agent/ # Bundled reference docs the agent reads
├── examples/ # Pi extensions + extension packages (reference)
├── flake.nix # Nix dev environment, package, and overlay
├── bun.lock # Bun lockfile (used by `bun install` in the devshell)
├── package-lock.json # npm dependency snapshot for reproducible Nix builds
└── package.json # Frontend deps + tauri CLI
For agent-side authoring docs (the API surface, A2UI components, extension recipes), see docs/aethon-agent/. The same files ship inside the binary as bundled resources so the agent can read them at runtime.
For repository conventions and architecture deep-dives, see CLAUDE.md.
RELEASING.md walks through generating an updater signing keypair, configuring GitHub Actions secrets, and cutting a release that the in-app updater can consume.
MIT © James Brink
Aethon is independent of and not affiliated with Anthropic. Pi is © its respective authors.