diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs
index 23cc19a..e4268a3 100644
--- a/src-tauri/src/config.rs
+++ b/src-tauri/src/config.rs
@@ -43,6 +43,9 @@ pub struct ClaudeStartOptions {
#[serde(default = "default_enable_claudeai_mcp_servers")]
pub enable_claudeai_mcp_servers: bool,
+
+ #[serde(default)]
+ pub auto_memory_directory: Option,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -186,6 +189,9 @@ pub struct HikariConfig {
#[serde(default = "default_enable_claudeai_mcp_servers")]
pub enable_claudeai_mcp_servers: bool,
+
+ #[serde(default)]
+ pub auto_memory_directory: Option,
}
impl Default for HikariConfig {
@@ -235,6 +241,7 @@ impl Default for HikariConfig {
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: None,
}
}
}
@@ -384,6 +391,7 @@ mod tests {
assert!(!config.disable_cron);
assert!(config.include_git_instructions);
assert!(config.enable_claudeai_mcp_servers);
+ assert!(config.auto_memory_directory.is_none());
}
#[test]
@@ -433,6 +441,7 @@ mod tests {
disable_cron: true,
include_git_instructions: false,
enable_claudeai_mcp_servers: false,
+ auto_memory_directory: Some("/custom/memory".to_string()),
};
let json = serde_json::to_string(&config).unwrap();
@@ -453,6 +462,10 @@ mod tests {
assert!(deserialized.disable_cron);
assert!(!deserialized.include_git_instructions);
assert!(!deserialized.enable_claudeai_mcp_servers);
+ assert_eq!(
+ deserialized.auto_memory_directory,
+ Some("/custom/memory".to_string())
+ );
}
#[test]
diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs
index d423e23..0ea63bc 100644
--- a/src-tauri/src/wsl_bridge.rs
+++ b/src-tauri/src/wsl_bridge.rs
@@ -291,6 +291,13 @@ impl WslBridge {
cmd.arg("--worktree");
}
+ // Pass auto-memory directory via settings if specified
+ if let Some(ref dir) = options.auto_memory_directory {
+ if !dir.is_empty() {
+ cmd.args(["--settings", &format!(r#"{{"autoMemoryDirectory":"{}"}}"#, dir)]);
+ }
+ }
+
cmd.current_dir(working_dir);
// Set API key as environment variable if specified
@@ -434,6 +441,17 @@ impl WslBridge {
claude_cmd.push_str(" --worktree");
}
+ // Pass auto-memory directory via settings if specified
+ if let Some(ref dir) = options.auto_memory_directory {
+ if !dir.is_empty() {
+ let escaped_dir = dir.replace('\'', "'\\''");
+ claude_cmd.push_str(&format!(
+ " --settings '{{\"autoMemoryDirectory\":\"{}\"}}'",
+ escaped_dir
+ ));
+ }
+ }
+
// Use bash -lc to load login profile (ensures PATH includes claude)
cmd.args(["-e", "bash", "-lc", &claude_cmd]);
@@ -3036,4 +3054,25 @@ mod tests {
let result = parse_worktree_hook(line);
assert!(result.is_none());
}
+
+ /// Build the auto-memory settings JSON without executing a command (for testing)
+ #[cfg(test)]
+ fn build_auto_memory_settings_arg(dir: &str) -> String {
+ format!(r#"{{"autoMemoryDirectory":"{}"}}"#, dir)
+ }
+
+ #[test]
+ fn test_e2e_auto_memory_settings_structure() {
+ let settings_json = build_auto_memory_settings_arg("/custom/memory/dir");
+ assert_eq!(
+ settings_json,
+ r#"{"autoMemoryDirectory":"/custom/memory/dir"}"#
+ );
+ }
+
+ #[test]
+ fn test_e2e_auto_memory_settings_empty_path_skipped() {
+ let dir = "";
+ assert!(dir.is_empty(), "Empty directory should be skipped");
+ }
}
diff --git a/src/lib/commands/slashCommands.test.ts b/src/lib/commands/slashCommands.test.ts
index c91d967..eed98ac 100644
--- a/src/lib/commands/slashCommands.test.ts
+++ b/src/lib/commands/slashCommands.test.ts
@@ -67,6 +67,7 @@ vi.mock("$lib/stores/config", () => ({
max_output_tokens: null,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
}),
},
}));
diff --git a/src/lib/commands/slashCommands.ts b/src/lib/commands/slashCommands.ts
index e5cc471..c59cb9b 100644
--- a/src/lib/commands/slashCommands.ts
+++ b/src/lib/commands/slashCommands.ts
@@ -68,6 +68,7 @@ async function changeDirectory(path: string): Promise {
max_output_tokens: config.max_output_tokens ?? null,
include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: config.auto_memory_directory || null,
},
});
@@ -147,6 +148,7 @@ async function startNewConversation(): Promise {
max_output_tokens: config.max_output_tokens ?? null,
include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: config.auto_memory_directory || null,
},
});
diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte
index b939c33..c07528d 100644
--- a/src/lib/components/ConfigSidebar.svelte
+++ b/src/lib/components/ConfigSidebar.svelte
@@ -61,6 +61,7 @@
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
@@ -602,6 +603,25 @@
being cut off mid-reply
+
+
+
+
+
+
+ Custom directory for auto-memory storage. Passed via
+ --settings autoMemoryDirectory. Leave blank to use the
+ default (working directory).
+
+
diff --git a/src/lib/components/InputBar.svelte b/src/lib/components/InputBar.svelte
index ab79a3a..221a189 100644
--- a/src/lib/components/InputBar.svelte
+++ b/src/lib/components/InputBar.svelte
@@ -404,6 +404,7 @@ User: ${formattedMessage}`;
disable_1m_context: config.disable_1m_context ?? false,
include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: config.auto_memory_directory || null,
},
});
diff --git a/src/lib/components/PermissionModal.svelte b/src/lib/components/PermissionModal.svelte
index c40bf90..ce240d0 100644
--- a/src/lib/components/PermissionModal.svelte
+++ b/src/lib/components/PermissionModal.svelte
@@ -91,6 +91,7 @@
disable_1m_context: config.disable_1m_context ?? false,
include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: config.auto_memory_directory || null,
},
});
diff --git a/src/lib/components/StatusBar.svelte b/src/lib/components/StatusBar.svelte
index fe96c34..9c0d8fb 100644
--- a/src/lib/components/StatusBar.svelte
+++ b/src/lib/components/StatusBar.svelte
@@ -91,6 +91,7 @@
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
});
let streamerModeActive = $state(false);
@@ -173,6 +174,7 @@
max_output_tokens: currentConfig.max_output_tokens ?? null,
include_git_instructions: currentConfig.include_git_instructions ?? true,
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: currentConfig.auto_memory_directory || null,
},
});
@@ -332,6 +334,7 @@
max_output_tokens: currentConfig.max_output_tokens ?? null,
include_git_instructions: currentConfig.include_git_instructions ?? true,
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: currentConfig.auto_memory_directory || null,
},
});
diff --git a/src/lib/components/TaskLoopPanel.svelte b/src/lib/components/TaskLoopPanel.svelte
index 5a1b0a0..c5ab836 100644
--- a/src/lib/components/TaskLoopPanel.svelte
+++ b/src/lib/components/TaskLoopPanel.svelte
@@ -220,6 +220,7 @@
max_output_tokens: cfg.max_output_tokens ?? null,
include_git_instructions: cfg.include_git_instructions ?? true,
enable_claudeai_mcp_servers: cfg.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: cfg.auto_memory_directory || null,
},
});
} catch (error) {
diff --git a/src/lib/components/UserQuestionModal.svelte b/src/lib/components/UserQuestionModal.svelte
index 833d702..96dc7f1 100644
--- a/src/lib/components/UserQuestionModal.svelte
+++ b/src/lib/components/UserQuestionModal.svelte
@@ -110,6 +110,7 @@
disable_1m_context: config.disable_1m_context ?? false,
include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
+ auto_memory_directory: config.auto_memory_directory || null,
},
});
diff --git a/src/lib/stores/config.test.ts b/src/lib/stores/config.test.ts
index 9dad7b4..3cf9ccb 100644
--- a/src/lib/stores/config.test.ts
+++ b/src/lib/stores/config.test.ts
@@ -223,6 +223,7 @@ describe("config store", () => {
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
};
expect(config.model).toBe("claude-sonnet-4");
@@ -285,6 +286,7 @@ describe("config store", () => {
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
};
expect(config.model).toBeNull();
@@ -902,6 +904,7 @@ describe("config store", () => {
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
};
const mockInvokeImpl = vi.mocked(invoke);
diff --git a/src/lib/stores/config.ts b/src/lib/stores/config.ts
index be203eb..6d2b102 100644
--- a/src/lib/stores/config.ts
+++ b/src/lib/stores/config.ts
@@ -87,6 +87,8 @@ export interface HikariConfig {
include_git_instructions: boolean;
// Claude.ai MCP servers setting
enable_claudeai_mcp_servers: boolean;
+ // Auto-memory directory
+ auto_memory_directory: string | null;
}
const defaultConfig: HikariConfig = {
@@ -143,6 +145,7 @@ const defaultConfig: HikariConfig = {
disable_cron: false,
include_git_instructions: true,
enable_claudeai_mcp_servers: true,
+ auto_memory_directory: null,
};
function createConfigStore() {
diff --git a/vitest.setup.ts b/vitest.setup.ts
index 5090215..204b9ac 100644
--- a/vitest.setup.ts
+++ b/vitest.setup.ts
@@ -49,6 +49,7 @@ vi.mock("@tauri-apps/api/core", () => ({
profile_avatar_path: null,
profile_bio: null,
custom_theme_colors: {},
+ auto_memory_directory: null,
});
case "list_quick_actions":
return Promise.resolve([]);