diff --git a/docs/reference.md b/docs/reference.md index 2fdf4f727..906a1e263 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -154,7 +154,7 @@ each bundle registers a **distinct** tag. | `bun run smoke:playground` | Opens every element of the auto-generated SPA by deep link in Firefox and proves it boots: element defined, shadow DOM populated, no error card, a WebGL canvas for map profiles (checked through nested shadow roots), no HTML-for-JSON data responses. `--json ` writes the evidence; exit 1 on any failure. The pre-handoff gate. | | `bun run smoke:share` | The share round-trip gate (Firefox): opens a host page (`--playground` = every canvas element of the dev SPA; `--url --tag ` = the website or any CDN page), clicks Share, reads the URL, fetches it, reopens it in a fresh page and asserts the SAME custom element mounts with a WebGL canvas. `--json `; exit 1 on any failure — proves REQ-1 ("links work wherever the tree is hosted"). | | `bun run check:public-hygiene [] [--strict]` | Proves a served folder is fit to publish: scans for local paths, internal folder names, dev-server URLs, JWT-shaped tokens, `.env`/token files, source maps, documentation and staging/preview pages, and prints an inventory (bundles, leaf pages, assets by folder). Under `--strict` any root entry other than `index.html`, `assets/` and `doxa-maps/` is a finding ("outside the drop-in contract"). Exit 1 on a finding. Run it on the website's drop-in before any public push. | -| `bun run sync:dropin [--from-config \| --only a,b] [--prune]` / `bun run deploy:dev` | Syncs the built `public/` into a host checkout (e.g. the website's `public/js/doxa-maps-build/`). **The drop-in contract** lives in ONE place — `vite.doxa-maps-build-config.json` → `dropin.include`, exactly three root entries: `index.html` (the root page generated by `internal/generate-spa.mjs`, listing every bundle/profile/instance and mounting the chosen one), `assets/` (data) and `doxa-maps/` (the bundle folders + `manifest.json`). `--from-config` copies only those, `--prune` removes everything else in the destination, so a host carries exactly the served web-root and nothing else at its root. Without an allowlist it is a plain full mirror. Never copies credentials, docs or staging pages; `--protect a,b` keeps host-owned files; `--dry-run` first; prints a copied/unchanged/deleted/pruned summary and the resulting top-level tree. `deploy:dev` = `build` → sync `--from-config --prune` into the website (`DOXA_DROPIN_DEST` overrides the path) — the only sanctioned way a map changes on the site; then commit in both repos. | +| `bun run sync:dropin [--from-config \| --only a,b] [--prune]` / `bun run deploy:dev` | Syncs the built `public/` into a host checkout (e.g. the website's `public/embed/doxa-maps-build/`). **The drop-in contract** lives in ONE place — `vite.doxa-maps-build-config.json` → `dropin.include`, exactly three root entries: `index.html` (the root page generated by `internal/generate-spa.mjs`, listing every bundle/profile/instance and mounting the chosen one), `assets/` (data) and `doxa-maps/` (the bundle folders + `manifest.json`). `--from-config` copies only those, `--prune` removes everything else in the destination, so a host carries exactly the served web-root and nothing else at its root. Without an allowlist it is a plain full mirror. Never copies credentials, docs or staging pages; `--protect a,b` keeps host-owned files; `--dry-run` first; prints a copied/unchanged/deleted/pruned summary and the resulting top-level tree. `deploy:dev` = `build` → sync `--from-config --prune` into the website (`DOXA_DROPIN_DEST` overrides the path) — the only sanctioned way a map changes on the site; then commit in both repos. | | `bun run build` | `clean` → one `vite build` per `app-profiles/*/` folder → `tree` → `check:drop` → `check:parse` → `verify` → `spa` (writes `public/index.html` from the manifest). | | `bun run build:bundle` | Builds ONE bundle (needs `BUNDLE=`). | | `bun run build:watch` | Rebuilds into `public/` on every change (integration loop). | diff --git a/internal/generate-spa.mjs b/internal/generate-spa.mjs index 08bc2c359..7a740c2e7 100644 --- a/internal/generate-spa.mjs +++ b/internal/generate-spa.mjs @@ -6,7 +6,7 @@ * and this one page, which lists every bundle → profile → instance the manifest declares and * mounts the chosen one. It is GENERATED — never hand-edited — as a single static file: inline * CSS, inline vanilla JS, every path relative, so the same file works from any static host, - * under a subpath (the website serves it at /js/doxa-maps-build/index.html) and from file://. + * under a subpath (the website serves it at /embed/doxa-maps-build/index.html) and from file://. * * At runtime the page fetches /manifest.json so it stays correct when bundles change; a * compact copy of the manifest is baked in as the fallback (file://, or the fetch fails). Embed diff --git a/internal/staging-forge.js b/internal/staging-forge.js index 9191c1aa8..c44561667 100644 --- a/internal/staging-forge.js +++ b/internal/staging-forge.js @@ -157,7 +157,7 @@ function renderStage() {
` // COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from // location.href, so it always carries the FULL URL of whatever host serves - // this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds + // this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds // work no matter where the build folder lives. utm_source placeholder = // per-partner traffic attribution (see the manifest snippets). const copyBtn = $('#copyEmbed') diff --git a/internal/sync-dropin.mjs b/internal/sync-dropin.mjs index 2207ff76f..349e080d2 100644 --- a/internal/sync-dropin.mjs +++ b/internal/sync-dropin.mjs @@ -3,7 +3,7 @@ * sync-dropin.mjs — mirror the built web-root (public/) into a HOST checkout as a "drop-in". * * WHY: the website (doxa-life) consumes this bundler's output as generated files under - * public/js/doxa-maps-build/. Hand-editing there is forbidden — the ONLY way a map changes + * public/embed/doxa-maps-build/. Hand-editing there is forbidden — the ONLY way a map changes * on the site is: change the bundler → `bun run build` → sync. This is that one honest step, * so it is a script and not a remembered rsync incantation. * @@ -36,7 +36,7 @@ * * Usage: node internal/sync-dropin.mjs [--from public] [--tree doxa-maps] [--keep-staging] * [--only a,b | --from-config] [--prune] [--protect a.txt,other] [--dry-run] - * e.g. node internal/sync-dropin.mjs ../doxa-life/public/js/doxa-maps-build --from-config --prune + * e.g. node internal/sync-dropin.mjs ../doxa-life/public/embed/doxa-maps-build --from-config --prune * Prints: copied · unchanged · deleted (stale inside the allowlist) · pruned (outside it) · * excluded (credentials/docs/staging), then the destination's top-level tree after the sync. * Exit: 0 synced (or dry-run printed) · 1 bad arguments / dest missing / no allowlist in config diff --git a/package.json b/package.json index bc70e1961..24b0db9dc 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "smoke:share": "node internal/share-roundtrip-smoke.mjs", "probe:legend-columns": "node internal/legend-columns-probe.mjs", "sync:dropin": "node internal/sync-dropin.mjs", - "deploy:dev": "bun run build && node internal/sync-dropin.mjs \"${DOXA_DROPIN_DEST:-../doxa-life/public/js/doxa-maps-build}\" --from-config --prune # every bundler slice ends here: the website worktree gets exactly the drop-in contract (dropin.include in the build-config); then commit + push BOTH repos", + "deploy:dev": "bun run build && node internal/sync-dropin.mjs \"${DOXA_DROPIN_DEST:-../doxa-life/public/embed/doxa-maps-build}\" --from-config --prune # every bundler slice ends here: the website worktree gets exactly the drop-in contract (dropin.include in the build-config); then commit + push BOTH repos", "check:public-hygiene": "node internal/public-hygiene-check.mjs" }, "devDependencies": {