fix: open memory browser panel for /memory command and default agent type to general-purpose
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m14s
CI / Lint & Test (pull_request) Successful in 17m8s
CI / Build Linux (pull_request) Successful in 24m24s
CI / Build Windows (cross-compile) (pull_request) Successful in 35m25s

This commit is contained in:
2026-03-13 00:57:38 -07:00
committed by Naomi Carrigan
parent 5c16037f8b
commit 8af898c92a
6 changed files with 97 additions and 11 deletions
+17
View File
@@ -878,6 +878,23 @@ describe("slashCommands", () => {
});
});
describe("/memory execute", () => {
it("opens the memory browser panel without requiring an active conversation", () => {
getMock.mockReturnValue(null);
const memoryCmd = slashCommands.find((cmd) => cmd.name === "memory")!;
memoryCmd.execute("");
expect(claudeStore.addLine).not.toHaveBeenCalled();
expect(invokeMock).not.toHaveBeenCalledWith("send_prompt", expect.anything());
});
it("does not send a prompt to Claude when executed", () => {
getMock.mockReturnValue("conv-123");
const memoryCmd = slashCommands.find((cmd) => cmd.name === "memory")!;
memoryCmd.execute("");
expect(invokeMock).not.toHaveBeenCalledWith("send_prompt", expect.anything());
});
});
describe("/context execute", () => {
it("shows error when no active conversation", async () => {
getMock.mockReturnValue(null);
+4 -8
View File
@@ -6,6 +6,7 @@ import { setSkipNextGreeting, updateDiscordRpc } from "$lib/tauri";
import { searchState } from "$lib/stores/search";
import { conversationsStore } from "$lib/stores/conversations";
import { configStore } from "$lib/stores/config";
import { memoryBrowserStore } from "$lib/stores/memoryBrowser";
export interface SlashCommand {
name: string;
@@ -287,16 +288,11 @@ export const slashCommands: SlashCommand[] = [
},
{
name: "memory",
description: "View and manage auto-memory (Claude Code built-in)",
description: "Open the memory browser panel to view and manage memory files",
usage: "/memory",
source: "cli",
execute: async () => {
const conversationId = get(claudeStore.activeConversationId);
if (!conversationId) {
claudeStore.addLine("error", "No active conversation");
return;
}
await invoke("send_prompt", { conversationId, message: "/memory" });
execute: () => {
memoryBrowserStore.open();
},
},
{
+6 -2
View File
@@ -6,6 +6,7 @@
import { editorStore } from "$lib/stores/editor";
import { configStore } from "$lib/stores/config";
import { debugConsoleStore } from "$lib/stores/debugConsole";
import { memoryBrowserStore } from "$lib/stores/memoryBrowser";
import type { ConnectionStatus } from "$lib/types/messages";
import StatsDisplay from "./StatsDisplay.svelte";
import AboutPanel from "./AboutPanel.svelte";
@@ -71,6 +72,9 @@
let showTaskLoop = $state(false);
let showWorkflowPanel = $state(false);
let showMemoryPanel = $state(false);
memoryBrowserStore.subscribe((s) => {
showMemoryPanel = s.isOpen;
});
const progress = $derived($achievementProgress);
const activeAgentCount = $derived($runningAgentCount);
@@ -179,7 +183,7 @@
</button>
<!-- Memory Manager -->
<button onclick={menuAction(() => (showMemoryPanel = true))} class="nav-item">
<button onclick={menuAction(() => memoryBrowserStore.open())} class="nav-item">
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
@@ -563,7 +567,7 @@
{/if}
{#if showMemoryPanel}
<MemoryBrowserPanel isOpen={showMemoryPanel} onClose={() => (showMemoryPanel = false)} />
<MemoryBrowserPanel isOpen={showMemoryPanel} onClose={() => memoryBrowserStore.close()} />
{/if}
{#if showWorkflowPanel}
+49
View File
@@ -0,0 +1,49 @@
import { describe, it, expect, beforeEach } from "vitest";
import { get } from "svelte/store";
import { memoryBrowserStore } from "./memoryBrowser";
beforeEach(() => {
memoryBrowserStore.close();
});
describe("memoryBrowserStore", () => {
it("initialises with panel closed", () => {
const state = get(memoryBrowserStore);
expect(state.isOpen).toBe(false);
});
it("open() sets isOpen to true", () => {
memoryBrowserStore.open();
expect(get(memoryBrowserStore).isOpen).toBe(true);
});
it("close() sets isOpen to false", () => {
memoryBrowserStore.open();
memoryBrowserStore.close();
expect(get(memoryBrowserStore).isOpen).toBe(false);
});
it("toggle() opens the panel when closed", () => {
memoryBrowserStore.close();
memoryBrowserStore.toggle();
expect(get(memoryBrowserStore).isOpen).toBe(true);
});
it("toggle() closes the panel when open", () => {
memoryBrowserStore.open();
memoryBrowserStore.toggle();
expect(get(memoryBrowserStore).isOpen).toBe(false);
});
it("calling open() when already open keeps it open", () => {
memoryBrowserStore.open();
memoryBrowserStore.open();
expect(get(memoryBrowserStore).isOpen).toBe(true);
});
it("calling close() when already closed keeps it closed", () => {
memoryBrowserStore.close();
memoryBrowserStore.close();
expect(get(memoryBrowserStore).isOpen).toBe(false);
});
});
+20
View File
@@ -0,0 +1,20 @@
import { writable } from "svelte/store";
interface MemoryBrowserState {
isOpen: boolean;
}
function createMemoryBrowserStore() {
const { subscribe, update } = writable<MemoryBrowserState>({
isOpen: false,
});
return {
subscribe,
open: () => update((state) => ({ ...state, isOpen: true })),
close: () => update((state) => ({ ...state, isOpen: false })),
toggle: () => update((state) => ({ ...state, isOpen: !state.isOpen })),
};
}
export const memoryBrowserStore = createMemoryBrowserStore();