A Claude Code clone built with Agno agents
Project description
aru
An intelligent coding assistant for the terminal, powered by LLMs and Agno agents.
Highlights
- Multi-Agent Architecture — Specialized agents for planning, execution, and conversation
- Interactive CLI — Streaming responses, multi-line paste, session management
- Image Support — Attach images via
@mentions for multimodal analysis (Claude, GPT-4o, Gemini) - 11 Integrated Tools — File operations, code search, shell, web search, task delegation
- Task Planning — Break down complex tasks into steps with automatic execution
- Multi-Provider — Anthropic, OpenAI, Ollama, Groq, OpenRouter, DeepSeek, and others via custom configuration
- Custom Commands, Skills, and Agents — Extend aru via the
.agents/directory - MCP Support — Integration with Model Context Protocol servers
Quick Start
1. Install
pip install aru-code
Requirements: Python 3.11+
2. Configure the API Key
Aru uses Claude Sonnet 4.6 from Anthropic as the default model. You need an Anthropic API key to get started.
Set your API key as an environment variable or create a .env file in your project directory:
ANTHROPIC_API_KEY=sk-ant-your-key-here
Using another provider? See the Models and Providers section to configure OpenAI, Ollama, Groq, etc.
3. Run
aru
That's it — aru is available globally after install.
Usage
Commands
| Command | Description |
|---|---|
| Natural language | Just type — aru handles the rest |
/plan <task> |
Creates a detailed implementation plan |
/model [provider/model] |
Switch models and providers |
/mcp |
List available MCP servers and tools |
/commands |
List custom commands |
/skills |
List available skills |
/agents |
List custom agents |
/sessions |
List recent sessions |
/help |
Show all commands |
! <command> |
Execute shell commands |
/quit or /exit |
Exit aru |
CLI Options
aru # Start new session
aru --resume <id> # Resume session
aru --resume last # Resume last session
aru --list # List sessions
aru --dangerously-skip-permissions # Skip permission prompts
Examples
aru> /plan create a REST API with FastAPI to manage users
aru> refactor the authentication module to use JWT tokens
aru> ! pytest tests/ -v
aru> /model ollama/codellama
Image Support
Attach images to your messages using the same @ mention syntax used for files. Aru detects image files by extension and sends them to the LLM as visual content for multimodal analysis.
Supported formats: .png, .jpg, .jpeg, .gif, .webp, .bmp
aru> describe @screenshot.png
aru> compare @before.png and @after.png
aru> review @code.py and explain the diagram in @architecture.png
aru> analyze @D:/full/path/to/image.jpg
Images are sent natively to the model via the provider's multimodal API — no base64 text is injected into the conversation. Works with any multimodal model (Claude Opus/Sonnet, GPT-4o, Gemini, etc.). The autocomplete shows an [image] label for image files.
Note: Images require a multimodal model. Local models via Ollama may not support image input. Maximum file size: 20MB.
Configuration
Models and Providers
By default, aru uses Claude Sonnet 4.6 (Anthropic). You can switch to any supported provider during a session with /model:
| Provider | Command | API Key (.env) |
Extra Installation |
|---|---|---|---|
| Anthropic | /model anthropic/claude-sonnet-4-6 |
ANTHROPIC_API_KEY |
— (included) |
| Ollama | /model ollama/llama3.1 |
— (local) | pip install "aru-code[ollama]" |
| OpenAI | /model openai/gpt-4o |
OPENAI_API_KEY |
pip install "aru-code[openai]" |
| Groq | /model groq/llama-3.3-70b-versatile |
GROQ_API_KEY |
pip install "aru-code[groq]" |
| OpenRouter | /model openrouter/deepseek/deepseek-chat-v3-0324 |
OPENROUTER_API_KEY |
pip install "aru-code[openai]" |
| MiniMax | /model openrouter/minimax/minimax-m2.7 |
OPENROUTER_API_KEY |
pip install "aru-code[openai]" |
To install all providers at once:
pip install "aru-code[all-providers]"
Ollama (local models)
To run models locally without an API key, install Ollama, start the server, and use any installed model:
ollama serve # Start the Ollama server
ollama pull codellama # Download a model
aru # Start aru
# Inside aru:
/model ollama/codellama
Configuring the default model
You can set the default provider/model in aru.json so you don't need to switch manually every session:
{
"default_model": "openrouter/minimax/minimax-m2.7",
"model_aliases": {
"minimax": "openrouter/minimax/minimax-m2.5",
"minimax-m2.7": "openrouter/minimax/minimax-m2.7",
"deepseek-v3": "openrouter/deepseek/deepseek-chat-v3-0324",
"sonnet-4-6": "anthropic/claude-sonnet-4-6",
"opus-4-6": "anthropic/claude-opus-4-6"
}
}
The default_model field sets the main model. The model_aliases are shortcuts that can be used with /model <alias>.
Custom providers
You can configure custom providers with specific token limits:
{
"providers": {
"deepseek": {
"models": {
"deepseek-chat-v3-0324": { "max_tokens": 16384 }
}
},
"openrouter": {
"models": {
"minimax/minimax-m2.5": { "max_tokens": 65536 },
"minimax/minimax-m2.7": { "max_tokens": 131072 }
}
}
}
}
Permissions (aru.json)
Aru uses a granular permission system where each tool action resolves to one of three outcomes:
allow— executes without askingask— prompts for confirmation (once / always / no)deny— blocks the action silently
Configure permissions per tool category with glob patterns:
{
"permission": {
"*": "ask",
"read": "allow",
"glob": "allow",
"grep": "allow",
"list": "allow",
"edit": {
"*": "allow",
"*.env": "deny"
},
"write": {
"*": "allow",
"*.env": "deny"
},
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"pytest *": "allow",
"rm -rf *": "deny"
},
"web_search": "allow",
"web_fetch": "allow",
"delegate_task": "allow"
}
}
Available categories
| Category | Matched against | Default |
|---|---|---|
read |
file path | allow |
edit |
file path | ask |
write |
file path | ask |
bash |
command string | safe prefixes = allow, rest = ask |
glob |
— | allow |
grep |
— | allow |
list |
— | allow |
web_search |
— | allow |
web_fetch |
URL | allow |
delegate_task |
— | allow |
Rule precedence
Rules use last-match-wins ordering. Place catch-all "*" first, then specific patterns:
{
"edit": {
"*": "allow",
"*.env": "deny",
"*.env.example": "allow"
}
}
Shorthands
"permission": "allow"
Allows everything (equivalent to --dangerously-skip-permissions).
"permission": { "read": "allow", "edit": "ask" }
String value applies to all patterns in that category.
Defaults
Without any aru.json config, aru applies safe defaults:
- Read-only tools (
read,glob,grep,list) →allow - Mutating tools (
edit,write) →ask - Bash → ~40 safe command prefixes auto-allowed (
ls,git status,grep, etc.), rest →ask - Sensitive files (
*.env,*.env.*) →denyfor read/edit/write (except*.env.example)
aru.jsoncan also be placed at.aru/config.json.A full
aru.jsonconfig reference here:aru.json
AGENTS.md
Place an AGENTS.md file in your project root with custom instructions that will be appended to all agent system prompts.
Instructions (Rules)
You can load additional instructions from local files, glob patterns, or remote URLs via the instructions field in aru.json:
{
"instructions": [
"CONTRIBUTING.md",
"docs/coding-standards.md",
"packages/*/AGENTS.md",
"https://raw.githubusercontent.com/my-org/shared-rules/main/style.md"
]
}
Each entry is resolved as follows:
| Format | Example | Behavior |
|---|---|---|
| Local file | "CONTRIBUTING.md" |
Reads the file relative to the project root |
| Glob pattern | "docs/**/*.md" |
Expands the pattern, respects .gitignore |
| Remote URL | "https://example.com/rules.md" |
Fetches via HTTP (5s timeout, cached per session) |
All resolved content is combined and appended to the agent's system prompt alongside AGENTS.md. Individual files are capped at 10KB, and the total combined size is capped at 50KB to prevent context bloat. Missing files and failed URL fetches are skipped with a warning.
.agents/ Directory
.agents/
├── agents/ # Custom agents with their own model, tools, and prompt
│ └── reviewer.md # Usage: /reviewer <args>
├── commands/ # Custom slash commands (filename = command name)
│ └── deploy.md # Usage: /deploy <args>
└── skills/ # Custom skills/personas
└── review/
└── SKILL.md
Command files support frontmatter with description, agent, and model fields, plus OpenCode-style argument placeholders: $ARGUMENTS (full string), $1/$2 (positional), and $ARGUMENTS[N] (0-indexed).
Custom Agents
Custom agents are Markdown files with YAML frontmatter stored in .agents/agents/. Each agent runs with its own system prompt, model, and tool set — unlike commands and skills, which reuse the General Agent.
---
name: Code Reviewer
description: Review code for quality, bugs, and best practices
model: anthropic/claude-sonnet-4-5
tools: read_file, grep_search, glob_search
max_turns: 15
mode: primary
---
You are an expert code reviewer. Analyze code for bugs, security,
performance, and readability. Do NOT modify files.
Frontmatter fields
| Field | Required | Description |
|---|---|---|
name |
Yes | Display name of the agent |
description |
Yes | When to use this agent (shown in /agents and tab completion) |
model |
No | Provider/model reference (e.g., anthropic/claude-sonnet-4-5). Defaults to session model |
tools |
No | Comma-separated tool names (allowlist) or JSON object for granular control (e.g., {"bash": false}). Defaults to all general tools |
max_turns |
No | Max tool calls before the agent stops. Default: 20 |
mode |
No | primary (invocable via /name) or subagent (only via delegate_task). Default: primary |
permission |
No | Permission overrides (same format as aru.json permission section). Replaces global rules for specified categories while the agent runs |
Invocation
There are three ways to invoke a custom agent:
| Method | Syntax | When to use |
|---|---|---|
| Slash command | /reviewer src/auth.py |
Directly invoke a primary agent by name |
| @mention | @reviewer check this function |
Mention an agent anywhere in your message |
| delegate_task | Automatic (subagents only) | Subagent names and descriptions are injected into the delegate_task tool description, so the LLM sees them and can call delegate_task(task="...", agent="name") on its own when it judges the task fits |
aru> /reviewer src/auth.py # slash command (primary agents)
aru> @reviewer check the auth module # @mention (primary or subagent)
aru> /agents # list all custom agents
Note: Slash commands (
/name) are only available forprimaryagents — subagents are blocked with a warning.@mentionworks for any agent regardless of mode. Subagents can be invoked in two ways: automatically by the LLM viadelegate_task, or manually by the user via@name.
Discovery paths
Agents are discovered from multiple locations (later overrides earlier):
~/.agents/agents/— global (available in all projects)~/.claude/agents/— global (Claude Code compatible path).agents/agents/— project-local.claude/agents/— project-local
Agent-level permissions
Agents can override global permission rules. Overrides replace the entire category — unspecified categories inherit from global config.
---
name: Code Reviewer
description: Read-only code reviewer
permission:
edit: deny
write: deny
bash:
git diff *: allow
grep *: allow
---
You can also set agent permissions in aru.json (overrides frontmatter):
{
"agent": {
"reviewer": {
"permission": { "edit": "deny", "write": "deny" }
}
}
}
Each agent gets its own isolated "always" memory — approvals during an agent's run don't carry over to the global scope.
Subagent mode
Agents with mode: subagent can be referenced by the LLM via delegate_task(task, agent="name") but are not directly invocable from the CLI.
MCP Support (Model Context Protocol)
Aru can load tools from MCP servers. Configure in .aru/mcp_config.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"]
}
}
}
Agents
| Agent | Role | Tools |
|---|---|---|
| Planner | Analyzes codebase, creates structured implementation plans | Read-only tools, search, web |
| Executor | Implements code changes based on plans or instructions | All tools including delegation |
| General | Handles conversation and simple operations | All tools including delegation |
Tools
File Operations
read_file— Reads files with line range support and binary detectionread_file_smart— Answers specific questions about a file without returning raw contentwrite_file— Writes content to files, creating directories as needededit_file— Find-and-replace edits on files
Search & Discovery
glob_search— Find files by pattern (respects .gitignore)grep_search— Content search with regex and file filteringlist_directory— Directory listing with gitignore filtering
Shell & Web
bash— Executes shell commands with permission gatesweb_search— Web search via DuckDuckGoweb_fetch— Fetches URLs and converts HTML to readable text
Advanced
delegate_task— Spawns autonomous sub-agents for parallel task execution
Architecture
aru-code/
├── aru/
│ ├── cli.py # Main REPL loop, argument parsing, and entry point
│ ├── agent_factory.py # Agent instantiation (general and custom agents)
│ ├── commands.py # Slash commands, help display, shell execution
│ ├── completers.py # Input completions, paste detection, @file mentions
│ ├── context.py # Token optimization (pruning, truncation, compaction)
│ ├── display.py # Terminal display (logo, status bar, streaming output)
│ ├── runner.py # Agent execution orchestration with streaming
│ ├── session.py # Session state, persistence, plan tracking
│ ├── config.py # Configuration loader (AGENTS.md, .agents/)
│ ├── providers.py # Multi-provider LLM abstraction
│ ├── permissions.py # Granular permission system (allow/ask/deny)
│ ├── agents/
│ │ ├── planner.py # Planning agent
│ │ └── executor.py # Execution agent
│ └── tools/
│ ├── codebase.py # 11 core tools
│ ├── ast_tools.py # Tree-sitter code analysis
│ ├── ranker.py # File relevance ranking
│ ├── mcp_client.py # MCP client
│ └── gitignore.py # Gitignore-aware filtering
├── aru.json # Permissions and model configuration
├── .env # API keys (not committed)
├── .aru/ # Local data (sessions)
└── pyproject.toml
Built With
- Agno — Agent framework with tool orchestration
- Anthropic Claude — Sonnet 4.6, Opus 4.6, Haiku 4.5
- tree-sitter — AST-based code analysis
- Rich — Terminal UI
- prompt-toolkit — Advanced input handling
Development
# Clone and install in editable mode with dev dependencies
git clone https://github.com/estevaofon/aru.git
cd aru
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=aru --cov-report=term-missing
Built with Claude and Agno
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aru_code-0.18.0.tar.gz.
File metadata
- Download URL: aru_code-0.18.0.tar.gz
- Upload date:
- Size: 165.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f1c23bb4b273795f273c0dbe932537d94d5c6e3ac4093d57caaece3d96869ae
|
|
| MD5 |
597cedf9bd592979e45dd659aabd520a
|
|
| BLAKE2b-256 |
01158444a325b6cb060a838c00808c51061de7801debe590d3716cfc2c376673
|
File details
Details for the file aru_code-0.18.0-py3-none-any.whl.
File metadata
- Download URL: aru_code-0.18.0-py3-none-any.whl
- Upload date:
- Size: 107.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f17216beaa40638c875c2219e08db934e3b493b01f7803275d1d04f01cff442
|
|
| MD5 |
feea7b884e2d6e2d6b80d3e5311ab91b
|
|
| BLAKE2b-256 |
dedd39c869e52b52be0ab2f3a53e55c02dd516fb1a3af49181cd2b9f3180b0ec
|