# Publishing the Studio **What this is.** The UI/UX Studio (`9 - System/ui-ux/`) is a live public site at **https://studio.smartrules.ai** (also served at smartrules.ai/studio). Editing the local files changes nothing anyone can see. **Every change ends with this.** Verified working 05-08-2026. ## Just run the script **`9 - System/ui-ux/publish.sh`** does all five steps and verifies the live site (15-08-2026). `./publish.sh --dry` stages and repairs links without uploading, so you can see what would change. It resolves its own folder, so it works from anywhere and on any machine. It also improves on step 2 below: instead of unlinking every `../../` href, it resolves each relative link inside the staged tree and unlinks only the ones that escape the site or point at nothing — so real in-site links between subfolders survive. ## The five steps (what the script does) 1. **Copy to a staging folder.** `cp -R "9 - System/ui-ux" /studio-site`, then delete `.DS_Store` and any `assets-old/`. 2. **Repair the links**, in python over `**/*.html`: - `href="file://…/skills//SKILL.md"` where `` is in the public pack → `https://github.com/gfrankgva/studio-skills/blob/master//SKILL.md` - every other `file://` or `../../` href → `data-local="…"` (visible, not a broken link) - Assert zero `href="file://` left. Last run: 17 rewritten, 49 unlinked. 3. **Upload:** `rsync -az --delete /studio-site/ louis:/tmp/studio-stage/` 4. **Publish:** `ssh louis "sudo rsync -a --delete /tmp/studio-stage/ /var/www/studio/ && sudo chown -R www-data:www-data /var/www/studio"` 5. **Verify against the LIVE site, never the local files.** Every new page returns 200, plus one count that must have moved — the number of criteria, or a string only the new build contains. A local file that looks right proves nothing. ## Two things that will trip you - **The nginx vhost is locked.** `sites-available/openclawd-dashboard` is `chattr +i`. Only touch it if a new path is needed: `sudo chattr -i` → edit → `nginx -t` → reload → `sudo chattr +i`. - **Certbot once broke every site on louis silently** by leaving `le_http_01_cert_challenge.conf` included eight times in `nginx.conf`; port 80 failed to bind and a stale config kept being served. If a reload seems to do nothing, look there first. ## And tell Frank the URL Never a file path. https://studio.smartrules.ai/people/index.html Related: `5 - Handovers/ui-ux-library-02-aug-26-23h.md` (where this recipe was born), memory `reference-uiux-studio`. **Publishing from louis (27-09-2026, Frank authorised sessions to publish):** `publish.sh` now detects the server (`/var/www/studio` exists) and publishes in place with sudo, **without `--delete`**: Syncthing ignores `node_modules`, `dist`, `out` and `__pycache__`, so the server's copy lacks built files the Mac publishes (`fossflow/.../dist`, 80,000 files), and a delete would wipe them. Pages removed on the Mac therefore stay live until a Mac publish. Before any delete-sync into `/var/www/studio`, dry-run it with `--itemize-changes` and read the `*deleting` lines. **Publishing one page alone (03-10-2026).** When only one new page must go live and the folder may hold other sessions' unpublished edits, copy that file alone: `scp louis:/tmp/x.html && ssh louis "sudo install -o www-data -g www-data -m 644 /tmp/x.html /var/www/studio/"`, then `curl` the live address for a string only the new page has. `publish.sh` ships the whole folder, other sessions' work included. **Publishing a set of files without publish.sh (04-10-2026, the doors rebuild).** Raw copies skip publish.sh's link repair, so a link to a file outside the studio goes live as a 404 instead of a quiet non-link. Run the repair on your own list first (the Python block of publish.sh, resolving against the source folder, writing to a scratch copy), then `rsync -az` that copy to `louis:/tmp//`, `sudo rsync -a` it into `/var/www/studio/` (never `--delete`) and `sudo chown -R www-data:www-data /var/www/studio`: a root rsync keeps the uploader as owner. Last, HEAD-check every local target the new pages link: a file present on the Mac may never have been published (two were missing on 04-10-2026). **Who writes the front door (04-10-2026).** `index.html`, `make/*.html` and `studio-map.md` are written by `catalogue/build_doors.py` from `catalogue/doors.json`; `catalogue/build.py` now writes the old catalogue as `library.html` and never deletes the files listed in `catalogue/doors-files.json`. Hand edits to `studio-map.md` are taken back into doors.json at the next build (tracked by `catalogue/doors-state.json`).