FUG-103: interactive tutorial + generated user guide with real Playwright screenshots - #78
Open
issuefleet[bot] wants to merge 30 commits into
Open
FUG-103: interactive tutorial + generated user guide with real Playwright screenshots#78issuefleet[bot] wants to merge 30 commits into
issuefleet[bot] wants to merge 30 commits into
Conversation
|
…talog Add end-user documentation driven by a single source of truth so the in-app tutorial and the static docs site can't drift. - web/src/ui/guide/catalog.ts: DOM-free, typed feature catalog covering every user-facing surface (onboarding, capture/mapping, maps, effects + editor, devices, flashing, color correction, performance/calibration, MIDI, settings, help). Each topic carries docs prose + optional interactive coach-mark steps. Consumed by BOTH the tour and the doc generator. Interactive tutorial: - guide/tourStore.ts: localStorage state (dismissed / hint-seen / completed), pure parts unit-tested. - guide/overlay.ts: spotlight coach-mark engine (dim + cutout + anchored bubble with Back/Next/Skip), self-injected styles from the kit tokens. - guide/tour.ts: full guided walk (navigates screens) + a dismissible first-run "?" hint (built on the kit HelpTip) that never nags once dismissed. - Wire the first-run hint into app/main.ts; add a "Help & tutorial" group to Settings (Start tutorial / Open user guide / Reset) so it's always recallable. Static docs site, generated + CI-gated (mirrors FUG-95's perf doc): - web/tests/tools/genUserGuide.ts: emits docs/user-guide.md (prettier + markdownlint clean, a fixed point) and a self-contained docs/user-guide/ static site with a generated schematic figure per topic. - //web:gen_user_guide (regen in place) + //web:user_guide_freshness genrule under `bazel test //...`; export the docs from the root BUILD. - Publish the site at /user-guide/ via stage_site.lib.sh (both origins). - Document the regen command in DEVELOPERS.md; link the guide from README. Verified: web_ts typecheck + tour_test pass; markdown is a prettier/markdownlint fixed point; freshness gate passes fresh and fails on a perturbed catalog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "New to Splanc?" first-run hint anchors just above the tab bar at the bottom of the viewport, but HelpTip's popover renders downward by default, so the bubble spilled off the bottom edge (review feedback). Add an opt-in `direction: "up"` to the shared HelpTip (mirroring the existing `align` option): a `.k-helptip-pop--up` variant anchors the popover above the trigger and flips the entrance animation. The tour hint uses it; existing top-anchored HelpTip usages are unchanged (default stays "down"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
issuefleet
Bot
force-pushed
the
agent/fug-103-build-out-user-docs
branch
from
August 12, 2026 01:36
31e7140 to
e9973dd
Compare
…ut-user-docs # Conflicts: # web/src/ui/app/main.ts
…ifest Add a `screenshot` hash-route to the guide catalog for screens that render standalone headless. The generator now emits docs/user-guide/shots.json (the Playwright capture manifest) and embeds img/<id>.png (site) / user-guide/img/<id>.png (Markdown) for those topics, keeping the schematic figure for the rest. Freshness gate extended to the manifest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add docs/capture_user_guide.py (//docs:capture_user_guide) — a bazel-run tool that serves //web:dist and drives headless Chromium via Playwright over the shots.json routes, writing docs/user-guide/img/<id>.png. //docs:build_user_guide is the one-target rebuild: regenerate md/site/manifest then capture. Neither runs in 'bazel test //...' (py_binary only builds), so CI needs no browser. stage_site publishes the img/ dir on the deployed site. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Run //docs:capture_user_guide to produce the 8 real headless-Chromium screenshots (welcome, maps, effects, color-correction, performance, midi, appearance, help) now embedded in the guide, and fix the Playwright browser auto-install to carry this process's sys.path so the toolchain python can import playwright. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n Playwright) A prior session left a Node playwright-core in web/package.json + pnpm-lock and a web/tools/capture_screenshots.mjs; the shipped capturer is the Python docs/capture_user_guide.py (Playwright via @pypi). Remove the unused Node dep and orphan script.
…ix narrow layout Extend the screenshot spec with screenshotClick/screenshotWaitMs so screens reached by interaction get real captures: map-workspace + effect-editor open a library .map-row, device-management opens the Device-tab sheet. Fix the narrow layout — the figure kept position:sticky when stacked and floated over the text; it's now a normal width-capped block above the prose. Drop a duplicate .shot rule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fix Add real screenshots for interaction-reached screens (mapping workspace + effect editor via a library-row tap, device sheet via the Device tab) and connect-device, driven by a new catalog screenshotClick selector the manifest now emits and the capturer taps. Only Capture (camera) and Flashing (USB) stay schematic. Fix the narrow layout: the figure was position:sticky in a single column so it floated over the prose — it now stacks as a centered, size-capped block above the text. Restore the .shot styling.
…or row is tappable
…less) The editor renders headless but its off-thread wasm compiler can't be fetched by the static capturer, so a live shot shows a compiler-error banner. Revert just that topic to the schematic figure; workspace/device/connect-device stay real.
…/connect-device added)
… contamination) A prior shot's opened sheet/drawer, navigation, or seeded state no longer carries into the next screenshot — each shot gets a clean context + blank DOM (Kevin's review: the device drawer was leaking into later shots).
… camera, BLE) A ?demo=<scenario> flag lazy-loads src/demo/init.ts, which mocks hardware states a headless browser can't reach: a connected 'Living Room' device with a 24ms RTT (appState.setDemoConnection seam), a simulated camera frame for the mapping screen, and a Web Bluetooth seam so the add-device BLE button appears. No-op in normal loads (guarded + lazy); the background device prober is skipped in demo mode so it can't override the injected state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nshots Capturer passes ?demo=<scenario> per shot (fresh context each, so no drawer/nav contamination). Catalog: capture=device,camera (simulated fixture camera feed), connect-device=bluetooth (BLE add button shows), device-management=device (connected 'Living Room' + 24ms RTT). Force client.isConnected in the device demo so the sheet renders the RTT. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tor shot ?demo=effect intercepts the compile-worker construction and returns a canned FxCompiled (uniforms) + disassembly, so the editor renders its docked workspace (Code / Uniforms / Disassembly, no 'Failed to fetch' banner) without the wasm compiler. Live LED preview still needs the fx-vm wasm bundle served — follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tabs render ?demo=effect intercepts the compile-worker construction and returns a canned FxCompiled (speed/glow/tint uniforms + disassembly), so the editor shows a green 'compiled · 3 uniforms' status with the Uniforms + Disassembly panels populated instead of the wasm 'Failed to fetch' banner. Live LED preview still needs the fx-vm wasm bundle served (follow-up; see WORKLOG). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
?demo=flash opens the flash sheet in a finished state with a canned esptool log (chip detect, stub, erase, write %, hash verify, reset) + full progress bar, via a flashSheet.enableDemoFlash() seam — no Web Serial / firmware / chip needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
?demo=flash auto-opens the flash sheet (flashSheet.enableDemoFlash) into a finished-flash view with a canned esptool log (chip detect, stub, compressed write %, hash verified, hard reset) + a full progress bar — no USB/firmware/chip needed headless. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
added 3 commits
August 16, 2026 04:27
…or -> switch tab)
…s prettier array wrapping)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
FUG-103: Build out user docs
Interactive in-app tutorial + a programmatically-generated user guide (Markdown + a static site) with real app screenshots captured by Playwright + headless Chromium, all driven from one catalog (
web/src/ui/guide/catalog.ts).//docs:capture_user_guidecaptures;//docs:build_user_guideis the one-target rebuild. Both arebazel runtools (never inbazel test), so CI needs no browser.Interactive tutorial
Dismissible first-run hint (opens upward, never nags once dismissed), spotlight coach-marks, recallable from Settings ▸ Help & tutorial.
Real screenshots with an in-app demo/capture seam
A guarded, lazy
?demo=<scenario>seam (web/src/demo/init.ts, no-op in production) mocks hardware states a headless browser can't reach, and the capturer takes every shot in a fresh browser context (no drawer/nav contamination between shots):Multi-shot flows + dedicated sub-pages
Flow topics define a
gallery(multiple captioned shots reached by a click sequence). The effect editor is the first flow — Uniforms (hero), Disassembly, and Device tab shots — with a dedicated sub-page (docs/user-guide/effect-editor.html) the top-level guide links out to ("Full walkthrough — N screenshots →"). Extensible to onboarding and other flows.Follow-up (documented in WORKLOG)
The editor's live LED preview needs the fx-vm wasm bundle served; building those bundles OOMs the build container today. The editor shot shows Code/Uniforms/Disassembly; once container memory is bumped, serve the wasm bundles and drop the compiler mock for a real preview (steps in WORKLOG.md).
Verification
Freshness gate green; all web unit tests + typecheck pass; buildifier/black/isort/flake8/prettier/markdownlint clean. Every screenshot was captured and visually verified. Merged onto latest
main(incl. the HITL flake fix).🤖 Generated with Claude Code
Closes-Linear: FUG-103 (https://linear.app/fughilli/issue/FUG-103/build-out-user-docs)