Skip to content

[Design] Onboarding – demo project - #358

Draft
Julia Shilova (juliashilovaa) wants to merge 23 commits into
mainfrom
demo-project-investigation
Draft

[Design] Onboarding – demo project#358
Julia Shilova (juliashilovaa) wants to merge 23 commits into
mainfrom
demo-project-investigation

Conversation

@juliashilovaa

Copy link
Copy Markdown
Collaborator

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, mocked OnboardingSimulation rendered 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.
  • Entry points: left-panel launcher (ProjectTree) and an empty-state "Try the To Do App" card (WelcomePanel), both flipping a non-persisted demoOpen view flag (store). The real NewWorkspaceDialog is reused in an inert preview mode via a renderCreateDialog render-prop injected by the shell (no onboarding → panels import).
  • Design system: an inverse-surface semantic colour family (styles/colors.json) for the "your computer" picker, and xxl/xxxl/xxxxl (32/48/64px) spacing steps for the intro/outro rhythm (named outside Tailwind's --container-* scale so they can't shadow max-w-*).
  • packages/server — bundled demo capability (src/demo/, assets/demo/to-do-app/): a "To Do App" demo template + demo.ensure/demo.reset retained for a future real flow (the shipped UI uses the mocked simulation and does not call these).
  • Dormant, retained-not-wired: the earlier real-domain coach (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.
  • Note: @thinkrail/website typecheck fails only on this machine's Node v20.15.0 (astro check needs ≥22.12); unrelated to this change (apps/website is untouched).

Base note: branch is currently behind origin/main; it will be rebased/synced before this leaves draft.

Julia.Shilova 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-*).
@juliashilovaa Julia Shilova (juliashilovaa) changed the title Add interactive demo onboarding [Design] Onboarding – demo project Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant