swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-03-25 20:20:06 -0400
committermain <main@swarm.moe>2026-03-25 20:20:06 -0400
commit2bb470f0b28b75863809f127b7f12222db07496c (patch)
tree3c6f7a1917bcd80edfafba8fd1acf00141de725d /crates
parent0dda9748e55bcffe6194c4b1d15f10c7753e8b29 (diff)
downloadphone_opus-2bb470f0b28b75863809f127b7f12222db07496c.zip
Bypass current_dir for absolute consult cwd
Diffstat (limited to 'crates')
-rw-r--r--crates/phone-opus/src/mcp/service.rs65
1 files changed, 57 insertions, 8 deletions
diff --git a/crates/phone-opus/src/mcp/service.rs b/crates/phone-opus/src/mcp/service.rs
index 4a65e6d..051ff83 100644
--- a/crates/phone-opus/src/mcp/service.rs
+++ b/crates/phone-opus/src/mcp/service.rs
@@ -250,14 +250,39 @@ struct WorkingDirectory(PathBuf);
impl WorkingDirectory {
fn resolve(raw: Option<String>) -> Result<Self, ConsultRequestError> {
- let base =
- std::env::current_dir().map_err(|source| ConsultRequestError::CurrentDir { source })?;
- let requested = raw.map_or_else(|| base.clone(), PathBuf::from);
- let candidate = if requested.is_absolute() {
- requested
- } else {
- base.join(requested)
- };
+ let requested = raw.map(PathBuf::from);
+ let base = requested
+ .as_ref()
+ .is_none_or(|path| !path.is_absolute())
+ .then(|| {
+ std::env::current_dir().map_err(|source| ConsultRequestError::CurrentDir { source })
+ })
+ .transpose()?;
+ let candidate = Self::resolve_candidate(base.as_deref(), requested)?;
+ Self::canonicalize_directory(candidate)
+ }
+
+ fn resolve_candidate(
+ base: Option<&Path>,
+ requested: Option<PathBuf>,
+ ) -> Result<PathBuf, ConsultRequestError> {
+ match requested {
+ Some(path) if path.is_absolute() => Ok(path),
+ Some(path) => Ok(Self::require_base(base)?.join(path)),
+ None => Ok(Self::require_base(base)?.to_path_buf()),
+ }
+ }
+
+ fn require_base(base: Option<&Path>) -> Result<&Path, ConsultRequestError> {
+ base.ok_or_else(|| ConsultRequestError::CurrentDir {
+ source: io::Error::new(
+ io::ErrorKind::NotFound,
+ "current working directory is unavailable",
+ ),
+ })
+ }
+
+ fn canonicalize_directory(candidate: PathBuf) -> Result<Self, ConsultRequestError> {
let canonical =
candidate
.canonicalize()
@@ -2252,3 +2277,27 @@ fn generation_from_wire(raw: u64) -> Generation {
}
generation
}
+
+#[cfg(test)]
+mod tests {
+ use super::WorkingDirectory;
+ use std::path::{Path, PathBuf};
+
+ #[test]
+ fn absolute_working_directory_resolution_bypasses_base() {
+ let absolute = PathBuf::from("/tmp");
+ let nonexistent = Path::new("/definitely/not/a/real/base");
+ let resolved =
+ WorkingDirectory::resolve_candidate(Some(nonexistent), Some(absolute.clone())).unwrap();
+ assert_eq!(resolved, absolute);
+ }
+
+ #[test]
+ fn relative_working_directory_resolution_uses_base() {
+ let base = Path::new("/tmp");
+ let resolved =
+ WorkingDirectory::resolve_candidate(Some(base), Some(PathBuf::from("phone_opus")))
+ .unwrap();
+ assert_eq!(resolved, PathBuf::from("/tmp/phone_opus"));
+ }
+}