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.
Files changed (59) hide show
  1. {aru_code-0.4.0/aru_code.egg-info → aru_code-0.6.0}/PKG-INFO +177 -13
  2. {aru_code-0.4.0 → aru_code-0.6.0}/README.md +176 -12
  3. aru_code-0.6.0/aru/__init__.py +1 -0
  4. aru_code-0.6.0/aru/agent_factory.py +66 -0
  5. aru_code-0.6.0/aru/cli.py +568 -0
  6. aru_code-0.6.0/aru/commands.py +102 -0
  7. aru_code-0.6.0/aru/completers.py +300 -0
  8. aru_code-0.6.0/aru/config.py +471 -0
  9. aru_code-0.6.0/aru/display.py +334 -0
  10. aru_code-0.6.0/aru/permissions.py +507 -0
  11. aru_code-0.6.0/aru/runner.py +448 -0
  12. aru_code-0.6.0/aru/session.py +475 -0
  13. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/codebase.py +115 -175
  14. {aru_code-0.4.0 → aru_code-0.6.0/aru_code.egg-info}/PKG-INFO +177 -13
  15. {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/SOURCES.txt +8 -0
  16. {aru_code-0.4.0 → aru_code-0.6.0}/pyproject.toml +83 -83
  17. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_advanced.py +3 -3
  18. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_completers.py +104 -2
  19. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_shell.py +17 -17
  20. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_codebase.py +96 -18
  21. aru_code-0.6.0/tests/test_config.py +804 -0
  22. aru_code-0.6.0/tests/test_permissions.py +748 -0
  23. aru_code-0.4.0/aru/__init__.py +0 -1
  24. aru_code-0.4.0/aru/cli.py +0 -2071
  25. aru_code-0.4.0/aru/config.py +0 -242
  26. aru_code-0.4.0/tests/test_config.py +0 -378
  27. {aru_code-0.4.0 → aru_code-0.6.0}/LICENSE +0 -0
  28. {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/__init__.py +0 -0
  29. {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/base.py +0 -0
  30. {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/executor.py +0 -0
  31. {aru_code-0.4.0 → aru_code-0.6.0}/aru/agents/planner.py +0 -0
  32. {aru_code-0.4.0 → aru_code-0.6.0}/aru/context.py +0 -0
  33. {aru_code-0.4.0 → aru_code-0.6.0}/aru/providers.py +0 -0
  34. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/__init__.py +0 -0
  35. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/ast_tools.py +0 -0
  36. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/gitignore.py +0 -0
  37. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/mcp_client.py +0 -0
  38. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/ranker.py +0 -0
  39. {aru_code-0.4.0 → aru_code-0.6.0}/aru/tools/tasklist.py +0 -0
  40. {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/dependency_links.txt +0 -0
  41. {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/entry_points.txt +0 -0
  42. {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/requires.txt +0 -0
  43. {aru_code-0.4.0 → aru_code-0.6.0}/aru_code.egg-info/top_level.txt +0 -0
  44. {aru_code-0.4.0 → aru_code-0.6.0}/setup.cfg +0 -0
  45. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_agents_base.py +0 -0
  46. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_ast_tools.py +0 -0
  47. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli.py +0 -0
  48. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_base.py +0 -0
  49. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_new.py +0 -0
  50. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_run_cli.py +0 -0
  51. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_cli_session.py +0 -0
  52. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_context.py +0 -0
  53. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_executor.py +0 -0
  54. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_gitignore.py +0 -0
  55. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_main.py +0 -0
  56. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_mcp_client.py +0 -0
  57. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_planner.py +0 -0
  58. {aru_code-0.4.0 → aru_code-0.6.0}/tests/test_providers.py +0 -0
  59. {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.4.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 Skills** — Extend aru via the `.agents/` directory
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
- The `aru.json` file in the project root controls which shell commands aru can execute **without asking for confirmation**:
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
- "allow": [
215
- "git *",
216
- "npm *",
217
- "pytest *",
218
- "python *",
219
- "uv run pytest *"
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
- Each entry is a glob pattern. Any command that doesn't match a listed pattern will prompt for confirmation before executing.
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.md # Loaded as additional agent instructions
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 # Interactive CLI with streaming display
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 Skills** — Extend aru via the `.agents/` directory
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
- The `aru.json` file in the project root controls which shell commands aru can execute **without asking for confirmation**:
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
- "allow": [
168
- "git *",
169
- "npm *",
170
- "pytest *",
171
- "python *",
172
- "uv run pytest *"
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
- Each entry is a glob pattern. Any command that doesn't match a listed pattern will prompt for confirmation before executing.
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.md # Loaded as additional agent instructions
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 # Interactive CLI with streaming display
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
+ )