dashsquad

Architecture

The parts of dashsquad, how they connect, and how a message moves through them.

dashsquad has one central process, the HQ, that runs your agents. Desktop, the web app and the phone apps are clients of the HQ. Away from the HQ machine, clients reach it through the hosted relay.

System overview

PartWhat it does
HQA long-lived background process that runs all your agents. It keeps conversations, credentials and settings, and it connects to AI providers, Telegram and WhatsApp.
DesktopThe desktop app. It starts the HQ, and you use it to deploy agents, chat, and change settings.
RelayA hosted service that dashsquad operates. It forwards traffic from your devices to the HQ through a connection that the HQ opens.
Control planeA hosted service that keeps your dashsquad account, the addresses of your HQs, and your paired devices.
Web app, iOS app, Android appClients that connect to your HQ through the relay.

The HQ

The HQ is one process. It keeps all agents in memory and owns all conversations. It has two servers, and both servers listen only on 127.0.0.1:

ServerDefault portPurpose
Management API9300Health, agents, conversations, credentials, models, settings. Also the /mobile/v1 API for the apps.
Channel server9200The /ws/chat WebSocket for live chat.

The HQ has no listener on your local network. Other devices reach it only through the relay. See the API reference for the endpoints.

Paths and ports on this page

The paths ~/.dash/gateway and the ports 9300 and 9200 on this page apply to a standalone HQ. An HQ that Desktop starts keeps its files in ~/.dashsquad/<hq-id>/. It uses free ports and writes them to ports.json in that folder. See Configuration.

Desktop starts the HQ as a separate process on its first start. When you close Desktop, the HQ continues to operate. When Desktop starts again, it finds the HQ and uses it again. Desktop keeps the HQ tokens in the system credential store: the macOS Keychain, Windows Credential Manager, or the Linux secret service.

The HQ also supplies these functions:

  • AI providers. The HQ calls the provider APIs directly. Built-in providers are Anthropic, Google, Moonshot (Kimi), OpenAI and OpenRouter. Plugins can add more. Model IDs use the provider/model format. See AI Providers.
  • Agents. An agent loads the conversation context, calls the model, and runs the tools that the model asks for. It continues until the model gives a final reply.
  • Telegram and WhatsApp. The HQ connects out to these platforms. See Telegram and WhatsApp.
  • Credentials. The HQ keeps provider keys and bot tokens in ~/.dash/gateway/credentials.enc, encrypted with AES-256-GCM. See Secrets.

Deployment options

OptionHow
This computerThe default. Desktop starts the HQ on the same computer and connects over loopback.
Remote HQThe HQ operates on a different computer, for example a VPS. Desktop connects to it through the relay. See Remote HQ runtime.

How clients reach the HQ

ClientConnection
Desktop (local HQ)Loopback HTTP to port 9300 and a loopback WebSocket to port 9200.
Desktop (remote HQ)Through the relay, with the tokens that you give in Desktop.
iOS appYou sign in with your dashsquad account and select an HQ. The app then connects through the relay.
Android appYou scan the Pair Device QR code in Desktop. The QR code has the relay address of the HQ and a credential for this device.
Web appYou sign in with your dashsquad account. The web app connects to the HQ through the relay.

The authenticated GET /v1/gateways response can include online for each HQ. true means the relay has an open connection to that HQ. false means a presence check confirmed that no connection was open at the time of the check. If online is absent, the connection state is unknown. A failed or unsupported presence lookup can omit this field. An open relay connection does not guarantee that agents or AI providers can run.

No client gets the administrative token of the HQ. Each device gets a phone-scoped token and its own device credential. You can revoke a device credential at any time. See Remote access.

Local network pairing was removed

Earlier releases let phones connect over the local network. dashsquad removed this listener and local network pairing. The HQ ignores the old --lan-port flag. If your phone has an old local network profile, pair it again through the relay.

Remote access identity

The HQ proves its identity to the relay with its own key pair, not with a shared password.

  • On the first start, the HQ makes an Ed25519 key pair. It keeps the private key in ~/.dash/gateway/relay-gateway-key, which only your user can read. The private key never leaves the machine.
  • dashsquad gets only the public key. Thus, the hosted services hold nothing that can act as your HQ.
  • An organization owns your HQs, not one person. To set up remote access, you sign in to dashsquad in Desktop. Desktop selects the organization for you. A new account gets an organization with the name My squad. You can then share access with teammates.
  • Each HQ has its own address on the relay. Desktop makes the address from a generated ID, so you do not select it. dashsquad never gives that address to a different HQ, also after you remove the HQ.
  • At first, the name of the HQ is the computer name of your Mac. You can change it in the setup wizard or in the HQ card in Desktop.

When the HQ connects to the relay, it sends its address token and a short-lived proof that it signs with the private key. The relay makes sure that dashsquad issued the token for that address. It also makes sure that the HQ holds the private key for that token. A copied token is thus not sufficient to connect.

Address tokens have a short life. The HQ gets a new token by itself:

  • on a timer, before the old token expires
  • after the relay refuses a connection
  • when the HQ starts, also after many days off

Thus, an HQ that was off reconnects by itself. You do not enroll it again, and Desktop does not have to be open.

Conversation history across devices

The HQ keeps the one true copy of each conversation. Desktop, the web app, the iOS app and the Android app show the same history. This history includes the turn that is in progress, replay of missed output, names, and deletions.

  • Desktop keeps a read cache, so you can see history when the HQ is offline. Desktop does not change this cache directly.
  • If a client disconnects, the turn continues on the HQ. The turn stops only when it is complete or when a client cancels it.

Steer and Follow Up

Each conversation has one active run and a queue of inputs on the HQ. When you send a message during a run, you select how the HQ uses it:

ChoiceWhat happens
SteerThe HQ gives the message to the current run at a safe point.
Follow UpThe message waits in the queue for a later run.

The queue stays on the HQ, so it continues after a reconnection or a restart. If you stop the active run or a run fails, the HQ pauses the queue until you click Resume Follow Ups.

The HQ can also make the choice for you. A decision model reads your message, the current task and the reply so far. If the model is sure, the HQ applies its choice and shows it as automatic. If the model is not sure, or does not answer in time, the app asks you. See Message routing.

Message flow

These steps show what occurs when you send a message from a dashsquad app.

Load the conversation

The app makes or loads the conversation on the HQ.

Send the message

Desktop sends the message on the loopback chat socket. The other apps send it on the chat socket through the relay. The message has a turn ID and the conversation ID.

Accept the turn

In one database transaction, the HQ locks the conversation for this turn and makes the user and assistant messages. Then it tells the app that it accepted the turn.

Run the agent

The HQ runs the agent. The agent calls the model and runs the tools that the model asks for.

Save, then send

The HQ gives each piece of output a sequence number and saves it. Then it sends the output to all apps that show this conversation.

Finish or reconnect

If an app loses its connection, it can replay the missed output and attach to the same turn again. The turn ends when the agent completes, fails, or a client cancels it.

Desktop and a phone app see the same turn. Each app can show the output, answer a question from the agent, or cancel the turn. If you close one app, the work continues. For the frame format, see Chat WebSocket.

Where the HQ keeps conversations

DataLocation
Conversations, messages, the active turn and the replay journal~/.dash/gateway/agent-stream-events.db (SQLite)
Model context for each conversation~/.dash/gateway/sessions/<agent-name>/<conversation-id>/ (JSONL files)

The database is the history that the apps show. The JSONL files keep the context that the agent sends to the model on the next call.

The HQ saves each event before it sends it. Thus, if an app gets event 12, it can always replay event 12 later. If the HQ stops during a turn, it marks the turn as interrupted when it starts again.

Sub-agents

An agent can give a self-contained task to a sub-agent. A sub-agent is a child agent that works in the same workspace, with its own context. The parent can wait for the report of the child in its own turn (foreground). Or the parent can let the child operate on its own (background) and get a message when it is complete. The tools are agent and send_message.

A sub-agent is a conversation. Each child has its own conversation, messages, status and session folder. Thus, you can replay its transcript, resume it after it is complete, and keep it after an HQ restart. The normal conversation list does not show child conversations. You open them from the parent. The HQ credentials that give access to a conversation also give access to its sub-agents.

Limits. Cancellation of a foreground turn also cancels its children. A background child continues after the turn. Each child has a time limit (maxRunSeconds). When you cancel a child or delete its conversation, all work that it started stops. See Sub-agents for the limits.

The parent starts children

The agent tool finds the sub-agent type and gives the child only tools that the parent also has. The HQ applies the limits for each agent and for the HQ before it starts a child. More than one child can operate at the same time.

The children work

Each child works from its prompt. With isolation: worktree, a child gets its own git worktree. A child can stop and ask the parent a question.

The apps show each child

The conversation of the parent shows one row for each child, with its status and report. The text and tool output of a child stay in the conversation of the child. An app loads them when you open the row.

The report comes back

The report of a foreground child is the result of the agent tool. For a background child, the HQ starts a new turn on the parent with a notification.

Notification turns. When a background child is complete, the HQ starts a system turn on the parent conversation. The parent sees the notification as an automatic event, not as a message from you. If the parent is busy, the notification waits until its current turn is complete. The apps show the notification as a small system row.

Where to see sub-agents. Desktop has a Sub-agents panel. The web app and the iOS app show sub-agents in Tasks. All three use the HQ routes to list, stop and resume sub-agents. See the API reference.

After a restart. If the HQ stops during a run, it marks each sub-agent that was in progress as interrupted when it starts again. It keeps the transcript and tells each parent. You or the parent agent can resume an interrupted sub-agent. The HQ also removes old sub-agent worktrees, but it keeps worktrees that have unsaved work.

On this page