Architecture

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.

01 / Client

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 TestFlight
02 / Account

Account 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 · Postgres
03 / Bridge

Local 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 · TypeScript
04 / Adapters

Per-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 · ACP
05 / Relay

Managed relay

Cloud service that routes encrypted frames between paired app and bridge devices so both sides can make outbound WebSocket connections.

TypeScript · managed pre-alpha

The path of a prompt.

What happens between typing "ls" on your phone and seeing the listing scroll back.

  1. You type "ls" on the client.
  2. 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.
  3. 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.
  4. Bridge accepts a direct protocol message or decrypts a relay envelope, then parses it and dispatches to the right adapter.
  5. Adapter calls the agent's native API.
  6. Agent emits its native tool_start / stdout / file_changed events.
  7. Adapter translates each event to a Helmora Protocol session/update, hands to the bridge.
  8. 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.
  9. 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 client does not render a Steer affordance. 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 maxTokens.

CapabilityMeaning
interruptStop a turn the adapter can actually control.
steerInject or redirect a live turn, with the adapter declaring its steer mode.
queueHold a prompt for delivery after the current turn.
toolApprovalShow an approval surface before a gated tool executes.
toolStreamsStream tool progress and output.
plansRender structured plan state when the runtime provides it.
usage / planUsageSurface per-turn tokens and provider-plan usage windows.
modelsPopulate model, effort, and mode controls from runtime metadata.

Explore the current docs →