Files
hanzo.ai/scripts/sync-rooms.mjs
zeekay 0196c620dd A room is withheld for being a room, and the tree says which ones exist
/bots, /cal, /contacts and /meet were rooms nobody added to the list that
withholds rooms, so they shipped in sitemap.xml. /contacts renders thirty-one
characters before a session arrives, and because the thin-page floor is measured
against the shortest published page, five pages correctly declared empty were
reported as having grown copy. One forgotten line, two red gates, and neither of
them named the room.

`scripts/sync-rooms.mjs` walks `app/(app)` and writes what it finds. A room is a
route under it — a fact about the tree, not a judgement about copy — so the
literal is gone and the next room withholds itself.

Three gates were measuring a shape that had moved:
- fold named two doors by href. The hero was cut to one entry point on purpose,
  and the gate kept passing the count off a `/dev` action eleven thousand pixels
  down the page before failing on its position. It measures the first band now
  and names nothing in it.
- settings addressed the places as if they were the column. Under the grid the
  rail holds the places and the list holds what a place has, so it asserts
  against both, with a roster answered so the disappearance it checks is a change
  rather than a locator that never matched.
- shell handed /v1/agents a bare array. The client reads `body.agents` off that
  route, so the roster arrived empty and the agent it looks for was never drawn.
2026-09-07 00:14:04 -07:00

37 lines
1.6 KiB
JavaScript

/**
* The rooms, read off the tree that already decides which ones exist.
*
* A room is a route under `app/(app)`: a surface that renders a session rather
* than copy. Its exported HTML is a heading and a word, because everything in
* it arrives from `@hanzo/ai` after the session settles — so it must never be
* offered to a crawler, and it never wants approving.
*
* This existed as a literal in `lib/publish.ts` and drifted the first time
* somebody added a room: /bots, /cal, /contacts and /meet shipped in
* sitemap.xml, /contacts rendered thirty-one characters, and because the
* thin-page floor is measured against the shortest published page, five pages
* that were correctly declared empty were reported as having grown copy. One
* forgotten line, two red gates, and neither of them named the room.
*
* `lib/publish` reaches a client bundle and cannot read a directory, so the
* walk happens here and the answer travels as data. Runs before `sync-pages`,
* which asks `publish` what is published.
*/
import { writeFileSync } from 'node:fs'
import { join } from 'node:path'
import { routes } from '../lib/routes.ts'
const ROOT = join(import.meta.dirname, '..')
const APP = join(ROOT, 'app', '(app)')
const OUT = join(ROOT, 'lib', 'data', 'rooms.json')
const rooms = routes(APP)
.map((r) => r.path)
.filter((p) => p !== '/')
.sort()
if (rooms.length === 0) throw new Error(`no rooms under ${APP} — the walk found nothing to withhold`)
writeFileSync(OUT, JSON.stringify(rooms, null, 2) + '\n')
console.log(`[rooms] ${rooms.length} withheld: ${rooms.join(' ')}`)