[Design] Onboarding – demo project - #358
Draft
Julia Shilova (juliashilovaa) wants to merge 23 commits into
Draft
Conversation
added 23 commits
August 24, 2026 20:19
Adds packages/server/assets/demo/to-do-app (a tiny, dependency-free working to-do app) and embeds it into the single-file binary via a new demo-assets manifest, staged on boot to THINKRAIL_DEMO_DIR (mirrors the web/skills/runtime asset pipeline). No consumer yet.
…a real repo Adds packages/server/src/demo: ensureDemoProject() copies the bundled template into dataDir/demo/to-do-app (never mutating the source) and hands off to the existing initProject (git init + open); idempotent. removeDemoFiles() is the file half of reset. Adds deleteProject() to the projects module for the record half. Specs + unit tests included.
demo.ensure materializes + opens the bundled To Do App demo (idempotent). demo.reset archives the demo's workspaces (reusing the shared per-workspace teardown, now factored out of workspace.remove), drops the project record, and deletes the user-local copy — so onboarding can be restarted safely. No project/workspace persistence, session lifecycle, or tab-close semantics change.
The bundled demo now carries a goal-and-requirements spec node, so it is a specced project from first open: project.hasSpecs is true, the Specs side-tool has content, and Welcome leads with Start building — the natural onboarding path. Demo SPEC notes the reset-as-replay door.
Adds an onboarding state slice (flow/demoProjectId/dismissed) with start/dismiss/reset/hydrate actions, per-browser localStorage persistence (host-qualified key, mirrors projectExpansion), and derived selectors: the current step (0..3) is computed from real domain state (demo workspace count + whether each has a sent user turn), so it auto-advances and self-heals across reloads. Unit tests for the advance predicates.
Adds apps/web/src/onboarding: OnboardingCoach (one shell-mounted overlay that anchors a Radix popover to real UI elements by stable attribute, tracked per animation frame), the pure selectCoach step mapping, and the startDemo/resetDemo orchestration. Three steps: create two workspaces → start the first agent → run a second agent in parallel; each advances on the real action. Adds anchor attributes to the rail (attributes only) and mounts the coach in the shell. New submodule-web-onboarding SPEC.
Adds the 'Try the To Do App' card to the no-projects Welcome state (calls onboarding.startDemo) and a quiet 'Reset demo' button on the demo project's Welcome (calls onboarding.resetDemo). Panels SPEC documents the cards and the one-way panels→onboarding edge.
demo.reset called forgetWorkspace on the demo's Default workspace, which throws by design (Default is non-removable). Add forgetProjectWorkspaces — a project-deletion primitive that drops every record for a project (including user-owned kinds) and emits removed for each — and have demo.reset tear down + reclaim worktrees, then bulk-forget, deleteProject, and remove files. Worktree reclaim still refuses user-owned kinds.
No-agent spec: the demo card enters the demo, the coach guides creating two workspaces (step 1 → step 2), Reset demo returns to the empty first-run state, and Skip hides the coach while keeping the project.
Uses the Project model's existing display-name field (name, distinct from the path-derived slug): ensureDemoProject sets name via a new setProjectName registry setter, leaving the folder + slug as to-do-app. No new naming concept, no directory rename. e2e asserts the hero title.
Renders the existing 'Try the To Do App' card (same demoCard element, same demo.ensure behavior/copy/styling) alongside the project Welcome cards in both has-specs and no-specs states, not only the empty first-run state. Frontend-only, no wire/contract change. Temporary review aid for this branch — revert this commit to restore empty-state-only placement.
Adds a persistent Help-style OnboardingLauncher at the bottom of the left panel (ProjectTree footer) that starts the demo from a simulated empty first-run state — view-only, never touching the real project registry. Flow: step 1 spotlights a simulated empty Welcome 'Open project' card, then a simulated (frontend-only) folder picker offering a single 'to-do-app' folder; selecting it runs the real demo.ensure and continues into the existing live coach (steps 2-4: create two workspaces, first agent, parallel agent). All steps now use one Spotlight treatment: a container-workspace-overlay (workspace bg @ veil/70% alpha, a sanctioned color token) dim around a clear, interactive target + a tooltip with an arrow; coach marks are non-dismissible, with a separate Exit control that restores the normal UI. Replaces the temporary always-visible Welcome demo card (empty-state card retained as a direct entry). Frontend-only; no wire/contract/backend changes. Specs + e2e updated.
Replaces the onboarding entry behavior with a fully self-contained, frontend-only interactive simulation in a ~90vw x 90vh modal card (OnboardingSimulation). It renders a faithful but mocked ThinkRail (header / left panel / center) driven entirely by local React state: scripted flow of open project -> fake folder picker (to-do-app) -> create two isolated workspaces -> run agent 1 -> run agent 2 in parallel (first shown done while the second works) -> completion. Non-dismissible coach marks with a card-scoped container-workspace-overlay spotlight + arrow; only the current target is interactive. Touches NO domain state: no demo.ensure/reset, no Projects/Workspaces/ Sessions, no pi, no OS picker, no persistence. Launcher + Welcome card now flip a top-level store.demoOpen flag (openDemo/closeDemo). The prior real-domain onboarding coach + client demo orchestration are retained but unwired (dormant) for easy iteration; the server bundled-demo capability is untouched. Specs + e2e updated (e2e asserts the real registry stays empty throughout).
- Animated intro: three staggered fade/translate lines (Welcome / product one-liner / ~2-min setup note) before the first coach mark, then auto- advance into opening the demo project. Reduced-motion shows them static. - Persistent quiet 'Close demo' (ghost Button, top-right), available during the intro and every step; the only pre-completion exit. Coach marks stay non-dismissible. Closes only the mocked experience. - Overlay softened 70%→50%: retuned the container-workspace-overlay's veil alpha step (still derived from the workspace background), so the ThinkRail interface reads clearly under the spotlight. colors bumped to v1.3.0. - Coach tooltips drop the 'Step N of 4' line — title + instruction only. - Added one global 1px bg-primary progress line on the card's bottom edge, advancing across the scripted flow with a smooth width transition. - Active target gets a temporary ring-2 ring-primary pulse (motion-safe; static under reduced motion), moving with the coach, never a permanent component state. Scripted flow, mocked isolation, and design-system usage unchanged; no backend/wire/domain calls. Specs + e2e updated.
Adds a short environment-readiness beat between the product one-liner and the 'set up a demo project' note, inside the existing demo container: a 'Before we start' message plus one compact, fully mocked Git row that animates 'Checking Git…' (spinner) → 'Git is ready' (semantic success role + check), then auto-continues into the interactive walkthrough. No clicks needed; always ends ready. Purely presentational: no Git detection/invocation, no terminal, no server/contract calls, no domain state. Uses existing semantic typography + default/muted/success color roles; success uses the success role (not primary). Not a numbered step. Scripted demo, Close demo, coach marks, 50% spotlight, target pulse, and 1px progress line unchanged. Spec + e2e updated.
Adds a blurred, diffused glow behind the mocked onboarding 'Open project' card using the existing semantic primary alpha token (bg-primary-soft) on a pointer-events-none layer inset slightly beyond the card — no hardcoded color, no raw variable, no new token, not feedback-success. The card's background, border, layout, dimensions, position, and other states are unchanged; only the demo card is affected. Spec updated.
…dialog Prompt steps: the predetermined task is now prefilled in the composer when the step becomes active (no Insert button); the coach highlights the real Send button with the pulsing primary emphasis and the user just clicks Send. Prompts: 'Add search functionality to the To Do app.' and 'Add a filter for completed tasks.' Workspace-creation step: opens the real panels/NewWorkspaceDialog instead of a mocked control, teaching the exact production UI. To keep the demo isolated, the shared dialog gains an inert, default-off 'preview' seam (preview + onPreviewCreate) that skips all its wire reads and scripts submit — no workspace/session/wire work. The shell injects the dialog into OnboardingSimulation via a renderCreateDialog render-prop, so onboarding never imports panels (no cycle); its coach uses a viewport-scoped spotlight while the portaled dialog is visible. Frontend-only; production dialog path unchanged (verified). Specs + e2e updated.
Replaces the small single-folder picker card with a simplified macOS Finder-style folder window that fills the content area below the coach mark: Locations (Home selected) → Home contents (Projects selected) → Projects (my-app / notes / to-do-app), plus a minimal toolbar. Only to-do-app is interactive (pulsing primary emphasis; coach moved above it with a downward arrow); the rest stays under the 50% spotlight and does nothing. Selecting to-do-app continues the existing mocked flow. Fully mocked — no OS picker, filesystem, paths, or backend. Built from existing ThinkRail semantic typography/color tokens (no macOS assets or hardcoded colors); container size and the rest of the flow unchanged. Spec + e2e coverage updated.
- The two predetermined tasks are now 'Implement a search feature in my To Do app.' and 'Add filtering by tags so I can quickly show tasks with a specific tag.', used in both the create dialog and the composer/chat. - Each Create-workspace step opens the real NewWorkspaceDialog (preview seam) with its prompt prefilled + focused (blinking caret, no typing animation); the Create button is emphasized and the coach sits to the dialog's right with its arrow on Create. - Composer prompts are prefilled; the coach highlights the real Send button (no Insert button). - All coach marks now use an inverted/high-contrast surface (bg-primary + text-on-primary + fill-primary arrow) so they stand out from the dark UI; every coach keeps a directional Popover arrow that reorients with side. - Preview-only: the Create button's ↵ key-badge is hidden (text-only 'Create') via the existing preview seam — production button unchanged. Fully mocked/isolated; reduced-motion keeps a static ring. Specs + e2e updated. Design-system flag: the semantic layer has no neutral light/inverse surface role, so coaches reuse the closest existing high-contrast combo (primary/ on-primary) rather than a new token — a true near-white inverse would need a sanctioned role.
The fake folder picker now reads as a system 'your computer' window: a light/inverse neutral surface (radius-lg), a 'Your computer' header with a plain 'Your computer › My Documents › Projects' breadcrumb (no /Users path), and three columns communicating Your computer → My Documents → Projects → to-do-app. Only to-do-app is actionable (primary pulse, coach above with a downward arrow). Rest of the onboarding stays dark. Since the semantic layer had no light/inverse surface (flagged last iteration), the color model is extended with a small reusable inverse family in colors.json — container-inverse-bg / container-inverse-selected / text-on-inverse(-muted) / border-inverse, derived from existing palette keys + the shared alpha scale (no hardcoded grays, no picker-specific tokens). colors bumped to v1.4.0; COLOR.md documents the family. Fully mocked; no OS picker/filesystem/paths/backend. Specs + e2e green.
The second half now demonstrates working with two agents in parallel, fully mocked inside the demo container: - Create Workspace: both dialogs animate the task typing into the real NewWorkspaceDialog prompt (preview seam) with Create inactive until the text finishes; reduced-motion populates instantly. onPreviewReady gates the Create coach. - First workspace: agent shows concise activity (reads → plan → Working…) and keeps running when the user moves on. - Second workspace: a faithful mocked workbench — active agent chat + right-side Files/Specs/Changes strip + bottom Terminal strip — then the agent pauses with a mocked question widget (options + custom field). A coach guides answering; on answer the agent resumes. - Parallel payoff: coach moves to the left nav and highlights the first workspace (still running); returning to it shows the first task completed (result + Changes summary). - Final state: central primary-subtle 'That's the workflow.' surface with Finish + a 'Learn more in the docs' link (existing https://thinkrail.ai); progress line at 100%. Faithful mocks for the chat/workbench/terminal/question surfaces (the real ones are chat-runtime/store-coupled); only NewWorkspaceDialog is the real component via the preview seam. No agents/sessions/workspaces/wire/fs. Coach-mark behavior, spotlight, progress, Close demo, intro/Git-readiness, light picker all preserved. Specs + e2e updated.
Refine the mocked demo's first and final screens onto a single shared OnboardingScreen: same full-card overlay, content width, sequential reveal, vertical rhythm, and a single primary CTA — no separate final card. Intro: hero on one line, 32px to an 18px (tr-heading-md) subtitle, 64px to 'Before we start', 32px to the kept Git-readiness row. No auto-advance — a 'Start demo project' CTA gates entry and the intro persists until clicked. Final: drop the primary-subtle success card and the docs link; render the same layout with 'That's the workflow.' / 'Now try it with your own project.' and a single 'Start working on your own project' CTA. Add xxl/xxxl (~32/64px) spacing steps for the layout rhythm — named outside Tailwind's --container-* scale so they can't shadow max-w-3xl in ChatView.
…on row Drop the 'Before we start' section heading and merge the Git readiness check with the demo-start action into a single coherent block on the shared onboarding intro layout. - Subtitle frame capped at max-w-[400px]; 48px before the Git prerequisite copy, which now reads as two deliberate lines (each its own block, so the second never wraps up onto the first) and 16px before the actions. - Actions are one horizontal row (Git status control + CTA, same h-8 height, flex-wrap for the mobile single-view). - Git readiness is one status control: 'Git:' + spinner while checking → 'Git: is Ready' (success role) when ready — no redundant labels. - 'Start demo project' stays explicit and is disabled (existing disabled semantics) until the mocked readiness confirms, then enables; no auto-start. Add a 48px spacing step: xxl/xxxl/xxxxl now map to 32/48/64px (names kept outside Tailwind's --container-* scale to avoid shadowing max-w-*).
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.
Draft — still needs refinement.
Adds an interactive onboarding flow that simulates working on a demo project directly inside ThinkRail. It walks users through the core workflow with prepared interactions and mocked project/agent activity, without affecting real project state.
The overall flow is in place, but the visual treatment still needs polishing, and we may add or refine onboarding steps based on what is most useful to explain before this is ready to merge.
Changes
apps/web— onboarding module (apps/web/src/onboarding/): a fully self-contained, mockedOnboardingSimulationrendered over the (dimmed) real UI. Shared intro/outro layout, a Finder-style folder picker on an inverse system surface, coach marks (card- and viewport-scoped spotlights), and a scripted parallel-agents payoff. All state is local React state — it never creates real Projects/Workspaces/Sessions or calls the wire.ProjectTree) and an empty-state "Try the To Do App" card (WelcomePanel), both flipping a non-persisteddemoOpenview flag (store). The realNewWorkspaceDialogis reused in an inertpreviewmode via arenderCreateDialogrender-prop injected by the shell (noonboarding → panelsimport).styles/colors.json) for the "your computer" picker, andxxl/xxxl/xxxxl(32/48/64px) spacing steps for the intro/outro rhythm (named outside Tailwind's--container-*scale so they can't shadowmax-w-*).packages/server— bundled demo capability (src/demo/,assets/demo/to-do-app/): a "To Do App" demo template +demo.ensure/demo.resetretained for a future real flow (the shipped UI uses the mocked simulation and does not call these).OnboardingDemo,OnboardingCoach,coach.ts,Spotlight,demo.ts,persistence.ts, the store slice/selectors/wire) — kept intact so this prototype stays easy to iterate on or swap back.Testing
bun run e2e— all 6 shards passed (no-agent suite: projects/workspaces/files/editor/changes/terminals + the onboarding demo flow).bun run test— 10 packages pass (incl. 692 server tests, onboarding store/selectors, demo template).bun run lint(biome) — clean;bunx tsc -p apps/web/tsconfig.json+ contracts typecheck — clean.bun run check:deps+bun run check:seams— OK.@thinkrail/websitetypecheck fails only on this machine's Node v20.15.0 (astro checkneeds ≥22.12); unrelated to this change (apps/websiteis untouched).Base note: branch is currently behind
origin/main; it will be rebased/synced before this leaves draft.