The setup wizard
"i need a perfect onboarding experience for first setup … an onboarding wizard where other plugins can inject a part … a graphically appealing variant where he can click through to configure all his communication channels, all his accounts, to get set up with home entertainment and all is connected" · "create an assistant memex to introduce himself and explain that they will help to manage the life. asking to onboard all the communications … we can intermix setup steps and explanations" — the owner, 2026-10-17.
Right after sign-up a person lands on /area/{you}/GettingStarted — until now a flat list of
Getting-started steps (Getting started and Connections). It is now
the setup wizard: the assistant, Memex, introduces itself and says what it will do for the
person, then walks them chapter by chapter through the panels the installed packages contribute,
with its own words before each chapter and a closing panel at the end. Every panel has a URL, so
the browser's Back works and a chat line can point straight at one step.
The whole journey — from the public instance's welcome page through the account to this wizard and what the system does afterwards — is written as a process in First setup, end to end.
What the person sees
It is built to feel like setting up a new device: the portal's bare page (/area/…, no shell,
no side menu), full height, one panel at a time in a centred card, from the platform's layout
controls only (Stack, Progress, Icon, HeroTitle, Markdown, LayoutArea, Button, the
Card skin):
| Above the card | The card | Below |
|---|---|---|
| who is speaking (the assistant's icon and name) · the chapter strip — one button per chapter, Welcome · Communications · Accounts & services · Your home · More · Done, the done ones ticked, the current one lit, each jumping to the chapter's first panel · a thin progress bar reading Step 3 of 9 | a large icon · the hero title · what the assistant says · the package's embedded panel (its own connect form, switch or settings — rendered live on its own hub, with its own access checks) or an Open button | Back · Set up later · Continue (Finish on the last), and one quiet I'll finish this later to the launcher |
Continue marks a panel done (when passing it is all there is to do) and opens the next panel still
open; Set up later marks a setup step as skipped — it never returns — and moves on; Finish goes
home. A step that is done only once something actually happened (connecting an account) is not
marked by Continue: its source retires it by itself. The in-shell URL /{you}/GettingStarted renders
the same area inside the portal; onboarding and every link the wizard makes use the bare page.
The wizard renders only for its owner. A visitor to a profile gets one line.
Where the panels come from
Three sources, all answered live per person and combined by OnboardingService:
Packages contribute panels as DATA — a
UiContributionnode withcontext: "Onboarding", shipped in the package's own partition (Mail/Onboarding/Mail,HomeAssistant/Onboarding/HomeAssistant,AppleMusic/Onboarding/AppleMusic). No code in the engine, no release of the engine.{ "$type": "UiContribution", "context": "Onboarding", "group": "communications", "order": 20, "label": "Your mail", "icon": "Mail", "tooltip": "Your mail is where most of what needs you arrives — so this is where I can help the most. …", "area": "OnboardingMail" }field the panel's … groupchapter: communications,accounts,home; anything else lands in Moreorderplace in the chapter labelheading tooltipwhat the assistant says — written in the assistant's voice, first person iconrail icon (a Fluent icon name, an emoji or an SVG URL) address+areathe embedded panel. addressunset ⇒ the person's own user node — where a panel that writes their settings lives (Mail's). Set ⇒ it must lie inside the contribution's own partition (HomeAssistant/MyHome), exactly like a person-app tab; anything else is dropped.hrefa page to open instead of an embedded panel (an Open button) neither area nor href an explanation — the assistant's words alone, for a package that wants to say something before its steps The catalog is read as the viewer, so a gated package's panel shows only to someone who holds the package — the same rule the Store's app tabs apply — and a panel shows only while its package is installed here (its
Plugins/{package}install record exists; a package uninstalled with its data retained keeps its nodes but loses the record, and the panel with it). The embedded area still runs its own access checks. The panel id is the contribution's full path through the app tabs' prefix-free escape (Mail/Onboarding/Mail→Mail~_Onboarding~_Mail), injective and URL-safe, and it is the key of the per-person ledger.The Getting-started steps modules contribute in code (
IChatNudgeSource— Connect your accounts, Find your learning path) are panels too, throughNudgeOnboardingStepSource: one source feeds the chat line and the wizard, nothing is declared twice, and the ledger is shared — a step dismissed in a chat is skipped in the wizard and the other way round. Connect your accounts embeds the connection tiles (OnboardingConnections) in the communications chapter, with the panel's own URL as the return target, so a consent round trip comes back to the wizard; any other step is a panel with an Open button in More.The assistant's own words —
OnboardingNarrative: the welcome, one introduction per well-known chapter, the finish. An introduction appears only when its chapter has at least one panel: the assistant never announces an empty chapter. A contributor cannot shadow these ids or claim the welcome or finish chapter.
A module that needs code to decide whether its panel applies implements IOnboardingStepSource
(DI, like IChatNudgeSource) instead of shipping a node. The wizard shows a loading line until
every source has answered once (a faulted source counts as answered, with nothing): a person is
never handed a welcome-and-finish they could complete while the catalog is still being read.
The per-person state
One ledger, AiSettings.DoneNudges on {you}/_Memex/AiSettings, shared with the chat line
(ChatNudgeProgress). The selected panel is the area's id in the URL
(/area/{you}/GettingStarted/Mail~_Onboarding~_Mail); with none, the first open panel shows, and once everything is
done, the closing one.
The mail panel — the three questions
The owner wanted three things asked on the mail step: whether mails should be pre-categorized,
whether it should be synced and for how long, whether replies should be prepared even before
reading — and the person told that the reply can be edited before sending. The Mail package's
panel (MailOnboardingPanel, area OnboardingMail on the person's user node) answers all of it:
- a form bound to the person's own
{you}/_Mail/Preferencesnode (MailPreferences, the platform's content editor — no copy, no save button): sort before I read (sorting, default on), prepare replies before I read (draftReplies, default off — the description says the reply lands as a draft in their own Drafts folder and nothing is sent until they send it), and how far back a copy reaches (copyWindow: last month / three months / year); - the Inbox copies switch right under it, embedded from its own area, so "synced, and for how long" is one panel: the window on the form, the switch below. The copy keeps its ONE switch and its confirmation — a wizard default must never be able to delete a copy switched on elsewhere.
What the preferences drive today: the inbox's triage offers nothing for a person whose sorting
is off (OutlookMailboxQueryProvider, read live on every offer; an unreadable preference reads as
the default, never as "declined"); Keep a copy starts the backfill at the chosen window
(OutlookMailCopy.Enable(owner, windowDays)). draftReplies is recorded and not yet acted on:
the pre-drafter — a pass over reply-tagged verdicts that drafts through the Executive Assistant's
own DraftReply, into the person's Drafts — is the next piece of Personal triage.
The same form is the Mail tab of the person's settings app (/{you}/Settings/Mail), so every
answer can be changed later.
What was decided, and why
- The wizard replaces the list, in place. Same area, same URL, same ledger: onboarding's last redirect, the chat line's Start button and every existing deep link keep working.
- Panels are data, read as the viewer. A package extends the wizard the way it extends the person app and a host app — one contribution lane, one gating rule — and the engine never learns a package's name.
- The assistant speaks only where there is something to say. Chapter introductions are conditional on contributed panels, so a small installation gets a short wizard, not a tour of empty rooms.
- Not now is final, like the chat line's. The rail still lists the panel (ticked), and the settings app keeps every switch; nothing a person skipped is lost, it just stops being asked.
- A home panel handles first use IN PLACE. With app home-writes off (
Home:AppSource = Directory) acquiring Home Assistant or Apple Music copies nothing, so an entitled person's first visit finds no personal node to configure. TheirConnectionareas therefore offer Start on the showcase itself — the Store's own install request for the package's declaredstartPaths, filed as the viewer, its verdict streamed into a line under the button — and the reactive grid of the person's copies shows the form the moment it lands. Nothing navigates, so the wizard keeps its position; the cover stays a link to read, never the only way in. A panel passed with Continue counts as done, as every panel does — the same form stays in the settings app. - Connect your accounts moved to the communications chapter. What it connects today — Microsoft 365, Teams, iMessage, mail for everyone — is how people reach you; the accounts chapter is for the services a package brings (signing, Google, …).
Where it is implemented
| Part | Code |
|---|---|
| The panel model, chapters, source interface | src/MeshWeaver.AI/Onboarding/OnboardingStep.cs |
| The pure rules (arrange, narrative, current, next, progress, URL), the narrative and its words | OnboardingSteps.cs — tests OnboardingWizardTests |
| The contributed-panel source (query as the viewer), the Getting-started adapter, the combiner | OnboardingStepSources.cs |
| The area | OnboardingWizardArea.cs, registered as GettingStarted on every user node (GettingStartedAreas) |
The Onboarding context |
scripts/check-menu-contexts.py (COMPILED_CONTEXTS) |
| The mail panel and preferences | src/MeshWeaver.Mail.MicrosoftGraph/Inbox/MailOnboardingPanel.cs, MailPreferences.cs; nodes Mail/Onboarding/Mail; tests MailPreferencesTests, MailPreferencesMeshTest, InboxTriageTests |
| The home panels | HomeAssistant/Onboarding/HomeAssistant, AppleMusic/Onboarding/AppleMusic (each embeds the Connection area its person-app tab already shows) |