# Working on MangaCircus Guide for contributors and coding agents. Users who only want to run it: [docs/deployment.md](docs/deployment.md). ## Layout | Path | What | |---|---| | `server.js`, `library.js` | Reader: HTTP server, accounts, progress, JSON storage; folder scanner and image-size reader | | `chapter-identity.js`, `chapter-dates.js`, `reading-*.js`, `catalog.js`, `backup.js` | Shared modules (chapter keys, chapter dates, reading clock/limits, collections, built-in backup) | | `public/` | The web pages: plain HTML, CSS and JavaScript, no build step | | `scraper/` | Download queue daemon (`service.js`, `daemon.js`), source adapters and parsers, the publisher that writes the library, metadata lookups | | `peering/` | Optional server-to-server sharing (gateway, client, adapter) | | `runtime/` | In-container supervisor and configuration | | `discovery/`, `greatest/` | Discovery Scout and the Greatest of All Time dashboard | | `tools/` | Demo library, health checks, maintenance tools (dry run by default), UI and Compose test drivers | | `deploy/` | `circus.sh` operations helper, HTTPS with Caddy | | `docs/`, `vision/` | Contracts and guides; design notes for planned features | ## Rules - **No runtime dependencies.** Node.js built-ins only. Playwright is an optional dev tool for UI tests. - **One writer per store.** The reader alone writes `DATA` (users, progress, catalog). The scraper alone writes the library and its queue. Tools that edit `chapter.json` files are dry runs by default and need `--apply --writers-stopped`. - **Library writes go through the publisher** (`scraper/lib/publisher.js`): staging folder, validated images, one atomic rename. The folder contract is [docs/scraper-guide.md](docs/scraper-guide.md). - **Sources are polite.** Sequential requests, persisted per-host delays, stop on 401/403/429, never bypass access controls ([scraper/AGENT_RUNBOOK.md](scraper/AGENT_RUNBOOK.md)). - **No secrets or personal data in the repository**: no `.env`, `.secrets/`, `data/`, libraries, host names, IP addresses or local paths. Tests use disposable fixtures and never a real library or user database. - Keep the docs current in the same change: a new file format field goes into [docs/library-format.md](docs/library-format.md), a new setting into the README or [docs/deployment.md](docs/deployment.md), an API change into [docs/architecture.md](docs/architecture.md). - Match the surrounding style: small functions, short comments that say why, no framework. ## Tests ```bash npm test # reader, scraper, runtime and peering suites (node --test) ``` Without Node on the machine, run them in Docker (the peering test needs `openssl`, present in `node:24`): ```bash docker run --rm -v "$PWD:/app" -w /app node:24 npm test ``` Browser and Compose acceptance tests (Playwright, disposable data, never the live stack): `npm run test:ui`, `npm run test:discovery-ui`, `npm run test:direction-ui`, `npm run test:peer-ab`. Try changes against demo data: `node tools/make-dummy.js library && npm run start:all`, or `docker compose -f docker-compose.yml -f compose.dev.yml up -d --build` (mounts the editable source).