Skip to content

Conversation

@yodeput
Copy link

@yodeput yodeput commented Feb 2, 2026

No description provided.

yodeput and others added 18 commits January 31, 2026 11:24
Add onboarding page for detecting existing Claude CLI configuration
and allow users to use their existing API proxy settings.

- Add cli-config-detected-page.tsx for showing detected CLI config
- Add cliConfigDetectedShownAtom to track if page was shown
- Update onboarding flow to check for existing CLI config
- Add pnpm workspace configuration
- Detect and merge CLI config from ~/.claude/settings.json
- Standardize new-chat-form model selector to match chat-input-area
- Reorder new-chat-form buttons (Model -> Thinking -> Plan)
- Remove legacy 'Migrated Config' creation
- Remove 'System (No Profile)' option to enforce profile usage
- Rename fallback display label to 'System'
- Fix React object child error in conditional rendering
- Add system tray icon with context menu for macOS
- Support quick switching between model profiles from tray
- Add workspace selection and "New Workspace" from tray
- Add Settings menu item that opens settings dialog
- Bundle trayTemplate.png in production build via extraResources
- Add tray-events hook for renderer communication
- Fix timing issues with Settings navigation from tray
- Ensure profiles are read even when no window exists
# Conflicts:
#	bun.lockb
#	src/renderer/features/agents/main/active-chat.tsx
Add complete remote access feature allowing web chat to connect to desktop app:

- WebSocket server that proxies tRPC calls (queries, mutations, subscriptions)
- Proper subscription handling via _def.resolver to bypass client-side checks
- Remote access dialog with cloudflared tunnel integration
- Model profiles sync between localStorage and database
- tRPC transport adapter for web chat communication
- Session and cleanup management for cloudflared processes

Fixed issues:
- Made token optional in chat subscription validation (for proxy configs)
- Fixed JSON parsing for database profiles (config/models stored as strings)
- Added error handling for activeConfigAtom access

WebSocket subscription fix is the key change - accessing _def.resolver directly
to call tRPC subscriptions from server-side context.

Related files:
- src/main/lib/remote-access/ws-server.ts: WebSocket server with tRPC proxy
- src/main/lib/remote-access/*.ts: Remote access controllers
- src/renderer/lib/remote-transport/*: Transport adapter for web chat
- src/main/lib/trpc/routers/remote-access.ts: tRPC router for remote access

Co-Authored-By: Claude <noreply@anthropic.com>
Implement shared subscription system so all clients receive chat updates:

- Shared subscriptions per subChatId in WebSocket server
- IPC clients can register listeners to receive broadcasts
- Desktop IPC transport subscribes to WebSocket server broadcasts
- When web sends message, desktop receives it via broadcast
- When desktop sends message, web receives it via shared subscription

Key changes:
- ws-server.ts: Add sharedChatSubscriptions map with clients + listeners
- ws-server.ts: Add subscribeToChatData() for IPC clients
- main.ts: Add chat:subscribe IPC handler
- preload/index.ts: Add subscribeToChatData to desktopApi
- ipc-chat-transport.ts: Subscribe to broadcasts when creating stream

This ensures bidirectional sync: desktop and web clients see all messages
from each other in real-time.

Co-Authored-By: Claude <noreply@anthropic.com>
Add isRemoteModeAtom that detects when running in web browser (not desktop).
Hide Settings and Remote Access buttons in sidebar when in remote mode.

Remote mode detection:
- Check for remote_ws_auth in sessionStorage (set after login)
- Check if window.desktopApi is missing (web browser)

This prevents web users from seeing desktop-only features.

Co-Authored-By: Claude <noreply@anthropic.com>
Add polling to projects and chats queries when running in remote mode (web browser).

When in remote mode, the following queries now poll every 5 seconds:
- trpc.projects.list - workspace list
- trpc.chats.list - local chat list
- trpc.chats.listArchived - archived chats
- api.agents.getAgentChats - team chats
- api.teams.getUserTeams - teams list

This ensures that web clients see updates made on desktop (new chats,
new workspaces, etc.) within 5 seconds.

Co-Authored-By: Claude <noreply@anthropic.com>
Add visual feedback when web client loses connection to desktop app:

Connection state tracking:
- Add onConnectionStateChange() callback for connection state updates
- States: "connecting" | "connected" | "disconnected"
- Notify listeners on auth success, connection close, and errors

UI components:
- remoteConnectionStateAtom - tracks connection state in Jotai
- useRemoteConnection() - hook that subscribes to state changes
- ConnectionErrorOverlay - full-screen overlay when disconnected

Overlay features:
- Shows "Connection Lost" message with WiFiOff icon
- Displays current connection state
- "Reconnect" button that reloads the page
- Backdrop blur effect with centered card

Only active in remote mode (web browser), not in desktop app.

Co-Authored-By: Claude <noreply@anthropic.com>
Fix several issues that were preventing the app from running:

1. Circular dependency fix:
- Move ModelProfile, OFFLINE_PROFILE, CustomClaudeConfig, ModelMapping to
  separate model-profile-types.ts file
- This avoids circular dependency between atoms/index.ts and model-profiles-sync.ts

2. WebSocket server routing fix:
- Access router directly instead of through caller for nested paths
- Fix "Router not found: external" error by using router instead of caller
- Caller may not expose nested routers properly

3. Import fix in main.ts:
- Import subscribeToChatData at module level instead of dynamic require
- Fix "Cannot find module '../lib/remote-access/ws-server'" error

Co-Authored-By: Claude <noreply@anthropic.com>
…ex.ts

- Deleted model-profile-types.ts (was causing Vite HMR issues)
- Restored ModelProfile, CustomClaudeConfig, OFFLINE_PROFILE types inline
- Updated model-profiles-sync.ts to import from ./index

Co-Authored-By: Claude <noreply@anthropic.com>
…r dependency

- Moved activeConfigAtom and normalizeCustomClaudeConfig to model-profiles-sync.ts
- Updated index.ts to re-export activeConfigAtom from model-profiles-sync.ts
- This breaks the circular dependency where:
  - index.ts imports modelProfilesAtom from model-profiles-sync.ts
  - model-profiles-sync.ts imports types from index.ts
  - index.ts defines activeConfigAtom which reads modelProfilesAtom

Co-Authored-By: Claude <noreply@anthropic.com>
- Move activeConfigAtom and normalizeCustomClaudeConfig to model-profiles-sync.ts
  to break circular dependency (modelProfilesAtom is not defined error)
- Fix IPC cloning error by not returning functions through Electron IPC
  - Store chat subscriptions in a Map in main process
  - Add chat:unsubscribe IPC handler for cleanup
  - Update preload to call chat:unsubscribe instead of storing function

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix sharedSub.clients type (Set → Map) for subscription ID tracking
- Fix ws-link to handle subscription confirmation without deleting handler
- Fix tRPC query syntax (refetchInterval in options, not input)
- Add WebSocket chat relay implementation plan

This fixes web app not receiving chat responses and ensures
desktop and web stay in sync with shared subscription pattern.

Co-Authored-By: Claude <noreply@anthropic.com>
- Auth success → push projects + model profiles
- Subscribe to project → push chat list
- Subscribe to chat → push message history + stream updates
- Send message → WebSocket → Desktop → tRPC

Co-Authored-By: Claude <noreply@anthropic.com>
- Add conditional wsLink only for desktop
- Remove tRPC queries from web sidebar/content
- Guard all tRPC usage with isDesktopApp()
- Update TRPCProvider for web compatibility

Co-Authored-By: Claude <noreply@anthropic.com>
@bunasQ
Copy link
Member

bunasQ commented Feb 2, 2026

@1code whats that whats the purpose of this PR ?

@1code-async
Copy link
Contributor

1code-async bot commented Feb 2, 2026

Task completed.

Here's a summary of this PR to post as a reply:

This PR bundles several related features together into one branch. Here's what it does:

1. CLI Config Detection & Proxy Claude Support — Adds an onboarding page that detects existing Claude CLI configuration (~/.claude/settings.json) and lets users reuse their existing API proxy settings instead of re-entering them.

2. Model Profile System Refactor — Standardizes the UI for model selection, removes legacy "Migrated Config" and "System (No Profile)" options, and enforces profile-based usage.

3. System Tray — Adds a macOS system tray icon with a context menu for quick switching between model profiles, workspaces, and opening settings.

4. Remote Access via WebSocket (the main feature) — This is the core of the PR. It allows users to access their desktop app remotely from a web browser:

  • A WebSocket server in the main process proxies tRPC calls (queries, mutations, subscriptions)
  • Cloudflared tunnel integration exposes the local WebSocket server to the internet
  • A web-based tRPC transport adapter connects to the desktop app over WebSocket
  • Bidirectional chat sync — messages sent from web appear on desktop and vice versa via shared subscriptions
  • Connection state tracking with a "Connection Lost" overlay for the web client
  • Workspace and chat list polling (every 5s) for web clients
  • Desktop-only UI (Settings, Remote Access buttons) is hidden in web mode

5. Bug Fixes — Several commits fix circular dependency issues, IPC cloning errors, and WebSocket routing problems that came up during development.

In short: this PR lets you use the 1Code desktop app remotely from any web browser by tunneling a WebSocket connection through Cloudflare. It's a significant feature addition (~27k lines added) that also includes supporting features (system tray, profile refactoring) that were developed on the same branch.


View full conversation

Powered by 1Code

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.

2 participants