Onboarding process

September 21, 2026 · View on GitHub

The signed-in /onboarding wizard, the derived setup checklist, and the optional first-win email guide share one contract:

packages/worker/universal/onboarding-process.ts

SurfaceRole
Wizard index /onboardingRedirects to the first unfinished step (Step 3 once Step 2 is done)
Wizard Step 1 /onboarding/step-1Connect an MCP host
Wizard Step 2 /onboarding/step-2Make something useful (one prompt + first search + guide:onboarding first-win picker)
Wizard Step 3 /onboarding/step-3Connect a second agent (same-ecosystem hosts greyed; guide:portability)
ChecklistVerify email, complete the three wizard steps, then persist a package
first-winOptional email → reply → memories loop after a host is connected

Step 2 is one copy-paste prompt that tells the connected agent to retrieve onboarding (search({ entity: "guide:onboarding" })). The guide presents six concrete first-win choices (PR readiness, an always-on ping, skill→owned package, email wake when the host can be woken, Slack/Raycast webhook, or something else) and the agent does one small win from their pick. The page shows a spinner until Kody observes that first successful search (or an existing access win: memory, execute, or saved package). Leftover /onboarding/step-2/:service URLs redirect to Step 2. Hosted / platform OAuth is not the onboarding path; new connects are bring-your-own.

Step 3 reuses the Step 1 agent picker. Hosts in the same vendor family as the first agent are greyed so the second connect is a different ecosystem. After the person picks a host, a short portability-proof prompt is folded into the same step so the new agent looks up portability (search({ entity: "guide:portability" })) and reuses what Step 2 made. When the onboarding payload has a known memory subject or saved-package name, Step 3 shows a short "You made …" chip (truncated subject and @scope/kody-id, or hidden if nothing sensible). hasSecondMcpClient is unique inbound OAuth clientIds ≥ 2, not raw grant count and not attribution to the selected host — the connected label stays "You've connected a second agent." When the second-agent Standard gift is active, that status adds "Standard is free for 2 weeks." Step 3 copy advertises "Connect a second agent and get Standard free for 2 weeks." Same-ecosystem greying stays picker UX only. /onboarding resumes at that step instead of always opening the Step 1 picker. The Step 1 and Step 3 pickers, and Step 2, list already-connected hosts so a return visit cannot hide Cursor or Claude Desktop. A selected-agent card names only that host: another client's connection does not mark this one connected and does not put its logo on the card. A remembered picker choice is not a grant. When a different host actually authorized, Step 2 and Step 3 follow that grant instead of the pick. Account → Connections (/account/connections) lists those inbound hosts grouped by display name, with public logos for known kinds, newest-first sort, best-effort labels, and per-clientId revoke. That list is not users.mcp_client_name (first-touch) and not /account/mcp-oauth-clients (user-minted confidential clients).

first-win is not a wizard step and is not a checklist item. Signed-in /onboarding does not probe Mailbox for that loop. MCP registers onboarding_first_win and search({ entity: "guide:first_win" }) serves the guide.

Waiting (/account/waiting and waitingSummary) is a separate current-state queue. Wizard-resume and first-use cards live there. See Waiting.

Alignment check

packages/worker/universal/onboarding-process.node.test.ts (part of npm run test:node / npm run validate) requires docs/guides/first-win.md to name each current wizard step (label or path). docs/guides/quick-example.md names Step 2's label and the Step 1 path. The first-run briefing is docs/guides/onboarding.md and must name the six first-win choices.

Change the wizard in onboarding-process.ts first, then update those two guides until the test passes. The same check requires docs/guides/portability.md to name Step 3 and stay short. The checklist union has no first-win items; adding them fails the same check.