# RepoTool - Read-only Repository Access ## Overview RepoTool provides read-only access to the DAARION repository filesystem for agents (primarily Sofiia). It allows viewing code, configs, and searching through the codebase without any write or execute capabilities. ## Integration ### Tool Definition RepoTool is registered in `services/router/tool_manager.py` under `TOOL_DEFINITIONS`: ```python { "type": "function", "function": { "name": "repo_tool", "description": "📂 Read-only доступ до файловї системи репозиторію...", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": ["tree", "read", "search", "metadata"] }, "path": {"type": "string"}, "start_line": {"type": "integer"}, "end_line": {"type": "integer"}, "depth": {"type": "integer"}, "glob": {"type": "string"}, "query": {"type": "string"}, "limit": {"type": "integer"}, "max_bytes": {"type": "integer"} }, "required": ["action"] } } } ``` ### RBAC Configuration Added to `services/router/agent_tools_config.py` in `FULL_STANDARD_STACK` - available to all agents. ## Actions ### 1. tree - Directory Structure Show directory tree starting from a path. **Parameters:** - `path`: Starting path (default: ".") - `depth`: Maximum depth (default: 3, max: 10) - `glob`: Optional glob pattern to filter files **Example:** ```json { "action": "tree", "path": "services", "depth": 2 } ``` **Response:** ```json { "success": true, "result": { "tree": { "router": {"main.py": "[file]", "tool_manager.py": "[file]"}, "gateway": {"main.py": "[file]"} }, "path": "services" } } ``` ### 2. read - File Content Read file contents with optional line limits. **Parameters:** - `path`: File path (required) - `start_line`: Starting line (default: 1) - `end_line`: Ending line (optional) - `max_bytes`: Max bytes to read (default: 200KB, max: 1MB) **Example:** ```json { "action": "read", "path": "services/router/main.py", "start_line": 1, "end_line": 50 } ``` **Response:** ```json { "success": true, "result": { "path": "services/router/main.py", "content": "import asyncio\n...", "lines": 50, "start_line": 1, "end_line": 50 } } ``` ### 3. search - Text Search Search for text in files using grep. **Parameters:** - `query`: Search query (required) - `path`: Starting path (default: ".") - `glob`: File pattern (e.g., "**/*.py") - `limit`: Max results (default: 50, max: 200) **Example:** ```json { "action": "search", "query": "async def", "path": "services", "glob": "**/*.py", "limit": 20 } ``` **Response:** ```json { "success": true, "result": { "query": "async def", "path": "services", "matches": [ {"file": "router/main.py", "line": "45", "content": "async def handle_request"}, {"file": "router/main.py", "line": "102", "content": "async def process_message"} ], "count": 2 } } ``` ### 4. metadata - Git Information Get git repository metadata. **Parameters:** - `path`: Path within repo (optional) **Example:** ```json { "action": "metadata", "path": "." } ``` **Response:** ```json { "success": true, "result": { "path": ".", "repo_root": "/path/to/repo", "commit": "abc123def456", "branch": "main", "dirty": false } } ``` ## Security Features ### Path Traversal Protection - Blocks `..` in paths - Rejects absolute paths outside repo root - Validates resolved path stays within repo root ### Symlink Escape Prevention - Uses `os.path.realpath()` to resolve symlinks - Ensures resolved path is still within repo root - Blocks access through symlinks to external locations ### Secret Masking Files and content containing secrets are automatically masked: **Masked file patterns:** - `.env`, `.env.local`, `.env.production` - `*secrets*`, `*credentials*`, `*keys*`, `*tokens*`, `*passwords*` **Masked content patterns:** ``` api_key = xxx → api_key = *** token = xxx → token = *** password = xxx → password = *** SECRET_KEY=xxx → SECRET_KEY=*** Bearer xxx → Bearer *** -----BEGIN PRIVATE KEY----- → [MASKED] ``` ### Limits | Limit | Default | Max | |-------|---------|-----| | Tree depth | 3 | 10 | | Search results | 50 | 200 | | File size | 200KB | 1MB | | Lines per read | 1000 | - | | Search timeout | - | 10s | ## Example Usage ### Sofiia Commands ``` "Покажи структуру папки services" "Прочитай файл services/router/main.py перші 50 рядків" "Знайди всі файли з 'async def' в папці services" "Який останній коміт?" ``` ## Error Responses ```json { "success": false, "result": null, "error": "Path traversal detected. Access denied." } ``` ```json { "success": false, "result": null, "error": "File too large: 500000 bytes (max: 204800)" } ``` ## Testing Run tests: ```bash cd /path/to/repo pytest tools/repo_tool/tests/test_repo_tool.py -v ``` Test coverage: - Path traversal blocked - Symlink escape blocked - Absolute path blocked - Tree action works - Read action works with line limits - Search finds content - Metadata returns git info - Secret files (.env) masked - Inline secrets masked - Size limits enforced - Depth limits enforced