Skip to content

fix(desktop): run agent in separate pane#1582

Merged
saddlepaddle merged 3 commits into
mainfrom
separate-agent-start
Feb 19, 2026
Merged

fix(desktop): run agent in separate pane#1582
saddlepaddle merged 3 commits into
mainfrom
separate-agent-start

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Feb 19, 2026

Summary

  • Run agent prompt in a separate terminal pane from the setup script instead of chaining them with && in the same terminal — prevents the agent from crashing when the setup script runs
  • Fix CORS for Electric Cloud: add X-Electric-Backend to allowed headers and expose all response headers via wildcard (fixes MissingHeadersError for electric-offset, electric-handle, electric-schema, electric-cursor)
  • Fix auth.apikeys Electric where clause: use LIKE instead of ::jsonb cast which Docker Electric doesn't support

Test plan

  • Create a workspace via MCP with a setup script in .superset/config.json
  • Call start_claude_session — verify setup script and agent run in separate panes
  • Call start_claude_session without a setup script — verify agent opens in its own tab
  • Verify Electric collections sync without CORS errors in desktop app
  • Verify auth.apikeys collection syncs without jsonb cast error

Summary by CodeRabbit

  • New Features

    • Workspace initialization now creates panes populated with agent commands during setup.
    • Agent command handling improved for session startup and pane creation.
  • Bug Fixes

    • Authentication filtering logic refined for more reliable key matching.
  • Chores

    • Backend CORS headers updated to expose and accept additional electric-specific headers.
    • Removed debug console logs to reduce noisy output.

…tric CORS

- Store agent command separately in PendingTerminalSetup instead of
  appending to initialCommands, so setup script and agent run in
  separate panes within the same tab
- Add X-Electric-Backend to CORS Access-Control-Allow-Headers (needed
  after Electric Cloud header was added in #1572)
- Use wildcard for Access-Control-Expose-Headers to expose all Electric
  response headers (electric-offset, electric-handle, electric-schema, etc.)
- Fix auth.apikeys where clause to use LIKE instead of ::jsonb cast
  which Docker Electric doesn't support
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 19, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This PR routes agentCommand through terminal/session setup to create panes with that command, updates CORS expose/allow headers for the proxy, changes API key metadata filtering from jsonb extraction to a string LIKE, and removes two debug logs in trpc storage.

Changes

Cohort / File(s) Summary
API auth filtering
apps/api/src/app/api/electric/[...path]/utils.ts
Replaced jsonb extraction (->>) organizationId comparison with a string LIKE pattern match in the auth.apikeys WHERE clause.
Proxy CORS headers
apps/api/src/proxy.ts
Added X-Electric-Backend to Access-Control-Allow-Headers and changed Access-Control-Expose-Headers to expose electric-prefixed headers (electric-offset, electric-handle, electric-schema, electric-cursor, electric-chunk-last-offset, electric-up-to-date) plus ETag.
Command/session startup
apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts
Stop appending the command into pending.initialCommands; pass current command separately as agentCommand in the pending terminal setup payload.
Workspace init & pane creation
apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx
Introduced addPane usage and dependency; conditionally create panes initialized with initialCommands: [agentCommand] across multiple setup branches when agentCommand is present.
Types: pending setup
apps/desktop/src/renderer/stores/workspace-init.ts
Added optional agentCommand?: string to PendingTerminalSetup interface.
Logging cleanup
apps/desktop/src/renderer/lib/trpc-storage.ts
Removed two console.log debug statements in getItem and setItem.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Watcher as useCommandWatcher
    participant Session as Session Init
    participant Terminal as TerminalSetup
    participant Workspace as WorkspaceInitEffects
    participant Tabs as Tabs Store

    User->>Watcher: run command / invoke agent
    Watcher->>Session: build session payload (extract agentCommand)
    Session->>Terminal: create pending setup (agentCommand + initialCommands)
    Terminal->>Workspace: persist pending terminal setup

    rect rgba(100, 200, 255, 0.5)
    Note over Workspace: detects agentCommand in pending setup
    Workspace->>Tabs: call addPane(initialCommands: [agentCommand])
    Tabs->>Tabs: create pane and populate terminal
    end

    Tabs-->>User: new pane shown with agent command
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I nudged a command into the light,
A pane unfurls to greet the night,
Headers waved and filters changed,
Logs tucked in, behavior arranged,
Hooray — terminals hop into sight! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two main changes: agent runs in a separate pane and Electric CORS is fixed, directly matching the PR's primary objectives.
Description check ✅ Passed The PR description covers the key changes with a summary section and test plan, though it omits the template's standard sections like Related Issues and Type of Change.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch separate-agent-start

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 19, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch
  • ✅ Electric Fly.io app

Thank you for your contribution! 🎉

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts (1)

29-29: ⚠️ Potential issue | 🟡 Minor

Stale comment — update to reflect the new separation of concerns.

The comment says "Append command to pending terminal setup", but the behaviour is now the opposite: agentCommand is stored separately and initialCommands is preserved unchanged (not appended to).

✏️ Suggested update
-		// Append command to pending terminal setup for the existing workspace
+		// Set agent command in pending terminal setup, keeping the setup script commands separate
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts`
at line 29, Update the stale inline comment in start-claude-session.ts to
reflect the new separation of concerns: explain that agentCommand is stored
separately (e.g., saved to agentCommand or similar variable) while
initialCommands are preserved and not appended to; replace the phrase "Append
command to pending terminal setup" with a clear note that the agent command is
stored independently and initialCommands remain unchanged so callers can rely on
the original initialCommands value.
🧹 Nitpick comments (2)
apps/api/src/app/api/electric/[...path]/utils.ts (1)

116-116: Performance: leading % wildcard prevents index use on metadata.

The LIKE '%...' pattern with a leading wildcard cannot use a B-tree index on metadata. If auth.apikeys grows, this causes a full sequential scan per sync request. Consider a GIN index on metadata cast to text (or a generated column) if query latency becomes an issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/app/api/electric/`[...path]/utils.ts at line 116, The current
fragment variable uses a leading-wildcard LIKE which prevents index use; change
the fragment in utils.ts from the LIKE expression to a JSON-aware predicate such
as using metadata->>'organizationId' = $1 (or metadata @>
jsonb_build_object('organizationId', $1)) so the DB can use an expression or GIN
index, and ensure a GIN index (or an expression index on
metadata->>'organizationId') exists on the metadata JSONB column to avoid
sequential scans when auth.apikeys grows.
apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx (1)

142-147: Duplicated agent-tab creation block — extract into a shared helper.

The identical five-line sequence (lines 142–146 and 152–156) is repeated verbatim across the hasPresets and agentCommand-only branches. Extracting it keeps the callback DRY and makes future changes (e.g., adding a pane layout option) a one-line edit.

♻️ Suggested refactor

Inside handleTerminalSetup, before the branch chain:

+		const openAgentTab = () => {
+			const { tabId: agentTabId } = addTab(setup.workspaceId, {
+				initialCommands: [agentCommand!],
+			});
+			setTabAutoTitle(agentTabId, "Agent");
+		};

		if (hasPresets) {
			for (const preset of presets) {
				openPreset(setup.workspaceId, preset);
			}
-			if (agentCommand) {
-				const { tabId: agentTabId } = addTab(setup.workspaceId, {
-					initialCommands: [agentCommand],
-				});
-				setTabAutoTitle(agentTabId, "Agent");
-			}
+			if (agentCommand) openAgentTab();
			onComplete();
			return;
		}

		if (agentCommand) {
-			const { tabId: agentTabId } = addTab(setup.workspaceId, {
-				initialCommands: [agentCommand],
-			});
-			setTabAutoTitle(agentTabId, "Agent");
+			openAgentTab();
			onComplete();
			return;
		}

Also applies to: 152-158

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx`
around lines 142 - 147, There’s duplicated logic adding an agent tab in
handleTerminalSetup; extract the five-line sequence that calls
addTab(setup.workspaceId, { initialCommands: [agentCommand] }) and
setTabAutoTitle(agentTabId, "Agent") into a small helper (e.g., createAgentTab
or addAgentTab) declared inside handleTerminalSetup before the branch, then
replace both repeated blocks (the hasPresets branch and the agentCommand-only
branch) with a single call to that helper using the existing agentCommand and
setup.workspaceId variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/proxy.ts`:
- Around line 28-29: The CORS response header "Access-Control-Expose-Headers" is
currently set to "*" which is ignored when "Access-Control-Allow-Credentials" is
"true"; update the proxy response headers in proxy.ts to explicitly list the
Electric headers instead of using "*". Replace the wildcard value for
"Access-Control-Expose-Headers" with a comma-separated string enumerating
"electric-offset", "electric-handle", "electric-schema", and "electric-cursor"
(keeping the existing "Access-Control-Allow-Credentials": "true") so the browser
can access those headers.

---

Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-claude-session.ts`:
- Line 29: Update the stale inline comment in start-claude-session.ts to reflect
the new separation of concerns: explain that agentCommand is stored separately
(e.g., saved to agentCommand or similar variable) while initialCommands are
preserved and not appended to; replace the phrase "Append command to pending
terminal setup" with a clear note that the agent command is stored independently
and initialCommands remain unchanged so callers can rely on the original
initialCommands value.

---

Nitpick comments:
In `@apps/api/src/app/api/electric/`[...path]/utils.ts:
- Line 116: The current fragment variable uses a leading-wildcard LIKE which
prevents index use; change the fragment in utils.ts from the LIKE expression to
a JSON-aware predicate such as using metadata->>'organizationId' = $1 (or
metadata @> jsonb_build_object('organizationId', $1)) so the DB can use an
expression or GIN index, and ensure a GIN index (or an expression index on
metadata->>'organizationId') exists on the metadata JSONB column to avoid
sequential scans when auth.apikeys grows.

In `@apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx`:
- Around line 142-147: There’s duplicated logic adding an agent tab in
handleTerminalSetup; extract the five-line sequence that calls
addTab(setup.workspaceId, { initialCommands: [agentCommand] }) and
setTabAutoTitle(agentTabId, "Agent") into a small helper (e.g., createAgentTab
or addAgentTab) declared inside handleTerminalSetup before the branch, then
replace both repeated blocks (the hasPresets branch and the agentCommand-only
branch) with a single call to that helper using the existing agentCommand and
setup.workspaceId variables.

Comment thread apps/api/src/proxy.ts Outdated
- Replace wildcard Access-Control-Expose-Headers with explicit list
  (wildcard is ignored when Access-Control-Allow-Credentials is true)
- Remove stray console.log calls from trpc-storage.ts
@saddlepaddle saddlepaddle merged commit ea86f3a into main Feb 19, 2026
14 checks passed
@saddlepaddle saddlepaddle changed the title fix(desktop): run agent in separate pane and fix Electric CORS fix(desktop): run agent in separate pane Feb 19, 2026
@Kitenite Kitenite deleted the separate-agent-start branch February 19, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant