aru-code 0.24.2__tar.gz → 0.25.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 (69) hide show
  1. {aru_code-0.24.2/aru_code.egg-info → aru_code-0.25.0}/PKG-INFO +2 -2
  2. {aru_code-0.24.2 → aru_code-0.25.0}/README.md +1 -1
  3. aru_code-0.25.0/aru/__init__.py +1 -0
  4. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agents/base.py +9 -10
  5. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agents/explorer.py +16 -14
  6. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agents/planner.py +7 -3
  7. {aru_code-0.24.2 → aru_code-0.25.0}/aru/display.py +8 -4
  8. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/codebase.py +564 -191
  9. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/gitignore.py +76 -11
  10. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/ranker.py +83 -16
  11. {aru_code-0.24.2 → aru_code-0.25.0/aru_code.egg-info}/PKG-INFO +2 -2
  12. {aru_code-0.24.2 → aru_code-0.25.0}/pyproject.toml +1 -1
  13. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_codebase.py +68 -101
  14. aru_code-0.24.2/aru/__init__.py +0 -1
  15. {aru_code-0.24.2 → aru_code-0.25.0}/LICENSE +0 -0
  16. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agent_factory.py +0 -0
  17. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agents/__init__.py +0 -0
  18. {aru_code-0.24.2 → aru_code-0.25.0}/aru/agents/executor.py +0 -0
  19. {aru_code-0.24.2 → aru_code-0.25.0}/aru/cache_patch.py +0 -0
  20. {aru_code-0.24.2 → aru_code-0.25.0}/aru/checkpoints.py +0 -0
  21. {aru_code-0.24.2 → aru_code-0.25.0}/aru/cli.py +0 -0
  22. {aru_code-0.24.2 → aru_code-0.25.0}/aru/commands.py +0 -0
  23. {aru_code-0.24.2 → aru_code-0.25.0}/aru/completers.py +0 -0
  24. {aru_code-0.24.2 → aru_code-0.25.0}/aru/config.py +0 -0
  25. {aru_code-0.24.2 → aru_code-0.25.0}/aru/context.py +0 -0
  26. {aru_code-0.24.2 → aru_code-0.25.0}/aru/history_blocks.py +0 -0
  27. {aru_code-0.24.2 → aru_code-0.25.0}/aru/permissions.py +0 -0
  28. {aru_code-0.24.2 → aru_code-0.25.0}/aru/plugins/__init__.py +0 -0
  29. {aru_code-0.24.2 → aru_code-0.25.0}/aru/plugins/custom_tools.py +0 -0
  30. {aru_code-0.24.2 → aru_code-0.25.0}/aru/plugins/hooks.py +0 -0
  31. {aru_code-0.24.2 → aru_code-0.25.0}/aru/plugins/manager.py +0 -0
  32. {aru_code-0.24.2 → aru_code-0.25.0}/aru/plugins/tool_api.py +0 -0
  33. {aru_code-0.24.2 → aru_code-0.25.0}/aru/providers.py +0 -0
  34. {aru_code-0.24.2 → aru_code-0.25.0}/aru/runner.py +0 -0
  35. {aru_code-0.24.2 → aru_code-0.25.0}/aru/runtime.py +0 -0
  36. {aru_code-0.24.2 → aru_code-0.25.0}/aru/session.py +0 -0
  37. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/__init__.py +0 -0
  38. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/ast_tools.py +0 -0
  39. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/mcp_client.py +0 -0
  40. {aru_code-0.24.2 → aru_code-0.25.0}/aru/tools/tasklist.py +0 -0
  41. {aru_code-0.24.2 → aru_code-0.25.0}/aru_code.egg-info/SOURCES.txt +0 -0
  42. {aru_code-0.24.2 → aru_code-0.25.0}/aru_code.egg-info/dependency_links.txt +0 -0
  43. {aru_code-0.24.2 → aru_code-0.25.0}/aru_code.egg-info/entry_points.txt +0 -0
  44. {aru_code-0.24.2 → aru_code-0.25.0}/aru_code.egg-info/requires.txt +0 -0
  45. {aru_code-0.24.2 → aru_code-0.25.0}/aru_code.egg-info/top_level.txt +0 -0
  46. {aru_code-0.24.2 → aru_code-0.25.0}/setup.cfg +0 -0
  47. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_agents_base.py +0 -0
  48. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_checkpoints.py +0 -0
  49. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli.py +0 -0
  50. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_advanced.py +0 -0
  51. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_base.py +0 -0
  52. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_completers.py +0 -0
  53. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_new.py +0 -0
  54. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_run_cli.py +0 -0
  55. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_session.py +0 -0
  56. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_cli_shell.py +0 -0
  57. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_confabulation_regression.py +0 -0
  58. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_config.py +0 -0
  59. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_context.py +0 -0
  60. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_executor.py +0 -0
  61. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_gitignore.py +0 -0
  62. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_guardrails_scenarios.py +0 -0
  63. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_main.py +0 -0
  64. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_mcp_client.py +0 -0
  65. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_permissions.py +0 -0
  66. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_planner.py +0 -0
  67. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_plugins.py +0 -0
  68. {aru_code-0.24.2 → aru_code-0.25.0}/tests/test_providers.py +0 -0
  69. {aru_code-0.24.2 → aru_code-0.25.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.24.2
3
+ Version: 0.25.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
@@ -519,7 +519,7 @@ Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
519
519
 
520
520
  ### File Operations
521
521
  - `read_file` — Reads files with line range support and binary detection
522
- - `read_file_smart` — Answers specific questions about a file without returning raw content
522
+ - `read_files` — Reads multiple files in parallel (single batched call)
523
523
  - `write_file` — Writes content to files, creating directories as needed
524
524
  - `edit_file` — Find-and-replace edits on files
525
525
 
@@ -472,7 +472,7 @@ Aru can load tools from MCP servers. Configure in `.aru/mcp_config.json`:
472
472
 
473
473
  ### File Operations
474
474
  - `read_file` — Reads files with line range support and binary detection
475
- - `read_file_smart` — Answers specific questions about a file without returning raw content
475
+ - `read_files` — Reads multiple files in parallel (single batched call)
476
476
  - `write_file` — Writes content to files, creating directories as needed
477
477
  - `edit_file` — Find-and-replace edits on files
478
478
 
@@ -0,0 +1 @@
1
+ __version__ = "0.25.0"
@@ -66,8 +66,8 @@ Every tool call accumulates its result in your context window. Use the minimum n
66
66
 
67
67
  1. **Find files/patterns** → `grep_search(pattern, file_glob="*.py")` or `glob_search`. \
68
68
  Default shows 10 lines of context — use `context_lines=30` for full function bodies.
69
- 2. **Understand a file** → `read_file_smart(file_path, query)` — returns a concise answer, not raw content
70
- 3. **Need raw content** → `read_file(file_path)` — returns first chunk + outline for large files
69
+ 2. **Need raw content** → `read_file(file_path)` — returns first chunk + outline for large files
70
+ 3. **Need several files at once** → `read_files(paths)` — parallel batch read
71
71
 
72
72
  **Batch independent tool calls**: When you need answers from multiple independent sources, \
73
73
  emit ALL those tool calls in a single response.
@@ -148,10 +148,10 @@ split into subtasks grouped by concern (e.g. "Create model files", "Create route
148
148
 
149
149
  ## Reading strategy — read, edit, test
150
150
 
151
- 1. **Know the file + have a question?** → `read_file_smart(file_path, query)`
152
- 2. **Need a specific pattern?** → `grep_search(pattern, file_glob="*.py")` — default 10 lines context. \
151
+ 1. **Need a specific pattern?** → `grep_search(pattern, file_glob="*.py")` — default 10 lines context. \
153
152
  Use `context_lines=30` for full function bodies.
154
- 3. **Need lines for editing?** → `read_file(file_path, start_line=N, end_line=M)` using line numbers from grep
153
+ 2. **Need lines for editing?** → `read_file(file_path, start_line=N, end_line=M)` using line numbers from grep
154
+ 3. **Need several files at once?** → `read_files(paths)` — parallel batch read
155
155
  4. **Need the whole file?** → `read_file(file_path)` — returns first chunk + outline for large files
156
156
  5. **Need the COMPLETE file (>60KB)?** → `read_file(file_path, max_size=0)` — reads in chunks. Use rarely.
157
157
 
@@ -194,10 +194,9 @@ Skip exploration when the task is clear and the relevant files are obvious.
194
194
 
195
195
  Every tool call accumulates its result in your context window. Use the minimum needed:
196
196
 
197
- 1. **Don't know which file?** → `grep_search` / `glob_search` for patterns, \
198
- `read_file_smart(file_path, query)` when you know the file.
199
- 2. **Know the file + have a question?** → `read_file_smart(file_path, query)`
200
- 3. **Need specific lines?** → `read_file(file_path, start_line=N, end_line=M)`
197
+ 1. **Don't know which file?** → `grep_search` / `glob_search` for patterns.
198
+ 2. **Need specific lines?** → `read_file(file_path, start_line=N, end_line=M)`
199
+ 3. **Need several files at once?** → `read_files(paths)` — parallel batch read.
201
200
  4. **Need the whole file?** → `read_file(file_path)` — returns first chunk + outline for large files.
202
201
 
203
202
  **NEVER read the same file twice.** Check if you already have the content in context.
@@ -218,7 +217,7 @@ For simple, directed lookups (one known file, one specific symbol) use \
218
217
 
219
218
  For **anything broader** — understanding a system, researching before implementing, \
220
219
  analyzing multiple files, writing specs or documentation — **always use explorer agents**. \
221
- Every `read_file` / `read_file_smart` / `grep_search` result you call directly accumulates \
220
+ Every `read_file` / `read_files` / `grep_search` result you call directly accumulates \
222
221
  in YOUR context window and stays there forever. Explorer agents read files in their own \
223
222
  isolated context and return only a concise summary. This is critical: \
224
223
  **3 explorer summaries < 8 raw file reads** in context cost.
@@ -7,24 +7,26 @@ from agno.agent import Agent
7
7
  from aru.providers import create_model
8
8
  from aru.runtime import get_ctx
9
9
  from aru.tools.codebase import (
10
+ _glob_search_tool,
11
+ _grep_search_tool,
12
+ _list_directory_tool,
13
+ _rank_files_tool,
14
+ _read_file_tool,
10
15
  bash,
11
- glob_search,
12
- grep_search,
13
- list_directory,
14
- rank_files,
15
- read_file,
16
- read_file_smart,
16
+ read_files,
17
17
  )
18
18
 
19
- # Read-only tools only — no write/edit/delegate (prevents recursion and mutations)
19
+ # Read-only tools only — no write/edit/delegate (prevents recursion and mutations).
20
+ # All wrappers are async so the Explorer's "multi-parallel tool calls" prompt
21
+ # actually matches runtime behavior — Agno can await them concurrently.
20
22
  EXPLORER_TOOLS = [
21
- read_file,
22
- read_file_smart,
23
- glob_search,
24
- grep_search,
25
- list_directory,
23
+ _read_file_tool,
24
+ read_files,
25
+ _glob_search_tool,
26
+ _grep_search_tool,
27
+ _list_directory_tool,
26
28
  bash,
27
- rank_files,
29
+ _rank_files_tool,
28
30
  ]
29
31
 
30
32
  EXPLORER_ROLE = """\
@@ -52,7 +54,7 @@ Guidelines:
52
54
  - Use glob_search for broad file pattern matching
53
55
  - Use grep_search for searching file contents with regex
54
56
  - Use read_file when you know the specific file path you need to read
55
- - Use read_file_smart when you know the file and have a specific question about it
57
+ - Use read_files (batch) when you need to pull several files at once
56
58
  - Use bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail)
57
59
  - NEVER use bash for: mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install, \
58
60
  or any file creation/modification
@@ -6,7 +6,11 @@ from agno.compression.manager import CompressionManager
6
6
  from aru.agents.base import build_instructions
7
7
  from aru.providers import create_model
8
8
  from aru.tools.codebase import (
9
- glob_search, grep_search, list_directory, read_file, read_file_smart,
9
+ _glob_search_tool,
10
+ _grep_search_tool,
11
+ _list_directory_tool,
12
+ _read_file_tool,
13
+ read_files,
10
14
  )
11
15
  from aru.runtime import get_ctx
12
16
 
@@ -34,8 +38,8 @@ Return ONLY the markdown plan. No explanation, no preamble.\
34
38
 
35
39
  # Planner uses read-only tools only — no write/edit/bash
36
40
  PLANNER_TOOLS = [
37
- read_file, read_file_smart,
38
- glob_search, grep_search, list_directory,
41
+ _read_file_tool, read_files,
42
+ _glob_search_tool, _grep_search_tool, _list_directory_tool,
39
43
  ]
40
44
 
41
45
 
@@ -161,6 +161,10 @@ class StatusBar:
161
161
  self._index = 0
162
162
  self._last_switch = time.monotonic()
163
163
  self._override: str | None = None
164
+ # A single persistent Spinner — Rich's Spinner tracks frames via
165
+ # (time - start_time), so instantiating a new one per render would
166
+ # reset start_time each frame and make the animation look frozen.
167
+ self._spinner = Spinner("dots", text="", style="cyan")
164
168
 
165
169
  @property
166
170
  def current_text(self) -> str:
@@ -187,8 +191,8 @@ class StatusBar:
187
191
 
188
192
  def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
189
193
  self._maybe_rotate()
190
- spinner = Spinner("dots", text=f"[dim]{self.current_text}[/dim]", style="cyan")
191
- yield from spinner.__rich_console__(console, options)
194
+ self._spinner.update(text=Text(self.current_text, style="dim"))
195
+ yield from self._spinner.__rich_console__(console, options)
192
196
 
193
197
  def __rich_measure__(self, console: Console, options: ConsoleOptions) -> Measurement:
194
198
  return Measurement(1, options.max_width)
@@ -196,7 +200,7 @@ class StatusBar:
196
200
 
197
201
  TOOL_DISPLAY_NAMES = {
198
202
  "read_file": "Read",
199
- "read_file_smart": "ReadSmart",
203
+ "read_files": "ReadBatch",
200
204
  "write_file": "Write",
201
205
  "edit_file": "Edit",
202
206
  "glob_search": "Glob",
@@ -209,7 +213,7 @@ TOOL_DISPLAY_NAMES = {
209
213
 
210
214
  TOOL_PRIMARY_ARG = {
211
215
  "read_file": "file_path",
212
- "read_file_smart": "file_path",
216
+ "read_files": "paths",
213
217
  "write_file": "file_path",
214
218
  "edit_file": "file_path",
215
219
  "glob_search": "pattern",