// docs
monorepo tour
The CozyLabs monorepo is a pnpm workspace of bounded contexts: each package owns one domain and
documents its own language in a CONTEXT.md glossary.
the map
| package | what it is |
|---|---|
packages/contract | the wire protocol: event envelope, DTOs, request/response shapes, WebSocket messages. The single source of truth shared by everything below. |
packages/crypto | the primitives layer over libsodium: identities, sealing, CK wrap/unwrap, signatures, artifact streams. Fixed algorithms, no knobs. |
packages/relay | the server: Postgres-backed encrypted event relay, REST API, auth, memberships, vault metadata. Zero-knowledge about content. |
packages/web-session | the browser-side session client: seals/opens events in the browser, holds the human identity in IndexedDB, signs management proofs. |
packages/agent-core | the agent’s local runtime: sealed keystore, relay client, board projection, the agent daemon. |
packages/cli | collab, the command-line shell over agent-core: pair, approval wait, agent run, board verbs. |
packages/mcp | the MCP server exposing agent-core verbs as collab_* tools plus the one-call broker_* interface. |
packages/mcp-gateway | the networked, multi-tenant MCP enrollment gateway: zero-install remote-agent self-enroll over TLS with a human-minted pairing code (MCP config only, no install); custodies remote-agent keystores and does crypto on their behalf (ADR-0028). |
packages/companion | the long-lived host process that runs many hosted agents as Hermes profiles inside one container, each with its own loopback gateway (ADR-0059). |
packages/agent-deployer | the host-side daemon that turns agent_deploy.* relay events into profiles on the companion; holds no docker socket. |
packages/dashboard-core | the framework-neutral dashboard data layer and React component library shared by the web app and Electron desktop renderer. |
packages/ui | the shared design-system component library: tactile workshop chrome, identity surfaces, and vault screens. |
packages/vault | secret storage: OpenBao KV-v2 holds credential values; the relational side holds metadata only. |
packages/vault-broker | the operator-side fulfiller that uses credentials on an agent’s behalf; the agent never sees them. |
apps/cozylabs | the Next.js dashboard: unlock, Agent Work board, members, vault management, settings. |
apps/desktop | the self-contained Electron app: embeds the relay, broker, and local agents as supervised child processes; renders the same dashboard. |
apps/ios | the CozyChat iOS client: Swift, ZK sealed DMs, and the CozyKit framework for cross-client keystore compatibility. |
deploy/ | the compose stack, TLS/tunnel overrides, bootstrap/backup/restore/validation scripts. |
security/ | cross-package adversarial and full-flow tests proving the SO invariants end to end. |
docs/adr/ | architecture decision records: the why behind every non-obvious choice. |
how a task flows through it
dashboard (web-session) agent (agent-core + mcp)
seal + sign task.created ──────────┐ │
▼ ▼
relay (contract shapes)
verify sig · assign seq · store ciphertext
│
WSS fan-out to subscribers
│
fold into board ◀───────────────────┴──────▶ fold into board
(decrypt locally) (decrypt locally)
The relay never decrypts; both ends verify every signature independently. The relay and contract pages go deeper.
decisions live next to the code
Non-obvious choices are recorded as ADRs, from “forward-only migrations, restore to roll back” to “re-pairing mints a new principal” to “DMs are per-pair sealed”. When a docs page here cites an ADR number, that’s the file it means.