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
+1 -1
View File
@@ -1455,7 +1455,7 @@ fn process_json_line(
let subagent_type = input let subagent_type = input
.get("subagent_type") .get("subagent_type")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.unwrap_or("unknown") .unwrap_or("general-purpose")
.to_string(); .to_string();
let model = input let model = input
.get("model") .get("model")
+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", () => { describe("/context execute", () => {
it("shows error when no active conversation", async () => { it("shows error when no active conversation", async () => {
getMock.mockReturnValue(null); getMock.mockReturnValue(null);
+4 -8
View File
@@ -6,6 +6,7 @@ import { setSkipNextGreeting, updateDiscordRpc } from "$lib/tauri";
import { searchState } from "$lib/stores/search"; import { searchState } from "$lib/stores/search";
import { conversationsStore } from "$lib/stores/conversations"; import { conversationsStore } from "$lib/stores/conversations";
import { configStore } from "$lib/stores/config"; import { configStore } from "$lib/stores/config";
import { memoryBrowserStore } from "$lib/stores/memoryBrowser";
export interface SlashCommand { export interface SlashCommand {
name: string; name: string;
@@ -287,16 +288,11 @@ export const slashCommands: SlashCommand[] = [
}, },
{ {
name: "memory", 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", usage: "/memory",
source: "cli", source: "cli",
execute: async () => { execute: () => {
const conversationId = get(claudeStore.activeConversationId); memoryBrowserStore.open();
if (!conversationId) {
claudeStore.addLine("error", "No active conversation");
return;
}
await invoke("send_prompt", { conversationId, message: "/memory" });
}, },
}, },
{ {
+6 -2
View File
@@ -6,6 +6,7 @@
import { editorStore } from "$lib/stores/editor"; import { editorStore } from "$lib/stores/editor";
import { configStore } from "$lib/stores/config"; import { configStore } from "$lib/stores/config";
import { debugConsoleStore } from "$lib/stores/debugConsole"; import { debugConsoleStore } from "$lib/stores/debugConsole";
import { memoryBrowserStore } from "$lib/stores/memoryBrowser";
import type { ConnectionStatus } from "$lib/types/messages"; import type { ConnectionStatus } from "$lib/types/messages";
import StatsDisplay from "./StatsDisplay.svelte"; import StatsDisplay from "./StatsDisplay.svelte";
import AboutPanel from "./AboutPanel.svelte"; import AboutPanel from "./AboutPanel.svelte";
@@ -71,6 +72,9 @@
let showTaskLoop = $state(false); let showTaskLoop = $state(false);
let showWorkflowPanel = $state(false); let showWorkflowPanel = $state(false);
let showMemoryPanel = $state(false); let showMemoryPanel = $state(false);
memoryBrowserStore.subscribe((s) => {
showMemoryPanel = s.isOpen;
});
const progress = $derived($achievementProgress); const progress = $derived($achievementProgress);
const activeAgentCount = $derived($runningAgentCount); const activeAgentCount = $derived($runningAgentCount);
@@ -179,7 +183,7 @@
</button> </button>
<!-- Memory Manager --> <!-- 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"> <svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path <path
stroke-linecap="round" stroke-linecap="round"
@@ -563,7 +567,7 @@
{/if} {/if}
{#if showMemoryPanel} {#if showMemoryPanel}
<MemoryBrowserPanel isOpen={showMemoryPanel} onClose={() => (showMemoryPanel = false)} /> <MemoryBrowserPanel isOpen={showMemoryPanel} onClose={() => memoryBrowserStore.close()} />
{/if} {/if}
{#if showWorkflowPanel} {#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();