# tiann/hapi architecture

> Architecture diagram of the GitHub repository tiann/hapi, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/tiann/hapi
- Repository: https://github.com/tiann/hapi

## Overview

HAPI runs supported AI-agent sessions on a user’s machine and lets native and web clients control them remotely. The main workflow is to launch an agent through the CLI, synchronize its session through the hub, and view or act on it from a paired client; the README also documents handoff, approvals, files, workspace browsing, voice, and push. The graph preserves those product branches. Some subsystem links are documented capabilities rather than inspected call sites, so those edges are dashed with no evidence path.

Main entry points: [`hub/src/web/server.ts`](https://github.com/tiann/hapi/blob/main/hub/src/web/server.ts) (Hub server), [`hub/src/sync/syncEngine.ts`](https://github.com/tiann/hapi/blob/main/hub/src/sync/syncEngine.ts) (Session sync), [`web/src/App.tsx`](https://github.com/tiann/hapi/blob/main/web/src/App.tsx) (Web client), [`android/app/src/main/kotlin/app/hapi/companion/HapiApp.kt`](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/HapiApp.kt) (Native apps)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Agent runtime"]
  node_cli["CLI launcher<br/>[bootstrap.ts]"]
  node_agent["Agent sessions<br/>[sessionFactory.ts]"]
  node_terminal["Remote terminal<br/>[TerminalManager.ts]"]
end

subgraph group_hub["Hub and sync"]
  node_hubserver["Hub server<br/>[server.ts]"]
  node_sync["Session sync<br/>[syncEngine.ts]"]
  node_sessionstore[("Session store<br/>[sessions.ts]")]
  node_sse["Live events<br/>[sseManager.ts]"]
  node_workspace["Workspace browser<br/>[tunnelManager.ts]"]
end

subgraph group_clients["Remote clients"]
  node_web["Web client<br/>[App.tsx]"]
  node_native["Native apps<br/>[HapiApp.kt]"]
  node_chat["Chat experience<br/>[ChatScreen.kt]"]
  node_pairing["Pairing<br/>[PairingClient.kt]"]
  node_files["Files and sessions<br/>[FilesGateway.kt]"]
  node_push["Push actions"]
end

subgraph group_transport["Connectivity"]
  node_relay["Encrypted relay<br/>[index.ts]"]
end

subgraph group_protocol["Shared protocol"]
  node_wire["Wire protocol<br/>[HapiJson.kt]"]
  node_messagewindow["Message windows"]
end

node_user(("User"))

node_user -.->|"starts session"| node_cli
node_cli -.->|"launches agent"| node_agent
node_agent -.->|"syncs session"| node_hubserver
node_user -.->|"controls remotely"| node_web
node_user -.->|"controls remotely"| node_native
node_hubserver -.->|"routes sessions"| node_sync
node_sync -->|"stores sessions"| node_sessionstore
node_sync -->|"publishes events"| node_sse
node_web -.->|"receives updates"| node_sse
node_native -.->|"receives updates"| node_sse
node_user -.->|"pairs device"| node_pairing
node_pairing -.->|"registers client"| node_hubserver
node_web -.->|"views sessions"| node_chat
node_native -.->|"views sessions"| node_chat
node_chat -.->|"renders messages"| node_messagewindow
node_web -.->|"browses files"| node_files
node_user -.->|"browses workspace"| node_workspace
node_terminal -.->|"connects remotely"| node_hubserver
node_hubserver -.->|"uses relay"| node_relay
node_native -.->|"receives notifications"| node_push
node_sync -->|"uses event format"| node_wire
node_wire -.->|"supplies messages"| node_messagewindow

click node_cli "https://github.com/tiann/hapi/blob/main/cli/src/bootstrap.ts"
click node_agent "https://github.com/tiann/hapi/blob/main/cli/src/agent/sessionFactory.ts"
click node_terminal "https://github.com/tiann/hapi/blob/main/cli/src/terminal/TerminalManager.ts"
click node_hubserver "https://github.com/tiann/hapi/blob/main/hub/src/web/server.ts"
click node_sync "https://github.com/tiann/hapi/blob/main/hub/src/sync/syncEngine.ts"
click node_sessionstore "https://github.com/tiann/hapi/blob/main/hub/src/store/sessions.ts"
click node_sse "https://github.com/tiann/hapi/blob/main/hub/src/sse/sseManager.ts"
click node_workspace "https://github.com/tiann/hapi/blob/main/hub/src/tunnel/tunnelManager.ts"
click node_relay "https://github.com/tiann/hapi/blob/main/relay/src/index.ts"
click node_web "https://github.com/tiann/hapi/blob/main/web/src/App.tsx"
click node_native "https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/HapiApp.kt"
click node_chat "https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/chat/ChatScreen.kt"
click node_pairing "https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/pairing/PairingClient.kt"
click node_files "https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/files/FilesGateway.kt"
click node_push "https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/fcm/HapiFirebaseMessagingService.kt"
click node_wire "https://github.com/tiann/hapi/blob/main/android/core/protocol/src/main/kotlin/app/hapi/protocol/wire/HapiJson.kt"
click node_messagewindow "https://github.com/tiann/hapi/blob/main/ios/Packages/HapiKit/Sources/HapiProtocol/Window/MessageWindowLogic.swift"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_agent,node_terminal,node_user toneBlue
class node_hubserver,node_sync,node_sessionstore,node_sse,node_workspace toneAmber
class node_web,node_native,node_chat,node_pairing,node_files,node_push toneMint
class node_relay toneRose
class node_wire,node_messagewindow toneIndigo
```

## Components

### Agent runtime

- [CLI launcher](https://github.com/tiann/hapi/blob/main/cli/src/bootstrap.ts): `cli/src/bootstrap.ts`
- [Agent sessions](https://github.com/tiann/hapi/blob/main/cli/src/agent/sessionFactory.ts): `cli/src/agent/sessionFactory.ts`
- [Remote terminal](https://github.com/tiann/hapi/blob/main/cli/src/terminal/TerminalManager.ts): `cli/src/terminal/TerminalManager.ts`

### Hub and sync

- [Hub server](https://github.com/tiann/hapi/blob/main/hub/src/web/server.ts): `hub/src/web/server.ts`
- [Session sync](https://github.com/tiann/hapi/blob/main/hub/src/sync/syncEngine.ts): `hub/src/sync/syncEngine.ts`
- [Session store](https://github.com/tiann/hapi/blob/main/hub/src/store/sessions.ts): `hub/src/store/sessions.ts`
- [Live events](https://github.com/tiann/hapi/blob/main/hub/src/sse/sseManager.ts): `hub/src/sse/sseManager.ts`
- [Workspace browser](https://github.com/tiann/hapi/blob/main/hub/src/tunnel/tunnelManager.ts): `hub/src/tunnel/tunnelManager.ts`

### Remote clients

- [Web client](https://github.com/tiann/hapi/blob/main/web/src/App.tsx): `web/src/App.tsx`
- [Native apps](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/HapiApp.kt): `android/app/src/main/kotlin/app/hapi/companion/HapiApp.kt`
- [Chat experience](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/chat/ChatScreen.kt): `android/app/src/main/kotlin/app/hapi/companion/feature/chat/ChatScreen.kt`
- [Pairing](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/pairing/PairingClient.kt): `android/app/src/main/kotlin/app/hapi/companion/feature/pairing/PairingClient.kt`
- [Files and sessions](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/feature/files/FilesGateway.kt): `android/app/src/main/kotlin/app/hapi/companion/feature/files/FilesGateway.kt`
- [Push actions](https://github.com/tiann/hapi/blob/main/android/app/src/main/kotlin/app/hapi/companion/fcm/HapiFirebaseMessagingService.kt): `android/app/src/main/kotlin/app/hapi/companion/fcm/HapiFirebaseMessagingService.kt`

### Connectivity

- [Encrypted relay](https://github.com/tiann/hapi/blob/main/relay/src/index.ts): `relay/src/index.ts`

### Shared protocol

- [Wire protocol](https://github.com/tiann/hapi/blob/main/android/core/protocol/src/main/kotlin/app/hapi/protocol/wire/HapiJson.kt): `android/core/protocol/src/main/kotlin/app/hapi/protocol/wire/HapiJson.kt`
- [Message windows](https://github.com/tiann/hapi/blob/main/ios/Packages/HapiKit/Sources/HapiProtocol/Window/MessageWindowLogic.swift): `ios/Packages/HapiKit/Sources/HapiProtocol/Window/MessageWindowLogic.swift`

### Other components

- **User**

## Connections

- User → CLI launcher: starts session (evidence: `README.md`)
- CLI launcher → Agent sessions: launches agent (evidence: `README.md`)
- Agent sessions → Hub server: syncs session (evidence: `README.md`)
- User → Web client: controls remotely (evidence: `README.md`)
- User → Native apps: controls remotely (evidence: `README.md`)
- Hub server → Session sync: routes sessions
- Session sync → Session store: stores sessions (evidence: `hub/src/sync/syncEngine.ts`)
- Session sync → Live events: publishes events (evidence: `hub/src/sync/syncEngine.ts`)
- Web client → Live events: receives updates (evidence: `README.md`)
- Native apps → Live events: receives updates (evidence: `README.md`)
- User → Pairing: pairs device (evidence: `README.md`)
- Pairing → Hub server: registers client (evidence: `README.md`)
- Web client → Chat experience: views sessions (evidence: `README.md`)
- Native apps → Chat experience: views sessions (evidence: `README.md`)
- Chat experience → Message windows: renders messages
- Web client → Files and sessions: browses files (evidence: `README.md`)
- User → Workspace browser: browses workspace (evidence: `README.md`)
- Remote terminal → Hub server: connects remotely (evidence: `README.md`)
- Hub server → Encrypted relay: uses relay (evidence: `README.md`)
- Native apps → Push actions: receives notifications (evidence: `README.md`)
- Session sync → Wire protocol: uses event format (evidence: `hub/src/sync/syncEngine.ts`)
- Wire protocol → Message windows: supplies messages
