sgr_agent_core/backend.rs
1//! FileBackend trait — the abstraction over filesystem operations.
2//!
3//! Implement this for your runtime:
4//! - `PcmClient` (BitGN Connect-RPC) for PAC1 agents
5//! - `LocalFs` (std::fs) for CLI tools
6//! - `MockFs` (HashMap) for tests
7
8use anyhow::Result;
9
10/// Filesystem backend that tools delegate to.
11///
12/// All paths are workspace-relative (e.g. "contacts/john.md", not absolute).
13/// Implementations handle the actual I/O (RPC, local fs, in-memory mock).
14#[async_trait::async_trait]
15pub trait FileBackend: Send + Sync {
16 /// Read file contents, optionally with line numbers and range.
17 ///
18 /// - `number`: if true, prefix each line with its 1-indexed number (like `cat -n`)
19 /// - `start_line`/`end_line`: 1-indexed range (0 = no limit)
20 async fn read(
21 &self,
22 path: &str,
23 number: bool,
24 start_line: i32,
25 end_line: i32,
26 ) -> Result<String>;
27
28 /// Write content to a file, optionally replacing a line range.
29 ///
30 /// - `start_line`/`end_line`: 1-indexed range to replace (0 = overwrite entire file)
31 async fn write(&self, path: &str, content: &str, start_line: i32, end_line: i32) -> Result<()>;
32
33 /// Delete a file.
34 async fn delete(&self, path: &str) -> Result<()>;
35
36 /// Search file contents with regex pattern.
37 ///
38 /// Returns grep-style output: `path:line_number:content`
39 async fn search(&self, root: &str, pattern: &str, limit: i32) -> Result<String>;
40
41 /// List directory entries.
42 ///
43 /// Returns one entry per line, directories suffixed with `/`.
44 async fn list(&self, path: &str) -> Result<String>;
45
46 /// Show recursive directory tree.
47 ///
48 /// - `level`: max depth (0 = unlimited)
49 async fn tree(&self, root: &str, level: i32) -> Result<String>;
50
51 /// Get workspace context (date, time, environment info).
52 async fn context(&self) -> Result<String>;
53
54 /// Create a directory.
55 async fn mkdir(&self, path: &str) -> Result<()>;
56
57 /// Move or rename a file.
58 async fn move_file(&self, from: &str, to: &str) -> Result<()>;
59
60 /// Find files by name pattern.
61 ///
62 /// - `file_type`: "files", "dirs", or empty for all
63 /// - `limit`: max results (0 = no limit)
64 async fn find(&self, root: &str, name: &str, file_type: &str, limit: i32) -> Result<String>;
65}