Architecture Overview
System architecture for ReCursor: a Flutter mobile app with OpenCode-like UI. Bridge-first, no-login: connects to your user-controlled desktop bridge via secure tunnel.
System Context
Section titled “System Context”flowchart TB subgraph Mobile["📱 ReCursor Flutter App"] UI["OpenCode-like UI Layer"] State["Riverpod State Management"] WSClient["WebSocket Client"] end
subgraph Desktop["💻 Development Machine"] Bridge["ReCursor Bridge Server\n(TypeScript/Node.js)"]
subgraph Integration["Claude Code Integration"] Hooks["Hooks System\n(HTTP Event Observer)"] AgentSDK["Agent SDK\n(Parallel Session)"] CC["Claude Code CLI"] end end
subgraph Anthropic["☁️ Anthropic Services"] API["Claude API"] end
UI <--> State State <--> WSClient WSClient <-->|wss:// (Tailscale/WireGuard)| Bridge Bridge <-->|HTTP POST| Hooks Hooks -->|Observes| CC Bridge <-->|Optional| AgentSDK AgentSDK <-->|API Calls| API CC <-->|Internal| APIKey Architectural Decisions
Section titled “Key Architectural Decisions”1. Claude Code Integration Strategy
Section titled “1. Claude Code Integration Strategy”| Approach | Status | Notes |
|---|---|---|
| Direct Remote Control Protocol | ❌ Not Available | First-party only (claude.ai/code, official apps). No public API for third-party clients. |
| Claude Code Hooks | ✅ Supported | HTTP-based event observation (one-way) |
| Agent SDK | ✅ Supported | Parallel agent sessions (not mirroring) |
| MCP (Model Context Protocol) | ✅ Supported | Tool interoperability |
Selected Architecture: Hybrid approach using Hooks for event observation + Agent SDK for parallel sessions. ReCursor does not claim to mirror or control existing Claude Code sessions.
2. UI/UX Pattern
Section titled “2. UI/UX Pattern”ReCursor adopts OpenCode’s UI patterns for the mobile interface:
- Tool Cards: Rich, interactive cards for tool use and results
- Diff Viewer: Syntax-highlighted unified/side-by-side diffs
- Session Timeline: Visual timeline of agent actions and decisions
- Chat Interface: Streaming text with markdown rendering
3. Communication Pattern
Section titled “3. Communication Pattern”Mobile App <--WebSocket--> Bridge Server <--HTTP--> Claude Code Hooks ↑ | | ↓ └────────────────────────────────────── Observes Events- WebSocket: Bidirectional, real-time communication between mobile and bridge
- HTTP Hooks: One-way event streaming from Claude Code to bridge
- No Direct Mobile-to-Claude-Code: All communication flows through the bridge
Component Responsibilities
Section titled “Component Responsibilities”ReCursor Flutter App
Section titled “ReCursor Flutter App”| Component | Responsibility |
|---|---|
| UI Layer | Render OpenCode-style tool cards, diff viewer, timeline |
| State Management | Riverpod providers for sessions, messages, connection |
| WebSocket Client | Connect to bridge, handle reconnections, heartbeat |
| Local Storage | Drift for persistence, Hive for caching |
Bridge Server
Section titled “Bridge Server”| Component | Responsibility |
|---|---|
| WebSocket Server | Accept mobile connections, manage sessions |
| Event Queue | Buffer events from Hooks, replay on reconnect |
| HTTP Endpoint | Receive events from Claude Code Hooks |
| Agent SDK Adapter | Optional parallel session management |
Claude Code Integration
Section titled “Claude Code Integration”| Component | Responsibility |
|---|---|
| Hooks | POST events to bridge (tool use, messages, session state) |
| Agent SDK | Parallel agent session (if user wants independent agent) |
| Claude Code CLI | Source of truth for actual coding session |
Security Model
Section titled “Security Model”flowchart LR subgraph Network["Network Layers"] WireGuard["WireGuard/Tailscale\n(Network Layer)"] TLS["TLS 1.3\n(Transport Layer)"] Auth["Device Pairing Token\n(Application Layer)"] end
Phone["📱 Mobile"] --> WireGuard WireGuard --> TLS TLS --> Auth Auth --> Bridge["Bridge Server"]- Network Layer: Tailscale/WireGuard mesh VPN (or your preferred secure tunnel)
- Transport Layer: WSS (WebSocket Secure) with TLS 1.3
- Application Layer: Device pairing token on WebSocket handshake (no user accounts, no login)
Connection Mode Detection
Section titled “Connection Mode Detection”After establishing the WebSocket connection, the bridge analyzes the connection to determine the connection mode. This informs the user of the security posture and triggers appropriate warnings:
| Mode | Detection Criteria | Security Level | User Experience |
|---|---|---|---|
| Local-only | Loopback address (127.0.0.1, ::1) | ✅ Secure | House icon indicator |
| Private network | RFC1918 private IP (10.x, 172.16-31.x, 192.168.x) | ✅ Secure | WiFi icon indicator |
| Secure remote | Tailscale/WireGuard IP (100.x.x.x) or validated tunnel domain | ✅ Secure | Shield icon indicator |
| Direct public remote | Public IP or domain without tunnel validation | ⚠️ Warning | Warning triangle, requires acknowledgment |
| Misconfigured | ws:// instead of wss://, or other insecure setup | ❌ Blocked | Error screen, connection refused |
Health Verification: After connection_ack, the client sends a health_check message. The bridge responds with health_status including the detected connection mode. The app displays the mode indicator and, for “direct public remote,” requires explicit user acknowledgment before proceeding to the main shell.
Data Flow Summary
Section titled “Data Flow Summary”Outbound (Mobile → Agent)
Section titled “Outbound (Mobile → Agent)”- User sends message from mobile app
- Message queued locally (if offline)
- WebSocket transmits to bridge
- Bridge forwards to Agent SDK session (if active)
- Agent SDK calls Claude API
Inbound (Agent → Mobile)
Section titled “Inbound (Agent → Mobile)”- Claude Code executes tool/action
- Hooks POST event to bridge
- Bridge queues event (if mobile disconnected)
- WebSocket transmits to mobile
- UI renders OpenCode-style component
Limitations & Constraints
Section titled “Limitations & Constraints”| Constraint | Impact | Mitigation |
|---|---|---|
| Hooks are one-way | Cannot inject messages into Claude Code | Use Agent SDK for parallel session |
| No session mirroring | Mobile sees events but not full context | Hooks include rich event metadata |
| Requires local Claude Code | Cannot work without desktop agent | Clear user messaging, offline queue |
Related Documentation
Section titled “Related Documentation”- Data Flow Details — Message-level sequence diagrams
- Claude Code Hooks Integration — Hook configuration
- Agent SDK Integration — Parallel session setup
- OpenCode UI Patterns — UI component mapping
- Bridge Protocol — WebSocket message specification
- Security Architecture — Security implementation details
Last updated: 2026-03-17