Tutorial: 2026-07-05

2026-07-05

Newest entry on top.

Adopt hub docs-site chrome + reader-menu refresh — 2.43.1

Trigger: owner asked to check the fairyfox system hub (site updated), sync the docs-site chrome (header/footer + submenu), and adopt the changed Reader Settings — new localStorage key, new menu — "and use the new key", plus "same defaults as main hub to keep consistency".

Flow: refreshed the read-only hub clone (assets/references/fairyfox.io/). Hub dev had been force-pushed, so --ff-only aborted as documented → used the fetch + reset --hard origin/dev fallback on the reference clone only (now at 63fef52, site 0.14.3). The change is covered by the standing adopt-standards-by-default express authorization in hub/authorizations.yml, so it was adopted directly (no check-report-wait pause) — but the full safety floor still ran (copy-not-clobber, verification before/after, process report, reviewable commit).

What changed (all in assets/docs-theme/):

  • modules/reader.js — rebuilt to the new master reader: theme icon tiles (sun/sunset/moon) + Auto toggle, a new accent-colour row (7 hues + reset swatch, recolouring --accent/--violet/--link live), a text-size slider that scales the <html> root font-size ([15,16.5,18,20,22]px), panel head (title/close) + foot (hint/Reset). New versioned key fairyfox:reader:b (was fairyfox:reader). Kept the module split (loadAndApply() early + initReader()).
  • theme/reader.css — replaced with the new panel design (icon tiles, swatches, slider, head/foot), ported to the project's var(--*) tokens.
  • modules/chrome.js — primary nav to the fixed mesh-wide set (added Games, dropped Downloads from primary — Download stays in the subnav); footer Explore column synced; reader button moved to after the nav.
  • theme/chrome.css.site-header .nav { margin-left:auto } so the nav + reader button right-align (reader btn margin .5rem).
  • theme/tokens.css + theme/base.css — reading defaults aligned to the hub: html 16.5px, body 1rem/var(--reading-lh), --reading-lh 1.65 (was 1.8), --reading-fs 1rem (was 1.05rem), width 46rem.
  • notes/reference/documentation.md — fixed the stale primary-nav list.

Verify: npm run lint (JS + CSS) green; npm run docs builds; npm run smoke + npm run check:docs green. Live browser check on the built site (served over local http, since the extension blocks file://): header/subnav correct, reader panel matches the master, fairyfox:reader:b written on interaction, old key unused, light theme + accent + slider apply live, and a cleared (fresh-visitor) load computes root 16.5px / body 16.5px / line-height 1.65 / --reading-fs 1rem / width 46rem — matching the hub.

Follow-up: docs-site spillover + sidebar-flash fixes (still 2.43.1)

Two defects the owner spotted in the online docs after the chrome/reader adoption, folded into the same (unreleased) 2.43.1:

  • Overview spillover. docdash appends file-level doclet <section>s (the data/blocks/…js files that carry a top-level file comment but no @module) plus an empty .package section after the README on index.html — they leaked in past the License section. Fixed with html.ff-home #main > section:not(.readme){display:none} (content.css).
  • Sidebar flash. html.ff-no-sidebar body > nav{display:none} was only applied by the deferred module entry, so docdash's sidebar painted full-height then vanished on non-API pages.
  • Footer placeholder logo. The footer brand rendered a gradient "F" monogram (.ff-brand/.ff-logo) instead of the real fox logo. Swapped brandMark() to the shared .brand/.brand-logo mark (fox.png, same as the header and the hub footer); removed the now-dead .ff-brand/.ff-logo CSS.

Both fixed by moving the page-type class onto <html> before first paint: a tiny inline <head> script injected into every page during enrichHtml() in scripts/build-docs.mjs (mirrors util.js here/isApiPage; adds ff-no-sidebar / ff-home / ff-download). run() still re-adds them (idempotent fallback). Verified in-browser on the built site: <html> shows ff-no-sidebar ff-home at load, all spillover sections compute display:none, only the README renders, body > nav is display:none from first paint, and the page ends cleanly at License → footer. Doc-theme has no Vitest harness, so this follows the project's standing verify-by-build-and-browser practice for assets/docs-theme/.

Pre-built distribution + desktop edition (Tauri) — 2.43.0

Branch: feature/prebuilt-distribution (off dev).

Why: the docs forced everyone to build from source to get the full edition, and framed the hosted online site as "the" version vs. self-built "theirs". Goal: ship every edition pre-built and reframe them as interchangeable artifacts of one codebase — download or build, your call; self-host the online edition too.

What landed:

  • Desktop edition via Tauri (gui/src-tauri/) — a thin Rust shell that runs the unmodified local SPA + Node /api backend as a sidecar (bundles the platform node, runs serve.js); no app logic duplicated. Staging (stage.mjs) assembles the payload + prod dep closure + Node runtime; the shell stages to a writable working copy (per-user app-data, or beside the exe for portable) preserving user data across upgrades, spawns node on a free port with NO_OPEN=1, and navigates the WebView once it listens. Write-up: ../../systems/desktop.md.
  • CI (release.yml): the online edition now ships as a self-hostable …-online.zip release asset (signed like the rest), and a per-OS desktop matrix (Windows/macOS/Linux) builds the installers + Windows portable zip via the runners' preinstalled Rust (no new unpinned actions), signs them, and attaches them to the Release.
  • Framing flip: README leads with "download pre-built or build from source", badges restored (all 21, version-badge path de-engine-v3'd), and a "Get the desktop app / Run it yourself" group added to the in-app LinksMenu.
  • Updates/upgrades: pulled out of this pass as too big/case-dependent; captured as a design brainstorm (../../plans/updates-upgrades.md) for a pre-3.0 feature. Desktop ships update-agnostic (manual per edition) for now.

Verified locally (Windows): Rust toolchain installed; tauri build produces MSI + NSIS; assembled a portable layout and ran it end-to-end — the shell staged a working copy, spawned the bundled node sidecar on a free port (64809), and served the SPA over HTTP 200. Found + fixed a staging bug: apiHandler.js imports the gui/-root vite-api-helpers.js, which the stager now copies (along with every top-level gui/*.js). Cross-OS installers are CI-only (each produced on its own OS).

Version: 2.43.0 (MINOR — notable feature set). VERSION + package.json + tauri.conf.json synced.

Online docs — modular refactor + SEO/social + WCAG AA

Owner asked (in one pass, confirmed) for: small modular browser-imported CSS/JS, full SEO/social/crawler compliance, and a WCAG AA bar.

  • Modular: fairyfox-docs.css@import entry over theme/{tokens,base,layout,chrome,content, reader,download}.css; fairyfox-docs.js → ES-module entry importing modules/{util,chrome,sidebar, reader}.js. build-docs.mjs copies both and rewrites docdash's <script> to type="module". (ES modules don't load over file://, so verification runs a tiny Node http server + Playwright.)
  • SEO/social: static post-processing of all 649 pages — description (first paragraph), canonical, OG + Twitter, robots, JSON-LD — plus sitemap.xml, robots.txt, lang="en".
  • A11y (AA): skip link, visible focus, underlined in-text links, darker light/sepia inks + faint text for contrast, a prettyprint code-surface fix (was light-on-light in light theme because pre.prettyprint{background:none} exposed the page bg), a label on docdash's drawer checkbox, and a keyboard-operable reader menu. @axe-core/playwright: 0 violations in light + dark across Overview/notes/API/Download.

Online docs — reading experience + Kindle-style reader menu

Owner wanted the doc-site rendering to be genuinely comfortable to read, plus softer themes and a Kindle-like settings menu. Delivered:

  • Readability: centred reading column on Overview + notes with gentler type (bigger base, relaxed line-height, slight letter-spacing, text-wrap:pretty); images framed/centred/sized to the column.
  • Tutorial titles: build-docs.mjs strips duplicate leading H1 + {#anchor} heading syntax; fairyfox-docs.js removes docdash's Tutorial: prefix + duplicate <h2> → one clean title.
  • Softer palettes: light is a gentler warm cream (no stark white); added a sepia theme.
  • Reader menu: an "Aa" button in the header top-right opens a panel (Theme Auto/Light/Sepia/Dark, Text size, Line spacing, Width), driving --reading-* vars + data-theme live. (Started as a sun/moon toggle per an earlier ask, then the owner asked for the Kindle-style panel instead.)
  • Shared across the mesh: prefs persist under an origin-wide key fairyfox:reader. Confirmed the hub, random-ai-prompt, and fairyfox-games are all served from the same origin (fairyfox.io/…, no per-repo CNAME), so localStorage is shared automatically — the other two repos just need to read the same key (owner to wire up; I can't touch those repos from here).

Verified all four themes, the live text controls, and cross-reload persistence with headless Playwright (the Chrome extension was offline). Next: owner asked for full SEO / social / crawler compliance.

Online docs cleanup — sidebar only on the API pages

Owner follow-ups on the new doc-site: (1) move the sidebar's Tutorials into the subnav, drop the sidebar GitHub and Home (Overview is home); then (2) don't show the module sidebar on general pages at all — put the code reference behind a subnav item and only show the sidebar there. First tried naming it "Docs", but that clashes with the hub navbar's own Docs link, so it's API (lands on global.html).

Implemented in fairyfox-docs.js + fairyfox-docs.css + jsdoc.config.json: isApiPage() = not index.html and not tutorial-*; non-API pages get .ff-no-sidebar (CSS hides body > nav + the mobile hamburger and centres #main); the subnav gained API (active across the whole reference area). GitHub removed from docdash.menu; the script still prunes the sidebar's Home + Tutorials. Verified at 1280/768/360 — Overview + notes are full-width, global.html keeps the module sidebar. Still no VERSION bump.

Online docs redone to match fairyfox-games — hub header + organized subnav

Owner asked to redo the online docs the way the sibling fairyfox-games project does: copy the fairyfox.io system hub and add a well-organized submenu. Cloned fairyfox-games into assets/references/ (git-ignored) to study it — it vendors the hub styles.css + self-hosted fonts, and its index.html copies the hub .site-header (brand → fairyfox.io, primary nav) plus a project .subnav section bar.

Applied the same pattern to our JSDoc/docdash doc-site (kept the strong from-scratch fairyfox-docs.css rather than swapping in the 37 KB hub sheet):

  • Rewrote fairyfox-docs.js to inject a copy of the hub site-header + an organized project subnav (Overview · Project Notes · Systems · Reference · Changelog + Repository/Notes), active item tracked by page. Replaced the old sidebar-brand block + breadcrumb. Header+subnav go in one fixed .ff-top whose measured height sets --ff-header-h; docdash's sidebar/#main are offset by that var.
  • Ported the hub .site-header/.subnav CSS into fairyfox-docs.css.
  • Two collisions found via screenshots + fixed: docdash's sidebar is <nav class="wrap">, so the bare nav{position:fixed;width:264px} rule was capturing the injected <nav class="nav">/.subnav (stacked them into the sidebar box), and the header's .wrap was blowing the sidebar to full width. Scoped the docdash rules to body > nav and .ff-top .wrap.
  • Self-hosted the fonts: vendored the hub's Fraunces/Inter/JetBrains woff2 (from fairyfox-games, OFL-1.1) into assets/docs-theme/fonts/, linked via fonts.css, and dropped the Google Fonts request — the doc-site now makes no third-party call, matching the app's privacy stance. build-docs.mjs copies the fonts into docs/jsdoc/assets/docs-theme/fonts/.

Verified the built site visually at 1280/768/360 (Playwright headless — the Chrome extension wasn't connected). Desktop shows the full hub header + subnav; ≤820px collapses the primary nav (brand still links home) and the subnav scrolls horizontally, leaving docdash's own hamburger as the only one. No VERSION bump (doc-site tooling only). Updated notes/reference/documentation.md.

README: third image → the prompt-blocks GIF

Owner asked to replace README image 3 (the static Generate screenshot under How to run) with the animated walkthrough. The toolkit already renders + publishes prompt-blocks.gif on release (confirmed live: 200, image/gif, ~483 KB), so this was a one-line README swap to its Pages URL.

Screenshots dropped to 512px tall; README hero → Single desktop shot

Follow-up tweaks: owner wanted the capture height at 512px instead of 768, and the README hero switched to the Single-view desktop shot (the other three embeds are desktop, so this makes the set consistent). Changed STATIC_HEIGHT 768 → 512 in scripts/screenshots/config.mjs; updated the ?v= cache-bust to ?v=3 on all four README images so GitHub refetches the new heights; swapped the hero single-tablet.pngsingle-desktop.png. Local capture confirms every PNG is ‹width›×512.

README overhaul + CONTRIBUTING.md; screenshots captured at a uniform 768px height

Owner asked to fully rewrite the README to a cleaner look and add a proper contributing guide, then iterated on the details across several rounds.

README. Rebuilt around: a "Random AI Prompt" title, an extended one-paragraph description (from the GitHub description), and What is this / Some of the features / How to run / How to build / Contributing / Credits / Links sections. Plain Markdown only (owner rejected <div>/<img> HTML, emojis, and the arrow/"Try it now" treatment). Dropped the badge wall (the "4 images grouped together"). Four app screenshots embedded by their stable Pages URL, spread one-per-section (hero = single-tablet; then gallery, generate, manage). Toned an overstated "hundreds of hand-tuned generators" down to the truthful "dozens of blocks plus dozens of word lists." Owner also raised whether crediting copyrighted lists is risky — clarified that crediting/linking is not the exposure (redistribution is), the one genuinely unlicensed item being the AUTOMATIC1111 artist list already in the repo.

CONTRIBUTING.md (new). Neutral, factual tone: ways to contribute, Node 24 + content-policy requirements, local setup, the two-branch git-flow model, commit style, the npm test gate, and the fork → branch-off-dev → PR-against-dev flow.

Screenshots — captured at 768px, not cropped. Owner clarified the intent (originally stated in another tab): every shot should be taken at a native height of 768px, with widths varying by device, not cropped after the fact. First mis-attempts (committing cropped copies; then cropping the emitted PNGs) were reverted. Final: the static-capture context keeps each viewport's native width but forces STATIC_HEIGHT = 768; STATIC_SCALE dropped 2 → 1 so the native pixel height is exactly 768; the shot helper (shots.mjs) now takes a viewport screenshot (fullPage: false) instead of a full-page one. Ran a local capture to verify — every PNG is ‹width›×768 (desktop 1025×768, tablet 770×768, phone 345×768). README keeps its existing hosted Pages links; the images update at the next Pages rebuild.