aru-code 0.4.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aru_code-0.4.0/aru_code.egg-info → aru_code-0.6.0}/PKG-INFO +177 -13
- {aru_code-0.4.0 → aru_code-0.6.0}/README.md +176 -12
- aru_code-0.6.0/aru/__init__.py +1 -0
- aru_code-0.6.0/aru/agent_factory.py +66 -0
- aru_code-0.6.0/aru/cli.py +568 -0
- aru_code-0.6.0/aru/commands.py +102 -0
- aru_code-0.6.0/aru/completers.py +300 -0
- aru_code-0.6.0/aru/config.py +471 -0
- aru_code-0.6.0/aru/display.py +334 -0
- aru_code-0.6.0/aru/permissions.py +507 -0
- aru_code-0.6.0/aru/runner.py +448 -0
- aru_code-0.6.0/aru/session.py +475 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/codebase.py +115 -175
- {aru_code-0.4.0 → aru_code-0.6.0/aru_code.egg-info}/PKG-INFO +177 -13
- {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/SOURCES.txt +8 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/pyproject.toml +83 -83
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_advanced.py +3 -3
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_completers.py +104 -2
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_shell.py +17 -17
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_codebase.py +96 -18
- aru_code-0.6.0/tests/test_config.py +804 -0
- aru_code-0.6.0/tests/test_permissions.py +748 -0
- aru_code-0.4.0/aru/__init__.py +0 -1
- aru_code-0.4.0/aru/cli.py +0 -2071
- aru_code-0.4.0/aru/config.py +0 -242
- aru_code-0.4.0/tests/test_config.py +0 -378
- {aru_code-0.4.0 → aru_code-0.6.0}/LICENSE +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/__init__.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/base.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/executor.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/planner.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/context.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/providers.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/__init__.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/ast_tools.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/gitignore.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/mcp_client.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/ranker.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/tasklist.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/dependency_links.txt +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/entry_points.txt +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/requires.txt +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/top_level.txt +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/setup.cfg +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_agents_base.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_ast_tools.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_base.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_new.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_run_cli.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_session.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_context.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_executor.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_gitignore.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_main.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_mcp_client.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_planner.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_providers.py +0 -0
- {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_ranker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aru-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A Claude Code clone built with Agno agents
|
|
5
5
|
Author-email: Estevao <estevaofon@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -58,7 +58,7 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
58
58
|
- **16 Integrated Tools** — File operations, code search, shell, web search, task delegation
|
|
59
59
|
- **Task Planning** — Break down complex tasks into steps with automatic execution
|
|
60
60
|
- **Multi-Provider** — Anthropic, OpenAI, Ollama, Groq, OpenRouter, DeepSeek, and others via custom configuration
|
|
61
|
-
- **Custom Commands and
|
|
61
|
+
- **Custom Commands, Skills, and Agents** — Extend aru via the `.agents/` directory
|
|
62
62
|
- **MCP Support** — Integration with Model Context Protocol servers
|
|
63
63
|
|
|
64
64
|
## Quick Start
|
|
@@ -103,6 +103,7 @@ That's it — `aru` is available globally after install.
|
|
|
103
103
|
| `/mcp` | List available MCP servers and tools |
|
|
104
104
|
| `/commands` | List custom commands |
|
|
105
105
|
| `/skills` | List available skills |
|
|
106
|
+
| `/agents` | List custom agents |
|
|
106
107
|
| `/sessions` | List recent sessions |
|
|
107
108
|
| `/help` | Show all commands |
|
|
108
109
|
| `! <command>` | Execute shell commands |
|
|
@@ -206,25 +207,96 @@ You can configure custom providers with specific token limits:
|
|
|
206
207
|
|
|
207
208
|
### Permissions (`aru.json`)
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
Aru uses a granular permission system where each tool action resolves to one of three outcomes:
|
|
211
|
+
|
|
212
|
+
- **`allow`** — executes without asking
|
|
213
|
+
- **`ask`** — prompts for confirmation (once / always / no)
|
|
214
|
+
- **`deny`** — blocks the action silently
|
|
215
|
+
|
|
216
|
+
Configure permissions per tool category with glob patterns:
|
|
210
217
|
|
|
211
218
|
```json
|
|
212
219
|
{
|
|
213
220
|
"permission": {
|
|
214
|
-
"
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
"*": "ask",
|
|
222
|
+
"read": "allow",
|
|
223
|
+
"glob": "allow",
|
|
224
|
+
"grep": "allow",
|
|
225
|
+
"list": "allow",
|
|
226
|
+
"edit": {
|
|
227
|
+
"*": "allow",
|
|
228
|
+
"*.env": "deny"
|
|
229
|
+
},
|
|
230
|
+
"write": {
|
|
231
|
+
"*": "allow",
|
|
232
|
+
"*.env": "deny"
|
|
233
|
+
},
|
|
234
|
+
"bash": {
|
|
235
|
+
"*": "ask",
|
|
236
|
+
"git *": "allow",
|
|
237
|
+
"npm *": "allow",
|
|
238
|
+
"pytest *": "allow",
|
|
239
|
+
"rm -rf *": "deny"
|
|
240
|
+
},
|
|
241
|
+
"web_search": "allow",
|
|
242
|
+
"web_fetch": "allow",
|
|
243
|
+
"delegate_task": "allow"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Available categories
|
|
249
|
+
|
|
250
|
+
| Category | Matched against | Default |
|
|
251
|
+
|----------|----------------|---------|
|
|
252
|
+
| `read` | file path | `allow` |
|
|
253
|
+
| `edit` | file path | `ask` |
|
|
254
|
+
| `write` | file path | `ask` |
|
|
255
|
+
| `bash` | command string | safe prefixes = `allow`, rest = `ask` |
|
|
256
|
+
| `glob` | — | `allow` |
|
|
257
|
+
| `grep` | — | `allow` |
|
|
258
|
+
| `list` | — | `allow` |
|
|
259
|
+
| `web_search` | — | `allow` |
|
|
260
|
+
| `web_fetch` | URL | `allow` |
|
|
261
|
+
| `delegate_task` | — | `allow` |
|
|
262
|
+
|
|
263
|
+
#### Rule precedence
|
|
264
|
+
|
|
265
|
+
Rules use **last-match-wins** ordering. Place catch-all `"*"` first, then specific patterns:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"edit": {
|
|
270
|
+
"*": "allow",
|
|
271
|
+
"*.env": "deny",
|
|
272
|
+
"*.env.example": "allow"
|
|
221
273
|
}
|
|
222
274
|
}
|
|
223
275
|
```
|
|
224
276
|
|
|
225
|
-
|
|
277
|
+
#### Shorthands
|
|
278
|
+
|
|
279
|
+
```json
|
|
280
|
+
"permission": "allow"
|
|
281
|
+
```
|
|
282
|
+
Allows everything (equivalent to `--dangerously-skip-permissions`).
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
"permission": { "read": "allow", "edit": "ask" }
|
|
286
|
+
```
|
|
287
|
+
String value applies to all patterns in that category.
|
|
288
|
+
|
|
289
|
+
#### Defaults
|
|
290
|
+
|
|
291
|
+
Without any `aru.json` config, aru applies safe defaults:
|
|
292
|
+
- Read-only tools (`read`, `glob`, `grep`, `list`) → `allow`
|
|
293
|
+
- Mutating tools (`edit`, `write`) → `ask`
|
|
294
|
+
- Bash → ~40 safe command prefixes auto-allowed (`ls`, `git status`, `grep`, etc.), rest → `ask`
|
|
295
|
+
- Sensitive files (`*.env`, `*.env.*`) → `deny` for read/edit/write (except `*.env.example`)
|
|
226
296
|
|
|
227
297
|
> `aru.json` can also be placed at `.aru/config.json`.
|
|
298
|
+
>
|
|
299
|
+
> A full `aru.json` config reference here: [`aru.json`](./aru.json)
|
|
228
300
|
|
|
229
301
|
### AGENTS.md
|
|
230
302
|
|
|
@@ -234,14 +306,98 @@ Place an `AGENTS.md` file in your project root with custom instructions that wil
|
|
|
234
306
|
|
|
235
307
|
```
|
|
236
308
|
.agents/
|
|
309
|
+
├── agents/ # Custom agents with their own model, tools, and prompt
|
|
310
|
+
│ └── reviewer.md # Usage: /reviewer <args>
|
|
237
311
|
├── commands/ # Custom slash commands (filename = command name)
|
|
238
312
|
│ └── deploy.md # Usage: /deploy <args>
|
|
239
313
|
└── skills/ # Custom skills/personas
|
|
240
|
-
└── review
|
|
314
|
+
└── review/
|
|
315
|
+
└── SKILL.md
|
|
241
316
|
```
|
|
242
317
|
|
|
243
318
|
Command files support frontmatter with `description` and the `$INPUT` template variable for arguments.
|
|
244
319
|
|
|
320
|
+
### Custom Agents
|
|
321
|
+
|
|
322
|
+
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.
|
|
323
|
+
|
|
324
|
+
```markdown
|
|
325
|
+
---
|
|
326
|
+
name: Code Reviewer
|
|
327
|
+
description: Review code for quality, bugs, and best practices
|
|
328
|
+
model: anthropic/claude-sonnet-4-5
|
|
329
|
+
tools: read_file, grep_search, glob_search, code_structure
|
|
330
|
+
max_turns: 15
|
|
331
|
+
mode: primary
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
You are an expert code reviewer. Analyze code for bugs, security,
|
|
335
|
+
performance, and readability. Do NOT modify files.
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
#### Frontmatter fields
|
|
339
|
+
|
|
340
|
+
| Field | Required | Description |
|
|
341
|
+
|-------|----------|-------------|
|
|
342
|
+
| `name` | Yes | Display name of the agent |
|
|
343
|
+
| `description` | Yes | When to use this agent (shown in `/agents` and tab completion) |
|
|
344
|
+
| `model` | No | Provider/model reference (e.g., `anthropic/claude-sonnet-4-5`). Defaults to session model |
|
|
345
|
+
| `tools` | No | Comma-separated tool names (allowlist) or JSON object for granular control (e.g., `{"bash": false}`). Defaults to all general tools |
|
|
346
|
+
| `max_turns` | No | Max tool calls before the agent stops. Default: 20 |
|
|
347
|
+
| `mode` | No | `primary` (invocable via `/name`) or `subagent` (only via `delegate_task`). Default: `primary` |
|
|
348
|
+
| `permission` | No | Permission overrides (same format as `aru.json` permission section). Replaces global rules for specified categories while the agent runs |
|
|
349
|
+
|
|
350
|
+
#### Invocation
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
aru> /reviewer src/auth.py # invoke by slash + filename (without .md)
|
|
354
|
+
aru> /agents # list all custom agents
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### Discovery paths
|
|
358
|
+
|
|
359
|
+
Agents are discovered from multiple locations (later overrides earlier):
|
|
360
|
+
|
|
361
|
+
1. `~/.agents/agents/` — global (available in all projects)
|
|
362
|
+
2. `~/.claude/agents/` — global (Claude Code compatible path)
|
|
363
|
+
3. `.agents/agents/` — project-local
|
|
364
|
+
4. `.claude/agents/` — project-local
|
|
365
|
+
|
|
366
|
+
#### Agent-level permissions
|
|
367
|
+
|
|
368
|
+
Agents can override global permission rules. Overrides replace the entire category — unspecified categories inherit from global config.
|
|
369
|
+
|
|
370
|
+
```markdown
|
|
371
|
+
---
|
|
372
|
+
name: Code Reviewer
|
|
373
|
+
description: Read-only code reviewer
|
|
374
|
+
permission:
|
|
375
|
+
edit: deny
|
|
376
|
+
write: deny
|
|
377
|
+
bash:
|
|
378
|
+
git diff *: allow
|
|
379
|
+
grep *: allow
|
|
380
|
+
---
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
You can also set agent permissions in `aru.json` (overrides frontmatter):
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{
|
|
387
|
+
"agent": {
|
|
388
|
+
"reviewer": {
|
|
389
|
+
"permission": { "edit": "deny", "write": "deny" }
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Each agent gets its own isolated "always" memory — approvals during an agent's run don't carry over to the global scope.
|
|
396
|
+
|
|
397
|
+
#### Subagent mode
|
|
398
|
+
|
|
399
|
+
Agents with `mode: subagent` can be referenced by the LLM via `delegate_task(task, agent="name")` but are not directly invocable from the CLI.
|
|
400
|
+
|
|
245
401
|
### MCP Support (Model Context Protocol)
|
|
246
402
|
|
|
247
403
|
Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
|
|
@@ -296,9 +452,17 @@ Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
|
|
|
296
452
|
```
|
|
297
453
|
aru-code/
|
|
298
454
|
├── aru/
|
|
299
|
-
│ ├── cli.py #
|
|
455
|
+
│ ├── cli.py # Main REPL loop, argument parsing, and entry point
|
|
456
|
+
│ ├── agent_factory.py # Agent instantiation (general and custom agents)
|
|
457
|
+
│ ├── commands.py # Slash commands, help display, shell execution
|
|
458
|
+
│ ├── completers.py # Input completions, paste detection, @file mentions
|
|
459
|
+
│ ├── context.py # Token optimization (pruning, truncation, compaction)
|
|
460
|
+
│ ├── display.py # Terminal display (logo, status bar, streaming output)
|
|
461
|
+
│ ├── runner.py # Agent execution orchestration with streaming
|
|
462
|
+
│ ├── session.py # Session state, persistence, plan tracking
|
|
300
463
|
│ ├── config.py # Configuration loader (AGENTS.md, .agents/)
|
|
301
464
|
│ ├── providers.py # Multi-provider LLM abstraction
|
|
465
|
+
│ ├── permissions.py # Granular permission system (allow/ask/deny)
|
|
302
466
|
│ ├── agents/
|
|
303
467
|
│ │ ├── planner.py # Planning agent
|
|
304
468
|
│ │ └── executor.py # Execution agent
|
|
@@ -11,7 +11,7 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
11
11
|
- **16 Integrated Tools** — File operations, code search, shell, web search, task delegation
|
|
12
12
|
- **Task Planning** — Break down complex tasks into steps with automatic execution
|
|
13
13
|
- **Multi-Provider** — Anthropic, OpenAI, Ollama, Groq, OpenRouter, DeepSeek, and others via custom configuration
|
|
14
|
-
- **Custom Commands and
|
|
14
|
+
- **Custom Commands, Skills, and Agents** — Extend aru via the `.agents/` directory
|
|
15
15
|
- **MCP Support** — Integration with Model Context Protocol servers
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
@@ -56,6 +56,7 @@ That's it — `aru` is available globally after install.
|
|
|
56
56
|
| `/mcp` | List available MCP servers and tools |
|
|
57
57
|
| `/commands` | List custom commands |
|
|
58
58
|
| `/skills` | List available skills |
|
|
59
|
+
| `/agents` | List custom agents |
|
|
59
60
|
| `/sessions` | List recent sessions |
|
|
60
61
|
| `/help` | Show all commands |
|
|
61
62
|
| `! <command>` | Execute shell commands |
|
|
@@ -159,25 +160,96 @@ You can configure custom providers with specific token limits:
|
|
|
159
160
|
|
|
160
161
|
### Permissions (`aru.json`)
|
|
161
162
|
|
|
162
|
-
|
|
163
|
+
Aru uses a granular permission system where each tool action resolves to one of three outcomes:
|
|
164
|
+
|
|
165
|
+
- **`allow`** — executes without asking
|
|
166
|
+
- **`ask`** — prompts for confirmation (once / always / no)
|
|
167
|
+
- **`deny`** — blocks the action silently
|
|
168
|
+
|
|
169
|
+
Configure permissions per tool category with glob patterns:
|
|
163
170
|
|
|
164
171
|
```json
|
|
165
172
|
{
|
|
166
173
|
"permission": {
|
|
167
|
-
"
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
"*": "ask",
|
|
175
|
+
"read": "allow",
|
|
176
|
+
"glob": "allow",
|
|
177
|
+
"grep": "allow",
|
|
178
|
+
"list": "allow",
|
|
179
|
+
"edit": {
|
|
180
|
+
"*": "allow",
|
|
181
|
+
"*.env": "deny"
|
|
182
|
+
},
|
|
183
|
+
"write": {
|
|
184
|
+
"*": "allow",
|
|
185
|
+
"*.env": "deny"
|
|
186
|
+
},
|
|
187
|
+
"bash": {
|
|
188
|
+
"*": "ask",
|
|
189
|
+
"git *": "allow",
|
|
190
|
+
"npm *": "allow",
|
|
191
|
+
"pytest *": "allow",
|
|
192
|
+
"rm -rf *": "deny"
|
|
193
|
+
},
|
|
194
|
+
"web_search": "allow",
|
|
195
|
+
"web_fetch": "allow",
|
|
196
|
+
"delegate_task": "allow"
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### Available categories
|
|
202
|
+
|
|
203
|
+
| Category | Matched against | Default |
|
|
204
|
+
|----------|----------------|---------|
|
|
205
|
+
| `read` | file path | `allow` |
|
|
206
|
+
| `edit` | file path | `ask` |
|
|
207
|
+
| `write` | file path | `ask` |
|
|
208
|
+
| `bash` | command string | safe prefixes = `allow`, rest = `ask` |
|
|
209
|
+
| `glob` | — | `allow` |
|
|
210
|
+
| `grep` | — | `allow` |
|
|
211
|
+
| `list` | — | `allow` |
|
|
212
|
+
| `web_search` | — | `allow` |
|
|
213
|
+
| `web_fetch` | URL | `allow` |
|
|
214
|
+
| `delegate_task` | — | `allow` |
|
|
215
|
+
|
|
216
|
+
#### Rule precedence
|
|
217
|
+
|
|
218
|
+
Rules use **last-match-wins** ordering. Place catch-all `"*"` first, then specific patterns:
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"edit": {
|
|
223
|
+
"*": "allow",
|
|
224
|
+
"*.env": "deny",
|
|
225
|
+
"*.env.example": "allow"
|
|
174
226
|
}
|
|
175
227
|
}
|
|
176
228
|
```
|
|
177
229
|
|
|
178
|
-
|
|
230
|
+
#### Shorthands
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
"permission": "allow"
|
|
234
|
+
```
|
|
235
|
+
Allows everything (equivalent to `--dangerously-skip-permissions`).
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
"permission": { "read": "allow", "edit": "ask" }
|
|
239
|
+
```
|
|
240
|
+
String value applies to all patterns in that category.
|
|
241
|
+
|
|
242
|
+
#### Defaults
|
|
243
|
+
|
|
244
|
+
Without any `aru.json` config, aru applies safe defaults:
|
|
245
|
+
- Read-only tools (`read`, `glob`, `grep`, `list`) → `allow`
|
|
246
|
+
- Mutating tools (`edit`, `write`) → `ask`
|
|
247
|
+
- Bash → ~40 safe command prefixes auto-allowed (`ls`, `git status`, `grep`, etc.), rest → `ask`
|
|
248
|
+
- Sensitive files (`*.env`, `*.env.*`) → `deny` for read/edit/write (except `*.env.example`)
|
|
179
249
|
|
|
180
250
|
> `aru.json` can also be placed at `.aru/config.json`.
|
|
251
|
+
>
|
|
252
|
+
> A full `aru.json` config reference here: [`aru.json`](./aru.json)
|
|
181
253
|
|
|
182
254
|
### AGENTS.md
|
|
183
255
|
|
|
@@ -187,14 +259,98 @@ Place an `AGENTS.md` file in your project root with custom instructions that wil
|
|
|
187
259
|
|
|
188
260
|
```
|
|
189
261
|
.agents/
|
|
262
|
+
├── agents/ # Custom agents with their own model, tools, and prompt
|
|
263
|
+
│ └── reviewer.md # Usage: /reviewer <args>
|
|
190
264
|
├── commands/ # Custom slash commands (filename = command name)
|
|
191
265
|
│ └── deploy.md # Usage: /deploy <args>
|
|
192
266
|
└── skills/ # Custom skills/personas
|
|
193
|
-
└── review
|
|
267
|
+
└── review/
|
|
268
|
+
└── SKILL.md
|
|
194
269
|
```
|
|
195
270
|
|
|
196
271
|
Command files support frontmatter with `description` and the `$INPUT` template variable for arguments.
|
|
197
272
|
|
|
273
|
+
### Custom Agents
|
|
274
|
+
|
|
275
|
+
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.
|
|
276
|
+
|
|
277
|
+
```markdown
|
|
278
|
+
---
|
|
279
|
+
name: Code Reviewer
|
|
280
|
+
description: Review code for quality, bugs, and best practices
|
|
281
|
+
model: anthropic/claude-sonnet-4-5
|
|
282
|
+
tools: read_file, grep_search, glob_search, code_structure
|
|
283
|
+
max_turns: 15
|
|
284
|
+
mode: primary
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
You are an expert code reviewer. Analyze code for bugs, security,
|
|
288
|
+
performance, and readability. Do NOT modify files.
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### Frontmatter fields
|
|
292
|
+
|
|
293
|
+
| Field | Required | Description |
|
|
294
|
+
|-------|----------|-------------|
|
|
295
|
+
| `name` | Yes | Display name of the agent |
|
|
296
|
+
| `description` | Yes | When to use this agent (shown in `/agents` and tab completion) |
|
|
297
|
+
| `model` | No | Provider/model reference (e.g., `anthropic/claude-sonnet-4-5`). Defaults to session model |
|
|
298
|
+
| `tools` | No | Comma-separated tool names (allowlist) or JSON object for granular control (e.g., `{"bash": false}`). Defaults to all general tools |
|
|
299
|
+
| `max_turns` | No | Max tool calls before the agent stops. Default: 20 |
|
|
300
|
+
| `mode` | No | `primary` (invocable via `/name`) or `subagent` (only via `delegate_task`). Default: `primary` |
|
|
301
|
+
| `permission` | No | Permission overrides (same format as `aru.json` permission section). Replaces global rules for specified categories while the agent runs |
|
|
302
|
+
|
|
303
|
+
#### Invocation
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
aru> /reviewer src/auth.py # invoke by slash + filename (without .md)
|
|
307
|
+
aru> /agents # list all custom agents
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### Discovery paths
|
|
311
|
+
|
|
312
|
+
Agents are discovered from multiple locations (later overrides earlier):
|
|
313
|
+
|
|
314
|
+
1. `~/.agents/agents/` — global (available in all projects)
|
|
315
|
+
2. `~/.claude/agents/` — global (Claude Code compatible path)
|
|
316
|
+
3. `.agents/agents/` — project-local
|
|
317
|
+
4. `.claude/agents/` — project-local
|
|
318
|
+
|
|
319
|
+
#### Agent-level permissions
|
|
320
|
+
|
|
321
|
+
Agents can override global permission rules. Overrides replace the entire category — unspecified categories inherit from global config.
|
|
322
|
+
|
|
323
|
+
```markdown
|
|
324
|
+
---
|
|
325
|
+
name: Code Reviewer
|
|
326
|
+
description: Read-only code reviewer
|
|
327
|
+
permission:
|
|
328
|
+
edit: deny
|
|
329
|
+
write: deny
|
|
330
|
+
bash:
|
|
331
|
+
git diff *: allow
|
|
332
|
+
grep *: allow
|
|
333
|
+
---
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
You can also set agent permissions in `aru.json` (overrides frontmatter):
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"agent": {
|
|
341
|
+
"reviewer": {
|
|
342
|
+
"permission": { "edit": "deny", "write": "deny" }
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Each agent gets its own isolated "always" memory — approvals during an agent's run don't carry over to the global scope.
|
|
349
|
+
|
|
350
|
+
#### Subagent mode
|
|
351
|
+
|
|
352
|
+
Agents with `mode: subagent` can be referenced by the LLM via `delegate_task(task, agent="name")` but are not directly invocable from the CLI.
|
|
353
|
+
|
|
198
354
|
### MCP Support (Model Context Protocol)
|
|
199
355
|
|
|
200
356
|
Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
|
|
@@ -249,9 +405,17 @@ Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
|
|
|
249
405
|
```
|
|
250
406
|
aru-code/
|
|
251
407
|
├── aru/
|
|
252
|
-
│ ├── cli.py #
|
|
408
|
+
│ ├── cli.py # Main REPL loop, argument parsing, and entry point
|
|
409
|
+
│ ├── agent_factory.py # Agent instantiation (general and custom agents)
|
|
410
|
+
│ ├── commands.py # Slash commands, help display, shell execution
|
|
411
|
+
│ ├── completers.py # Input completions, paste detection, @file mentions
|
|
412
|
+
│ ├── context.py # Token optimization (pruning, truncation, compaction)
|
|
413
|
+
│ ├── display.py # Terminal display (logo, status bar, streaming output)
|
|
414
|
+
│ ├── runner.py # Agent execution orchestration with streaming
|
|
415
|
+
│ ├── session.py # Session state, persistence, plan tracking
|
|
253
416
|
│ ├── config.py # Configuration loader (AGENTS.md, .agents/)
|
|
254
417
|
│ ├── providers.py # Multi-provider LLM abstraction
|
|
418
|
+
│ ├── permissions.py # Granular permission system (allow/ask/deny)
|
|
255
419
|
│ ├── agents/
|
|
256
420
|
│ │ ├── planner.py # Planning agent
|
|
257
421
|
│ │ └── executor.py # Execution agent
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.0"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Agent creation: general-purpose and custom agent instantiation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from aru.agents.base import build_instructions as _build_instructions
|
|
6
|
+
from aru.config import AgentConfig, CustomAgent
|
|
7
|
+
from aru.providers import create_model
|
|
8
|
+
from aru.session import Session
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def create_general_agent(session: Session, config: AgentConfig | None = None):
|
|
12
|
+
"""Create the general-purpose agent."""
|
|
13
|
+
from agno.agent import Agent
|
|
14
|
+
from agno.compression.manager import CompressionManager
|
|
15
|
+
|
|
16
|
+
from aru.tools.codebase import GENERAL_TOOLS, _get_small_model_ref
|
|
17
|
+
|
|
18
|
+
extra = config.get_extra_instructions() if config else ""
|
|
19
|
+
|
|
20
|
+
return Agent(
|
|
21
|
+
name="Aru",
|
|
22
|
+
model=create_model(session.model_ref, max_tokens=8192),
|
|
23
|
+
tools=GENERAL_TOOLS,
|
|
24
|
+
instructions=_build_instructions("general", extra),
|
|
25
|
+
markdown=True,
|
|
26
|
+
compress_tool_results=True,
|
|
27
|
+
compression_manager=CompressionManager(
|
|
28
|
+
model=create_model(_get_small_model_ref(), max_tokens=1024),
|
|
29
|
+
compress_tool_results=True,
|
|
30
|
+
compress_tool_results_limit=7,
|
|
31
|
+
),
|
|
32
|
+
tool_call_limit=20,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_custom_agent_instance(agent_def: CustomAgent, session: Session,
|
|
37
|
+
config: AgentConfig | None = None):
|
|
38
|
+
"""Create an Agno Agent from a CustomAgent definition."""
|
|
39
|
+
from agno.agent import Agent
|
|
40
|
+
from agno.compression.manager import CompressionManager
|
|
41
|
+
from aru.agents.base import BASE_INSTRUCTIONS
|
|
42
|
+
from aru.tools.codebase import resolve_tools, _get_small_model_ref
|
|
43
|
+
|
|
44
|
+
model_ref = agent_def.model or session.model_ref
|
|
45
|
+
tools = resolve_tools(agent_def.tools)
|
|
46
|
+
|
|
47
|
+
extra = config.get_extra_instructions() if config else ""
|
|
48
|
+
parts = [agent_def.system_prompt, BASE_INSTRUCTIONS]
|
|
49
|
+
if extra:
|
|
50
|
+
parts.append(extra)
|
|
51
|
+
instructions = "\n\n".join(parts)
|
|
52
|
+
|
|
53
|
+
return Agent(
|
|
54
|
+
name=agent_def.name,
|
|
55
|
+
model=create_model(model_ref, max_tokens=8192),
|
|
56
|
+
tools=tools,
|
|
57
|
+
instructions=instructions,
|
|
58
|
+
markdown=True,
|
|
59
|
+
compress_tool_results=True,
|
|
60
|
+
compression_manager=CompressionManager(
|
|
61
|
+
model=create_model(_get_small_model_ref(), max_tokens=1024),
|
|
62
|
+
compress_tool_results=True,
|
|
63
|
+
compress_tool_results_limit=7,
|
|
64
|
+
),
|
|
65
|
+
tool_call_limit=agent_def.max_turns or 20,
|
|
66
|
+
)
|