- Python 86%
- Shell 10.4%
- Dockerfile 2.1%
- Just 1.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Two workflows. ci runs the suite and the linter in the dev-base image the rest of the estate builds on. publish builds and pushes on a push to main, tagged with the full 40-hex commit SHA because coilyco-bridge/deploy refuses a moving tag at rollout time. No buildx and no multi-arch: quire deploys to one amd64 node, so a plain build and push is the whole requirement and the binfmt setup the dev-base publisher needs buys nothing here. REGISTRY_TOKEN is an existing org secret on coilyco-flight-deck, so this repo inherits it and no new credential is minted. Co-authored-by: Angie <coilysiren@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
| .forgejo/workflows | ||
| docs | ||
| scripts/ci | ||
| src/quire | ||
| tests | ||
| .gitignore | ||
| AGENTS.md | ||
| Dockerfile | ||
| justfile | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
quire
A markdown page server for sites that agents write while an audience watches.
A quire is a gathering of folded pages. This one holds a set of named markdown pages behind a hot-reloading server, and exposes exactly three verbs over HTTP: list the pages, read one, replace one. There is no delete route anywhere in the codebase, which is what lets a guarded MCP in front of it deny deletion by absence rather than by rule.
The three verbs
GET /pages # every page, with title, revision and size
GET /pages/{name} # one page's exact markdown, plus its revision
PUT /pages/{name} # replace one whole page, atomically
PUT takes {"markdown": "..."} and replaces the entire page. There is no
partial update, so a write is always a complete page rather than a patch that
has to agree with what was there. revision changes on every write, so a
writer sharing a site with other writers can read first and tell whether the
page moved under it.
Two layers, and only one of them can fail
Plain markdown is the substrate and always renders. Optional YAML front matter
drives the pretty layer: title, subtitle, order, tags, status.
Front matter that is malformed, unclosed, not a mapping, or carrying an unknown
key does not fail the page. The renderer falls back to treating the whole file
as markdown, renders it, and reports what it ignored in a banner on the page and
in the warnings field on the API. A page can look wrong. It cannot go down.
That asymmetry is deliberate: when a writer is unsure, plain markdown with no front matter at all is always the safe form.
Run it
just serve # http://localhost:8080, pages in ./pages
just test
just lint
QUIRE_PAGES_DIR sets the page directory, QUIRE_PORT the port.
The API is guarded, the site is not
QUIRE_API_TOKEN puts a bearer token on the three /pages routes and leaves
the rendered HTML public. Unset, as in local development, the API is open.
Set it anywhere the site is reachable from outside. A quire on a public host
during a live stream has its URL on screen, and an unauthenticated PUT on that
host is an open write surface for anyone reading the address bar.
Hot reload
Every rendered page polls /version once a second and reloads when the token
changes. A write is visible to a reader within about a second. The poll is a
poll and not a websocket on purpose: if it fails, a reader sees a stale page
instead of a broken one.
Layout
src/quire/store.py # page files, slug validation, atomic whole-file replace
src/quire/render.py # front matter splitting and markdown to HTML
src/quire/theme.py # the self-contained pretty layer and the reload poll
src/quire/app.py # the three API routes and the two HTML routes
Docs
- docs/FEATURES.md - what ships today.
- docs/rendering.md - the layering rule and every degrade path.
- AGENTS.md - operating context for agents writing pages here.