diff --git a/proposals/tutorial-tab.md b/proposals/tutorial-tab.md new file mode 100644 index 0000000..6e0420a --- /dev/null +++ b/proposals/tutorial-tab.md @@ -0,0 +1,557 @@ +# Proposal: an interactive tutorial tab ("Try it") + +Status: **accepted** (revision 3) — all maintainer decisions are folded in and +marked *Decided*, including the v1 chapter scope (all 11 chapters). Contains the +full implementation plan; being executed on `feat/tutorial-tab`. +Author: prepared with Claude Code, July 2026. + +## Summary + +Add a third top-level destination — reached via a **mini CTA button** in the top +bar's right-hand action group (next to the GitHub and theme buttons), label along +the lines of **"Try it"** — that teaches flashtrace hands-on. The page is +dominated by a large, *editable* IDE mock in the spirit of the hero mock on the +landing page: a Markdown spec editor on the left, an exemplary JavaScript file on +the right, and a terminal at the bottom. The terminal is not a capture: it +**executes the real, released `dist/flashtrace.mjs`** in the browser against the +two editor buffers, treated as temporary in-memory files. + +Content is organized into short chapters, each teaching one feature (or a small +set of connected features) of flashtrace. Two assist buttons — **"Help me"** and +**"Do the next step for me"** — explain respectively perform the next step *inside* +the IDE, via anchored popups and (for the second button) a typewriter edit. +Progress is tracked in an explicit per-chapter map in `localStorage`, keyed by +stable chapter ids so that newly inserted chapters are never auto-checked; each +entry carries detailed metadata (title, a content-hash identity of the chapter +definition, language, assist usage). + +A proof of concept for the critical piece — running the unmodified bundle against +an in-memory filesystem — was built and works; see [Appendix A](#appendix-a-proof-of-concept). + +## Naming & internal naming (Decided) + +The public label ("Try it", "Try Editor", "Try It Out", …) may be swapped at any +time, so nothing internal derives from it: + +- **URL**: `/try/` (short, label-agnostic enough; if ever renamed, the old path + keeps a redirect stub). +- **Code & storage names**: `tutorial` throughout — `src/tutorial.mjs`, + `src/scripts/tutorial.js`, `localStorage` keys `ft-tutorial-*`. Renaming the + button never touches code or invalidates stored progress. + +## Goals + +- Teach the core feature set (items, needs, code tags, revisions, coverage, + forwarding, tags/filtering) through doing, not reading. +- Run the *real* CLI, at the *same version* the docs on the site are built from, + so output, exit codes and edge cases are authentic and stay authentic across + releases without manual re-capturing. +- Keep the site's constraints intact: static hosting, zero runtime dependencies, + minimal dev dependencies, graceful degradation. +- Structure all chapter content for **multiple code languages** from day one + (Decided): v1 ships Markdown specs + JavaScript code only, but chapter + definitions keep every language-specific detail in per-language variant data so + further languages slot in without touching the engine or the neutral parts. + +## Non-goals (v1) + +- A free-form multi-file playground (the two-pane layout is fixed per chapter; + a "Playground" could later reuse the same runner). +- Additional code-pane languages (the data model is ready; content lands later). +- Server-side anything. + +## Entry point and layout + +Instead of a third plain nav link, the top bar's action group gains a small +call-to-action button (Decided) — visually a compact `btn-primary`, sitting left +of the GitHub icon, rendered by `topBar()` in `src/layout.mjs`. On the `/try/` +page itself it renders in an active/current state. + +The page is a two-column layout, mirroring the docs shell's proportions but with +the IDE where the article would be: + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ topbar: flashtrace v0.7.1 Home Docs [ Try it ] ⌂ ☾ │ +├────────────┬─────────────────────────────────────────────────────────┤ +│ CHAPTERS │ ┌─ ide (large, fills the column) ─────────────────────┐│ +│ │ │ ● ● ● ch. 2: cover a requirement [Reset files] ││ +│ ✓ 1 Your │ ├──────────────────────────┬──────────────────────────┤│ +│ first │ │ spec.md │ login.js ││ +│ item │ │ ┌──────────────────────┐ │ ┌──────────────────────┐ ││ +│ ▶ 2 Cover │ │ │## Login │ │ │export function login│ ││ +│ a req. │ │ │ │ │ │ ... │ ││ +│ 3 Read │ │ │`req:login#1` ┌─────┴─┴─┴────────┐ │ ││ +│ the │ │ │ │ Add a Needs: line │ ← popup │ ││ +│ report │ │ │ │ demanding impl:… │ inside │ ││ +│ 4 Rev- │ │ │ └─────┬─┬─┬────────┘ the IDE │ ││ +│ isions │ │ └──────────────────────┘ │ └──────────────────────┘ ││ +│ 5 … │ ├──────────────────────────┴──────────────────────────┤│ +│ │ │ terminal [▶ Run] ││ +│ progress │ │ $ npx flashtrace ││ +│ stored │ │ ✔ req:login#1 … [deep-covered] ││ +│ locally │ │ ok ││ +│ │ └─────────────────────────────────────────────────────┘│ +│ │ Goal: make the trace pass ─ 2 of 3 steps done │ +│ │ [ Help me ] [ Do the next step for me ] │ +└────────────┴─────────────────────────────────────────────────────────┘ +``` + +Key points: + +- **Chapter rail** (left): reuses the docs sidebar component and its mobile + drawer behavior; each entry shows a completion check from the progress map, + with a distinct mark for assisted completions. +- **IDE mock**: visually derived from the hero's `.ide-mock` (chrome bar with + dots, pane tabs, terminal bar) but sized to fill the main column — roughly + the space `.doc-main` + `.toc` occupy on docs pages, with a min-height that + keeps editors and terminal comfortably usable. The hero mock stays untouched; + shared styles get extracted into common classes where that falls out naturally. +- **Editors**: two `