Skip to content

feat: run Electron chat through local Claude and Codex - #206

Closed
NarwhalChen wants to merge 29 commits into
mainfrom
kobe/local-first-electron-backend
Closed

feat: run Electron chat through local Claude and Codex#206
NarwhalChen wants to merge 29 commits into
mainfrom
kobe/local-first-electron-backend

Conversation

@NarwhalChen

@NarwhalChen NarwhalChen commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • replace the Electron app Foxychat service dependency with a local Main-process AI runtime
  • stream chat through a context-isolated preload and IPC bridge to authenticated Claude Code and Codex CLI subscriptions
  • expose Main-process MCP and builtin tools to local providers with request-scoped user approval
  • add builtin:computer_control for atomic screenshot, pointer, keyboard, scroll, drag, and wait actions
  • preserve screenshot image content through a loopback-only authenticated Codex MCP transport
  • add a General Settings selector for Claude Code and Codex; the selection uses the existing local persisted model state consumed by new chats
  • keep chat history and provider selection local; ~/proj/foxychat-server remains unchanged
  • retain the atomic WDIO/MCP automation as an AI-operated local testing method; no CI workflow is added by this work

Runtime and safety boundaries

  • renderer input is validated and size-bounded at IPC; events are isolated by sender and request ID
  • Main owns provider discovery, trusted cwd selection, lifecycle, abort, and disposal
  • all state-changing computer_control calls require the existing in-app approval flow
  • screenshot checks macOS Screen Recording permission; pointer and keyboard actions check Accessibility permission and return actionable errors when denied
  • Codex MCP listens only on loopback, uses a random bearer token, and preserves MCP image blocks rather than serializing them to text
  • background automation profiles remain hidden and isolated unless show_window is explicitly enabled

Verification

  • pnpm --filter @convera/app test — 20 files / 60 tests passed
  • pnpm --filter @convera/app lint — 0 errors (7 existing React Hook warnings)
  • pnpm --filter @convera/app exec tsc --noEmit --skipLibCheck
  • pnpm --filter @convera/app automation:typecheck
  • pnpm automation:prepare — Electron/Vite package and matching native automation dependencies prepared
  • real hidden Electron profile selected Codex in Settings and retained aria-pressed=true after relaunch
  • real Codex subscription selected builtin:computer_control, displayed the in-app approval prompt, completed wait(1ms), and returned CODEX_CUA_PASS
  • Codex MCP integration test verifies PNG image blocks survive the transport and unauthenticated callers are rejected

Deliberate limitations

  • no new Claude model or Claude CUA run was performed for this update
  • this Mac currently denies Screen Recording to the Electron development host, so a real screenshot cannot be captured until the user grants that OS permission; the image transport itself is covered by integration tests
  • attachments remain hidden and unsupported in this local streaming slice
  • Codex uses the Main-process working directory for now
  • full TypeScript checking without skipLibCheck still reports upstream third-party declaration errors; app source and automation typechecks pass
  • packages/website and ~/proj/foxychat-server are unchanged

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
foxyfox-docs Skipped Skipped Jul 30, 2026 1:19pm
foxyfox-website Skipped Skipped Jul 30, 2026 1:19pm

Request Review

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

@NarwhalChen must be a member of the codefox-repo team on Vercel to deploy.
- Click here to add @NarwhalChen to the team.
- If you initiated this build, request access.

Learn more about collaboration on Vercel and other options here.

@NarwhalChen

Copy link
Copy Markdown
Collaborator Author

Goal update after rebasing onto origin/main f751ac0:

  • Remote head: ad928d2
  • Electron local-first agent path now exposes builtin and connected MCP tools to Claude/Codex while keeping execution and interaction in the main process.
  • Codex root cause fixed: removed the obsolete features.rmcp_client flag and kept native mcp_servers.convera HTTP configuration; MCP tool-call elicitation now returns structured empty content.
  • Regression coverage: Vitest 15 files / 49 tests passed; lint 0 errors (7 existing hook warnings); Prettier, automation typecheck, and git diff check passed.
  • Real Electron E2E passed with a fresh isolated profile and hidden/unfocused window: Codex invoked builtin ask_user_input, the UI presented Alpha/Beta, automation selected Alpha, and Codex completed with CODEX_TOOL_OK: Alpha. The session and Chromedriver were closed cleanly.

No merge performed.

@vercel
vercel Bot temporarily deployed to Preview – foxyfox-docs July 30, 2026 11:39 Inactive
@vercel
vercel Bot temporarily deployed to Preview – foxyfox-website July 30, 2026 11:39 Inactive
@NarwhalChen

Copy link
Copy Markdown
Collaborator Author

Added commit bf2c1c3 to complete Codex tool-call display through the AI SDK UI stream.

What changed:

  • Electron Main now forwards AI SDK UIMessageChunk events instead of rebuilding a parallel text/tool protocol.
  • Renderer aggregates chunks with readUIMessageStream, renders native/dynamic tool states through the existing tool UI, and persists parts in IndexedDB.
  • Tool name qualification remains intact for injected Convera tools while native Codex tools such as exec pass through unchanged.

Verification:

  • pnpm --filter app test: 16 files / 50 tests passed
  • pnpm --filter app automation:typecheck: passed
  • full Prettier and ESLint checks passed (7 existing hook warnings, no errors)
  • pnpm automation:prepare: packaged Electron and driver successfully
  • real hidden Electron run with gpt-5.3-codex-spark: Codex called exec, UI displayed arguments/result, output was CODEX_TOOL_UI_OK, exit code 0, final reply DONE; persisted part was dynamic-tool / output-available with input and output

@vercel
vercel Bot temporarily deployed to Preview – foxyfox-website July 30, 2026 11:55 Inactive
@vercel
vercel Bot temporarily deployed to Preview – foxyfox-docs July 30, 2026 11:55 Inactive
@NarwhalChen

Copy link
Copy Markdown
Collaborator Author

Follow-up commit 4d0c160 removes the legacy tool-call compatibility layer entirely.

  • deleted legacy ToolInvocation, tool-invocation, and toolInvocations types/fields/rendering/persistence
  • generic and custom tool renderers now consume AI SDK ToolUIPart | DynamicToolUIPart directly
  • repository search confirms no legacy tool-call identifiers remain
  • 17 test files / 52 tests passed; lint, format, automation typecheck, and Electron package passed
  • real hidden Codex run passed after the removal: native exec rendered AI_SDK_ONLY_OK, exit code 0, final DONE; IndexedDB stored only AI SDK parts and no legacy field

@NarwhalChen

Copy link
Copy Markdown
Collaborator Author

Superseded by the reviewable split merged through #208, #209, and #210. The complete #206 tree is now on main through those three PRs.

@NarwhalChen

Copy link
Copy Markdown
Collaborator Author

Implementation refresh for the local-first Electron target is available on kobe/local-first-electron-backend at ad928d278d204b854dae27471bb77417a20999cb (rebased onto origin/main f751ac093aebafd3a95c8a08f3126238582133a4).

Scope:

  • Removes Electron renderer dependencies on hosted auth/chat service paths while preserving local data.
  • Runs Claude Code and Codex subscriptions through an Electron main-process AI SDK runtime and IPC bridge.
  • Exposes controlled builtin and configured MCP tools to local agents, with renderer-mediated input/approval interactions.
  • Keeps background automation parameterized and isolated per agent/session.

Root cause fixed in the final Codex tool path:

  • Codex 0.144.6/0.146.0 rejects the obsolete features.rmcp_client override.
  • The adapter now uses native HTTP MCP server configuration without rmcpClient, and returns structured empty content for accepted MCP elicitation.
  • The automation click driver now returns the pre-click element snapshot so successful clicks remain successful when a popover option immediately unmounts.

Verification:

  • pnpm --filter @convera/app test: 15 files, 49 tests passed.
  • pnpm --filter @convera/app lint: 0 errors; 7 pre-existing React Hook warnings.
  • pnpm --filter @convera/app format: passed.
  • pnpm --filter @convera/app automation:typecheck: passed.
  • git diff --check origin/main...HEAD: passed.
  • Tracked-file audit found no .env, secrets, automation screenshots/logs, or generated build artifacts.

Real hidden Electron E2E evidence (fresh isolated profile goal-codex-ui-final-20260730-1758, session 302d3e8204cda34c3178c5caf889a3b6):

  • Window remained visible=false and focused=false before and after the flow.
  • gpt-5.3-codex-spark called builtin:ask_user_input through the local MCP bridge.
  • Renderer displayed Choose one with Alpha / Beta; selecting Alpha completed and produced CODEX_TOOL_OK: Alpha.
  • Driver cleanup returned running:false; the Chromedriver listener was gone.

PR #206 was already closed when this refresh was published, so this comment records the verified branch update without reopening or merging it.

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