Skip to content

fix(desktop): keep first launch quiet until the user is onboarded - #9219

Open
Kitenite wants to merge 1 commit into
mainfrom
fix/desktop-first-launch-quiet
Open

Kitenite wants to merge 1 commit into
mainfrom
fix/desktop-first-launch-quiet

Conversation

@Kitenite

@Kitenite Kitenite commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

From the biweekly fresh-Mac onboarding walkthrough (https://app.superset.sh/page/onboarding-walkthrough-on-a-fresh-mac-udhhym): a filmed production first launch of desktop v2.0.2 on a clean macOS 26 VM.

Findings and root causes

1. Two permission prompts at launch, before any UI.

  • Local Network: we ask for it on purpose. requestLocalNetworkAccess() (apps/desktop/src/main/lib/local-network-permission.ts) sends one mDNS packet to 224.0.0.251:5353 so macOS shows the prompt. It ran at boot in apps/desktop/src/main/index.ts:515 (on main). Nothing else in desktop or host-service touches the LAN at boot: no other dgram, Bonjour, or multicast code, and listening sockets do not trigger the prompt. The probe came from fix (desktop): local network permission request #737 so that LAN dev servers work before a terminal hits them. It is not needed before the user can open a terminal.
  • Notifications: registerWithMacOSNotificationCenter() (index.ts:513) shows a silent notification so the app gets listed in System Settings > Notifications. fix(desktop): register with macOS Notification Center at startup #1492 added it because on macOS 26 notifications were never delivered without it. That is what causes the prompt.
  • The same block also ran requestAppleEventsAccess() (index.ts:514, fix(desktop): request Apple Events permission upfront to prevent repeated macOS prompts #1567). It has the same no-context problem, so it moves with the other two.

2. Writes to other tools' config dirs before sign-in. setupAgentIntegrations() ran at boot (index.ts:648) with no auth check. It writes hooks and settings for every supported agent. A probe against an empty $HOME reproduces the list from the walkthrough: .claude .codex .config/{amp,devin,muse} .cursor .factory .gemini .grok .kimi-code .mastracode .omp .pi .vibe. Managed skills, run from the same call, write ~/.agents/skills (managed-skills.ts:401). syncInstalledPluginMcpServers() (index.ts:656) ran next to it. After sign-in, <OrganizationPluginSync /> (_authenticated/layout.tsx:350) also ran plugins sync during onboarding, because onboarding renders inside the authenticated layout.

3. DMG volume "Superset 2.0.2-arm64". electron-builder.ts set no dmg.title. dmg-builder's default is ${productFilename} ${shortVersion}${arch}.

What changed

  • New main/lib/post-onboarding-setup: it holds a list of boot steps and runs them once per process, but only after the renderer asks for them. If one step fails, it logs the error and runs the rest. The renderer asks through a new electronTrpc mutation postOnboardingSetup.run. <PostOnboardingSetup /> sends it when session.user.onboardedAt is set.
  • These steps move from boot into that list: Notification Center registration, Apple Events probe, Local Network probe, setupAgentIntegrations (with the disabled-agent/skill mirror writes), and plugin MCP sync. setAgentSetupTemplatesDir, the CLI shims (~/.superset/bin), and finishPendingOrganizationForget still run at boot.
  • <OrganizationPluginSync /> renders only for onboarded users.
  • dmg.title is ${displayName} ${version}, so the volume is "Paradev 2.0.2". displayName comes from DESKTOP_DISPLAY_NAME, which is set on the Build Electron app step. Canary gets "Paradev Canary ${version}". productName, appId, bundle name, artifactName, update feed, and protocol scheme do not change. The arch suffix is no longer in the volume name. It is still in the DMG file name.

Existing users: nothing is removed. Provisioning stays declarative. The desired set and the reaping do not change, only when they run. An onboarded user reaches the gate a moment after launch, so hooks, skills, and MCP entries refresh as before, just a little later. Files from earlier runs stay in place in the meantime. If the session cannot be confirmed (offline screen), the refresh waits until the next launch that reaches the dashboard. A new user is provisioned when onboarding finishes, before they can open a terminal. The prompts also appear at that point, right as the dashboard opens.

Not changed: provision only installed agents

I did not skip agents that are not installed. Claude, Gemini and others take hooks only from their global config, and nothing re-provisions while the app runs. If we skipped ~/.claude because it is absent, a new user who installs Claude Code after Paradev (a common first-day order) would get no agent status or notifications until the next app restart. Doing this safely needs a re-provision trigger, for example when a terminal starts an agent or when an agent's config dir appears. That is a separate change.

Verification

  • bun test src/main/lib/post-onboarding-setup: 4 pass. Before keeping the tests, I broke the run-once/requested guard and 3 of 4 failed.
  • apps/desktop bun run typecheck: exit 0, no errors.
  • apps/desktop bun test: 9024 pass, 36 fail. All 36 are real-git and login-shell suites (getStatus, getBranches, createWorktree, shell env, and others; e.g. git update-ref refs/remotes/origin/main fails). They fail in this sandboxed worktree, and none of them touch files in this diff.
  • bun run lint:fix: clean. No new user-facing strings, so no check:i18n change.
  • Probe: setupAgentIntegrations() against an empty temp $HOME creates the dirs listed above (confirms the root cause for item 2).
  • Builder config: loading electron-builder.ts/.canary.ts with DESKTOP_DISPLAY_NAME=Paradev gives dmg.title Paradev ${version} / Paradev Canary ${version}. dmg-builder 26.8.1 computeVolumeName replaces ${version}.
  • Not verified: the macOS permission prompts and the mounted DMG volume name. Both need a signed production build on a clean Mac. I did not run the dev desktop app over CDP for this change. The next fresh-Mac walkthrough should confirm: no prompts and no new dotfiles before sign-in and onboarding, the prompts and hooks appear once onboarding finishes, and the volume reads "Paradev 2.0.2".

Summary by cubic

Defers macOS permission prompts and writes to other tools' config directories until the user finishes onboarding, so a first launch on a fresh Mac no longer shows two permission prompts or creates dotfiles before sign-in.

  • New postOnboardingSetup runs deferred boot steps once per process, triggered by the renderer via a tRPC mutation when session.user.onboardedAt is set.
  • Deferred steps: Notification Center registration, Apple Events and Local Network probes, agent hook/skill provisioning, and plugin MCP sync. CLI shims, the templates dir, and pending organization cleanup still run at boot.
  • Organization plugin sync now only renders for onboarded users.
  • The DMG volume name now uses the display name and version (e.g. "Paradev 2.0.2") instead of the product name with an arch suffix.

Side effects: existing users get the same provisioning, just a moment after launch. If the session can't be confirmed (offline), the refresh waits until a launch that reaches the dashboard. A new user is provisioned when onboarding finishes, before they can open a terminal.

Written for commit 5d5baa1. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • Post-onboarding setup now runs after onboarding is complete, including agent integrations, plugin services, and permission requests. If one setup task fails, later tasks can still proceed.
    • macOS installation disk images now display the app’s name and version in the mounted volume title.

Defer the macOS Notification Center registration, the Apple Events and
Local Network permission probes, agent hook provisioning, and plugin MCP
sync until the renderer reports a signed-in, onboarded user. Organization
plugin sync waits for onboarding too. Name the DMG volume with the
display name instead of productName.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ac4353b4-d72b-4777-822a-cca576af0d5a
Commits

Reviewing files that changed from the base of the PR and between 5cf7c28 and 5d5baa1.

Files selected for processing: 11
  • apps/desktop/electron-builder.canary.ts
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/lib/trpc/routers/post-onboarding-setup.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/post-onboarding-setup/index.ts
  • apps/desktop/src/main/lib/post-onboarding-setup/post-onboarding-setup.test.ts
  • apps/desktop/src/main/lib/post-onboarding-setup/post-onboarding-setup.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/PostOnboardingSetup/PostOnboardingSetup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/PostOnboardingSetup/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/layout.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

Walkthrough

The desktop app now defers notification, permission, agent-integration, and plugin synchronization tasks until setup is requested for an onboarded session. It adds a one-time setup coordinator and tRPC trigger. macOS DMG volume titles now include the app display name and version placeholder.

Changes: Post-onboarding setup

Layer / File(s) Summary
Setup coordinator and validation
apps/desktop/src/main/lib/post-onboarding-setup/*
A coordinator stores labeled setup steps and runs them once after steps are set and setup is requested. It logs step errors and continues with later steps. Tests cover request timing, repeated requests, and errors.
Startup task registration
apps/desktop/src/main/index.ts
Startup prepares agent integrations from settings and registers notification, permission, agent-integration, and plugin synchronization tasks with the coordinator.
Onboarded-session trigger
apps/desktop/src/lib/trpc/routers/*, apps/desktop/src/renderer/routes/_authenticated/components/PostOnboardingSetup/*, apps/desktop/src/renderer/routes/_authenticated/layout.tsx
The authenticated layout renders the setup component and organization plugin sync only for onboarded sessions or when environment validation is skipped. The component calls a tRPC mutation that requests coordinator execution.

macOS DMG volume titles

Layer / File(s) Summary
Set DMG volume titles
apps/desktop/electron-builder.ts, apps/desktop/electron-builder.canary.ts
The standard and canary DMG configurations set the volume title to the app display name followed by the version placeholder. The canary configuration extends the base DMG configuration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant MainIndex as main/index.ts
  participant postOnboardingSetup
  participant AuthenticatedLayout
  participant PostOnboardingSetup
  participant postOnboardingSetupRouter
  MainIndex->>postOnboardingSetup: register setup steps
  AuthenticatedLayout->>PostOnboardingSetup: render when onboarded
  PostOnboardingSetup->>postOnboardingSetupRouter: call run mutation
  postOnboardingSetupRouter->>postOnboardingSetup: request setup
  postOnboardingSetup->>postOnboardingSetup: execute registered steps once
Loading

Suggested reviewers: avipeltz, saddlepaddle

Merge Risk: Minimal · up to 5d5ba

No merge-blocking issue is established. Signed macOS prompt behavior and mounted DMG titles remain unverified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: deferring first-launch actions until onboarding is complete. It follows conventional commit format.
Description check Passed The description is detailed and on-topic. It explains the root causes, implemented changes, behavior for existing and new users, testing results, known test failures, and unverified macOS checks. It d…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is detailed and on-topic. It explains the root causes, implemented changes, behavior for existing and new users, testing results, known test failures, and unverified macOS checks. It does not reproduce the template checklist, but the required change rationale and testing information are substantially covered.

Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 11 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@greptile-apps

greptile-apps Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable defects were found.

Summary

Moves permission prompts and agent config writes behind the onboarding gate.

  • Desktop setup waits until the user finishes onboarding.
  • Mounted DMG volumes use the app’s display name and version.

No actionable issues were found. Kitenite explicitly acknowledges that offline session confirmation delays setup until a later launch reaches the dashboard; this is intentional. Signed macOS prompt behavior and mounted DMG names still need the stated fresh-Mac check.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Main process starts] --> B[Register deferred steps]
  C[Session confirms onboarding] --> D[Mount PostOnboardingSetup]
  D --> E[Request setup over IPC]
  B --> F{Requested and not yet run?}
  E --> F
  F -->|Yes| G[Run each step and log failures]
  F -->|No| H[Wait or do nothing]
Loading

Reviews (1) · Last reviewed commit: "fix(desktop): keep first launch quiet un..." · Reviewed by Greptile

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) ✅ View Branch
Vercel API (Vercel) ✅ Open Preview
Vercel Web (Vercel) ✅ Open Preview
Vercel Marketing (Vercel) ✅ Open Preview
Vercel Docs (Vercel) ✅ Open Preview

Preview updates automatically with new commits

This branch was successfully deployed

1 active deployment
preview — 5d5baa16 Deployed Oct 31, 2026 by Kitenite via Deploy Marketing #13478
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.

1 participant