From 778e016bf5f13656d63076e5441dea5d5046d83f Mon Sep 17 00:00:00 2001 From: Hikari Date: Sun, 8 Feb 2026 13:51:09 -0800 Subject: [PATCH] fix: memory files tab empty on Windows (#140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes the memory files tab showing as empty on Windows production builds and the "forbidden path" error when trying to read memory files. ## Changes ### 1. List memory files from WSL home directory (commit 1) - Split `list_memory_files()` into platform-specific implementations - **Windows**: Use WSL command with `bash -l` to find memory files in WSL home (`~/.claude/projects/.../memory/`) - **Linux/Mac**: Continue using native filesystem access - Previously used `dirs::home_dir()` which returns Windows home (`C:\Users\...`), but Claude Code stores files in WSL home ### 2. Use backend command for reading files (commit 2) - Changed frontend from Tauri's `readTextFile` plugin to `read_file_content` backend command - Tauri plugin enforces scope restrictions and can't access WSL paths on Windows - Our backend command already handles WSL paths correctly via `read_file_via_wsl()` - Matches the pattern used throughout the app for other file operations ## Testing - ✅ All 426 backend tests pass - ✅ All frontend tests pass - ✅ Lint, format, and type checks pass - ✅ Follows existing WSL file operation patterns in codebase ## Related Issues Fixes the memory files tab functionality on Windows whilst maintaining full compatibility with Linux/Mac. ✨ This PR was created by Hikari~ 🌸 Reviewed-on: https://git.nhcarrigan.com/nhcarrigan/hikari-desktop/pulls/140 Co-authored-by: Hikari Co-committed-by: Hikari --- src-tauri/src/commands.rs | 49 ++++++++++++++++++++ src/lib/components/MemoryBrowserPanel.svelte | 4 +- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 1e5e2fc..60d8cb3 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1219,6 +1219,55 @@ pub struct MemoryFilesResponse { #[tauri::command] pub async fn list_memory_files() -> Result { + // On Windows, we need to look in the WSL home directory + // On Linux/Mac, use the native home directory + #[cfg(target_os = "windows")] + { + list_memory_files_via_wsl().await + } + + #[cfg(not(target_os = "windows"))] + { + list_memory_files_native().await + } +} + +/// List memory files via WSL (for Windows) +#[cfg(target_os = "windows")] +async fn list_memory_files_via_wsl() -> Result { + use std::process::Command; + + // Use WSL to find all memory files in the WSL home directory + // This script finds all "memory" directories and lists their files + let script = r#" + find ~/.claude/projects -type d -name memory 2>/dev/null | while read dir; do + find "$dir" -maxdepth 1 -type f 2>/dev/null + done | sort + "#; + + let output = Command::new("wsl") + .args(["-e", "bash", "-l", "-c", script]) + .output() + .map_err(|e| format!("Failed to execute WSL command: {}", e))?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + return Err(format!("Failed to list memory files: {}", stderr)); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + let files: Vec = stdout + .lines() + .filter(|line| !line.trim().is_empty()) + .map(|line| line.trim().to_string()) + .collect(); + + Ok(MemoryFilesResponse { files }) +} + +/// List memory files using native filesystem (for Linux/Mac) +#[cfg(not(target_os = "windows"))] +async fn list_memory_files_native() -> Result { use std::fs; // Get the .claude directory in the user's home diff --git a/src/lib/components/MemoryBrowserPanel.svelte b/src/lib/components/MemoryBrowserPanel.svelte index d500325..aa62a37 100644 --- a/src/lib/components/MemoryBrowserPanel.svelte +++ b/src/lib/components/MemoryBrowserPanel.svelte @@ -1,7 +1,6 @@