chore: merge dev into v2 (#35591)

Co-authored-by: Frank <frank@anoma.ly>
Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com>
Co-authored-by: Brendan Allan <git@brendonovich.dev>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Jack <jack@anoma.ly>
Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: James Long <longster@gmail.com>
Co-authored-by: Dustin Deus <deusdustin@gmail.com>
Co-authored-by: starptech <starptech@starptechs-MBP.fritz.box>
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
Co-authored-by: 𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 <little-frank@opencord.local>
Co-authored-by: Dax <mail@thdxr.com>
Co-authored-by: usrnk1 <7547651+usrnk1@users.noreply.github.com>
Co-authored-by: Jay <53023+jayair@users.noreply.github.com>
Co-authored-by: runvip <164729189+runvip@users.noreply.github.com>
Co-authored-by: opencode <opencode@sst.dev>
Co-authored-by: Julian Coy <julian@ex-machina.co>
Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com>
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
Co-authored-by: Kit Langton <kit.langton@gmail.com>
Co-authored-by: Simon Klee <hello@simonklee.dk>
Co-authored-by: Jay <air@live.ca>
Co-authored-by: David Hill <1879069+iamdavidhill@users.noreply.github.com>
This commit is contained in:
Aiden Cline
2026-07-06 16:05:29 -05:00
committed by GitHub
co-authored by Frank Aarav Sareen Brendan Allan opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Jack Brendan Allan Shoubhit Dash opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> James Long Dustin Deus starptech Luke Parker 𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 Dax usrnk1 Jay runvip opencode Julian Coy Vladimir Glafirov Adam Kit Langton Simon Klee Jay David Hill
parent f87998f37f
commit 9e0d3976e1
332 changed files with 24650 additions and 4497 deletions
+14 -2
View File
@@ -23,6 +23,7 @@ import { render } from "solid-js/web"
import pkg from "../../package.json"
import { initI18n, t } from "./i18n"
import { initializationData, initializationReady } from "./initialization"
import { DesktopFirstLaunchOnboarding } from "./onboarding"
import { resetZoom, setPinchZoomEnabled, webviewZoom, zoomIn, zoomOut } from "./webview-zoom"
import { availableStartupServer, readyWslConnections } from "./wsl/connections"
import "./styles.css"
@@ -347,6 +348,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
const router = (props: BaseRouterProps) => (
<DesktopMemoryRouter {...props} windowID={platform.windowID ?? "browser"} />
)
const onboarding = Promise.withResolvers<void>()
function handleClick(e: MouseEvent) {
const link = (e.target as HTMLElement).closest("a.external-link") as HTMLAnchorElement | null
@@ -400,12 +402,22 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
const effectiveDefaultServer = createMemo(() =>
ServerConnection.Key.make(availableStartupServer(defaultServer.latest, wslServers.data)),
)
return (
<Show when={ready()} fallback={<LoadingSplash />}>
<Show when={effectiveDefaultServer()} keyed>
{(key) => (
<AppInterface defaultServer={key} servers={servers()} router={router}>
<AppInterface
defaultServer={key}
servers={servers()}
router={router}
startup={onboarding.promise}
serverScoped={
<DesktopFirstLaunchOnboarding
initialUrl={getLastActiveUrl(platform.windowID ?? "browser")}
onLoaded={onboarding.resolve}
/>
}
>
<Inner />
</AppInterface>
)}
@@ -0,0 +1,79 @@
import {
ServerConnection,
useLayout,
useProviders,
useServer,
useServerSDK,
useServerSync,
useTabs,
} from "@opencode-ai/app"
import { onMount, startTransition } from "solid-js"
export function DesktopFirstLaunchOnboarding(props: { initialUrl: string; onLoaded: () => void }) {
const server = useServer()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const layout = useLayout()
const providers = useProviders()
const tabs = useTabs()
onMount(() => {
void runFirstLaunchOnboarding().finally(props.onLoaded)
})
async function runFirstLaunchOnboarding() {
try {
await Promise.all(
[server.ready.promise, layout.ready.promise, tabs.ready.promise, tabs.recentReady.promise].map(
(p) => p ?? Promise.resolve(),
),
)
if (!server.isLocal()) return
const pending = await window.api.isFirstLaunchOnboardingPending()
if (!pending) return
const sessions = await serverSDK()
.client.session.list()
.then((x) => x.data ?? [])
.catch(() => undefined)
const connectedProviders = providers.connected()
const paidProviders = providers.paid()
const persistedProjects = layout.projects.list()
const shouldTrigger =
props.initialUrl === "/" &&
sessions?.length === 0 &&
paidProviders.length === 0 &&
persistedProjects.length === 0 &&
tabs.store.length === 0 &&
server.list.every(ServerConnection.builtin)
console.info("[desktop-onboarding] first launch onboarding evaluated", {
pending,
shouldTrigger,
initialUrl: props.initialUrl,
sessions: sessions?.length,
connectedProviders: connectedProviders.length,
paidProviders: paidProviders.length,
serverProjects: serverSync().data.project.length,
persistedProjects: persistedProjects.length,
tabs: tabs.store.length,
servers: server.list.map(ServerConnection.key),
})
const directory = await window.api.finishFirstLaunchOnboarding(shouldTrigger)
if (!shouldTrigger || !directory) return
console.info("[desktop-onboarding] starting first launch draft", { directory })
server.projects.open(directory)
server.projects.touch(directory)
await startTransition(() => {
tabs.newDraft({ server: server.key, directory })
})
} catch (error) {
console.error("[desktop-onboarding] first launch onboarding failed", error)
}
}
return null
}