feat(desktop): first-run onboarding overlay for default provider API key#2752
Merged
Merged
Conversation
pnpm 11+ refuses to run build scripts (esbuild's postinstall fetches its native binary) unless explicitly approved. Without this file, every fresh clone hits ERR_PNPM_IGNORED_BUILDS and `wails dev` exits 1 on the first run. See https://pnpm.io/settings#onlybuiltdependencies. Setting `esbuild: true` here keeps the approval project-scoped so it travels with the repo.
Exposes two new bound methods on `App` so the React side can ask whether the default provider's API key is missing and, if so, write one in: - `NeedsOnboarding() bool` — true when DEEPSEEK_API_KEY is unset in the process. Cheap, no I/O; the frontend calls it once on mount. - `ConnectKey(apiKey string) error` — validates the pasted key against the vendor's balance endpoint (no tokens spent, ~hundreds of ms), persists it to `./.env` via the existing `upsertDotEnv` helper (which also `os.Setenv`s it so the next rebuild picks it up), then triggers a controller rebuild. The kernel emits `agent:ready` once boot.Build completes, and the frontend unmounts the overlay. A one-line `mustCwd` helper logs the process cwd for diagnostics when env probes look wrong; it lives next to NeedsOnboarding for now and can move if a second consumer appears.
When `app.NeedsOnboarding()` returns true (default provider's API key is unset in the process), App.tsx mounts a full-window overlay that asks the user to paste a `sk-...` key. The submit button calls `app.ConnectKey(key)`, which validates against the vendor's balance endpoint and persists to `./.env` (handled in the previous Go commit). UX choices: - One-shot probe on mount only. Settings panel changes that add a key don't re-trigger the overlay (the user has clearly already onboarded). - "Skip for now" footer link drops the user into the main UI; the topbar `startupError` banner surfaces the missing key when they try to chat. The Settings panel is the canonical path to set it later. - Validation errors map to i18n keys: 401/403 → "invalid", dial/timeout → "network", everything else → the raw message. The Go side returns human-readable strings already. - i18n keys live in en.ts and zh.ts alongside the rest of the dict (13 keys each). Missing keys fall back to English per the existing translate() behavior. - Styling matches the terminal-hacker aesthetic: dark `--bg-elev` card, `--accent` CTA, mono font for the input, spinner on submit. The browser dev mock in `bridge.ts` returns true from NeedsOnboarding when no provider has its key set, so the overlay is exercisable in `pnpm dev` outside the Wails shell (handy for layout tweaks without rebuilding the Go side).
CVEngineer66
pushed a commit
to CVEngineer66/DeepSeek-Reasonix
that referenced
this pull request
Jun 7, 2026
The .onboarding__skip:disabled block was missing its closing '}', causing esbuild (used by Vite dev mode) to abort CSS parsing at line 7049. All rules after line 7049 — including .workbench-dock layout positioning — were silently discarded, breaking the right-side dock layout. Introduced as a merge conflict artefact between esengine#2752 (onboarding) and esengine#3129 (InlineDiff component).
CVEngineer66
pushed a commit
to CVEngineer66/DeepSeek-Reasonix
that referenced
this pull request
Jun 7, 2026
A second merged conflict artefact from esengine#2752 (onboarding) and esengine#3129 (InlineDiff) left an unclosed block at line 7082. Same root cause as PR esengine#3418 but at a different offset. The check-css-syntax.mjs script (PR esengine#3420) now catches this, but upstream itself is affected.
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
Adds a first-run gate in the desktop app: when the default provider's
API key (DEEPSEEK_API_KEY, matching
Default()in internal/config) isunset in the process, the user sees a full-window overlay asking them
to paste a
sk-...key. The submit button validates the key againstthe vendor's balance endpoint, persists it to
./.env, and rebuildsthe controller. The overlay stays up until the kernel emits
agent:readyand the main UI takes over.Closes the "what does the user do when they download the desktop app
and launch it for the first time" gap — currently the chat composer
just shows a topbar error and the user has to dig into Settings to
find the API key field.
Changes (3 commits)
chore(desktop): allow esbuild postinstall in pnpm workspacepnpm 11+ refuses to run build scripts unless explicitly approved.
wails devwould exit 1 on a fresh clone withERR_PNPM_IGNORED_BUILDS. Project-scopeesbuild: trueso ittravels with the repo.
feat(desktop): add NeedsOnboarding/ConnectKey bindingsTwo new methods on
*App:NeedsOnboarding() bool— true when DEEPSEEK_API_KEY is emptyin the process. Cheap, no I/O.
ConnectKey(apiKey string) error— validates viabilling.FetchWithClient(zero-token, 8s timeout), persists viaupsertDotEnv(writes to./.envandos.Setenvs the key sothe next rebuild picks it up), then triggers a controller
rebuild. Returns "key is required" / "status 401" /
"network: ..." for the UI to map.
feat(desktop): add first-run OnboardingOverlaydesktop/frontend/src/components/OnboardingOverlay.tsx—full-window modal with logo, paste field, submit button (with
spinner), "How do I get a key?" link (opens
platform.deepseek.com/api_keysin the system browser), and asmall "Skip for now" footer link.
desktop/frontend/src/App.tsx— one-shotNeedsOnboarding()probe on mount; gates the entire app on the result. Probe is
useEffect([])so Settings panel changes don't re-trigger.desktop/frontend/src/lib/bridge.ts— adds both methods toAppBindings; browser dev mock returns true when no providerhas its key set, so the overlay flow is exercisable in
pnpm devoutside the Wails shell.desktop/frontend/src/styles.css—.onboarding*classes(dark
--bg-elevcard,--accentCTA, mono input, spinneranimation). Terminal-hacker aesthetic, matches the rest of
the theme.
desktop/frontend/src/locales/{en,zh}.ts— 13 i18n keys each(title, tagline, input label/placeholder, submit, validating,
get-key link, privacy, three error states, unknown, skip).
UX flow
window. Composer is hidden; no chat possible without a key.
Button shows a spinner; input locks.
active and has billing set up." Network fail → "Couldn't reach
DeepSeek — check your network and try again." Other → raw message.
./.env(ordesktop/.envin wailsdev), process env updated, controller rebuilt. Frontend unmounts
the overlay; agent:ready → main UI.
empty state. Trying to chat surfaces the topbar
startupErrorbanner; Settings panel is the path back.
i18n
Auto-detects from
navigator.language(WebView2 reflects the systemlocale on Windows). User override in Settings → Language. All 13
new keys present in both
en.tsandzh.ts;translate()fallsback to English on missing keys, so partial translations degrade
gracefully.
Test plan
go build ./...— cleantsc --noEmit— cleanvite build— cleango test ./...indesktop/— all pass.env→.env.bak, clearDEEPSEEK_API_KEYfrom User env, restart wails dev → overlayappears. Paste valid key → overlay dismisses,
desktop/.envhas the new key, restart wails dev → no overlay.
startupError, Settings panel accepts a key and the chatresumes after the kernel rebuilds.
overlay text flips to Chinese (title: 连接 Reasonix, submit:
连接并开始, skip: 稍后设置, etc.).
Notes
billing.FetchWithClient,upsertDotEnv,a.rebuild(). Adds one log line inConnectKeyfor save failures (will be added in a follow-up ifreviewers want).
main.go/startup()/buildController().Onboarding is purely a frontend gate; if the user skips, the
existing topbar error path takes over.
truefromNeedsOnboarding()when noprovider has its key set, so pure browser dev (
pnpm dev)exercises the overlay without rebuilding the Go side.
desktop/frontend/pnpm-workspace.yamlis unrelated to thefeature itself but blocks
wails devon a fresh clone; committingit here saves the next contributor the 10-minute debug session.