@@ -182,6 +182,60 @@ it.effect("leaves a newer service unchanged during onboarding without prompting"
182182 } ) ,
183183) ;
184184
185+ const withTerminal = ( isTTY : { readonly stdin : boolean ; readonly stdout : boolean } ) =>
186+ Effect . acquireRelease (
187+ Effect . sync ( ( ) =>
188+ (
189+ [
190+ [ process . stdin , isTTY . stdin ] ,
191+ [ process . stdout , isTTY . stdout ] ,
192+ ] as const
193+ ) . map ( ( [ stream , value ] ) => {
194+ const descriptor = Object . getOwnPropertyDescriptor ( stream , "isTTY" ) ;
195+ Object . defineProperty ( stream , "isTTY" , { configurable : true , value } ) ;
196+ return { stream, descriptor } ;
197+ } ) ,
198+ ) ,
199+ ( saved ) =>
200+ Effect . sync ( ( ) => {
201+ for ( const { stream, descriptor } of saved ) {
202+ if ( descriptor === undefined ) Reflect . deleteProperty ( stream , "isTTY" ) ;
203+ else Object . defineProperty ( stream , "isTTY" , descriptor ) ;
204+ }
205+ } ) ,
206+ ) ;
207+
208+ it . effect . each ( [
209+ { label : "stdin and stdout are" , stdin : false , stdout : false } ,
210+ { label : "stdin is" , stdin : false , stdout : true } ,
211+ { label : "stdout is" , stdin : true , stdout : false } ,
212+ ] ) ( "skips the onboarding service prompt when $label not a terminal" , ( isTTY ) =>
213+ Effect . gen ( function * ( ) {
214+ yield * withTerminal ( isTTY ) ;
215+ const { service, installOptions } = makeTestService ( {
216+ ...status ,
217+ installed : false ,
218+ current : false ,
219+ } ) ;
220+ const terminal = Terminal . make ( {
221+ columns : Effect . succeed ( 80 ) ,
222+ rows : Effect . succeed ( 24 ) ,
223+ readInput : Effect . die ( "Onboarding must not prompt without a terminal." ) ,
224+ readLine : Effect . die ( "Onboarding must not prompt without a terminal." ) ,
225+ display : ( ) => Effect . die ( "Onboarding must not prompt without a terminal." ) ,
226+ } ) ;
227+
228+ const ready = yield * offerServiceDuringOnboarding . pipe (
229+ Effect . provideService ( BootService . BootService , service ) ,
230+ Effect . provideService ( Terminal . Terminal , terminal ) ,
231+ Effect . provide ( NodeServices . layer ) ,
232+ ) ;
233+
234+ expect ( ready ) . toBe ( "skipped" ) ;
235+ expect ( installOptions ) . toEqual ( [ ] ) ;
236+ } ) ,
237+ ) ;
238+
185239// regression: #9602 diagnose incomplete headless server setup
186240it . effect ( "keeps the manual-server fallback when background prerequisites fail" , ( ) =>
187241 Effect . gen ( function * ( ) {
0 commit comments