feat(tui): first-run experience — launch decision tree, welcome readiness check, detected agents#598
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rereq notices
When the Welcome fork renders, surface machine readiness without gating
anything: a confidence beat listing detected executor CLIs ("Detected
agents: claude, codex", reusing availableExecutors detection) and, when
tmux or all executor CLIs are missing, a visible warning line with the
exact install hint (mirroring the desktop SetupCheck wording).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…readiness additions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…xit bug macOS stock bash 3.2 aborts a 'set -e' script when a failing command is prefixed with the 'command' builtin, even inside '|| true' lists. lib.sh's tmux() wrapper used 'command tmux', so every ty-qa script died at its first 'tmux kill-session' against a not-yet-running QA server. Resolve the real binary into TY_QA_TMUX_BIN at source time instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
QA screenshots (TUI)Captured with the real TUI via the VHS QA harness ( Welcome fork — agents detected. First run in a plain (non-project) folder; the new "Detected agents: …" confidence line lists the executor CLIs found on PATH. Welcome fork — missing prereqs. Same screen launched through a wrapper that strips Homebrew/npm from PATH (no tmux, no agent CLIs): both non-blocking warning notices show with exact install hints, and the fork stays usable. Project suggestion card. First run inside a seeded git repo with a README; after the Fuzzy folder picker. From the Welcome fork: Enter on "Set up a project", then typing 🤖 Generated with Claude Code |
The first-run folder picker was a bare hand-rolled list: full paths in a
flat column, a ">" cursor, bare "git ●" text, and a wall of dead space.
Rebuild the view on bubbles/list inside a centered bordered panel that
matches the Welcome fork:
- folder basename as the prominent title, dimmed ~-collapsed parent path
as the description, accent bar + accent color on the selected row
- typing drives the list's built-in fuzzy filter (SetFilterText), so
matched runes are underlined in place; the custom delegate mirrors
list.DefaultDelegate but can append a styled green "⏺ git" badge to
repo titles without mangling ANSI inside the title
- count line ("66 folders · git repos first" / "10 of 66 folders match")
plus the list's pagination dots when the list overflows
- all behavior preserved: type-to-filter, ↑↓ select, → descend (leaf
folders still picked with enter), enter pick (folderPickedMsg), esc back
fuzzyFilterFolders is gone (the list's fuzzy filter replaces it); its
test is replaced by coverage of the seeding/sorting logic that remains
(collectCandidateFolders / sortFolderEntries).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Picker restyleThe fuzzy folder picker is rebuilt on BeforeAfter — typing
|
Summary
Ships the first-run / first-folder experience plan (
docs/superpowers/plans/2026-06-05-first-run-experience.md, included with all checkboxes ticked) plus two Welcome-view additions from competitor onboarding research: a non-blocking machine-prerequisite check and a detected-agents confidence beat.The launch decision tree (runs on every startup)
Git stays optional: non-git candidates get
Worktrees: falseand project creation never inits git. Project-form validation always routes throughreshowProjectFormWithError, so input is never lost.Note: plan Tasks 1–9 were found already implemented on
main(thefeat/fix/test(onboarding)commit range25a64f80…34991e5d). This PR verifies each task against the plan's named commands (see the plan's Execution record section) rather than re-implementing, and contributes:feat(onboarding): Welcome view showsDetected agents: claude, codex, …(reusing the existingavailableExecutorsdetection) and, when tmux or all executor CLIs are missing, clearly visible non-blocking notices with exact install hints (tmux not found — brew install tmux/no coding agent found — npm install -g @anthropic-ai/claude-code), mirroring the desktop SetupCheck. Pure formatting/notice logic TDD-tested ininternal/ui/welcome_test.go.fix(qa): the ty-qa harness died on macOS stock bash 3.2 — a failingcommand tmux …inside|| truestill aborts underset -e(3.2command-builtin errexit bug).lib.shnow resolves the tmux binary at source time.docs: the plan, ticked, with an addendum documenting the additions and an execution record.Test evidence
go build ./...clean;gofmt -l internal/ui internal/aiempty;go vet ./internal/ui/... ./internal/ai/...clean.TestIsProjectCandidate,TestParseInferenceJSON,TestInferProjectMetadata_DegradesWhenClaudeMissing(passes withclaudeunreachable, by design),TestApplyInferredMetadata,TestFuzzyFilterFolders.TestFormatDetectedAgents,TestMissingPrereqNotices,TestWelcomeViewShowsEnvironmentStatus(asserts notices never hide the fork).go test ./...passes (internal/ui,internal/ai,internal/parityincluded). Twointernal/executortests fail only when the ambient shell exportsCLAUDE_CONFIG_DIR— pre-existing environment sensitivity onmain, unrelated to this branch; suite is green with it unset.Live QA exercised (isolated harness,
scripts/qa/ty-qa-firstrun.sh)claude -pinference (Name: Acme Rocket,Alias: acmerocket, instructions imported from README,Worktrees: true).Worktrees: false; pressedy→ project created (use_worktrees=0in DB), no.gitcreated.Detected agents: claude, codex, gemini, opencode, pi.workflow→ 3 git-tagged matches) → esc back to Welcome → "Just start a task" → New Task form inpersonal.ty projects create+ty createagainst the isolated DB, worktree created without error.Not exercised live
git worktree add, the executor's underlying operation) perscripts/qa/README.md./tmpscenario folders (it seeds from~/Projects,~/src, …), so "pickjust-a-foldervia the picker" was exercised as picker navigation + the same suggestion-card path driven from Scenario B instead.🤖 Generated with Claude Code