Give the desktop cold start its first-run setup - #128
Merged
Conversation
A fresh desktop launch bootstraps no project, so a cold start lands on the no-active-thread shell instead of a draft thread - and got none of the first-run guidance built for the npx door. Three fixes: - Setup card on the no-thread shell. useFirstRunSetupCard now owns the gate, project fallback, and actions for both empty canvases; the no-project surface leads with the amber "Choose a folder" row. Dismissal moved to a shared store so skipping on one surface settles both in the same tick. While the card owns the canvas the header reads "Set up Threadlines" instead of "No active thread". - The "Updates available" prompt waits while first-run setup is pending. Deferred, not consumed: the guard runs before the seen-key set, so the same prompt opens once setup completes or is skipped. Running/failed update progress is untouched. - Warm relaunch reopens the last thread or draft. A per-environment schema-validated localStorage record replaces the write-only lastChatThreadRef dead state; restore runs once per app load and is checked against live state, so deleted threads fall back cleanly and "Go to Home" never bounces back. Also extracts deriveDisplayProviderInstanceEntries, deduplicating the filter/sort/derive trio from ChatView and ChatComposer.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Ranking only consulted searchTerms, so typing exactly what an item says
on screen ("Go to Home") found nothing unless someone remembered to
duplicate the title into the terms - some items did, most didn't. The
title now ranks first when it is a plain string; hidden searchTerms
follow. Found by the desktop first-run verification walk (V-7).
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.
A fresh desktop launch bootstraps no project from a launch folder the way
npxdoes, so a cold start lands on the no-active-thread shell - which had none of the first-run guidance. Closes the last three gaps from the fresh-install audit (preview-7).Setup card on the no-thread shell
useFirstRunSetupCardnow owns the gate, the workspace-project fallback, and all three actions; both empty canvases (draft thread, no-thread shell) pass only what differs. On the no-project surface the amber "Choose a folder" row leads the checklist, since the missing folder is the whole reason the canvas is empty. Dismissal moved from per-component state to a shared store seeded from the same localStorage record, so "Skip for now" on either canvas settles both in the same tick. While the card owns the canvas, the header label reads "Set up Threadlines" instead of "No active thread".Update prompt waits for onboarding
ProviderUpdateLaunchNotificationmounts above the app shell, so it derives "is this environment still in first-run setup" from live state (useActiveEnvironmentFirstRunSetupPending) rather than a registration signal that would race first paint. The prompt is deferred, not consumed - the guard runs before the seen-key set, so it opens on the same key once setup is completed or skipped. Running/failed update progress still reports immediately.Warm relaunch reopens where you were
Root cause:
uiStateStore.lastChatThreadRefwas write-only dead state, and the only navigation off/was thenpxbootstrap payload desktop never sends - so every relaunch opened a brand-new draft. Replaced with a per-environment, schema-validated localStorage record (lastVisitedThreadRoute.ts) covering both server threads and drafts. Restore runs once per app load and is validated against live state: deleted threads fall back to the default-draft behaviour, and "Go to Home" / settings-back never bounce back to the thread.Also extracts
deriveDisplayProviderInstanceEntries(the filter/sort/derive trio was duplicated across ChatView and ChatComposer and needed a third copy here).Tests
firstRunSetup.test.ts: card onnoThread, shared dismissal across surfaces, per-surface exclusions.FirstRunSetupCard.browser.tsx: folder row leads with amber dot when no project exists, returns to the end when one does.ProviderUpdateLaunchNotification.logic.test.ts: prompt waits while first-run is pending, opens on the same key afterwards.lastVisitedThreadRoute.test.ts: restore when live, null on missing thread/draft/record, unreadable record reads as nothing remembered.Gates: fmt/lint/typecheck clean; apps/web unit suite 2100 tests green; full browser suite 390 tests green.