Skip to content

Comments

Add new welcome screen#5531

Merged
lambertjosh merged 19 commits intomainfrom
jl-new-welcome-screen
Feb 4, 2026
Merged

Add new welcome screen#5531
lambertjosh merged 19 commits intomainfrom
jl-new-welcome-screen

Conversation

@lambertjosh
Copy link
Contributor

Adds a new welcome screen:

image

@changeset-bot
Copy link

changeset-bot bot commented Jan 29, 2026

🦋 Changeset detected

Latest commit: e678523

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
kilo-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

// kilocode_change start: Onboarding handlers
const handleSelectFreeModels = useCallback(() => {
// Mark onboarding as complete
vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: "Free models" selection only sets onboarding complete; it may still show the Welcome screen

handleSelectFreeModels posts hasCompletedOnboarding but does not navigate to chat or otherwise affect showWelcome. On the next render, this falls through to showWelcome ? <WelcomeView /> : …, so users who still have showWelcome === true may immediately land on WelcomeView instead of "Start coding immediately".


const OnboardingOption: React.FC<OnboardingOptionProps> = ({ title, description, onClick }) => {
return (
<button
Copy link
Contributor

Choose a reason for hiding this comment

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

SUGGESTION: Add an explicit type="button"

Buttons default to type="submit", which can trigger unintended form submissions if this component is ever used within a <form>.

Suggested change
<button
<button type="button"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't seem to be a risk, since this is not in a form and unlikely to be.

vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
// Navigate to auth view which will show the device code and handle the OAuth flow
// The AuthView auto-starts device auth on mount
switchTab("auth")
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: switchTab("auth") won't take effect while onboarding is still rendered

handleSelectPremiumModels sets the tab to auth, but the render short-circuits to <OnboardingView /> while showOnboarding is true. Since hasCompletedOnboarding only flips after the extension posts updated state back, users can momentarily remain on the onboarding screen; and if showWelcome is still true when onboarding completes, they may land on <WelcomeView /> instead of the auth flow.

Consider hiding onboarding immediately (e.g., local state) or making the render conditional prioritize tab === "auth" / tab === "settings" after a selection.

//
// This ensures existing users who upgrade don't see the onboarding screen,
// while new users who have never used the extension will see it.
const isExistingUser = (taskHistoryFullLength ?? 0) > 0
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we can also set 'hasCompletedOnboarding' if this is true so we can choose this logic at some point in the future, that way this choice doesn't tie in to specific architecture choices

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@markijbema - can you review the new code? Hopefully this is better integrated now.

@@ -15,6 +15,7 @@ import ChatView, { ChatViewRef } from "./components/chat/ChatView"
import HistoryView from "./components/history/HistoryView"
import SettingsView, { SettingsViewRef } from "./components/settings/SettingsView"
import WelcomeView from "./components/kilocode/welcome/WelcomeView" // kilocode_change
Copy link
Contributor

Choose a reason for hiding this comment

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

we should now never show this right? so why have two? Any reason not to ditch the welcomeview?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@markijbema - can you take another look? I removed this in 0e8481f

}

// kilocode_change start: Show OnboardingView for new users who haven't completed onboarding
const showOnboarding = hasCompletedOnboarding !== true
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Onboarding may briefly flash for existing users

showOnboarding is derived solely from hasCompletedOnboarding, but existing users upgrading may initially have this unset/false. That means the UI renders <OnboardingView /> until the migration useEffect posts hasCompletedOnboarding and the extension sends updated state back.

If the goal is to never show onboarding to existing users, consider including taskHistoryFullLength (or another persisted signal) directly in the render condition so existing users skip onboarding on the first post-hydration render.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is an actual concern, and I don't see it in my testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Did you test it by completing the onboarding, doing zero tasks, and restarting the extensions (cmd-shift-p, reload webviews) with the extensions open? If the bot is right you'll probably see this screen flash. It sounds at least 70% probable to me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@markijbema - I've tested. It does not flash, at least for me. AI says the reason why is:

The Flow

  1. Initial state (line 297): hasCompletedOnboarding: undefined

  2. Before hydration (App.tsx line 349-350):
    if (!didHydrateState) {
    return null // Nothing renders at all
    }

  3. Hydration occurs (ExtensionStateContext.tsx lines 415-419):
    case "state": {
    const newState = message.state!
    setState((prevState) => mergeExtensionState(prevState, newState))
    // ...
    setDidHydrateState(true) // Only AFTER state is merged
    }

  4. The extension sends state (ClineProvider.ts line 2524):
    hasCompletedOnboarding: this.getGlobalState("hasCompletedOnboarding")

  5. State merge (line 242): { ...prevRest, ...newRest } - the extension's value overwrites the default undefined.

The key is that setDidHydrateState(true) is called AFTER setState merges the new state. This happens in the same event handler, so React batches these updates.

By the time the component renders for the first time (when didHydrateState becomes true), hasCompletedOnboarding already has the value from the extension's global state.

// Mark onboarding as complete
vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
// The default profile is already set up with a free model, so just close welcome
// This will trigger a state update that sets showWelcome to false

This comment was marked as outdated.

"description": "Sign up and receive $5 in credits"
},
"byok": {
"title": "Bring my own Key",

This comment was marked as off-topic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefer Bring your own Key

// One-time migration: mark existing users as having completed onboarding
useEffect(() => {
if (hasCompletedOnboarding !== true && (taskHistoryFullLength ?? 0) > 0) {
vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Onboarding migration may repeatedly post state updates

The migration useEffect posts hasCompletedOnboarding whenever hasCompletedOnboarding !== true && (taskHistoryFullLength ?? 0) > 0. If other state changes cause re-renders before the extension posts updated state back, this can send multiple duplicate hasCompletedOnboarding messages (and write global state multiple times).

Consider guarding with a useRef (send-once) or deriving the render condition directly from taskHistoryFullLength so existing users never render onboarding without needing to post a migration message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again don't think this is a concern and have not seen it in my testing.

// Mark onboarding as complete
vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
// Navigate to settings with providers section
switchTab("settings")
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Navigation won’t be visible until onboarding is dismissed

Because App short-circuits to OnboardingView while hasCompletedOnboarding !== true, this switchTab("settings") won’t render until the extension posts updated state. Consider also updating local UI state (optimistically hide onboarding) or deferring navigation until after the state refresh.

lambertjosh and others added 4 commits January 30, 2026 17:22
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
lambertjosh and others added 3 commits January 31, 2026 14:32
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>

const handleSelectPremiumModels = useCallback(() => {
// Mark onboarding as complete
vscode.postMessage({ type: "hasCompletedOnboarding", bool: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Onboarding is marked complete before premium sign-in succeeds

handleSelectPremiumModels posts hasCompletedOnboarding: true immediately, before the device auth flow has actually completed. If the user cancels / fails auth, they'll be treated as "onboarded" and may no longer see the onboarding entry point.

Consider setting completion only after successful authentication (or using a separate "started onboarding" flag).

@lambertjosh
Copy link
Contributor Author

I think this is ready for final review @markijbema. I added some icons too:
image

Copy link
Contributor

@markijbema markijbema left a comment

Choose a reason for hiding this comment

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

Please try the scenario i mentioned, but tbh I'm not too scared of it; even if it is true it will just mean a quick flash in certain situations on start of the extension.

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.

3 participants