Skip to content

feat(tui): interactive getting-started tour on first run, replayable on demand#3427

Merged
dgageot merged 2 commits into
mainfrom
feat/getting-started-tour
Jul 3, 2026
Merged

feat(tui): interactive getting-started tour on first run, replayable on demand#3427
dgageot merged 2 commits into
mainfrom
feat/getting-started-tour

Conversation

@Sayt-0

@Sayt-0 Sayt-0 commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

Implements #3426: a short, skippable, hands-on tour inside the TUI that teaches docker agent by doing, offered on the first interactive run and replayable on demand.

The tour is a floating card that observes the real UI's message stream: each step completes when the user actually performs the action it describes. The card never steals focus and renders below dialogs, so the feature being taught (palette, tool approval) is never hidden by it.

docker agent run                     (first interactive run)
  -> offer dialog: take the tour? [enter / n / d]
       enter -> scripted tour overlay starts
       n     -> hint toast, offer may reappear on a later run
       d     -> never again (persisted)

docker agent getting-started         (alias: tour)  -> tour starts immediately
/getting-started, palette Help entry                -> replay from inside the TUI

Card rendering (step, then completion flash before auto-advance; titles carry a small emoji in the real UI):

+--------------------------------------------+     +--------------------------------------------+
|  Getting started                   o.....  |     |  Getting started                   *.....  |
|  ----------------------------------------  |     |  ----------------------------------------  |
|  Talk to your agent                        |     |  Message away, the reply streams in live.  |
|                                            | ->  |                                            |
|  This is a conversation, not a form.       |     |  Next stop in a moment... (enter to jump)  |
|  Plain language works.                     |     |               enter continue Esc quit tour |
|                                            |     +--------------------------------------------+
|  > Type anything below and press Enter,    |
|    try "write a haiku about containers".   |
|             enter skip step  Esc quit tour |
+--------------------------------------------+

Steps

# Teaches Completes when
1 Send a message a non-slash message is sent
2 Tool calls need approval, Ctrl+y yolo the confirmation dialog is answered (or a tool ran in yolo mode)
3 Command palette the palette actually opens (Ctrl+k or status-bar click)
4 Slash commands /model, /sessions, /theme, /tools or /cost dispatches
5 Agents are YAML, docker agent new, catalog read step, Enter
6 Ctrl+h, replay, feedback read step, Enter finishes

Enter (on an empty editor) skips a step; Esc quits the tour at any point. Completed steps flash a short celebration, then auto-advance.

Issue expectations mapping

Issue item Status
Scripted TUI tour (option A), deterministic copy, no tokens for the tour itself implemented
First-run offer, prompt-first (not forced) implemented
CLI replay command implemented as getting-started with tour alias
/tour slash command + palette entry implemented as /getting-started, new Help palette category
Root --help pointer implemented
Never shown in non-interactive contexts offer only wired on the interactive full-TUI run path; also suppressed for --fake, --record, --exit-after-response, --session-read-only, lean mode, and runs that already carry an initial message
DOCKER_AGENT_NO_TOUR env implemented (plus CAGENT_NO_TOUR, matching the telemetry banner precedent)
Esc skippable at every step implemented
"Never" persisted, state next to first-run marker implemented, <config-dir>/.cagent_tour containing done or never
Telemetry banner folds into the flow the offer dialog carries the telemetry notice; the stderr banner itself is untouched since the alt screen covers it on TUI runs and it remains the only notice for non-TUI first runs
Provider setup step (no provider configured) not included; the existing AutoModelFallbackError already lists DMR and per-provider key instructions; candidate follow-up
Telemetry for tour started/completed/skipped-at-step partial: getting-started invocations tracked via the existing TrackCommand; per-step TUI events would need new telemetry plumbing in pkg/tui, left out
Tour agent hand-off (option B) in builtin-agents not included, kept to the deterministic scripted tour

Open questions resolution

Question Decision
Command name getting-started, with tour alias
Auto-offer vs auto-start prompt-first offer
Interrupted tour re-offered? starting the tour marks the offer as answered; "not now" re-offers on a later run; "never" is permanent
Ship a tour agent in builtin-agents? no, out of scope for this PR

Implementation notes

Piece Where
Persisted state (done/never, env suppression) pkg/tour
Tour engine, card, step checks pkg/tui/components/tour
First-run offer dialog pkg/tui/dialog/tour_offer.go
appModel wiring (observe wrapper, keys, layer, handlers) pkg/tui/tui.go, pkg/tui/tour.go
Palette Help category, /getting-started pkg/tui/commands
CLI command, hidden --tour on run, offer conditions cmd/root
  • The tour observes messages through a thin Update wrapper on the appModel; it never consumes messages, so normal routing is unchanged.
  • Step detection uses the messages the actions actually produce (OpenDialogMsg with the palette model, RuntimeResumeMsg, ToolCallResponseEvent, picker/browser messages) rather than raw key matches, so any path to the feature counts.
  • getting-started dispatches through the registered run command (same mechanism as the root command's no-args default), so the session behaves exactly like a regular interactive run.
  • Lean mode has no overlay support: the tour is disabled there and /getting-started surfaces a notification.

Testing

Layer Coverage
pkg/tour state read/write, env suppression
pkg/tui/components/tour step checks, celebration/advance, quit, progress, layout guards
pkg/tui/dialog offer choices, palette predicate
pkg/tui StartTourMsg and offer-result handlers, observation through Update, Esc/Enter keys, persistence
e2e (tuitest) full walkthrough including a real Ctrl+k, Esc quits, first-run offer decline

go build, go vet, golangci-lint run, and go run ./lint . are clean. The full test suite passes except five packages whose SSRF/private-address tests fail identically on a clean tree in the development environment (pkg/config, pkg/httpclient, tools builtin api/fetch/openapi), unrelated to this change. A manual run of the built binary (docker-agent getting-started with isolated state dirs) confirmed the full CLI to TUI to tour path executes and persists the state file.

closes #3426

@Sayt-0
Sayt-0 requested a review from a team as a code owner July 2, 2026 18:40
@aheritier aheritier added area/cli CLI commands, flags, output formatting area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat:). Use on PRs only. labels Jul 2, 2026
Add a hands-on onboarding tour that teaches docker agent by doing
instead of reading docs: a floating card observes the real UI and
advances when the user performs each step (send a message, approve a
tool call, open the palette, use a slash command), with read steps for
agent YAML concepts and where to find help. Enter skips a step, Esc
quits at any point. The card anchors to the bottom-right of the
content area, under the sidebar, and renders below dialogs, so it
never hides session info or the feature it teaches. The tool step
completes only when the user actually approves a tool call from the
confirmation dialog, not when an auto-approved tool responds.

Entry points: the getting-started command (alias tour), the
/getting-started slash command and palette entry (new Help category),
a first-run offer dialog, and a pointer in root help.

The offer is prompt-first and never shown in non-interactive, lean,
record/replay, read-only, or initial-message runs, honors
DOCKER_AGENT_NO_TOUR=1, and folds the telemetry notice into the
dialog. State persists in the config dir next to the first-run
marker: starting the tour or choosing never stops the offer, not now
re-offers on a later run.

Closes #3426
@Sayt-0
Sayt-0 force-pushed the feat/getting-started-tour branch from 2c5f17d to f7dccbf Compare July 3, 2026 08:53
The suggested ask ("what's in this folder?") routes to the filesystem
list tool, which carries ReadOnlyHint and is auto-approved by the
dispatcher, so no confirmation dialog ever appeared and the step could
not complete. Suggest "run ls in the shell" instead: the shell tool
always prompts. The step body now says that only side-effecting tools
wait for approval instead of claiming nothing runs unapproved.

Also tone the card down: drop the emoji from step titles and the
palette entry (keep the welcome wave and the end-of-tour confetti) and
replace the em-dashes in tour copy, notifications, and command help
with plain punctuation.
@dgageot
dgageot merged commit 1138afa into main Jul 3, 2026
11 checks passed
@dgageot
dgageot deleted the feat/getting-started-tour branch July 3, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cli CLI commands, flags, output formatting area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: interactive onboarding tour on first run, replayable on demand

3 participants