@@ -173,16 +173,58 @@ export async function scaffoldMonorepo(projectNameArg, options) {
173173 services . push ( { type, name, port } ) ;
174174 }
175175 } else {
176- const answer = await prompts ( {
177- type : 'multiselect' ,
178- name : 'serviceTypes' ,
179- message : 'Select services to include:' ,
180- choices : allServiceChoices ,
181- instructions : false ,
182- min : 1
176+ // New dynamic interactive flow: ask how many services, then collect each.
177+ const countAns = await prompts ( {
178+ type : 'number' ,
179+ name : 'svcCount' ,
180+ message : 'How many services do you want to create?' ,
181+ initial : 1 ,
182+ min : 1 ,
183+ validate : v => Number . isInteger ( v ) && v > 0 && v <= 50 ? true : 'Enter a positive integer (max 50)'
183184 } ) ;
184- const selected = answer . serviceTypes || [ ] ;
185- for ( const type of selected ) services . push ( { type, name : type , port : defaultPorts [ type ] } ) ;
185+ const svcCount = countAns . svcCount || 1 ;
186+ for ( let i = 0 ; i < svcCount ; i ++ ) {
187+ const typeAns = await prompts ( {
188+ type : 'select' ,
189+ name : 'svcType' ,
190+ message : `Service #${ i + 1 } type:` ,
191+ choices : allServiceChoices . map ( c => ( { title : c . title , value : c . value } ) ) ,
192+ initial : 0
193+ } ) ;
194+ const svcType = typeAns . svcType ;
195+ if ( ! svcType ) {
196+ console . log ( chalk . red ( 'No type selected; aborting.' ) ) ;
197+ process . exit ( 1 ) ;
198+ }
199+ const nameAns = await prompts ( {
200+ type : 'text' ,
201+ name : 'svcName' ,
202+ message : `Name for ${ svcType } service (leave blank for default '${ svcType } '):` ,
203+ validate : v => ! v || ( / ^ [ a - z A - Z 0 - 9 . _ - ] + $ / . test ( v ) ? true : 'Use alphanumerics, dash, underscore, dot' )
204+ } ) ;
205+ let svcName = nameAns . svcName && nameAns . svcName . trim ( ) ? nameAns . svcName . trim ( ) : svcType ;
206+ if ( reservedNames . has ( svcName ) || services . find ( s => s . name === svcName ) ) {
207+ console . log ( chalk . red ( `Name '${ svcName } ' is reserved or already used. Using '${ svcType } '.` ) ) ;
208+ svcName = svcType ;
209+ }
210+ const portDefault = defaultPorts [ svcType ] ;
211+ const portAns = await prompts ( {
212+ type : 'text' ,
213+ name : 'svcPort' ,
214+ message : `Port for ${ svcName } (${ svcType } ) (default ${ portDefault } ):` ,
215+ validate : v => ! v || ( / ^ \d + $ / . test ( v ) && + v > 0 && + v <= 65535 ) ? true : 'Enter a valid port 1-65535'
216+ } ) ;
217+ let svcPort = portDefault ;
218+ if ( portAns . svcPort ) {
219+ const parsed = Number ( portAns . svcPort ) ;
220+ if ( services . find ( s => s . port === parsed ) ) {
221+ console . log ( chalk . red ( `Port ${ parsed } already used; keeping ${ portDefault } .` ) ) ;
222+ } else if ( parsed >= 1 && parsed <= 65535 ) {
223+ svcPort = parsed ;
224+ }
225+ }
226+ services . push ( { type : svcType , name : svcName , port : svcPort } ) ;
227+ }
186228 }
187229
188230 // Always allow customization of name & port in interactive mode (not nonInteractive)
0 commit comments