Skip to content

Latest commit

 

History

672 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aethon — pi with a face

An agent-driven desktop shell where the agent decides what you see.

License: MIT Status: early development Tauri 2 React 19 Rust 1.92 Bun Nix flake Platforms: macOS | Linux | Windows

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. Extensions 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.

Aethon workstation showing projects, the project dashboard, and file explorer


What it can do

  • 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⌘9 jump, ⌘W close, ⌘⌥T reopen.
  • Projects & workspaces — the sidebar nests host → project → workspace. A project contains one or more workspaces: the main checkout plus zero or more git worktrees ("worktree" is now just the underlying git mechanism). New workspaces fork from origin/main by default, configurable per project, and GitHub issue "Send to agent" can target a new workspace or the current one — re-linking to an existing session for an already-handed-off issue — using per-repo .aethon/issues.toml handoff templates plus branch names inferred from the issue title/labels.
  • Native shell integration — system tray + macOS menu, auto-updater (tauri-plugin-updater against GitHub Releases), persistent chat history / tabs / themes / projects / ~/.aethon/config.toml, per-tab pi session continuity.
  • Agent-controlled UI — themes (aethon.registerTheme or ~/.aethon/themes/*.json) drive the whole palette including terminal ANSI; any A2UI built-in (composites or app-root overlays like command-palette, notification-stack, settings-panel, search-panel) is overridable via aethon.registerComponent. One built-in layout (workstation); extensions register more via aethon.registerLayout.
  • Native A2UI canvas windows — agents and extensions can open separate native OS windows that render bare A2UI canvas content, with window-local state, extension templates/React components, themes, event handlers, and restore-on-launch persistence. Exploratory dashboards can live there without replacing the main workspace chrome.
  • Agent ↔ shell sharing — four-value shareMode (private / read / read-write / read-write-trusted) per shell, clickable badge to cycle. Bridge surface aethon.shells.{list, read, write} exposes scrollback (forward-only, privacy floor enforced Rust-side) and keystroke injection (Allow/Deny prompt per write unless trusted).
  • First-class Nix devshell support — projects with flake.nix, .envrc (use_flake + direnv), or shell.nix get their devshell env auto-applied to every PTY shell tab AND the agent's pi bash tool, no manual nix develop wrap needed. One in-memory + on-disk cache keyed on flake.lock hash feeds both spawn paths; status-bar ⬡ direnv / ⬡ flake badge shows current state. Configurable via [devshell] in config.toml and per-project .aethon/devshell.toml.
  • Voice input — push-to-talk dictation straight into the composer (Cmd+Shift+M, plus an optional hold-to-record key). Transcription provider is selectable per host: a bundled local Whisper model (downloaded on demand), the native OS recognizer (macOS Speech, Windows SAPI 5.4), or LFM2-Audio — an end-to-end ASR+TTS mode for hands-free conversation with speak-aloud replies. Hotkeys configurable via [voice] in config.toml.
  • Multiple provider accounts — sign in to more than one account per provider and switch which one a tab uses with /login [list | use <account> | default <account>]. Each profile keeps its own credentials and model registry; the active profile is per-tab with a per-provider default.
  • MCP servers — connect Model Context Protocol servers via guided /mcp setup, with per-project config (.aethon/mcp.toml, .mcp.json import) gated by a host approval policy.
  • Subagents & tasks — delegate to multi-model subagents that run in parallel in the background, then fold their results back into the conversation.
  • Scheduled tasks & loops — a native scheduler for recurring work, driven by /tasks (list/run/pause/resume/cancel) and /loop (fixed-interval or self-paced loops bound to a session).
  • Memory — per-user and per-project memory the agent can read and write, surfaced with /memory.
  • Extensibility — drop a .ts into ~/.aethon/extensions/ for hot-reload, or npm install --prefix ~/.aethon/extensions <pkg> for npm-distributed extensions (manifest via package.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, /plan, /init, /config, /mcp, /mcp-auth, /login, /reset, /reload, /rename, /memory, /context, /session, /compact, /name, /export, /loop, /tasks, /terminal, /extensions, /sidebar, /files, /layout, /project. Unknown commands fall through to pi.

See SPEC.md for the full status checklist, docs/project-config.md for project-local .aethon config, and CHANGELOG.md for release notes.


Getting started

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 reload

Bring 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.

Nix package

The flake also exposes a distribution package and overlay:

nix build .#aethon
nix run .#aethon

Downstream 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.

Devshell commands

Command What it does
dev Launch the app with hot reload (auto-increments Vite + debug ports if 1420/19433 are busy)
docs Run the VitePress docs site on 0.0.0.0:5173 with hot reload
understand-dashboard Vite dashboard for the understand-anything knowledge graph (.understand-anything/knowledge-graph.json); open the printed ?token= URL
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 + JSON/MD/YAML/CSS + TOML with treefmt
clean Remove Rust build artifacts under src-tauri/target/

Versioning

package.json is the app-version source of truth. The sidebar version chip imports it directly, while scripts/sync-version.mjs mirrors it into Tauri and Cargo metadata.

bun run version:sync   # update package-lock, tauri.conf, Cargo.toml, Cargo.lock
bun run version:check  # fail if any copy drifted from package.json

Architecture

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
Loading
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 an extension (src/extensions/default-layout/). Replacing it requires no React changes — just register a different layout payload via aethon.setLayout(...).


Project layout

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         # App version source + 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

RELEASING.md walks through generating an updater signing keypair, configuring GitHub Actions secrets, and cutting a release that the in-app updater can consume.


License

MIT © James Brink

Aethon is independent of and not affiliated with Anthropic. Pi is © its respective authors.

About

Pi with a face — agent-driven desktop shell with A2UI

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages