From 6dca348325750059849ed03a6d9c7455262cdb55 Mon Sep 17 00:00:00 2001 From: brennanb2025 Date: Sun, 17 May 2026 15:19:26 -0700 Subject: [PATCH] Start default agent for onboarding folders Co-authored-by: Orca --- .../onboarding-folder-agent-startup.test.ts | 39 ++++++++++++++++++ .../onboarding-folder-agent-startup.ts | 41 +++++++++++++++++++ .../onboarding/use-onboarding-flow.ts | 8 +++- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/renderer/src/components/onboarding/onboarding-folder-agent-startup.test.ts create mode 100644 src/renderer/src/components/onboarding/onboarding-folder-agent-startup.ts diff --git a/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.test.ts b/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.test.ts new file mode 100644 index 00000000000..12363a143f9 --- /dev/null +++ b/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from 'vitest' +import { getDefaultSettings } from '../../../../shared/constants' +import { buildOnboardingFolderAgentStartup } from './onboarding-folder-agent-startup' + +describe('buildOnboardingFolderAgentStartup', () => { + it('queues the persisted default agent with onboarding telemetry', () => { + const startup = buildOnboardingFolderAgentStartup({ + ...getDefaultSettings('/tmp/orca-workspaces'), + defaultTuiAgent: 'codex' + }) + + expect(startup).toEqual({ + command: 'codex', + telemetry: { + agent_kind: 'codex', + launch_source: 'onboarding', + request_kind: 'new' + } + }) + }) + + it('respects the blank terminal preference', () => { + const startup = buildOnboardingFolderAgentStartup({ + ...getDefaultSettings('/tmp/orca-workspaces'), + defaultTuiAgent: 'blank' + }) + + expect(startup).toBeUndefined() + }) + + it('does not infer an agent from auto mode', () => { + const startup = buildOnboardingFolderAgentStartup({ + ...getDefaultSettings('/tmp/orca-workspaces'), + defaultTuiAgent: null + }) + + expect(startup).toBeUndefined() + }) +}) diff --git a/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.ts b/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.ts new file mode 100644 index 00000000000..8e46393baa0 --- /dev/null +++ b/src/renderer/src/components/onboarding/onboarding-folder-agent-startup.ts @@ -0,0 +1,41 @@ +import { buildAgentStartupPlan } from '@/lib/tui-agent-startup' +import { CLIENT_PLATFORM } from '@/lib/new-workspace' +import { tuiAgentToAgentKind } from '@/lib/telemetry' +import type { AgentStartedTelemetry } from '@/lib/worktree-activation' +import type { GlobalSettings } from '../../../../shared/types' + +export type OnboardingFolderAgentStartup = { + command: string + env?: Record + telemetry: AgentStartedTelemetry +} + +export function buildOnboardingFolderAgentStartup( + settings: GlobalSettings | null +): OnboardingFolderAgentStartup | undefined { + const agent = settings?.defaultTuiAgent + if (!settings || !agent || agent === 'blank') { + return undefined + } + + const startupPlan = buildAgentStartupPlan({ + agent, + prompt: '', + cmdOverrides: settings.agentCmdOverrides ?? {}, + platform: CLIENT_PLATFORM, + allowEmptyPromptLaunch: true + }) + if (!startupPlan) { + return undefined + } + + return { + command: startupPlan.launchCommand, + ...(startupPlan.env ? { env: startupPlan.env } : {}), + telemetry: { + agent_kind: tuiAgentToAgentKind(agent), + launch_source: 'onboarding', + request_kind: 'new' + } + } +} diff --git a/src/renderer/src/components/onboarding/use-onboarding-flow.ts b/src/renderer/src/components/onboarding/use-onboarding-flow.ts index bccafebe047..6a04f2d9eac 100644 --- a/src/renderer/src/components/onboarding/use-onboarding-flow.ts +++ b/src/renderer/src/components/onboarding/use-onboarding-flow.ts @@ -20,6 +20,7 @@ import { import { STEPS, type StepNumber } from './use-onboarding-flow-types' import { persistStep, useCloseWith, usePersistCurrentStep } from './use-onboarding-flow-persistence' import { callRuntimeRpc, getActiveRuntimeTarget } from '@/runtime/runtime-rpc-client' +import { buildOnboardingFolderAgentStartup } from './onboarding-folder-agent-startup' export { STEPS } from './use-onboarding-flow-types' export type { StepId, StepNumber } from './use-onboarding-flow-types' @@ -268,7 +269,10 @@ export function useOnboardingFlow( await fetchWorktrees(repoId) const worktree = useAppStore.getState().worktreesByRepo[repoId]?.[0] if (worktree) { - activateAndRevealWorktree(worktree.id) + // Why: onboarding asks for a default agent immediately before this step. + // Non-git folders skip the composer, so seed their first terminal here. + const startup = isGit ? undefined : buildOnboardingFolderAgentStartup(settings) + activateAndRevealWorktree(worktree.id, startup ? { startup } : undefined) } // Why: next() short-circuits step 4, so emit step_completed here once the // repo is successfully added to keep the funnel consistent. Gate on @@ -299,7 +303,7 @@ export function useOnboardingFlow( }) } }, - [closeWith, consumeStepDurationMs, fetchRepos, fetchWorktrees, openModal] + [closeWith, consumeStepDurationMs, fetchRepos, fetchWorktrees, openModal, settings] ) const persistCurrentStep = usePersistCurrentStep({