Skip to main content
The Conversation Hub carries a conversation across channels. A topic started on Telegram continues when you open chatcli on your notebook; what you answer in the notebook becomes context on Telegram/Slack/WhatsApp. Both sides stay in sync — without you repeating anything.
The hub is a momentary bridge, not long-term memory. It keeps the current conversation in sync across channels, with a bounded database (automatic pruning). Persistent memory across projects/sessions is still the memory system (/memory) and /session save.

How it works

  • Principal: the shared conversation identity. In single-user mode (the default), the local CLI and the gateway collapse to the same principal (default if you set nothing), so everything shares with zero configuration.
  • hub.db: an append-only SQLite log (~/.chatcli/hub.db). The CLI and the gateway daemon open the same file — that is how they understand each other across processes.
  • Ephemeral per session: opening chatcli starts a fresh conversation and the previous one is pruned — the database never grows and you don’t load a giant history. Conversations idle past the TTL (CHATCLI_HUB_TTL_HOURS, default 24h) are swept.
  • Silent: turns from other channels enter the model’s context without being printed in your prompt (no noise, no “press Enter to continue”).
  • /newsession resets the shared conversation for every channel.
It works in chat, /agent and /coder: the request and the final answer cross channels (tool-execution detail stays local on each machine).

Modes

The simplest case — chatcli + gateway on one notebook, zero configuration (the default principal is enough):
Talk on the notebook, then pick up the topic on Telegram → it has the context. Send on Telegram with the prompt open → it enters the context of the notebook’s next turn.
Cross-process, the notebook picks up context on its next turn (there is no live push into an already-open prompt). For real time, use the co-located mode below.

Commands

Hub settings are mutable at runtime and persist in hub.db (read live by the gateway, no restart):
Resolution precedence: setting (db) > environment variable > default.

Shared identity (single-user vs multi-user)

With isolation on, the gateway also gives each principal its own store set — saved sessions, long-term memory, knowledge contexts, the CCR archive, cost snapshots, the transcript journal and the live conversation — rooted at ~/.chatcli/tenants/<principal>/. The set is installed for that sender’s turn and the shared set restored afterwards, so /session list from one chat never shows another user’s sessions and one user’s facts never surface in another’s turn. CHATCLI_GATEWAY_MAX_TENANTS (16) caps how many sets stay resident; the least recently used are released and rebuilt from disk on their next turn. Parked runs (/park, /resume) and task-graph runs follow the tenant root too, and CHATCLI_DAILY_BUDGET_USD caps each tenant’s spend per calendar day on its own. Everything derived from one conversation swaps with the set too: the session-start memory card, the undo stack of /rewind compact, the last auto-recall trace, the external memory provider’s forward watermark, staged inbound images and the last agent reply; the base memory worker keeps reading the base history while a tenant’s turn runs, and the MCP memory_recall / memory_store calls of an external provider carry a tenant argument. What stays process-wide is listed under “Shared across tenants” in /config security: hooks, the MCP manager (servers and OAuth), the reflexion runner, the REPL history file, the hub database and the scheduler — plus the squad board and the tokenizer vocabulary cache (public data).

Relationship to memory and sessions

The hub is an additive parallel rail: local history, /session save and memory keep working exactly as before. For durable continuity of one named conversation across REPL, IDE, MCP and gateway, see Cross-surface continuity — the hub remains the real-time bridge for the current turn.

Observability — the hub never dies silently

Continuity depends on the hub being up, so every state it can be in is explicit in the log:
  • Hub active: the daemon logs gateway: conversation hub active (principal=…, isolate=…, idle_ttl=…) at boot; the CLI logs local hub mode enabled.
  • Hub disabled: a Warn names the exact source of the decisiondb setting enabled=false, env CHATCLI_HUB_ENABLED=false or default — instead of simply making continuity vanish.
  • Daemon serving without the hub (database unreachable): a once-per-run warning makes it clear replies have no cross-channel context.
The daemon inherits the environment of the shell that ran /gateway start, and .env does not override already-exported variables. A forgotten CHATCLI_HUB_ENABLED=false in the shell kills continuity even with a correct .env — the provenance log above exists precisely to catch that (ps eww <pid> confirms the process’s real environment).

See also