From 69f64df27964113c887aa67a585837a365457039 Mon Sep 17 00:00:00 2001 From: mesalogo Date: Thu, 8 Oct 2026 23:49:19 +0800 Subject: [PATCH] fix: restore composer overlay integration --- src/main/assistant/assistant-database.ts | 7 +++++-- src/main/ipc.ts | 1 + src/renderer/src/Composer.tsx | 23 +++++++++++++---------- tests/support/story-graph-switch-main.ts | 5 +++-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/main/assistant/assistant-database.ts b/src/main/assistant/assistant-database.ts index ee70bdbb..1839d222 100644 --- a/src/main/assistant/assistant-database.ts +++ b/src/main/assistant/assistant-database.ts @@ -9168,8 +9168,11 @@ export class AssistantDatabase { } listSupervisionResults(limit = 20, target?: SupervisionTarget, resultId?: string) { - const owner = target?.type === 'conversation' ? this.getConversation(target.conversationId) - : target?.type === 'task' ? this.getTask(target.taskId) : undefined + const owner = target?.type === 'conversation' + ? this.requireDatabase().prepare('SELECT project_id AS projectId FROM conversations WHERE id = ?').get(target.conversationId) as { projectId: string | null } | undefined + : target?.type === 'task' + ? this.requireDatabase().prepare('SELECT project_id AS projectId FROM tasks WHERE id = ?').get(target.taskId) as { projectId: string | null } | undefined + : undefined const sourceType = target?.type ?? null const sourceId = target?.type === 'conversation' ? target.conversationId : target?.taskId ?? null return this.requireDatabase().prepare(`SELECT id, run_id AS runId, summary, diff --git a/src/main/ipc.ts b/src/main/ipc.ts index ddc7d87d..e366755b 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -7090,6 +7090,7 @@ export function registerIpcHandlers( assertTrustedSender(event, window) const request = supervisionSuggestionListRequestSchema.parse(input ?? {}) if ((await applicationSettingsStore?.get())?.heartbeatEnabled !== true) return [] + if (!supervisionPorts) return [] return await (await supervisionDatabase.supervisionSuggestions()).list(request.status, request.limit, request.offset) }) registerHandler(ipcChannels.supervisionSuggestionAction, async (event, input: unknown) => { diff --git a/src/renderer/src/Composer.tsx b/src/renderer/src/Composer.tsx index 225dff7b..ae1c8090 100644 --- a/src/renderer/src/Composer.tsx +++ b/src/renderer/src/Composer.tsx @@ -327,6 +327,15 @@ export const Composer = memo(function Composer({ composerOptionsTriggerRef, closeComposerOptions, ); + useEffect(() => { + if (!composerOptionsOpen) return; + const frame = requestAnimationFrame(() => { + composerOptionsRef.current + ?.querySelector("button:not(:disabled), input:not(:disabled)") + ?.focus(); + }); + return () => cancelAnimationFrame(frame); + }, [composerOptionsOpen, knowledgeLibraries.length]); useDismissibleComposerDialog( runtimeOptionsOpen, runtimeOptionsRef, @@ -405,8 +414,6 @@ export const Composer = memo(function Composer({ runtime: runtimeControlsProvider, }) : ""; - const composerContextAvailable = - supervisorEnabled === true || knowledgeLibraries.length > 0; const composerOptionSummary = [ enabledKnowledgeLibraryIds.length > 0 ? t("composer.knowledge.select", { count: enabledKnowledgeLibraryIds.length }) @@ -808,8 +815,7 @@ export const Composer = memo(function Composer({
- {composerContextAvailable && ( - <> + <>
)} - - )} + - - )} + { const point = await js<{ x: number; y: number }>(`(() => { const r = document.querySelector('.composer__options-trigger').getBoundingClientRect(); return { x: Math.round(r.x+r.width/2), y: Math.round(r.y+r.height/2) }; })()`) win.webContents.sendInputEvent({ type: 'mouseDown', ...point, button: 'left', clickCount: 1 }) win.webContents.sendInputEvent({ type: 'mouseUp', ...point, button: 'left', clickCount: 1 }) - // First focus stays on the first menu button, matching the model picker. - await wait('document.activeElement === document.querySelector(".composer__options button:not(:disabled)")') + // Focus the first enabled context control, which is the story-graph + // switch when no knowledge libraries are available. + await wait('document.activeElement === document.querySelector(".composer__options button:not(:disabled), .composer__options input:not(:disabled)")') } const scenarios: object[] = [] try {