codetether_agent/telemetry/tools/file_change.rs
1//! Per-tool filesystem operation records.
2//!
3//! A [`FileChange`] is attached to a [`super::ToolExecution`] so that
4//! downstream consumers (audit log, TUI, persistent stats) can reconstruct
5//! exactly which files each tool invocation touched and how.
6
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10/// A single filesystem operation performed by a tool.
11///
12/// The `operation` field is a free-form string (`"read"`, `"create"`,
13/// `"modify"`, …) chosen by the emitting tool. Use the helper constructors
14/// below rather than building the struct by hand.
15///
16/// # Examples
17///
18/// ```rust
19/// use codetether_agent::telemetry::FileChange;
20///
21/// let r = FileChange::read("src/main.rs", Some((1, 20)));
22/// assert_eq!(r.operation, "read");
23/// assert!(r.summary().contains("src/main.rs"));
24///
25/// let c = FileChange::create("new.txt", "hello");
26/// assert_eq!(c.size_bytes, Some(5));
27/// ```
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct FileChange {
30 /// Filesystem path the tool touched.
31 pub path: String,
32 /// Operation name (`"read"` / `"create"` / `"modify"` / …).
33 pub operation: String,
34 /// When the operation happened.
35 pub timestamp: DateTime<Utc>,
36 /// Post-operation size in bytes, when known.
37 pub size_bytes: Option<u64>,
38 /// `(start_line, end_line)` the operation applied to, when known.
39 pub line_range: Option<(u32, u32)>,
40 /// Unified-diff or free-form diff text, when available.
41 pub diff: Option<String>,
42}
43
44mod file_change_ctors;
45
46impl FileChange {
47 /// One-line `"path (op)"` summary suitable for logs and the TUI.
48 pub fn summary(&self) -> String {
49 format!("{} ({})", self.path, self.operation)
50 }
51}