Files
simplex-orchestrate/CLAUDE.md
Jon 38ff96c576 Scaffold SimpleX Orchestrate: supervisor over official binaries
A standalone control-plane app that spawns and drives the official SimpleX
binaries (never modifies simplex source). Validated against simplex-chat
built from source (stable v6.5.4, GHC 9.6.3).

- CLAUDE.md: architecture notes mined from the upstream docs (WebSocket bot API,
  per-profile DBs, directory/broadcast bot config)
- supervisor/: process registry + port allocation (supervisor.py), corrId/cmd<->resp
  WebSocket client (ws_client.py), binary locator (binaries.py), FastAPI front with
  REST control + /events stream (server.py)
- smoke_test.py: Pattern-1 handshake (spawn simplex-chat -p, create+read user) — PASS
- group_test.py: two accounts, invitation connect + group invite/join, verified
  membership over the real SMP network — PASS
- build_chat.sh / install_ghc.sh: reproducible toolchain + from-source build

Key finding: fresh DB prompts for a display name on stdin; spawn with
--create-bot-display-name to start the WebSocket server non-interactively.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 12:31:37 +01:00

7.3 KiB

SimpleX Orchestrate — project notes for Claude

Goal: a web-managed orchestrator that runs the official SimpleX binaries (instead of re-implementing bot logic against the FFI libsimplex SDK, as the older simplex-manager prototype did). The manager spawns/supervises real SimpleX processes, drives the interactive ones over WebSocket, and reads the autonomous ones' output.

Reference checkout: ./simplex-chat/ (cloned from https://github.com/simplex-chat/simplex-chat). All facts below are taken from that repo's own docs — cited inline. There is no CLAUDE.md / AGENTS.md in the upstream repo; the authoritative interface docs are:

  • simplex-chat/bots/README.md — bot architecture & WebSocket API
  • simplex-chat/bots/api/COMMANDS.md, EVENTS.md, TYPES.md — full command/event/type reference
  • simplex-chat/docs/CLI.md — terminal client / DB / server flags
  • simplex-chat/apps/*/README.md + src/.../Options.hs — the official bot binaries
  • Official TypeScript SDK: simplex-chat/packages/simplex-chat-client/typescript/

Two integration patterns (this is the core design decision)

1. Interactive accounts → drive the CLI over WebSocket (bots/README.md)

  • Run the terminal client as a local WebSocket server: simplex-chat -p 5225
  • Our process connects over WebSocket and sends JSON commands / receives events.
  • This is how custom bots (TS/Python/Rust) and our manager talk to a profile.
  • Same command strings as the app's Settings → Developer tools → Chat Console.

2. Autonomous official bots → run the prebuilt Haskell binary directly

  • simplex-directory-service and simplex-broadcast-bot are standalone executables built on the chat core. They run their own logic, with their own DB + config, no WebSocket.
  • The manager's job for these is lifecycle (spawn/stop/monitor/logs) + reading their output.
  • Use these instead of reimplementing directory/broadcast in Python — they're battle-tested and include captcha, moderation, approval, periodic re-checks, website generation, etc.

WebSocket protocol (pattern 1) — bots/README.md

  • simplex-chat -p <port> starts the WS server. localhost only, NO authentication — keep the bot process on the same machine and firewall the port. Messages are unencrypted.
  • Command: {"corrId":"<unique>", "cmd":"<command string>"}
  • Response: {"corrId":"<same>", "resp":{"type":"<tag>", ...}} (matched by corrId)
  • Event: {"resp":{"type":"<tag>", ...}} (no corrId — connections, received messages, etc.)
  • NewChatItems arrives both as a command response (after APISendMessages) and as an event.
  • Parser must ignore unknown event types / union tags / extra fields (forward-compat rule).
  • Minimal bot loop: handle NewChatItems event → reply with APISendMessages.
  • Network usage per command is documented: no / interactive / background.

Per-profile databases — docs/CLI.md

  • simplex-chat -d <prefix> → creates <prefix>_v1_chat.db and <prefix>_v1_agent.db.
  • Default data dir ~/.simplex (%APPDATA%/simplex on Windows).
  • One process = one DB prefix. A single DB can hold multiple bot profiles via /create bot [files=on] <name> [<bio>], but the simple model is one process per profile.
  • SMP servers: -s smp://<fp>@host. Tor: -x or --socks-proxy=:9050. simplex-chat -h for all.

Bot profile setup — bots/README.md (needs app/CLI v6.4.3+)

  • Mark a profile as a bot: peerType: "bot". Set via:
    • CLI flags --create-bot-display-name, --create-bot-allow-files on first start, or
    • /create bot [files=on] '<name>' [<bio>], or
    • APIUpdateProfile (also sets command menus).
  • Command menus: /set bot commands '<label>':/'<keyword>[ <params>]', '<label>':{...nested...} (e.g. directory's 'Show your groups':/list). Per-contact overrides via APISetContactPrefs.
  • Business address (support): a special group chat per connecting customer; inherits the bot's preferences/commands. See docs/BUSINESS.md.

Official bot: Directory service — apps/simplex-directory-service/ (Directory/Options.hs)

Run the simplex-directory-service binary; it manages registration + search and writes the website files itself. Replaces the Python directory reimplementation in the old prototype.

Key CLI options:

  • --super-users CONTACT_ID:DISPLAY_NAME,... (required) — who can approve/manage listings
  • --admin-users CONTACT_ID:DISPLAY_NAME,... — directory managers
  • --owners-group GROUP_ID:DISPLAY_NAME — owners of listed groups auto-invited
  • --directory-file PATH — append-only log holding directory state
  • --web-folder PATHwhere static web assets / group listing files are written (this is what feeds the directory website; our old web/<bot>/data/listing.json was a hand-rolled stand-in)
  • --service-name "SimpleX Directory" — bot display name (default shown)
  • --captcha-generator EXE / --voice-captcha-generator EXE — anti-spam
  • --blocked-words-file / --blocked-fragments-file / --blocked-extenstion-rules / --name-spelling-file / --profile-name-limit — moderation
  • --link-check-interval SECONDS (default 1800) — periodic re-check of public group links
  • --run-cli — interactive CLI mode
  • --migrate-directory-file <check|import|export|listing>listing = saveGroupListingFiles regenerates the website listing files from the log
  • plus core chat options (DB file, SMP servers, Tor) shared with the CLI
  • Registration flow = owner adds the bot to their group; listing stays pending until a super-user approves (matches what we scoped for the prototype).

Official bot: Broadcast — apps/simplex-broadcast-bot/

  • --display-name, --publishers CONTACT_ID:DISPLAY_NAME,..., --welcome, --prohibited (+ core DB/SMP options). Re-broadcasts messages from publishers to all connected contacts.

Other official bot apps

  • apps/simplex-bot / simplex-bot-advanced — minimal Haskell bot examples
  • apps/simplex-support-bot — support/business example
  • apps/simplex-chat — the terminal CLI itself

Getting the binaries

  • Install script: curl -o- https://raw.githubusercontent.com/simplex-chat/simplex-chat/stable/install.sh | bashsimplex-chat on PATH (CLI only).
  • Prebuilt binaries: GitHub Releases (per stable version).
  • Build from source (docs/CLI.md): GHC 9.6.3 + cabal 3.10.1.0, or DOCKER_BUILDKIT=1 docker build --output ~/.local/bin .. Bot apps build via cabal install <exe> (e.g. simplex-directory-service, simplex-broadcast-bot).
  • Build the stable branch, not master.

Proposed orchestrator architecture (to flesh out)

  • Manager (web UI + supervisor) keeps a registry of profiles. Each profile has a kind:
    • cli (interactive: user/echo/support/custom) → spawn simplex-chat -p <port> -d data/<name>, connect WS, proxy commands; one port per profile.
    • directory → spawn simplex-directory-service with --directory-file, --web-folder, --super-users, DB; supervise + serve its web folder.
    • broadcast → spawn simplex-broadcast-bot with publishers/welcome; supervise.
  • Web frontend talks only to the manager; the manager owns process lifecycle, port allocation, log capture, and (for directory) serving the generated web folder.
  • Security: bind all CLI WS ports to localhost; never expose unauthenticated WS publicly.