Return fingerprints for dirty files and explicitly requested prior candidates. The protocol version also lets plugins refuse an older, unscoped CLI.
(root: &Path, extra: &[String])
| 82 | /// Return fingerprints for dirty files and explicitly requested prior candidates. |
| 83 | /// The protocol version also lets plugins refuse an older, unscoped CLI. |
| 84 | pub fn snapshot(root: &Path, extra: &[String]) -> Result<serde_json::Value, String> { |
| 85 | let repo = Repository::open_readonly_wait(root, std::time::Duration::from_secs(10)) |
| 86 | .map_err(|e| e.to_string())?; |
| 87 | let status = repo |
| 88 | .status(StatusOptions::default().with_untracked(true)) |
| 89 | .map_err(|e| e.to_string())?; |
| 90 | let dirty: Vec<String> = status |
| 91 | .entries() |
| 92 | .iter() |
| 93 | .map(|e| e.path().to_string_lossy().to_string()) |
| 94 | .collect(); |
| 95 | let mut files = FileManifest::new(); |
| 96 | for path in status |
| 97 | .entries() |
| 98 | .iter() |
| 99 | .map(|e| e.path().to_string_lossy().to_string()) |
| 100 | .chain(extra.iter().cloned()) |
| 101 | { |
| 102 | if root.join(&path).is_dir() && !root.join(&path).is_symlink() { |
| 103 | continue; |
| 104 | } |
| 105 | files.insert(path.clone(), fingerprint(root, &path)?); |
| 106 | } |
| 107 | Ok( |
| 108 | serde_json::json!({"scope_version":1, "view":repo.current_view(), "files":files, "dirty":dirty}), |
| 109 | ) |
| 110 | } |
| 111 | |
| 112 | pub(super) fn manifest(options: &TurnRecordOptions<'_>) -> AgentResult<Option<FileManifest>> { |
| 113 | let raw = options |