A lightweight, multi-model CLI AI coding agent — built for Termux on Android.
Generate, review, and test code through any LLM provider. Provider-agnostic. Offline-ready. All from your terminal.
curl -fsSL https://raw.githubusercontent.com/Patel-web-devloper/aether-cli/main/install.sh | bashOr install manually
git clone https://github.com/Patel-web-devloper/aether-cli.git
cd aether-cli
bun install
bun run build
sudo ln -s "$(pwd)/dist/cli.js" /usr/local/bin/aetherRequirements: Bun ≥ 1.2 (Node.js ≥ 20 as fallback).
Three commands to go from zero to productive:
# 1. Set up your LLM provider
aether setup
# 2. Generate code from a prompt
aether generate "Create a TypeScript REST API endpoint for user management" --provider openai
# 3. Review the generated code for issues
aether review ./src --severity warning --json| 🔌 Provider-agnostic | Swap between OpenAI, Anthropic, Google Gemini, DeepSeek, NVIDIA, OpenRouter, Groq, Together AI, and local models (Ollama, LM Studio, LocalAI, vLLM) with a single flag. No vendor lock-in. |
| 📁 Large context | Smart file indexing, AST-aware chunking, and context budgeting handle repositories of any size — up to 128K token context windows. |
| 📱 Termux-optimized | Detects Termux/Android automatically. Low-memory mode (< 2 GB RAM). Proot-aware. Config paths respect Termux conventions. |
| 🧪 Full test pipeline | Generates, runs, and auto-fixes test suites. Detects your test runner (vitest, jest, bun, mocha, node-test). |
| 🔍 Code review agent | Reviews code for bugs, security issues, and style problems. Filter by severity. Output as JSON for CI/CD pipelines. |
| 💬 Conversation history | Persistent session history. Resume conversations. Track context across commands. |
| ⚡ Lightweight | Bun runtime. Minimal dependencies. Fast startup. 1.2 MB binary. |
| 🤖 CI/CD friendly | JSON output. Dry-run mode. Non-interactive setup. Config via environment variables. |
Generate code from a natural language prompt.
# Basic generation
aether generate "Create a hello world TypeScript file" --dry-run
# Target a specific directory
aether generate "Build a React component" --target ./src/components
# Edit existing files (mode: create | edit | auto)
aether generate "Add input validation to src/api.ts" --mode edit
# Read prompt from a file
aether generate --file ./prompt.txt --provider anthropic
# Pipe prompt from stdin
echo "Write a sum utility" | aether generate
# Force overwrite existing files
aether generate "Rebuild the auth module" --force| Option | Short | Description | Default |
|---|---|---|---|
--provider <name> |
-p |
LLM provider | openai |
--model <name> |
-m |
Model name | Provider default |
--mode <mode> |
create, edit, or auto |
auto |
|
--target <dir> |
-t |
Output directory | cwd |
--file <path> |
Read prompt from file | — | |
--force |
-f |
Overwrite without prompting | false |
--dry-run |
-d |
Preview without writing files | false |
Review code for bugs, security issues, and improvements.
# Review a directory
aether review ./src
# Review a single file with severity filtering
aether review ./src/utils.ts --severity error
# JSON output (machine-readable)
aether review . --json
# Auto-apply suggested fixes
aether review ./src --apply
# Dry-run to preview what would be reviewed
aether review ./src --apply --dry-run| Option | Short | Description | Default |
|---|---|---|---|
--provider <name> |
-p |
LLM provider | openai |
--model <name> |
-m |
Model name | Provider default |
--json |
Machine-readable JSON output | false |
|
--apply |
Auto-apply suggested fixes | false |
|
--severity <level> |
Filter: error, warning, info |
Show all | |
--dry-run |
-d |
Preview without API calls | false |
Generate, run, and auto-fix tests.
# Generate and run tests for a file
aether test ./src/utils.ts --provider openai
# Generate tests with coverage
aether test ./src --coverage
# Auto-fix failing tests (re-generate until they pass)
aether test ./src --fix
# Only run existing tests (skip generation)
aether test ./src --run --coverage
# Run specific test files
aether test ./src --run --files src/foo.test.ts src/bar.test.ts
# Preview the test plan without calling the API
aether test ./src --dry-run| Option | Short | Description | Default |
|---|---|---|---|
--provider <name> |
-p |
LLM provider | openai |
--model <name> |
-m |
Model name | Provider default |
--framework <name> |
Override test framework | Auto-detect | |
--coverage |
Collect coverage | false |
|
--watch |
Watch mode | false |
|
--fix |
Auto-fix failing tests | false |
|
--dry-run |
-d |
Preview without API calls | false |
--run |
Run only (skip generation) | false |
|
--files <paths> |
Specific test files with --run |
— |
Manage project context, indexing, and conversation history.
# Show index stats (size, chunk count, token usage)
aether context stats
# Force re-index the project
aether context index
# Watch for live index updates
aether context index --watch
# List conversation history sessions
aether context history --list
# View a specific session
aether context history --view --session <id>
# Clear all sessions
aether context history --clearView and manage configuration.
# Show current configuration
aether config list
# Get a specific value
aether config get provider
# Set default provider
aether config set provider anthropic
# Set default model
aether config set model claude-sonnet-4-20250514
# Reset to defaults
aether config resetList all registered LLM providers and their capabilities.
aether providersExample output:
Registered providers:
OpenAI
Slug: openai
Features: streaming, vision, tool_calls, json_mode, multilingual
Anthropic Claude
Slug: anthropic
Features: streaming, vision, tool_calls, json_mode, multilingual
Google Gemini
Slug: google
Features: streaming, vision, tool_calls, json_mode, multilingual
DeepSeek
Slug: deepseek
Features: streaming, tool_calls, json_mode, multilingual
Ollama (Local)
Slug: ollama
Features: streaming, json_mode, local, free
Interactive setup wizard for configuring providers and API keys.
# Full interactive setup
aether setup
# Show configuration status without prompts (CI-friendly)
aether setup --checkShow environment info for debugging.
aether envDisplays runtime details, memory status, and API key configuration status.
Diagnose Aether CLI health and configuration. Runs 13+ checks:
# Full diagnostic
aether doctor
# Machine-readable JSON output
aether doctor --json
# Auto-fix common issues
aether doctor --fixChecks: Runtime, PATH, Git, Node.js, Bun, Config, API Keys, Provider Connectivity, Internet, Permissions, Updates, Install Integrity, Environment.
Check for and install newer versions:
# Check for updates
aether update --check
# Install latest version
aether update
# Reinstall same version
aether update --forceFix common issues with your Aether CLI installation:
aether repairFixes: rebuilds dist if missing, reinstalls node_modules, fixes broken symlinks, repairs config file.
Remove Aether CLI from your system:
# Preview what would be removed
aether uninstall --dry-run
# Remove but keep config
aether uninstall --keep-config
# Full uninstall
aether uninstallRun the Aether CLI test suite:
# Run all tests
aether self-test
# Run a specific suite
aether self-test --suite generate
aether self-test --suite contextAvailable suites: generate, review, test, context, termux.
| Provider | Slug | API Key Env Var | Local? | Features |
|---|---|---|---|---|
| OpenAI | openai |
OPENAI_API_KEY |
No | Streaming, Vision, Tool calls, JSON mode |
| Anthropic Claude | anthropic |
ANTHROPIC_API_KEY |
No | Streaming, Vision, Tool calls, JSON mode |
| Google Gemini | google |
GEMINI_API_KEY |
No | Streaming, Vision, Tool calls, JSON mode |
| DeepSeek | deepseek |
DEEPSEEK_API_KEY |
No | Streaming, Tool calls, JSON mode |
| Ollama | ollama |
OLLAMA_BASE_URL (optional) |
✅ Yes | Streaming, JSON mode, Free |
| NVIDIA NIM | nvidia |
NVIDIA_API_KEY |
No | Streaming, Tool calls, JSON mode |
| OpenRouter | openrouter |
OPENROUTER_API_KEY |
No | Streaming, Tool calls, JSON mode, Multilingual |
| Groq | groq |
GROQ_API_KEY |
No | Streaming, Tool calls, JSON mode |
| Together AI | together |
TOGETHER_API_KEY |
No | Streaming, Tool calls, JSON mode |
| LM Studio | lmstudio |
— | ✅ Yes | Streaming, JSON mode, Free |
| LocalAI | localai |
LOCALAI_API_KEY (optional) |
✅ Yes | Streaming, JSON mode, Free |
| vLLM | vllm |
— | ✅ Yes | Streaming, JSON mode, Free |
| Custom OpenAI | custom |
CUSTOM_OPENAI_API_KEY |
Cloud | Streaming, JSON mode |
Aether auto-detects available providers by checking for API keys in your environment:
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export GEMINI_API_KEY="..."
export DEEPSEEK_API_KEY="..."
# Ollama uses http://localhost:11434/v1 by default
export OLLAMA_BASE_URL="http://192.168.1.50:11434/v1" # optionalRun aether env to see which providers are ready.
| Variable | Description | Default |
|---|---|---|
OPENAI_API_KEY |
OpenAI API key | — |
ANTHROPIC_API_KEY |
Anthropic API key | — |
GEMINI_API_KEY |
Google Gemini API key | — |
DEEPSEEK_API_KEY |
DeepSeek API key | — |
OLLAMA_BASE_URL |
Ollama server URL | http://localhost:11434/v1 |
NVIDIA_API_KEY |
NVIDIA NIM API key | — |
OPENROUTER_API_KEY |
OpenRouter API key | — |
GROQ_API_KEY |
Groq API key | — |
TOGETHER_API_KEY |
Together AI API key | — |
CUSTOM_OPENAI_API_KEY |
Custom OpenAI endpoint key | — |
AETHER_MAX_CONTEXT_TOKENS |
Max context tokens | 131072 (128K) |
AETHER_MAX_HISTORY_TOKENS |
Max history tokens | 32768 (32K) |
AETHER_MAX_HISTORY_MESSAGES |
Max history messages | 50 |
AETHER_LOW_MEMORY |
Force low-memory mode | Auto-detected |
AETHER_TERMUX |
Force Termux mode | Auto-detected |
XDG_CONFIG_HOME |
Config directory | ~/.config |
XDG_DATA_HOME |
Data directory | ~/.local/share |
Aether stores persistent configuration in ~/.config/aether/config.json:
{
"version": 1,
"providers": {
"openai": {
"enabled": true,
"model": "gpt-4o"
},
"ollama": {
"enabled": true,
"model": "codellama:13b"
}
},
"defaults": {
"provider": "openai",
"model": "gpt-4o"
}
}Set defaults without editing the file:
aether config set provider openai
aether config set model gpt-4oThe easiest way to configure Aether:
aether setupWalk through provider configuration, enter API keys, and set defaults — all interactively.
Aether is designed to run as a first-class citizen on Android via Termux.
# Install Termux from F-Droid (recommended)
# Then in Termux:
pkg install tur-repo
pkg install bun
# Install Aether
curl -fsSL https://raw.githubusercontent.com/aether-cli/aether-cli/main/install.sh | bashFor a fully offline experience, run Ollama in Termux:
# In Termux
pkg install ollama
# Pull a coding model
ollama pull codellama:13b
ollama pull deepseek-coder:6.7b
# Use it with Aether
aether generate "Create a Python web scraper" --provider ollama --model codellama:13b- Low memory detection: Automatically enables reduced chunk sizes and compact prompts when < 2 GB RAM is available.
- Proot-aware: Detects
proot-distroenvironments and adjusts paths accordingly. - Config paths: Uses
$PREFIX/var/lib/aetherfor data on Termux (respects Android filesystem conventions). - No heavy dependencies: No Electron, no GUI frameworks. Text-only, terminal-native.
| Model | Size | Best For |
|---|---|---|
codellama:7b |
~4 GB | General coding, fast responses |
codellama:13b |
~8 GB | Complex generation, better quality |
deepseek-coder:6.7b |
~4 GB | Strong at code generation |
phi3:mini |
~2 GB | Lightweight, low-RAM devices |
Providers are the core extensibility mechanism. To add a new one:
- Create the provider class in
src/providers/<slug>.ts:
import type { LLMProvider, ChatMessage, ChatOptions, ChatResponse, ProviderFeature } from "./base.js";
export class MyProvider implements LLMProvider {
readonly name = "My Provider";
readonly slug = "myprovider";
async initialize(): Promise<void> {
// Validate API key, check connectivity
}
async chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse> {
// Call your provider's API
}
async streamChat(messages: ChatMessage[], options?: ChatOptions, callbacks?: StreamCallbacks): Promise<void> {
// Stream tokens to callbacks.onToken
}
supportsFeature(feature: ProviderFeature): boolean {
return ["streaming", "json_mode"].includes(feature);
}
async listModels(): Promise<string[]> {
return ["model-v1", "model-v2"];
}
}- Register it in
src/cli.ts:
import { MyProvider } from "./providers/myprovider.js";
providerRegistry.register(new MyProvider());- Add docs — update the providers table in this README.
All providers implement the LLMProvider interface (src/providers/base.ts):
| Method | Description |
|---|---|
chat(messages, options) |
Send a chat completion, return full response |
streamChat(messages, options, callbacks) |
Stream tokens via onToken callback |
initialize() |
Validate credentials, check connectivity |
listModels() |
Return available model names |
supportsFeature(f) |
Declare feature support (streaming, vision, etc.) |
Providers declare which features they support. Aether checks before using advanced functionality:
| Feature | Description |
|---|---|
streaming |
Token-by-token streaming |
vision |
Image input support |
tool_calls |
Function/tool calling |
json_mode |
Structured JSON output |
multilingual |
Non-English language support |
local |
Runs locally, no network needed |
free |
No API key or billing required |
Tests live in src/tests/ and use a mock provider — no API keys needed:
# Run all test suites
bun run src/tests/generate.test.ts # 8 tests — code generation pipeline
bun run src/tests/review.test.ts # 9 tests — code review pipeline
bun run src/tests/test.test.ts # 10 tests — test generation/runner
bun run src/tests/termux.test.ts # 17 tests — Termux detection & config
bun run src/tests/installer.test.ts # 15 tests — installer & CLI runtimeAll tests use bun run with a manual test harness (not bun test).
src/
├── cli.ts # Entry point, commander.js command definitions
├── providers/ # LLM provider implementations
│ ├── base.ts # LLMProvider interface + types
│ ├── registry.ts # ProviderRegistry singleton
│ ├── openai.ts # OpenAI provider
│ ├── anthropic.ts # Anthropic Claude provider
│ ├── google.ts # Google Gemini provider
│ ├── deepseek.ts # DeepSeek provider
│ ├── ollama.ts # Ollama local provider
│ ├── nvidia.ts # NVIDIA NIM provider
│ ├── openrouter.ts # OpenRouter provider
│ ├── groq.ts # Groq provider
│ ├── together.ts # Together AI provider
│ ├── lmstudio.ts # LM Studio local provider
│ ├── localai.ts # LocalAI provider
│ ├── vllm.ts # vLLM local provider
│ └── custom.ts # Custom OpenAI-compatible provider
├── agents/ # Agent pipelines (generate, review, test)
│ ├── generator.ts # Code generation agent
│ ├── reviewer.ts # Code review agent
│ └── tester.ts # Test generation + execution agent
├── commands/ # Command implementations
│ ├── config.ts # Config get/set/list/reset
│ ├── context.ts # Context index/stats/history
│ ├── generate.ts # Generate command handler
│ ├── review.ts # Review command handler
│ ├── setup.ts # Interactive setup wizard
│ ├── test.ts # Test command handler
│ ├── doctor.ts # Diagnostics (13+ checks)
│ ├── update.ts # Update checker
│ ├── repair.ts # Auto-repair
│ ├── uninstall.ts # Clean removal
│ └── selftest.ts # Test suite runner
├── context/ # Context management system
│ ├── types.ts # Shared types
│ ├── indexer.ts # File indexing
│ ├── chunker.ts # Smart code chunking
│ ├── builder.ts # Context payload builder
│ ├── history.ts # Conversation history persistence
│ └── manager.ts # ContextManager orchestrator
├── utils/ # Shared utilities
│ ├── scanner.ts # Project structure scanner
│ ├── writer.ts # Safe file writer with diff
│ ├── differ.ts # Diff generation
│ ├── runner.ts # Test runner detection & execution
│ ├── fixer.ts # Auto-fix failing tests
│ ├── linter.ts # Code linting support
│ ├── memory.ts # Low-memory detection
│ └── termux.ts # Termux environment detection
└── tests/ # Test suites (82 tests total)
MIT © Aether CLI Contributors
See LICENSE for full details.