How Helmora fits together.
Helmora separates identity, transport, local execution, and agent-specific behavior. The account service pairs devices, the managed relay routes encrypted remote traffic, and the bridge invokes agents on your machine through first-party adapters.
The five responsibilities
Each part does one job and ships on its own cadence. Adapters absorb churn from individual agent runtimes while the shared client and protocol stay stable.
Client app
One Expo + React Native codebase. The current private pre-alpha is exercised on web and iOS TestFlight; Android and desktop artifacts are not publicly offered.
Web · iOS TestFlightAccount service
Authenticates users, pairs app and bridge devices, issues short-lived device-scoped relay tokens, and stores identity, device, agent, notification, and subscription metadata.
Hono · Better Auth · PostgresLocal bridge
Small Node / TypeScript daemon you run beside your agents. Hosts adapters, coordinates local session state, and terminates endpoint encryption when the relay is in the path.
Node · TypeScriptPer-agent adapters
First-party integrations for Claude Code, Codex, and Copilot, plus a generic ACP core with OpenCode and Goose presets. Each translates its runtime's events and reports the controls it can actually support.
Claude Code · Codex · Copilot · ACPManaged relay
Cloud service that routes encrypted frames between paired app and bridge devices so both sides can make outbound WebSocket connections.
TypeScript · managed pre-alphaThe path of a prompt.
What happens between typing "ls" on your phone and seeing the listing scroll back.
- You type "ls" on the client.
- Client frames it as a Helmora Protocol session/prompt. On the relay path it encrypts with the per-device Double Ratchet and sends the opaque envelope over WebSocket.
- If a relay is in the path, it routes ciphertext within the authenticated user's device map. Same-machine loopback or an operator-authenticated TLS/SSH tunnel bypasses the relay-specific wrapper.
- Bridge accepts a direct protocol message or decrypts a relay envelope, then parses it and dispatches to the right adapter.
- Adapter calls the agent's native API.
- Agent emits its runtime-native tool, stdout, and diff events.
- Adapter translates each event to a Helmora Protocol session/update, hands to the bridge.
- Only the relay path wraps the update in the endpoint ratchet. Direct loopback or an authenticated TLS/SSH tunnel returns the protocol message inside that transport; the client unwraps when required and updates the transcript in real time.
- Turn ends. Bridge sends session/prompt response with stopReason.
Why this shape works.
- Adapters absorb churn. When an agent framework ships a breaking change, only that adapter updates. The client is untouched.
- Capabilities absorb heterogeneity. If an adapter does not support steer, the Steer option is disabled with the reason, and a steer request degrades safely to queue. Agent-specific checks stay out of shared UI.
- The relay absorbs network complexity. Both client and bridge make outbound WebSocket connections; the bridge does not need an inbound public port.
- E2EE narrows the relay boundary. Endpoint keys keep protocol payloads out of the relay. Routing metadata remains visible, and the account service remains the trusted identity directory.
- The bridge absorbs local variation. Windows, macOS, and Linux differences stay on the machine side. The client does not need to know how a runtime is installed or authenticated.
Capabilities.
Each adapter declares what it can do. The client renders only the affordances that are supported. Capabilities can change mid-session — for example, a model swap can change contextWindow.
| Capability | Meaning |
|---|---|
| interrupt | Stop a turn the adapter can actually control. |
| steer | Inject or redirect a live turn, with the adapter declaring its steer mode. |
| queue | Hold a prompt for delivery after the current turn. |
| toolApproval | Show an approval surface before a gated tool executes. |
| toolStreams | Stream tool progress and output. |
| plans | Render structured plan state when the runtime provides it. |
| usage / planUsage | Surface per-turn tokens and provider-plan usage windows. |
| models | Populate model, effort, and mode controls from runtime metadata. |