1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
//! Built-in tools for the AI coding agent.
//!
//! This module provides a comprehensive suite of file manipulation and system execution tools
//! that enable the AI agent to interact with the filesystem and execute commands.
//!
//! # Available Tools
//!
//! ## File Reading & Writing
//!
//! - **ReadTool** (`read`) - Read file contents with optional line range filtering
//! - **WriteTool** (`write`) - Write content to files with diff display for existing files
//! - **EditTool** (`edit`) - Surgical file editing with exact text replacement and ambiguity detection
//!
//! ## File Discovery
//!
//! - **FindTool** (`find`) - Find files by name pattern using glob syntax (*, ?, \\[abc\\])
//! - **GrepTool** (`grep`) - Search file contents using regex patterns
//! - **LsTool** (`ls`) - List directory contents with metadata (size, type)
//!
//! ## System Operations
//!
//! - **BashTool** (`bash`) - Execute shell commands in a controlled environment
//!
//! ## Web
//!
//! - **WebSearchTool** (`web_search`) - Search the web via DuckDuckGo (no API key required)
//!
//! # Usage
//!
//! All tools follow the same pattern:
//! 1. Create a tool instance with a working directory
//! 2. Execute with JSON input (validated via schema)
//! 3. Receive result as a string or error
//!
//! ## Using Individual Tools
//!
//! ```rust
//! use saorsa_agent::{ReadTool, Tool};
//! use std::env;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let read_tool = ReadTool::new(env::current_dir()?);
//!
//! let result = read_tool.execute(serde_json::json!({
//! "file_path": "Cargo.toml",
//! "line_range": "1-10"
//! })).await?;
//!
//! println!("First 10 lines:\n{}", result);
//! # Ok(())
//! # }
//! ```
//!
//! ## Using the Tool Registry
//!
//! The recommended approach is to use the `default_tools()` function which creates
//! a ToolRegistry with all built-in tools:
//!
//! ```rust
//! use saorsa_agent::{default_tools, Tool};
//! use std::env;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let tools = default_tools(env::current_dir()?);
//!
//! // Access tools by name
//! let read_tool = tools.get("read").unwrap();
//! let result = read_tool.execute(serde_json::json!({
//! "file_path": "README.md"
//! })).await?;
//! # Ok(())
//! # }
//! ```
//!
//! # Tool Details
//!
//! ## ReadTool
//!
//! Read file contents, optionally limiting to specific line ranges.
//!
//! **Input:**
//! - `file_path` (required): Path to file
//! - `line_range` (optional): Line range like "10-20", "5-", or "-10"
//!
//! **Example:**
//! ```json
//! {
//! "file_path": "/path/to/file.txt",
//! "line_range": "10-20"
//! }
//! ```
//!
//! ## WriteTool
//!
//! Write content to files, creating parent directories if needed. Shows diff for existing files.
//!
//! **Input:**
//! - `file_path` (required): Path to file
//! - `content` (required): Content to write
//!
//! **Example:**
//! ```json
//! {
//! "file_path": "/path/to/file.txt",
//! "content": "New file content"
//! }
//! ```
//!
//! ## EditTool
//!
//! Surgically edit files by replacing exact text matches. Detects ambiguity if multiple
//! matches found without `replace_all` flag.
//!
//! **Input:**
//! - `file_path` (required): Path to file
//! - `old_text` (required): Exact text to replace
//! - `new_text` (required): Replacement text
//! - `replace_all` (optional): Replace all occurrences (default: false)
//!
//! **Example:**
//! ```json
//! {
//! "file_path": "/path/to/file.txt",
//! "old_text": "old content",
//! "new_text": "new content"
//! }
//! ```
//!
//! ## GrepTool
//!
//! Search file contents using regex patterns. Searches recursively if path is a directory.
//!
//! **Input:**
//! - `pattern` (required): Regex pattern
//! - `path` (required): File or directory to search
//! - `case_insensitive` (optional): Case-insensitive search (default: false)
//!
//! **Example:**
//! ```json
//! {
//! "pattern": "TODO|FIXME",
//! "path": "/path/to/project",
//! "case_insensitive": true
//! }
//! ```
//!
//! ## FindTool
//!
//! Find files by name pattern using glob syntax. Searches recursively.
//!
//! **Input:**
//! - `pattern` (required): Glob pattern (*, ?, \\[abc\\])
//! - `path` (optional): Directory to search (default: working directory)
//!
//! **Example:**
//! ```json
//! {
//! "pattern": "*.rs",
//! "path": "/path/to/project"
//! }
//! ```
//!
//! ## LsTool
//!
//! List directory contents with metadata (size, type).
//!
//! **Input:**
//! - `path` (optional): Directory to list (default: working directory)
//! - `recursive` (optional): Recursive listing (default: false)
//!
//! **Example:**
//! ```json
//! {
//! "path": "/path/to/directory",
//! "recursive": true
//! }
//! ```
//!
//! ## BashTool
//!
//! Execute shell commands with timeout and output capture.
//!
//! **Input:**
//! - `command` (required): Shell command to execute
//!
//! **Example:**
//! ```json
//! {
//! "command": "ls -la"
//! }
//! ```
//!
//! ## WebSearchTool
//!
//! Search the web using DuckDuckGo. No API key required.
//!
//! **Input:**
//! - `query` (required): Search query string
//! - `max_results` (optional): Maximum number of results (default: 5, max: 20)
//!
//! **Example:**
//! ```json
//! {
//! "query": "Rust async programming",
//! "max_results": 3
//! }
//! ```
//!
//! # Error Handling
//!
//! All tools return `Result<String, SaorsaAgentError>`. Common errors include:
//! - **File not found** - Path doesn't exist
//! - **Permission denied** - Insufficient permissions
//! - **Invalid input** - JSON schema validation failed
//! - **Pattern error** - Invalid regex or glob pattern
//! - **Ambiguity** - Multiple matches in EditTool without `replace_all`
//!
//! # Security
//!
//! - File operations use the working directory as the security boundary
//! - Commands execute in a sandboxed environment with timeout limits
//! - Output is limited to prevent memory exhaustion
//! - All tool executions are logged for auditability
pub use BashTool;
pub use EditTool;
pub use FindTool;
pub use GrepTool;
pub use LsTool;
pub use ReadTool;
pub use WebSearchTool;
pub use WriteTool;
use ;
use ;
/// Resolve a file path relative to a working directory.
///
/// Returns the path as-is if absolute, otherwise joins it with the working directory.
pub
/// Generate a unified diff between old and new content.
///
/// The `label` parameter is appended to the `+++` header (e.g., "new", "edited").
pub