fix(onboarding): inline input at every step + agent-neutral multi-provider wizard#1422
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused tags prop from StepForm/StepExecution and capture narrowed selectedAgentId for authMethodLabel to fix string|null typecheck error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add onboarding-inline-audit.spec.ts (Playwright, 375px + 1280px) covering the agent grid, inline api-key/oauth-token/SAM-budget forms, and the Hetzner/Scaleway cloud toggle with no-overflow assertions. Update unit tests for the agent-neutral path generator, inline step actions, questions tree, and project-selector full-name submission. Remove the obsolete recordings spec replaced by the inline audit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All checklist items done; task-completion-validator PASS. cloud-sam resolved as an honest rule-42 no-op confirmation (no backend field exists for a SAM-infra preference). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ui-ux: role="group" + aria-labelledby on agent/auth/cloud toggle groups; text-[11px] -> text-xs across budget/agent labels. security: spellCheck/autoCorrect/autoCapitalize off on Codex auth.json textarea; capture audit screenshots before fill() so no credential value (even test values) is ever written to disk. test-engineer: CompletionScreen assertion replaces wrong project-URL wait; null selectedAuthMethod error-branch test; validateAgentCredential payload assertion; positive dailyOutputTokenLimit test; StepExecution render tests for ai-setup (six-agent grid + api-key reveal) and cloud-byoc (Hetzner default + Scaleway toggle). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
|
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.



Summary
The onboarding "Choose-Your-Path" wizard had no-op steps that collected nothing and was structurally Claude-locked. A user reached the OAuth step and got no field to enter a token — the step just advanced. Root cause:
ai-oauth,ai-sam, andcloud-samsteps were no-ops; the only OAuth step was gated on ahas-claudetag, making non-Anthropic OAuth (Codex) and the 4 non-major agents unreachable.This PR makes every step collect AND persist real input inline, and makes the wizard fully agent-neutral:
AGENT_CATALOGagents selectable; per-agent auth methods driven by catalog/capabilities (api-keyall;oauth-tokenonlyoauthSupportagents = claude-code/openai-codex;samonly proxy-supported = claude-code/openai-codex).saveAgentCredential({ credentialKind: 'oauth-token', autoActivate: true })(literal'oauth-token'). Reuses the setup-token password field + Codexauth.jsontextarea widgets.providerMode:'sam'viasaveAgentSettingsAND collects budget inline (daily input/output token limits + monthly cost cap →PUT /api/usage/ai/budget).secretKey+projectId). No GCP (multi-step WIF/OAuth — left to Settings).has-claudeOAuth gate replaced with a generic per-agentoauthSupportcapability check; all copy made provider-neutral.markStepDone→onComplete→CompletionScreen("You're all set!"), no spurious navigation.openai-key,has-api-key,no-ai,has-hetzner,no-cloud,sam-infra).Validation
pnpm lint— 0 errors (pre-existing warnings only)pnpm typecheck— cleanpnpm test— 2432 web tests pass (85 onboarding unit tests across 6 files)Staging Verification (REQUIRED for all code changes — merge-blocking)
Deploy Stagingrun28245891076conclusion=success ononboarding-inline-multi-agentapp.sammy.partyviaPOST /api/auth/token-login(200), drove the wizard live/dashboard?onboarding; two-question tree works; Start setup → cloud-byoc step renders#onboarding-hetzner-tokeninline; Scaleway toggle reveals#onboarding-scaleway-secret+#onboarding-scaleway-projectinline at both 375px and 1280pxN/A: no infra changes(no cloud-init / VM agent / DNS / TLS / deploy-script paths touched)Staging Verification Evidence
Authenticated via token-login (200), then drove the live wizard on
app.sammy.party:I have Hetzner or Scaleway) and repo question (Yes, I have a repo) answerable,Start setupadvances to execution.#onboarding-scaleway-secret+#onboarding-scaleway-projectappear, no overflow at 375px or 1280px.path-generatorbehavior — ai-setup becomes optional). That surface is fully covered by the 8 local Playwright audits (existingAgent:false) and theStepExecutionrender unit tests.UI Compliance Checklist (Required for UI changes)
role="group"+aria-labelledby(orphaned<label>fixed); Codex auth.json textareaspellCheck={false}fill()so no secret value is written to disk (onboarding-inline-audit.spec.ts)End-to-End Verification (Required for multi-component changes)
Data Flow Trace
StepForm.tsxagent grid (role="group") setsStepFormState.selectedAgentauthMethodsForAgent(agentId)(step-actions.ts) → renders only supported auth toggles (api-key / oauth-token / sam)StepExecution.tsxcollects into form state →executeStep()→saveAgentCredential({ agentType, credentialKind, credential, autoActivate: true })(step-actions.ts)saveAgentSettings({ providerMode: 'sam' })+buildBudgetRequest()→updateUserAiBudget()(PUT /api/usage/ai/budget)createCredential({ provider: 'hetzner'|'scaleway', ... })createProject()→markStepDone()→onComplete()→ChoosePathWizardsetPhase('complete')→CompletionScreenUntested Gaps
The ai-setup/OAuth agent grid path is not reachable on the staging primary user (already has an agent credential, so the step is correctly optional/filtered). It is covered by: 8 local Playwright real-browser audits with
existingAgent:falsemock (asserts the OAuth#onboarding-oauth-tokenfield renders — the exact original bug),StepExecutionrender unit tests (six-agent grid + api-key reveal), andstep-actionsunit tests (oauth-token / sam payload shape).Post-Mortem (Required for bug fix PRs)
What broke
During onboarding a user selected the OAuth/subscription option and was shown no input field — the step silently advanced, persisting nothing. Non-Anthropic agents (Codex) and the 4 non-major agents (Gemini/Mistral/OpenCode/Amp) were structurally unreachable.
Root cause
ai-oauth,ai-sam, andcloud-samsteps were implemented as no-ops (StepForm.tsx/step-actions.ts) that rendered no field and called no persistence API. The flow was Claude-locked structurally:questions.tstagged the subscription optionhas-claudeandpath-generator.tsgated the only OAuth step on that tag, so any non-Claude OAuth path produced an empty step.Class of bug
Unwired UI control — a UI affordance (the OAuth step) that collects input but never sends it anywhere, combined with provider lock-in encoded in routing logic rather than derived from capabilities. Same class as the rule 06 "UI-to-Backend data path" failures.
Why it wasn't caught
The no-op steps had no behavioral test asserting a field rendered or a persistence call fired; the existing tests asserted step navigation, not data capture. No test exercised a non-Claude OAuth agent through path generation.
Process fix included in this PR
Coverage added so this class is caught going forward:
StepExecutionrender tests assert the credential input actually appears after agent selection;step-actionstests assert the exactsaveAgentCredential/ budget payload shape; Playwright audits assert#onboarding-oauth-tokenrenders (the literal original bug). The work also exercisespath-generatorwith all 6 agents so provider-specific gating regressions surface in unit tests. (Aligns with existing rules 06 UI-to-Backend and 35 vertical-slice; no rule file change required — the gap was missing tests, now added.)Post-mortem file
tasks/archive/2026-06-26-onboarding-inline-multi-agent.mdSpecialist Review Evidence (Required for agent-authored PRs)
needs-human-reviewlabel added and merge deferred to human — N/A, all completed<label>→role="group"+aria-labelledbyon agent/auth/cloud groups; M3role="group"on button containers; M1text-[11px]→text-xs; fixed in 2696fbfspellCheck={false}on Codex auth.json textarea; screenshots moved beforefill()for all secret fields so no secret value hits disk; credential literals/kinds correct; fixed in 2696fbfExceptions (If any)
Agent Preflight (Required)
Classification
External References
N/A: <reason>— reuses existing in-repo APIs (saveAgentCredential,validateAgentCredential,saveAgentSettings,createCredential,updateUserAiBudget) and the existingAGENT_CATALOG/capabilities; no new external API surface consulted.Codebase Impact Analysis
apps/web/src/components/onboarding/choose-path/(questions, path-generator, step-actions, StepForm, StepExecution, ChoosePathWizard). Reads frompackages/shared(AGENT_CATALOG,CredentialKind,AgentProviderMode, Scaleway/Hetzner provider shapes). No API or shared package changes — purely consumes existing endpoints.Documentation & Specs
N/A: no user-facing docs describe the internal onboarding step tree; behavior is self-contained in the wizard component and covered by tests. Task record updated intasks/archive/.Constitution & Risk Check
Principle XI (no hardcoded values): auth methods + provider list derived from
AGENT_CATALOG/capabilities, not hardcoded branches. Risk: credential handling — mitigated by security-auditor review (secrets never screenshotted, correct credentialKind literals,spellCheck={false}). Multi-tenant: all persistence uses existing per-user credential APIs.