Skip to main content

A Claude Code clone built with Agno agents

Project description

aru

An intelligent coding assistant for the terminal, powered by LLMs and Agno agents.

0329(3)

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)
  • 16 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 asking
  • ask — 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.*) → deny for read/edit/write (except *.env.example)

aru.json can also be placed at .aru/config.json.

A full aru.json config 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, code_structure
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 for primary agents — subagents are blocked with a warning. @mention works for any agent regardless of mode. Subagents can be invoked in two ways: automatically by the LLM via delegate_task, or manually by the user via @name.

Discovery paths

Agents are discovered from multiple locations (later overrides earlier):

  1. ~/.agents/agents/ — global (available in all projects)
  2. ~/.claude/agents/ — global (Claude Code compatible path)
  3. .agents/agents/ — project-local
  4. .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 detection
  • read_file_smart — Smart file reading focused on relevant snippets for the query
  • write_file / write_files — Writes single or batch files
  • edit_file / edit_files — Find-replace edits across multiple files

Search & Discovery

  • glob_search — Find files by pattern (respects .gitignore)
  • grep_search — Content search with regex and file filtering
  • list_directory — Directory listing with gitignore filtering
  • rank_files — Multi-factor file relevance ranking (name, structure, recency)

Code Analysis

  • code_structure — Extracts classes, functions, imports via tree-sitter AST
  • find_dependencies — Analyzes import relationships between files

Shell & Web

  • bash — Executes shell commands with permission gates
  • web_search — Web search via DuckDuckGo
  • web_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     # 16 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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aru_code-0.14.1.tar.gz (153.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aru_code-0.14.1-py3-none-any.whl (96.2 kB view details)

Uploaded Python 3

File details

Details for the file aru_code-0.14.1.tar.gz.

File metadata

  • Download URL: aru_code-0.14.1.tar.gz
  • Upload date:
  • Size: 153.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for aru_code-0.14.1.tar.gz
Algorithm Hash digest
SHA256 dccd976d20c72993521d4b6cd95be3eeca16c2593aaa7d881d58ff9197f34c50
MD5 3b01cce2fcdedcb5ce9d6c15d14374f8
BLAKE2b-256 7d675a15a3409aebf504f04ad89255cf1a31e5ee3b3795b2d52e6c4ad410881b

See more details on using hashes here.

File details

Details for the file aru_code-0.14.1-py3-none-any.whl.

File metadata

  • Download URL: aru_code-0.14.1-py3-none-any.whl
  • Upload date:
  • Size: 96.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for aru_code-0.14.1-py3-none-any.whl
Algorithm Hash digest
SHA256 84ecd9caf9dfcd3fef0de4734c19ac246c35ec8f12025db6e2e0f81046c9335c
MD5 04f1cf8b0ff49de7423578cfe875671f
BLAKE2b-256 bf5e0cde0689a7d17d502230120708ed7bc0ca7188f9efaf3748f2b6da0a5a0d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page