aetherdz
v0.5.0
Published
AETHER - a cross-platform terminal AI coding agent. Chat with LLMs, call tools, and write code straight from your terminal.
Maintainers
Readme
Aether
Building tools that break assumptions.
Aether is a personal, cross-platform terminal AI coding agent that runs on Windows, macOS, and Linux. It ships with a free, no-key default provider, so you can start chatting the moment you install it, and it falls back to local models or any provider you have a key for when free tiers run dry. It remembers your sessions, calls tools, runs parallel swarms, and syncs across devices, all from one terminal.
Contents
Features
| Pillar | What you get |
| --- | --- |
| Chat | Interactive Ink TUI with a scrollable transcript, a right sidebar (session title, model tag, live token ledger in/out/total, turns, cwd), and token-by-token streaming. --no-tui falls back to a lightweight node:readline REPL for dumb terminals and pipes. |
| Tools | read_file, write_file, list_dir, grep_files, run_bash (explicit confirmation required), and web_fetch, plus MCP client support. |
| Swarm | Decompose a task into parallel subagents and get a clean boxed summary per subtask. Analysis-only by default; opt-in --worktree for isolated git worktrees. |
| Agents | Route any task to a dedicated subagent profile (explore, secure-coder, writer, critic, planner, default), auto-selected by keyword or forced by name, with injectable skills and background jobs. |
| Memory | Every conversation is saved as JSONL. /recall searches every past session, so aether remembers decisions from weeks ago. |
| Sync | New in v0.5.0: aether sync carries your sessions between machines for free, via a private gist or a local folder. |
| Providers | 20+ providers, from the free OpenCode Zen default to OpenAI, Anthropic, Google, DeepSeek, OpenRouter, Ollama, and any custom OpenAI-compatible endpoint. |
| Sessions | aether sessions list \| show \| delete \| resume, auto-titles from your first message, full JSONL under ~/.config/aether/sessions/. |
No emojis, ever. Plain ASCII and Unicode box-drawing only, as a hard brand requirement.
Demo
Run aether in any terminal and you get the interactive TUI:
┌──────────────────────────────────────────────────────────────────────────┐
│ Aether v0.5.0 terminal coding agent │
│ zen/deepseek-v4-flash-free cwd /path/to/your/project │
└──────────────────────────────────────────────────────────────────────────┘
aether > explain tail recursionOn a real terminal the right sidebar shows the session title, the active model, a live token ledger (in/out/total), the turn count, and your cwd. Scroll the transcript with PageUp/PageDown or Ctrl+U/Ctrl+D, pick a model with Alt+M, and reopen past prompts with Ctrl+P.
Install
Requires Node.js 18+.
npm install -g aetherdzIf the global npm install fails (EACCES, read-only prefix), use the fallback one-liner:
curl -fsSL https://raw.githubusercontent.com/Aetherdz/aethercode/main/install.sh | bashOr run from source:
git clone https://github.com/Aetherdz/aethercode.git
cd aethercode
npm install
npm run build
npm install -g . # makes the `aether` command available globally
aether --helpThe package is published on the npm registry as aetherdz. aether upgrade keeps you on the latest version. The marketing website lives in a separate repository: Aetherdz/aether-site.
Quickstart
The interactive TUI works immediately with the free zen provider and no API key:
aetherOne-shot questions:
aether ask "what is the difference between let and const in JavaScript?"Switch providers or models mid-session:
aether> /model claude-sonnet-5
aether> /use openrouterResume a past session:
aether sessions list
aether sessions resume <id>Commands
| Command | Description |
| --- | --- |
| aether | Interactive TUI chat with streaming, tools, and persisted history. |
| aether ask "<question>" | One-shot non-interactive streamed answer. |
| aether use <provider>[/<model>] | Set the default provider and model in config. |
| aether models [provider] | List models. zen fetches the live list from https://opencode.ai/zen/v1/models. |
| aether providers | List all providers with key status and the default marker. |
| aether swarm "<task>" | Orchestrate parallel subagents for a task. |
| aether agent "<task>" | Route a task to a subagent profile (auto by keywords, or force with -a). |
| aether agents | List the built-in agent profiles (tools + skills per profile). |
| aether jobs [id] | Show background agent job status (all jobs when no id). |
| aether sync setup gist | Point sync at a private GitHub gist (free). |
| aether sync setup folder <path> | Point sync at a local folder (Dropbox/Drive/Nextcloud style, no account). |
| aether sync push / aether sync pull | Send or fetch sessions from the sync backend. |
| aether sync status | Show the current sync backend and state. |
| aether doctor | Run environment diagnostics (config, keys, sessions). |
| aether status | Show the current configuration summary. |
| aether cost | Show approximate usage totals from saved sessions. |
| aether stats | Aggregated token usage across all sessions. |
| aether keys | Show which API keys are configured and where. |
| aether connect | Interactive provider setup: pick a provider, paste a key, or start a device login. |
| aether login <provider> | Save an API key (stored in ~/.config/aether/.env, 0600). |
| aether logout <provider> | Remove a saved API key. |
| aether login-device github \| google | OAuth device-code sign-in, no API key. |
| aether login-device list | Show which device accounts are signed in. |
| aether logout-device <provider> | Remove a device-flow sign-in. |
| aether cache stats \| clear | Inspect or clear the token-efficiency cache. |
| aether config [path\|get <k> \| set <k> <v> \| providers] | View or edit the config file. |
| aether alias [set\|list\|remove] | Manage command aliases. |
| aether completions <bash\|zsh\|fish> | Generate a shell completion script. |
| aether sessions list \| show <id> \| delete <id> | Manage saved sessions. |
| aether sessions resume <id> | Open the REPL with a saved session loaded. |
| aether sessions rename <id> <title> | Rename a saved session. |
| aether mcp | List MCP servers configured in ~/.config/aether/mcp.json. |
| aether recall "<phrase>" | Cross-session memory: search every past conversation. |
| aether upgrade | Update to the latest version. |
| aether --version / aether --help | Version and help. |
REPL commands
| Command | Description |
| --- | --- |
| /quit, /exit | Leave the session. |
| /clear | Clear the screen. |
| /reset | Forget conversation history. |
| /use <provider>[/<model>], /model <model> | Switch provider or model mid-session. |
| /rename <title> | Rename the current session. |
| /resume <id> | Load a saved session from disk. |
| /sessions | List saved sessions. |
| /mcp | List connected MCP servers and tools. |
| /recall <phrase> | Search every past session (cross-session memory). |
| /task <text> | Dispatch a task to a subagent (auto-routed by keywords). |
| /task <agent> <text> | Dispatch a task to a specific agent profile. |
| /agents | List agent profiles. |
| /jobs [id] | Show background agent job status. |
| /help | Show in-session help. |
TUI keys
| Key | Action |
| --- | --- |
| PageUp / PageDown | Scroll the transcript. |
| Ctrl+U / Ctrl+D | Scroll the transcript by half a page. |
| Alt+M | Open the model picker. |
| Ctrl+P | Open the prompt history palette. |
| Enter | Send the message; auto-completes slash commands. |
Agents
Aether routes tasks to named subagent profiles the way an orchestrator hands work to specialists. Each profile has its own system prompt, toolset, optional injected skills, and sampling temperature. Route by keyword automatically, or force a profile by name.
| Profile | Tools | Purpose |
| --- | --- | --- |
| explore | yes | Investigate, read, and search the codebase; report findings with evidence. |
| secure-coder | yes | Write new code safely: input validation, parameterized queries, output encoding, auth, no secrets. |
| writer | no | Documentation, READMEs, and reports only; no application code. |
| critic | read-only | Adversarial review: bugs, edge cases, security, missing tests. |
| planner | no | Decompose a task into focused, independent subtasks for parallel execution. |
| default | yes | Generic fallback; same system prompt as the main agent. |
aether agents # list profiles
aether agent "write a secure login form" # auto-routed by keywords
aether agent -a secure-coder "add a login endpoint" # force a profile
aether agent -s "plan and build a feature" # split with the planner, run parallel
aether agent -b "long background research" # run as a background job
aether jobs # poll job status / aether jobs <id>Inside the REPL, the same commands exist as slash commands: /task <text>, /task <agent> <text>, /agents, and /jobs [id]. Agent turns share the disk cache and rate-limit fallback chain, and their token usage is folded into the current session ledger.
Skills: a profile can inject markdown skill files from skills/ in the repo (or ~/.config/aether/skills/) into its system prompt, so a profile like secure-coder can act from the project's own guidance.
Sync
New in v0.5.0. aether sync carries your sessions between machines for free, with no backend of your own.
Two backends:
- Gist backend: a private GitHub gist.
aether sync setup gistwalks you through a device login (or reuses an existingGITHUB_TOKEN), creates the gist, and stores the token locally. - Folder backend: any local folder, so Dropbox, Google Drive, or Nextcloud style syncs work with no account at all.
aether sync setup folder ~/Dropbox/aether.
aether sync setup gist # or: aether sync setup folder <path>
aether sync push # send this machine's sessions
aether sync pull # fetch sessions from the backend
aether sync status # which backend, which gist, token present?Sessions are bundled into a single file on the backend. Pulling merges remote sessions into your local ~/.config/aether/sessions/ directory without overwriting anything you already have.
Providers
Keys are read from environment variables only. The zen provider needs no key and is the default, so the tool works with zero setup.
| id | name | env var | key | pricing |
| --- | --- | --- | --- | --- |
| zen | OpenCode Zen | - | none needed | free |
| openai | OpenAI | OPENAI_API_KEY | required | paid |
| anthropic | Anthropic | ANTHROPIC_API_KEY | required | paid |
| google | Google Gemini | GOOGLE_GENERATIVE_AI_API_KEY | required | free/paid |
| deepseek | DeepSeek | DEEPSEEK_API_KEY | required | paid |
| openrouter | OpenRouter | OPENROUTER_API_KEY | required | free/paid |
| ollama | Ollama (local) | - | local server | free |
| groq | Groq | GROQ_API_KEY | required | free/paid |
| mistral | Mistral | MISTRAL_API_KEY | required | paid |
| xai | xAI (Grok) | XAI_API_KEY | required | paid |
| cerebras | Cerebras | CEREBRAS_API_KEY | required | paid |
| togetherai | Together AI | TOGETHER_API_KEY | required | paid |
| fireworks | Fireworks AI | FIREWORKS_API_KEY | required | paid |
| perplexity | Perplexity | PERPLEXITY_API_KEY | required | paid |
| moonshot | Moonshot AI (Kimi) | MOONSHOT_API_KEY | required | paid |
| minimax | MiniMax | MINIMAX_API_KEY | required | paid |
| huggingface | Hugging Face | HF_TOKEN | required | free/paid |
| lmstudio | LM Studio (local) | - | local server | free |
| github | GitHub Models | GITHUB_TOKEN | required | free/paid |
| custom | any OpenAI-compatible endpoint | user-defined | optional | paid |
Set keys in your shell profile (or a .env file loaded by dotenv). See .env.example, or run aether connect to set them interactively. If a provider needs a key that is not set, aether falls back to the free zen provider with a notice.
Device login (OAuth)
GitHub and Google also work with no API key at all, using the OAuth 2.0 Device Authorization Grant (the opencode pattern). Run aether connect, pick the device option, open the printed URL in any browser, enter the one-time code, and approve. The terminal polls automatically and stores the token in ~/.config/aether/device-tokens.json (0600). aether login-device github | google does the same non-interactively.
Custom providers
Add an OpenAI-compatible endpoint in ~/.config/aether/config.json:
{
"defaultProvider": "zen",
"defaultModel": "deepseek-v4-flash-free",
"providers": {
"custom": [
{
"name": "myendpoint",
"baseURL": "https://my-gateway.example.com/v1",
"apiKeyEnv": "MY_ENDPOINT_KEY",
"models": ["model-a", "model-b"]
}
]
}
}How the free tier stretches
The default zen provider is free but rate-limited. Aether stretches the quota in three honest ways, no account rotation, no ToS games:
- Disk cache: the exact same prompt in the exact same conversation context is answered from
~/.config/aether/cache/at 0 tokens. The key includes the full conversation history, so a repeated question in a changed context is never served a stale answer. Content-addressed, TTL 7 days, capped at 500 entries / 64 MB.aether cache stats,aether cache clear. - Smart fallback chain: on a rate-limit error aether tries, in order, local ollama (free, unlimited, on your machine), Gemini free tier, then any provider you have a key for. You see a yellow notice for each hop. Aether never just dies.
- Transparent status:
aether statusshows cache size;aether costtracks usage. You always know where you stand.
Run a local model for effectively unlimited free use:
ollama pull llama3.2
aether use ollamaSessions and memory
Every conversation is appended, message by message, to ~/.config/aether/sessions/<ISO-timestamp>.jsonl. Sessions get an auto-title from your first message, which you can override with /rename or aether sessions rename.
aether sessions list
aether sessions show 2026-08-07T06-11-57-107Z
aether sessions resume 2026-08-07T06-11-57-107Z
aether sessions delete 2026-08-07T06-11-57-107ZCross-session memory works through /recall:
aether> /recall why did we choose postgresIt searches every past session and returns the best matching line per session, so aether can remember decisions made weeks ago.
Security
- API keys never leave your machine. Keys come from environment variables or
aether login, which writes them to~/.config/aether/.envwith 0600 permissions. The website only prints terminal commands; it never sees, stores, or transmits your keys. - No hardcoded secrets. Nothing is committed to the repo.
run_bashalways requires an explicity/nconfirmation; non-interactive contexts deny by default.write_filerefuses paths outside the working directory.- Tool output and file access are scoped to the current working directory.
- Swarm analysis mode performs no file writes by default.
- The
criticagent profile is read-only:read_file/list_dir/grep_files/web_fetchonly, neverwrite_fileorrun_bash; other agent profiles still confirmrun_bashinteractively. - Sync tokens are stored locally with 0600 permissions and are used only to reach the gist backend you chose.
Development
npm run build # tsc -> dist/
npm run typecheck # tsc --noEmit
npm run dev # run from source via tsxLicense
MIT. Copyright (c) 2026 Aether-DZ. See LICENSE.
