diff --git a/apps/api/src/app/api/electric/[...path]/utils.ts b/apps/api/src/app/api/electric/[...path]/utils.ts index 345b41c2842..f28980cd0e2 100644 --- a/apps/api/src/app/api/electric/[...path]/utils.ts +++ b/apps/api/src/app/api/electric/[...path]/utils.ts @@ -113,7 +113,7 @@ export async function buildWhereClause( return build(agentCommands, agentCommands.organizationId, organizationId); case "auth.apikeys": { - const fragment = `"metadata"::jsonb->>'organizationId' = $1`; + const fragment = `"metadata" LIKE '%"organizationId":"' || $1 || '"%'`; return { fragment, params: [organizationId] }; } diff --git a/apps/api/src/proxy.ts b/apps/api/src/proxy.ts index e73d197459e..31c86bc6598 100644 --- a/apps/api/src/proxy.ts +++ b/apps/api/src/proxy.ts @@ -24,17 +24,14 @@ function getCorsHeaders(origin: string | null) { "Access-Control-Allow-Origin": isAllowed ? origin : "", "Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS", "Access-Control-Allow-Headers": - "Content-Type, Authorization, x-trpc-source, trpc-accept", + "Content-Type, Authorization, x-trpc-source, trpc-accept, X-Electric-Backend", "Access-Control-Expose-Headers": [ - "Stream-Next-Offset", - "Stream-Cursor", - "Stream-Up-To-Date", - "Stream-Closed", - "Stream-Total-Size", - "Stream-Write-Units", - "Producer-Epoch", - "Producer-Expected-Seq", - "Producer-Received-Seq", + "electric-offset", + "electric-handle", + "electric-schema", + "electric-cursor", + "electric-chunk-last-offset", + "electric-up-to-date", "ETag", ].join(", "), "Access-Control-Allow-Credentials": "true", diff --git a/apps/desktop/src/renderer/lib/trpc-storage.ts b/apps/desktop/src/renderer/lib/trpc-storage.ts index bb4e67d94f1..71b95fded62 100644 --- a/apps/desktop/src/renderer/lib/trpc-storage.ts +++ b/apps/desktop/src/renderer/lib/trpc-storage.ts @@ -34,7 +34,6 @@ function createTrpcStorageAdapter(config: TrpcStorageConfig): StateStorage { localStorage.getItem(`${name}:version`) ?? "0", 10, ); - console.log(`[trpc-storage] getItem "${name}" version=${version}`); return JSON.stringify({ state, version }); } catch (error) { console.error("[trpc-storage] Failed to get state:", error); @@ -48,9 +47,6 @@ function createTrpcStorageAdapter(config: TrpcStorageConfig): StateStorage { version: number; }; // Persist version in localStorage, bare state via tRPC. - console.log( - `[trpc-storage] setItem "${name}" version=${parsed.version}`, - ); localStorage.setItem(`${name}:version`, String(parsed.version)); await config.set(parsed.state); } catch (error) { diff --git a/apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts b/apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts index 6c7bb002ab9..23237fc497d 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts @@ -32,8 +32,9 @@ async function execute( store.addPendingTerminalSetup({ workspaceId: workspace.id, projectId: pending?.projectId ?? workspace.projectId, - initialCommands: [...(pending?.initialCommands ?? []), params.command], + initialCommands: pending?.initialCommands ?? null, defaultPresets: pending?.defaultPresets, + agentCommand: params.command, }); return { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx index 9f5813a08b9..7be5c96864f 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx @@ -29,6 +29,7 @@ export function WorkspaceInitEffects() { const processingRef = useRef>(new Set()); const addTab = useTabsStore((state) => state.addTab); + const addPane = useTabsStore((state) => state.addPane); const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); const { openPreset } = useTabsWithPresets(); const createOrAttach = useCreateOrAttachWithTheme(); @@ -43,6 +44,7 @@ export function WorkspaceInitEffects() { (p) => p.commands.length > 0, ); const hasPresets = shouldApplyPreset && presets.length > 0; + const { agentCommand } = setup; if (hasSetupScript && hasPresets) { const { tabId: setupTabId, paneId: setupPaneId } = addTab( @@ -53,6 +55,12 @@ export function WorkspaceInitEffects() { openPreset(setup.workspaceId, preset); } + if (agentCommand) { + addPane(setupTabId, { + initialCommands: [agentCommand], + }); + } + createOrAttach.mutate( { paneId: setupPaneId, @@ -81,6 +89,13 @@ export function WorkspaceInitEffects() { if (hasSetupScript) { const { tabId, paneId } = addTab(setup.workspaceId); setTabAutoTitle(tabId, "Workspace Setup"); + + if (agentCommand) { + addPane(tabId, { + initialCommands: [agentCommand], + }); + } + createOrAttach.mutate( { paneId, @@ -124,13 +139,35 @@ export function WorkspaceInitEffects() { for (const preset of presets) { openPreset(setup.workspaceId, preset); } + if (agentCommand) { + const { tabId: agentTabId } = addTab(setup.workspaceId, { + initialCommands: [agentCommand], + }); + setTabAutoTitle(agentTabId, "Agent"); + } + onComplete(); + return; + } + + if (agentCommand) { + const { tabId: agentTabId } = addTab(setup.workspaceId, { + initialCommands: [agentCommand], + }); + setTabAutoTitle(agentTabId, "Agent"); onComplete(); return; } onComplete(); }, - [addTab, setTabAutoTitle, createOrAttach, openPreset, shouldApplyPreset], + [ + addTab, + addPane, + setTabAutoTitle, + createOrAttach, + openPreset, + shouldApplyPreset, + ], ); useEffect(() => { diff --git a/apps/desktop/src/renderer/stores/workspace-init.ts b/apps/desktop/src/renderer/stores/workspace-init.ts index 26aad9b4654..0bcce8f890c 100644 --- a/apps/desktop/src/renderer/stores/workspace-init.ts +++ b/apps/desktop/src/renderer/stores/workspace-init.ts @@ -9,6 +9,8 @@ export interface PendingTerminalSetup { initialCommands: string[] | null; /** When undefined, signals that presets haven't been fetched yet and should be loaded from the backend */ defaultPresets?: TerminalPreset[]; + /** Agent command to run in a separate pane from the setup script */ + agentCommand?: string; } interface WorkspaceInitState {