# __NAME__
TODO: one line on what __NAME__ is — live at
**[__HOST__](https://__HOST__)**, repo published at
**[git.ardegazu.ro/__SUB__](https://git.ardegazu.ro/__SUB__)**.
TODO: a short paragraph on what it does and why. Installable PWA, safe-area
aware, works from any static file host.
## Architecture
- **No server.** Browsers are [js-libp2p](https://libp2p.io) peers: they meet
through a circuit-relay-v2 node, upgrade to direct WebRTC, and replicate an
**encrypted OrbitDB log** over the same node (`ardegazu.rooms.lib.*`, from
[ardegazu-rooms-kit](https://git.ardegazu.ro/rooms-kit)). Rooms are keyed by a secret in the URL
fragment — membership is proved pairwise with a sealed hello, every log entry
is sealed at rest, and a decrypt failure *is* the access check. Members who
are never online together converge through the sealed **offline mailbox**.
- **Durable by design.** State survives every tab closing and reaches new
devices by replication, not by upload: reopening a room replays this device's
own blockstore (fully offline), then syncs. The app only adds its `LogOp`
union in `lib/protocol.cljs` and its projector in `client/src/…/app/`.
- **ClojureScript, shadow-cljs builds** (deps.edn classpath, exact-pinned
compiler pair). `npm run dev` watches on :5173, `npm run build` produces a
static `client/dist/` with relative asset paths. The shared rooms core —
`ardegazu.rooms.js` and `ardegazu.rooms.lib.*` — is **not in this repo**: it
is `ardegazu-rooms-kit`'s own sources, compiled off the classpath
(`client/deps.edn` adds `node_modules/ardegazu-rooms-kit/src`, the npm sha pin
decides which sha sits there). Fix it there, bump the pin here. What IS local
and yours to change: `lib/protocol.cljs` (your LogOp union), `lib/mailbox.cljs`,
`lib/selftest.cljs` and `stores.cljs`. `i18n/runtime.cljs` is still a vendored
copy, byte-identical to game1's modulo the namespace substitution — never edit
it here; fixes happen in the canon and replicate.
- **Versioned PWA.** `client/version.json` is bumped by every release and the
in-app banner offers a one-tap update. Never flip the worker to
auto-update — the prompt+banner pair is the suite's update contract.
- **Hosting without an origin server.** `client/dist/` is pinned to IPFS, named
by IPNS and served straight from the gateway on the app's own domain
(DNSLink). The published repo works the same way
(`deploy/publish-repo.sh` + the shared `git.ardegazu.ro` source root).
## Develop
```bash
cd client && npm install && npm run dev # http://localhost:5173
```
(needs JVM ≥ 17 + the clojure CLI for shadow-cljs; `deps.edn` carries a `:dev`
alias with cider-nrepl, so `cider-jack-in-cljs` works out of the box)
Open two tabs on the same `#room` URL to talk to yourself. From the suite
workspace, `ardz dev __SUB__` does the same, and `ardz relay` runs a local dev
relay **plus mailbox** on :9090 — needed to exercise offline delivery (close one
tab, post in the other, reopen).
`npm test` expects a `:testlib` shadow build and `test/*.test.mjs`; neither
exists yet in this scaffold — add them with your first black-box tests (chat's
`shadow-cljs.edn` and `test/` are the shape).
## Deploy
```bash
ardz build __SUB__ # shadow-cljs release + workbox → client/dist
ardz release __SUB__ # bumps version.json, then pins to IPFS + IPNS
ardz publish-src __SUB__ # anonymity-gated source mirror → git.ardegazu.ro
```
**Commit the `client/version.json` bump after every release**, or installed PWAs
never see the update banner.
Clone: `git clone https://git.ardegazu.ro/__SUB__.git`
MIT — see [LICENSE](LICENSE).