Skip to content

feat(desktop): add key backup and agent defaults to onboarding, make avatar optional#1767

Merged
wpfleger96 merged 1 commit into
mainfrom
wpfleger96/onboarding-key-backup-agent-setup
Jul 12, 2026
Merged

feat(desktop): add key backup and agent defaults to onboarding, make avatar optional#1767
wpfleger96 merged 1 commit into
mainfrom
wpfleger96/onboarding-key-backup-agent-setup

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Stack: #1765 → this PR

Reworks first-run onboarding around three fresh-install feedback items:

  • Private key backup step (fresh-key path). Buzz silently generates a Nostr key on first launch, and there was no way to ever see it — losing the machine meant losing the identity. A new backup step (between profile and avatar; the fresh-key path is 6 steps, key-import stays at 5 — both paths are declarative page arrays with the step number derived by position) fetches the nsec via the existing get_nsec command and shows it masked with reveal/copy controls, a "never share your private key" warning, and a checkbox acknowledgment gating Next (also gated while the key is loading or errored — load failures show Retry plus an explicit "Skip for now" so onboarding never bricks). When the backend has no key to return (null, no error), the step shows "No key available to back up." and omits the warning instead of rendering it beside nothing. The same NsecMaskedDisplay backs a new "Private key" reveal row in Settings → Profile → Identity, where the nsec is fetched only on reveal, cleared on collapse and unmount, and a late-resolving fetch can never repopulate the row after Hide.
  • Avatar is optional. The avatar step now always offers a "Skip for now" button (advances to the theme step); previously skipping was only reachable after a profile-save error.
  • Agent defaults in the setup step. The final onboarding step embeds the global agent config fields (provider, model, effort, env vars — extracted from the settings card into a shared GlobalAgentConfigFields component with zero visual change there) plus a readiness badge: green when a CLI harness is installed and authenticated — or needs no login at all (goose reports not_applicable and now counts as ready) — or when buzz-agent has provider, model, and the provider's required credential keys configured; amber "Not configured" otherwise, with a Re-check button that re-probes. Edits autosave through a coalescing queue (saveCoalescer.ts): local state applies optimistically, rapid consecutive edits serialize into a trailing save, and a resolving save never overwrites a newer edit made during the request. Finish stays enabled — when not ready the step says "You can finish now and configure agents later in Settings." The config-nudge cards remain the backstop.

Covered by unit tests across the save-coalescer interleavings, the readiness matrix, the step derivation, and the backup states, plus four Playwright specs (onboarding-avatar-skip, onboarding-backup, onboarding-agent-defaults, profile-nsec-reveal) including a rapid-consecutive-edit regression test and the backup error → Retry / Skip paths.

@wpfleger96

Copy link
Copy Markdown
Collaborator Author

🤖 Screenshots from the new onboarding Playwright specs.

Avatar step — always-visible skip

"Skip for now" now renders without needing a profile-save error first.

01-avatar-skip-button

Backup step — masked

Fresh-key path step 3: the generated nsec starts masked; the checkbox gates Next.

02-backup-step-masked

Backup step — revealed

The eye toggle reveals the key; copy is enabled only while revealed. Next stays disabled until the acknowledgment is checked.

03-backup-step-revealed

Setup step — agent defaults ready

Readiness badge when a harness is authenticated or buzz-agent is fully configured.

04-setup-readiness-badge

Setup step — not configured

Amber badge with advisory copy; Finish stays enabled so onboarding is never blocked.

05-setup-not-configured

wpfleger96 added a commit that referenced this pull request Jul 12, 2026

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking on the onboarding autosave race in AgentDefaultsSection.

The controls remain editable while isSaving, but onConfigChange only invokes handleSave(next) when !isSaving. A second edit during the first request therefore updates local state without being persisted; when the first request resolves, setConfig(saved) overwrites that newer edit with the older response. This can silently lose a provider/model/credential change during normal quick editing.

Please serialize/coalesce saves (persist the latest pending snapshot after the in-flight request), or disable the whole field group while saving, and add a rapid-consecutive-edit regression test. The stack also currently conflicts with its #1765 base and is one commit behind that branch, so it will need a rebase and fresh CI afterward.

@wpfleger96 wpfleger96 force-pushed the wpfleger96/onboarding-key-backup-agent-setup branch from 181f44e to faff006 Compare July 12, 2026 17:38
@wpfleger96

Copy link
Copy Markdown
Collaborator Author

🤖 hey @wesbillman, this should be sorted now. The autosave race in AgentDefaultsSection is fixed with the coalescing approach you suggested: edits always apply to local state optimistically, and persists go through a small save-coalescer (saveCoalescer.ts) that serializes rapid edits into a trailing request and only applies the backend response when no newer edit is pending — so a resolving save can't clobber anything fresher. In-flight saves are cancelled on unmount, and a failed save keeps the optimistic local state instead of reverting.

It's unit-tested across the interleavings (second-edit-during-save, burst of edits, stale-response suppression, error-path retention, cancel), plus a rapid-consecutive-edit Playwright regression test that holds the first save open with a mock delay, makes a second edit mid-flight, and asserts the later value survives in the UI and is what gets persisted.

The rebase onto #1765 is done as well (the stack conflict was just the playwright config) and CI is green on the rebased branch.

@wpfleger96 wpfleger96 requested a review from wesbillman July 12, 2026 18:21
@wpfleger96 wpfleger96 force-pushed the wpfleger96/doctor-install-reliability branch from d16bf95 to ea82454 Compare July 12, 2026 21:29
@wpfleger96 wpfleger96 force-pushed the wpfleger96/onboarding-key-backup-agent-setup branch from a053980 to 8f3e5d8 Compare July 12, 2026 21:33
Base automatically changed from wpfleger96/doctor-install-reliability to main July 12, 2026 21:42
@wpfleger96 wpfleger96 force-pushed the wpfleger96/onboarding-key-backup-agent-setup branch from 8f3e5d8 to f9d49d3 Compare July 12, 2026 21:55
…avatar optional

The nsec was generated silently on first run with no in-app way to view or
recover it; a new backup step surfaces it with a masked/reveal display and
acknowledgement gate. Onboarding never drove a valid agent configuration, so
first agent use would fail; a new agent defaults section in the setup step
steers toward a working setup before finish. Avatar selection was mandatory
with no skip path.

Review-round hardening: rapid edits during an in-flight autosave could
silently lose changes in AgentDefaultsSection — a createSaveCoalescer helper
now serialises saves and drains the trailing edit, applying local edits
optimistically and suppressing stale backend responses (unit tests for the
interleavings + a rapid-edit Playwright regression spec). BackupStep and
NsecRevealRow gained setState-after-unmount guards and nsec state cleanup.
OnboardingFlow's nested step ternaries became declarative FRESH_STEPS /
IMPORT_STEPS arrays; EMPTY_GLOBAL_CONFIG is shared from
GlobalAgentConfigFields; onboarding spec helpers are deduplicated into
tests/helpers/onboarding.ts. agentReadiness treats not_applicable as
CLI-ready (Goose). The e2e mock for set_global_agent_config unwraps the
{ config } invoke payload instead of echoing the whole payload.

E2E specs cover backup failure → retry/skip, import-path routing (no backup
step), fresh-path Back from avatar, nsec reveal in settings, and the
null-key backup state.
@wpfleger96 wpfleger96 force-pushed the wpfleger96/onboarding-key-backup-agent-setup branch from f9d49d3 to 42388f8 Compare July 12, 2026 22:29
@wpfleger96 wpfleger96 merged commit d2e87e1 into main Jul 12, 2026
25 checks passed
@wpfleger96 wpfleger96 deleted the wpfleger96/onboarding-key-backup-agent-setup branch July 12, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants