@@ -162,6 +162,130 @@ name: "Incomplete Config"
162162 } ) ;
163163} ) ;
164164
165+ describe ( "onboarding local config handling" , ( ) => {
166+ let tempDir : string ;
167+ let originalContinueGlobalDir : string | undefined ;
168+ let originalNodeEnv : string | undefined ;
169+ let originalCi : string | undefined ;
170+ let originalVitest : string | undefined ;
171+ let originalGithubActions : string | undefined ;
172+ let originalIsTTY : boolean ;
173+
174+ beforeEach ( ( ) => {
175+ tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "continue-home-" ) ) ;
176+ originalContinueGlobalDir = process . env . CONTINUE_GLOBAL_DIR ;
177+ originalNodeEnv = process . env . NODE_ENV ;
178+ originalCi = process . env . CI ;
179+ originalVitest = process . env . VITEST ;
180+ originalGithubActions = process . env . GITHUB_ACTIONS ;
181+ originalIsTTY = process . stdin . isTTY ;
182+
183+ process . env . CONTINUE_GLOBAL_DIR = tempDir ;
184+ vi . resetModules ( ) ;
185+ vi . doMock ( "./auth/workos.js" , ( ) => ( {
186+ login : vi . fn ( ) ,
187+ } ) ) ;
188+ vi . doMock ( "./config.js" , ( ) => ( {
189+ getApiClient : vi . fn ( ( ) => ( { } ) ) ,
190+ } ) ) ;
191+ vi . doMock ( "./configLoader.js" , ( ) => ( {
192+ loadConfiguration : vi . fn ( ) ,
193+ } ) ) ;
194+ } ) ;
195+
196+ afterEach ( ( ) => {
197+ if ( fs . existsSync ( tempDir ) ) {
198+ fs . rmSync ( tempDir , {
199+ force : true ,
200+ maxRetries : 3 ,
201+ recursive : true ,
202+ retryDelay : 100 ,
203+ } ) ;
204+ }
205+
206+ if ( originalContinueGlobalDir === undefined ) {
207+ delete process . env . CONTINUE_GLOBAL_DIR ;
208+ } else {
209+ process . env . CONTINUE_GLOBAL_DIR = originalContinueGlobalDir ;
210+ }
211+
212+ if ( originalNodeEnv === undefined ) {
213+ delete process . env . NODE_ENV ;
214+ } else {
215+ process . env . NODE_ENV = originalNodeEnv ;
216+ }
217+
218+ if ( originalCi === undefined ) {
219+ delete process . env . CI ;
220+ } else {
221+ process . env . CI = originalCi ;
222+ }
223+
224+ if ( originalVitest === undefined ) {
225+ delete process . env . VITEST ;
226+ } else {
227+ process . env . VITEST = originalVitest ;
228+ }
229+
230+ if ( originalGithubActions === undefined ) {
231+ delete process . env . GITHUB_ACTIONS ;
232+ } else {
233+ process . env . GITHUB_ACTIONS = originalGithubActions ;
234+ }
235+
236+ process . stdin . isTTY = originalIsTTY ;
237+
238+ vi . doUnmock ( "./auth/workos.js" ) ;
239+ vi . doUnmock ( "./config.js" ) ;
240+ vi . doUnmock ( "./configLoader.js" ) ;
241+ vi . doUnmock ( "./util/prompt.js" ) ;
242+ vi . resetModules ( ) ;
243+ } ) ;
244+
245+ test ( "should skip interactive onboarding when default config.yaml exists" , async ( ) => {
246+ fs . writeFileSync ( path . join ( tempDir , "config.yaml" ) , "name: Local Config\n" ) ;
247+
248+ delete process . env . NODE_ENV ;
249+ delete process . env . CI ;
250+ delete process . env . VITEST ;
251+ delete process . env . GITHUB_ACTIONS ;
252+ process . stdin . isTTY = true ;
253+
254+ const questionWithChoices = vi
255+ . fn ( )
256+ . mockRejectedValue ( new Error ( "prompted" ) ) ;
257+ vi . doMock ( "./util/prompt.js" , ( ) => ( {
258+ question : vi . fn ( ) ,
259+ questionWithChoices,
260+ } ) ) ;
261+
262+ const { runOnboardingFlow } = await import ( "./onboarding.js" ) ;
263+
264+ await expect ( runOnboardingFlow ( undefined ) ) . resolves . toBe ( false ) ;
265+ expect ( questionWithChoices ) . not . toHaveBeenCalled ( ) ;
266+ } ) ;
267+
268+ test ( "should mark onboarding complete after a successful --config load" , async ( ) => {
269+ const configPath = path . join ( tempDir , "custom-config.yaml" ) ;
270+ const flagPath = path . join ( tempDir , ".onboarding_complete" ) ;
271+ const loadConfiguration = vi . fn ( ) . mockResolvedValue ( {
272+ config : { name : "Custom Config" } ,
273+ source : { path : configPath , type : "cli-flag" } ,
274+ } ) ;
275+
276+ vi . doMock ( "./configLoader.js" , ( ) => ( {
277+ loadConfiguration,
278+ } ) ) ;
279+
280+ const { initializeWithOnboarding } = await import ( "./onboarding.js" ) ;
281+
282+ await initializeWithOnboarding ( null , configPath ) ;
283+
284+ expect ( loadConfiguration ) . toHaveBeenCalledOnce ( ) ;
285+ expect ( fs . existsSync ( flagPath ) ) . toBe ( true ) ;
286+ } ) ;
287+ } ) ;
288+
165289// Separate describe block with its own mocking for BEDROCK tests
166290describe ( "CONTINUE_USE_BEDROCK environment variable" , ( ) => {
167291 const mockConsoleLog = vi . fn ( ) ;
0 commit comments