Process boundaries
Which process runs each part, how calls cross the boundaries, how sessions relate to worktrees and threads, and where to start reading the source.
Checked against the source on 17 September 2026
On this page
The implementation stack
PlanToCode has four application boundaries and one agent process boundary. The desktop frontend is React and TypeScript inside a Tauri 2 WebView. Its Rust backend owns local commands, SQLite product state, the remote RPC router, and the Codex child process. The server is Rust with Actix Web, Tokio, SQLx for PostgreSQL, and Redis integration. The iOS companion uses Swift and SwiftUI, with UIKit for its chat collection view, and the Android companion uses Kotlin and Jetpack Compose. Both phones speak the same RPC contract to the desktop.
- Rust runtimecommands · remote_api
Serves the WebView’s commands and the phones’ RPC with the same domain services. It owns appdata.db and reads project files and Git itself.
- Codex app-server--listen stdio://
A child process, one per profile pair, and no more than three stay running unless all are busy. The runtime reads its history over the pipe with thread/items/list, never from its files.
- Regional server/ws/device-link
Runs in the US or the EU and passes messages between the socket the desktop opened and each phone’s socket. It keeps accounts, device rows, and presence, never project files or transcripts.
Trace a mobile request to execution
- Relayrequest_validation.rs
Checks the method name and the idempotency key and leaves the params to the desktop, except for session.syncHistoryState. When the desktop is offline or reconnecting, it answers -32010 or -32011 itself.
- RPC intakesnapshot_and_rpc.rs · router
Runs for every phone request: 8 light and 2 heavy slots, then the account match. A mutation takes a durable idempotency claim, and the adapter decodes the params into a request type that rejects unknown fields.
- Tauri commandcapabilities/default.json
Lets the main and session windows call workspace commands. Tauri decodes the arguments into the same request type, so unknown fields fail here too.
- Outbox servicesubmit_outbox_request
Both paths call it, so its rules hold for every caller, and a repeated operationId never adds a second message. It saves the message and returns the receipt, and a drain task starts the turn later.
Keep business rules in the domain service, where both paths meet. Matching UI controls are not an authorization check. The relay also answers -32012 when a desktop does not finish a request before the relay’s timeout, and the relay chapter lists its codes and timers.
Projects, worktrees, and sessions
- Worktreegit worktree list
PlanToCode lists the worktrees that exist and never creates one. A session is created in one of them, and the desktop rejects a projectDirectory that is not a worktree of the project.
- Subagent threadactiveRun: null
Spawned by the agent during its parent’s turn, in the parent’s worktree. It has its own timeline and live overlay, and only the parent reports the active run.
- Device selectionappSessionId
Each device picks its project, worktree, and session by itself, so two devices can show the same session or different ones. A subagent thread is opened through its session.
A project is a Git repository, grouped under its main worktree. A folder without Git is a project whose only workspace is the folder itself.
Navigate the source tree
| Path from repository root | Start here for |
|---|---|
| desktop/src/app/components/workspace-chat/ | React workspace composition, timeline state, viewport ownership, and outbox display. |
| desktop/src-tauri/src/commands/ | Tauri entry points and desktop domain operations. |
| desktop/src-tauri/src/services/codex_app_server/ | Child process transport, client actors, turn admission, and registry ownership. |
| desktop/src-tauri/src/remote_api/ | RPC types, validation, idempotency, dispatch, and remote method adapters. |
| server/src/services/device_link_ws/ | WebSocket registration, request validation, forwarding, and connection lifecycle. |
| mobile/ios/Core/Sources/Core/Connectivity/Relay/ | iOS relay connection and method contract. |
| mobile/ios/VibeUI/Sources/VibeUI/Features/Workspace/Chat/ | iOS chat ownership, timeline reconciliation, and collection rendering. |
| mobile/android/app/src/main/java/com/plantocode/mobile/ | Android entry routing, workspace tabs, relay client, and Compose screens. |