@@ -24,9 +24,8 @@ import { MonitoringCleanup } from "../../agents/monitoring/index.js"
2424import path from "path"
2525import { createRequire } from "node:module"
2626import { resolvePackageJson } from "../../shared/runtime/root.js"
27- import { getSelectedTrack , setSelectedTrack , hasSelectedConditions , setSelectedConditions , getProjectName , setProjectName , getControllerAgents , loadControllerConfig } from "../../shared/workflows/index.js"
28- import { loadTemplate } from "../../workflows/templates/loader.js"
29- import { getTemplatePathFromTracking } from "../../shared/workflows/template.js"
27+ import { setSelectedTrack , setSelectedConditions , setProjectName } from "../../shared/workflows/index.js"
28+ import { checkOnboardingRequired , needsOnboarding } from "../../workflows/preflight.js"
3029import type { TracksConfig , ConditionGroup } from "../../workflows/templates/types"
3130import type { AgentDefinition } from "../../shared/agents/config/types"
3231import type { InitialToast } from "./app"
@@ -168,39 +167,23 @@ export function App(props: { initialToast?: InitialToast }) {
168167 setDebugLogFile ( debugLogPath )
169168 }
170169
171- // Check if tracks/conditions exist and no selection yet
170+ // Run pre-flight checks
172171 try {
173- const templatePath = await getTemplatePathFromTracking ( cmRoot )
174- const template = await loadTemplate ( cwd , templatePath )
175- const selectedTrack = await getSelectedTrack ( cmRoot )
176- const conditionsSelected = await hasSelectedConditions ( cmRoot )
177- const existingProjectName = await getProjectName ( cmRoot )
178-
179- const hasTracks = template . tracks && Object . keys ( template . tracks . options ) . length > 0
180- const hasConditionGroups = template . conditionGroups && template . conditionGroups . length > 0
181- const needsTrackSelection = hasTracks && ! selectedTrack
182- const needsConditionsSelection = hasConditionGroups && ! conditionsSelected
183- const needsProjectName = ! existingProjectName
184-
185- // Check if workflow requires controller selection
186- // Skip if controller session already exists
187- let controllers : AgentDefinition [ ] = [ ]
188- const existingControllerConfig = await loadControllerConfig ( cmRoot )
189- const hasExistingControllerSession = existingControllerConfig ?. controllerConfig ?. sessionId
190- if ( template . controller === true && ! hasExistingControllerSession ) {
191- controllers = await getControllerAgents ( cwd )
192- }
193- const needsControllerSelection = controllers . length > 0
172+ const onboardingNeeds = await checkOnboardingRequired ( { cwd } )
173+ const { template, controllerAgents } = onboardingNeeds
194174
195- // If project name, tracks, conditions, or controller need selection , show onboard view
196- if ( needsProjectName || needsTrackSelection || needsConditionsSelection || needsControllerSelection ) {
175+ // If any onboarding is needed , show onboard view
176+ if ( needsOnboarding ( onboardingNeeds ) ) {
197177 debug ( '[AppShell] Starting onboarding flow' )
198178
199- // Store config for Onboard component (backward compatibility)
179+ const hasTracks = template . tracks && Object . keys ( template . tracks . options ) . length > 0
180+ const hasConditionGroups = template . conditionGroups && template . conditionGroups . length > 0
181+
182+ // Store config for Onboard component
200183 if ( hasTracks ) setTemplateTracks ( template . tracks ! )
201184 if ( hasConditionGroups ) setTemplateConditionGroups ( template . conditionGroups ! )
202- if ( needsControllerSelection ) setControllerAgents ( controllers )
203- setInitialProjectName ( existingProjectName )
185+ if ( onboardingNeeds . needsControllerSelection ) setControllerAgents ( controllerAgents )
186+ setInitialProjectName ( null )
204187
205188 // Create event bus and service for onboarding
206189 const eventBus = new WorkflowEventBus ( )
@@ -209,8 +192,8 @@ export function App(props: { initialToast?: InitialToast }) {
209192 const service = new OnboardingService ( eventBus , {
210193 tracks : hasTracks ? template . tracks : undefined ,
211194 conditionGroups : hasConditionGroups ? template . conditionGroups : undefined ,
212- controllerAgents : needsControllerSelection ? controllers : undefined ,
213- initialProjectName : existingProjectName ,
195+ controllerAgents : onboardingNeeds . needsControllerSelection ? controllerAgents : undefined ,
196+ initialProjectName : onboardingNeeds . needsProjectName ? undefined : undefined ,
214197 cwd,
215198 cmRoot,
216199 } )
@@ -233,12 +216,12 @@ export function App(props: { initialToast?: InitialToast }) {
233216 return
234217 }
235218 } catch ( error ) {
236- // If template loading fails, proceed to workflow anyway
237- appDebug ( '[AppShell] Failed to check tracks/conditions : %s' , error )
238- console . error ( "Failed to check tracks/conditions :" , error )
219+ // If pre-flight check fails, proceed to workflow anyway
220+ appDebug ( '[AppShell] Failed pre-flight check: %s' , error )
221+ console . error ( "Failed pre-flight check:" , error )
239222 }
240223
241- // No tracks/conditions or already selected - start workflow directly
224+ // No onboarding needed - start workflow directly
242225 appDebug ( '[AppShell] Starting workflow execution directly' )
243226 startWorkflowExecution ( )
244227 }
@@ -257,7 +240,7 @@ export function App(props: { initialToast?: InitialToast }) {
257240 pendingWorkflowStart = ( ) => {
258241 appDebug ( '[AppShell] Importing and running workflow' )
259242 import ( "../../workflows/run.js" ) . then ( ( { runWorkflow } ) => {
260- runWorkflow ( { cwd, specificationPath : specPath } ) . catch ( ( error ) => {
243+ runWorkflow ( { cwd } ) . catch ( ( error ) => {
261244 // Emit error event to show toast with actual error message
262245 const errorMsg = error instanceof Error ? error . message : String ( error )
263246 appDebug ( '[AppShell] Workflow error: %s' , errorMsg )
0 commit comments