generated from nhcarrigan/template
fix: work on paths
This commit is contained in:
+29
-16
@@ -8,6 +8,7 @@ use crate::bridge_manager::SharedBridgeManager;
|
||||
use crate::config::{ClaudeStartOptions, HikariConfig};
|
||||
use crate::stats::UsageStats;
|
||||
use crate::temp_manager::SharedTempFileManager;
|
||||
use crate::utils::normalize_path_separators;
|
||||
|
||||
const CONFIG_STORE_KEY: &str = "config";
|
||||
|
||||
@@ -126,7 +127,7 @@ pub async fn validate_directory(
|
||||
|
||||
// Expand ~ to home directory
|
||||
let expanded_path = if path.starts_with("~") {
|
||||
if let Some(home) = std::env::var_os("HOME") {
|
||||
if let Some(home) = std::env::var_os("HOME").or_else(|| std::env::var_os("USERPROFILE")) {
|
||||
let home_path = Path::new(&home);
|
||||
if path == Path::new("~") {
|
||||
home_path.to_path_buf()
|
||||
@@ -165,14 +166,7 @@ pub async fn validate_directory(
|
||||
// Return the canonicalized (absolute) path with forward slashes
|
||||
expanded_path
|
||||
.canonicalize()
|
||||
.map(|p| {
|
||||
// Convert to string and normalize path separators to forward slashes
|
||||
let path_str = p.to_string_lossy().to_string();
|
||||
// On Windows, replace backslashes with forward slashes
|
||||
#[cfg(target_os = "windows")]
|
||||
let path_str = path_str.replace('\\', "/");
|
||||
path_str
|
||||
})
|
||||
.map(|p| normalize_path_separators(&p.to_string_lossy()))
|
||||
.map_err(|e| format!("Failed to resolve path: {}", e))
|
||||
}
|
||||
|
||||
@@ -212,9 +206,10 @@ pub async fn list_skills() -> Result<Vec<String>, String> {
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
// Get the home directory
|
||||
let home =
|
||||
std::env::var_os("HOME").ok_or_else(|| "Could not determine home directory".to_string())?;
|
||||
// Get the home directory - use HOME on Unix, USERPROFILE on Windows
|
||||
let home = std::env::var_os("HOME")
|
||||
.or_else(|| std::env::var_os("USERPROFILE"))
|
||||
.ok_or_else(|| "Could not determine home directory".to_string())?;
|
||||
|
||||
let skills_dir = Path::new(&home).join(".claude").join("skills");
|
||||
|
||||
@@ -444,10 +439,7 @@ pub async fn list_directory(path: String) -> Result<Vec<FileEntry>, String> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let path_str = path.to_string_lossy().to_string();
|
||||
// On Windows, replace backslashes with forward slashes
|
||||
#[cfg(target_os = "windows")]
|
||||
let path_str = path_str.replace('\\', "/");
|
||||
let path_str = normalize_path_separators(&path.to_string_lossy());
|
||||
|
||||
file_entries.push(FileEntry {
|
||||
name,
|
||||
@@ -826,4 +818,25 @@ mod tests {
|
||||
assert!(json.contains("/tmp/test.txt"));
|
||||
assert!(json.contains("test.txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_directory_normalizes_backslashes() {
|
||||
// This test ensures that paths with backslashes are normalized
|
||||
// Create a temp directory for testing
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
|
||||
// On Windows, the canonicalized path will have backslashes
|
||||
// Our normalize_path_separators should convert them to forward slashes
|
||||
let result = run_async(validate_directory(
|
||||
temp_dir.path().to_string_lossy().to_string(),
|
||||
None,
|
||||
));
|
||||
|
||||
assert!(result.is_ok());
|
||||
let normalized_path = result.unwrap();
|
||||
|
||||
// The result should never contain backslashes
|
||||
assert!(!normalized_path.contains('\\'),
|
||||
"Path should not contain backslashes: {}", normalized_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ mod stats;
|
||||
mod temp_manager;
|
||||
mod tray;
|
||||
mod types;
|
||||
mod utils;
|
||||
mod vbs_notification;
|
||||
mod windows_toast;
|
||||
mod wsl_bridge;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/// Utility functions for cross-platform compatibility
|
||||
|
||||
/// Normalize path separators to forward slashes for consistent handling across platforms
|
||||
/// This always normalizes backslashes to forward slashes, regardless of platform,
|
||||
/// because Windows paths may be passed to WSL which expects Unix-style paths
|
||||
pub fn normalize_path_separators(path: &str) -> String {
|
||||
path.replace('\\', "/")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "windows")]
|
||||
fn test_normalize_path_windows() {
|
||||
assert_eq!(normalize_path_separators("C:\\Users\\test"), "C:/Users/test");
|
||||
assert_eq!(normalize_path_separators("path\\to\\file"), "path/to/file");
|
||||
assert_eq!(normalize_path_separators("already/forward"), "already/forward");
|
||||
assert_eq!(normalize_path_separators("mixed\\path/file"), "mixed/path/file");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn test_normalize_path_unix() {
|
||||
assert_eq!(normalize_path_separators("/home/user"), "/home/user");
|
||||
assert_eq!(normalize_path_separators("path/to/file"), "path/to/file");
|
||||
// Even on Unix, we normalize backslashes since paths may come from Windows
|
||||
assert_eq!(normalize_path_separators("weird\\path"), "weird/path");
|
||||
assert_eq!(normalize_path_separators("/home/user\\file"), "/home/user/file");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_normalize_wsl_paths() {
|
||||
// Test the exact issue that was happening
|
||||
assert_eq!(
|
||||
normalize_path_separators("/home/naomi/code/naomi/portfolio\\.."),
|
||||
"/home/naomi/code/naomi/portfolio/.."
|
||||
);
|
||||
|
||||
// Test mixed separators in WSL paths
|
||||
assert_eq!(
|
||||
normalize_path_separators("/mnt/c\\Users\\naomi\\Documents"),
|
||||
"/mnt/c/Users/naomi/Documents"
|
||||
);
|
||||
|
||||
// Test Windows paths that might be passed to WSL
|
||||
assert_eq!(
|
||||
normalize_path_separators("C:\\Users\\naomi\\.claude\\skills"),
|
||||
"C:/Users/naomi/.claude/skills"
|
||||
);
|
||||
|
||||
// Test that forward slashes remain unchanged
|
||||
assert_eq!(
|
||||
normalize_path_separators("/home/naomi/.claude/skills"),
|
||||
"/home/naomi/.claude/skills"
|
||||
);
|
||||
|
||||
// Test empty string
|
||||
assert_eq!(normalize_path_separators(""), "");
|
||||
|
||||
// Test single backslash
|
||||
assert_eq!(normalize_path_separators("\\"), "/");
|
||||
|
||||
// Test multiple consecutive backslashes
|
||||
assert_eq!(
|
||||
normalize_path_separators("path\\\\to\\\\file"),
|
||||
"path//to//file"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use crate::types::{
|
||||
PermissionPromptEvent, QuestionOption, SessionEvent, StateChangeEvent, UserQuestionEvent,
|
||||
WorkingDirectoryEvent,
|
||||
};
|
||||
use crate::utils::normalize_path_separators;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
const SEARCH_TOOLS: [&str; 5] = ["Read", "Glob", "Grep", "WebSearch", "WebFetch"];
|
||||
@@ -137,11 +138,7 @@ impl WslBridge {
|
||||
|
||||
let working_dir = &options.working_dir;
|
||||
// Normalize path separators to forward slashes
|
||||
#[cfg(target_os = "windows")]
|
||||
let normalized_dir = working_dir.replace('\\', "/");
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let normalized_dir = working_dir.clone();
|
||||
self.working_directory = normalized_dir;
|
||||
self.working_directory = normalize_path_separators(working_dir);
|
||||
|
||||
emit_connection_status(
|
||||
&app,
|
||||
|
||||
Reference in New Issue
Block a user