@@ -52,6 +52,7 @@ import {
5252 writeEnvFile ,
5353 openBrowserUrl ,
5454 BloomreachProfileManager ,
55+ BloomreachProjectsService ,
5556 BLOOMREACH_API_SETTINGS_URL ,
5657 createAuthManager ,
5758} from '@bloomreach-buddy/core' ;
@@ -12329,6 +12330,11 @@ program
1232912330 profileName : options . profile ,
1233012331 timeoutMs : Number ( options . timeout ) ,
1233112332 loginUrl : options . loginUrl ,
12333+ onCaptchaDetected : ( ) => {
12334+ if ( ! options . json ) {
12335+ console . error ( ' CAPTCHA detected. Please solve it in the browser window.' ) ;
12336+ }
12337+ } ,
1233212338 } ) ;
1233312339
1233412340 if ( options . json ) {
@@ -12405,6 +12411,219 @@ program
1240512411 } ,
1240612412 ) ;
1240712413
12414+ // --- Project management ---
12415+ const projects = program
12416+ . command ( 'projects' )
12417+ . description ( 'Manage Bloomreach project selection' ) ;
12418+
12419+ projects
12420+ . command ( 'list' )
12421+ . description ( 'List available Bloomreach projects' )
12422+ . option ( '--profile <name>' , 'Browser profile name' , 'default' )
12423+ . option ( '--json' , 'Output as JSON' )
12424+ . action (
12425+ async ( options : { profile : string ; json ?: boolean } ) => {
12426+ try {
12427+ const profilesDir = resolveProfilesDir ( ) ;
12428+ const profileManager = new BloomreachProfileManager ( { profilesDir } ) ;
12429+ const projectsService = new BloomreachProjectsService ( profileManager , { profilesDir } ) ;
12430+
12431+ const result = await projectsService . listProjects ( {
12432+ profileName : options . profile ,
12433+ } ) ;
12434+
12435+ if ( options . json ) {
12436+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
12437+ } else {
12438+ console . log ( '' ) ;
12439+ console . log ( ' Available Bloomreach Projects' ) ;
12440+ console . log ( ' ============================' ) ;
12441+ console . log ( '' ) ;
12442+ for ( const org of result . hierarchy . organizations ) {
12443+ console . log ( ` Organization: ${ org . name } ` ) ;
12444+ for ( const ws of org . workspaces ) {
12445+ console . log ( ` Workspace: ${ ws . name } ` ) ;
12446+ for ( const prod of ws . products ) {
12447+ console . log ( ` ${ prod . name } (${ prod . projectCount } project${ prod . projectCount !== 1 ? 's' : '' } )` ) ;
12448+ for ( const projName of prod . projects ) {
12449+ console . log ( ` - ${ projName } ` ) ;
12450+ }
12451+ }
12452+ }
12453+ }
12454+ console . log ( '' ) ;
12455+ console . log ( ` Total: ${ result . projects . length } project${ result . projects . length !== 1 ? 's' : '' } ` ) ;
12456+ console . log ( '' ) ;
12457+ }
12458+ } catch ( error ) {
12459+ if ( options . json ) {
12460+ console . log (
12461+ JSON . stringify (
12462+ { error : error instanceof Error ? error . message : String ( error ) } ,
12463+ null ,
12464+ 2 ,
12465+ ) ,
12466+ ) ;
12467+ } else {
12468+ console . error (
12469+ `Error: ${ error instanceof Error ? error . message : String ( error ) } ` ,
12470+ ) ;
12471+ }
12472+ process . exit ( 1 ) ;
12473+ }
12474+ } ,
12475+ ) ;
12476+
12477+ projects
12478+ . command ( 'select' )
12479+ . description ( 'Select a Bloomreach project to work in' )
12480+ . argument ( '<name-or-slug>' , 'Project name or URL slug' )
12481+ . option ( '--profile <name>' , 'Browser profile name' , 'default' )
12482+ . option ( '--json' , 'Output as JSON' )
12483+ . action (
12484+ async (
12485+ nameOrSlug : string ,
12486+ options : { profile : string ; json ?: boolean } ,
12487+ ) => {
12488+ try {
12489+ const profilesDir = resolveProfilesDir ( ) ;
12490+ const profileManager = new BloomreachProfileManager ( { profilesDir } ) ;
12491+ const projectsService = new BloomreachProjectsService ( profileManager , { profilesDir } ) ;
12492+
12493+ const result = await projectsService . selectProject ( nameOrSlug , {
12494+ profileName : options . profile ,
12495+ } ) ;
12496+
12497+ if ( options . json ) {
12498+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
12499+ } else {
12500+ console . log ( '' ) ;
12501+ console . log ( ` Project selected: ${ result . project . name } ` ) ;
12502+ console . log ( ` URL: ${ result . project . url } ` ) ;
12503+ console . log ( ` Organization: ${ result . project . organization } ` ) ;
12504+ console . log ( ` Workspace: ${ result . project . workspace } ` ) ;
12505+ console . log ( ` Product: ${ result . project . product } ` ) ;
12506+ if ( result . previousProject ) {
12507+ console . log ( ` Previous: ${ result . previousProject . name } ` ) ;
12508+ }
12509+ console . log ( '' ) ;
12510+ }
12511+ } catch ( error ) {
12512+ if ( options . json ) {
12513+ console . log (
12514+ JSON . stringify (
12515+ { error : error instanceof Error ? error . message : String ( error ) } ,
12516+ null ,
12517+ 2 ,
12518+ ) ,
12519+ ) ;
12520+ } else {
12521+ console . error (
12522+ `Error: ${ error instanceof Error ? error . message : String ( error ) } ` ,
12523+ ) ;
12524+ }
12525+ process . exit ( 1 ) ;
12526+ }
12527+ } ,
12528+ ) ;
12529+
12530+ projects
12531+ . command ( 'current' )
12532+ . description ( 'Show the currently selected project' )
12533+ . option ( '--profile <name>' , 'Browser profile name' , 'default' )
12534+ . option ( '--json' , 'Output as JSON' )
12535+ . action (
12536+ async ( options : { profile : string ; json ?: boolean } ) => {
12537+ try {
12538+ const profilesDir = resolveProfilesDir ( ) ;
12539+ const profileManager = new BloomreachProfileManager ( { profilesDir } ) ;
12540+ const projectsService = new BloomreachProjectsService ( profileManager , { profilesDir } ) ;
12541+
12542+ const result = await projectsService . currentProject ( {
12543+ profileName : options . profile ,
12544+ } ) ;
12545+
12546+ if ( options . json ) {
12547+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
12548+ } else if ( result . project ) {
12549+ console . log ( '' ) ;
12550+ console . log ( ` Current project: ${ result . project . name } ` ) ;
12551+ console . log ( ` URL: ${ result . project . url } ` ) ;
12552+ console . log ( ` Organization: ${ result . project . organization } ` ) ;
12553+ console . log ( '' ) ;
12554+ } else {
12555+ console . log ( '' ) ;
12556+ console . log ( ' No project selected. Run "bloomreach projects select <name>" to choose one.' ) ;
12557+ console . log ( '' ) ;
12558+ }
12559+ } catch ( error ) {
12560+ if ( options . json ) {
12561+ console . log (
12562+ JSON . stringify (
12563+ { error : error instanceof Error ? error . message : String ( error ) } ,
12564+ null ,
12565+ 2 ,
12566+ ) ,
12567+ ) ;
12568+ } else {
12569+ console . error (
12570+ `Error: ${ error instanceof Error ? error . message : String ( error ) } ` ,
12571+ ) ;
12572+ }
12573+ process . exit ( 1 ) ;
12574+ }
12575+ } ,
12576+ ) ;
12577+
12578+ projects
12579+ . command ( 'clear' )
12580+ . description ( 'Clear the current project selection' )
12581+ . option ( '--profile <name>' , 'Browser profile name' , 'default' )
12582+ . option ( '--json' , 'Output as JSON' )
12583+ . action (
12584+ async ( options : { profile : string ; json ?: boolean } ) => {
12585+ try {
12586+ const profilesDir = resolveProfilesDir ( ) ;
12587+ const profileManager = new BloomreachProfileManager ( { profilesDir } ) ;
12588+ const projectsService = new BloomreachProjectsService ( profileManager , { profilesDir } ) ;
12589+
12590+ const result = await projectsService . clearProject ( {
12591+ profileName : options . profile ,
12592+ } ) ;
12593+
12594+ if ( options . json ) {
12595+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
12596+ } else if ( result . cleared ) {
12597+ console . log ( '' ) ;
12598+ console . log ( ' Project selection cleared.' ) ;
12599+ if ( result . previousProject ) {
12600+ console . log ( ` Previous: ${ result . previousProject . name } ` ) ;
12601+ }
12602+ console . log ( '' ) ;
12603+ } else {
12604+ console . log ( '' ) ;
12605+ console . log ( ' No project was selected.' ) ;
12606+ console . log ( '' ) ;
12607+ }
12608+ } catch ( error ) {
12609+ if ( options . json ) {
12610+ console . log (
12611+ JSON . stringify (
12612+ { error : error instanceof Error ? error . message : String ( error ) } ,
12613+ null ,
12614+ 2 ,
12615+ ) ,
12616+ ) ;
12617+ } else {
12618+ console . error (
12619+ `Error: ${ error instanceof Error ? error . message : String ( error ) } ` ,
12620+ ) ;
12621+ }
12622+ process . exit ( 1 ) ;
12623+ }
12624+ } ,
12625+ ) ;
12626+
1240812627const auth = program
1240912628 . command ( 'auth' )
1241012629 . description ( 'Manage Bloomreach browser authentication' ) ;
0 commit comments