@@ -7,9 +7,15 @@ import { loadConfig, saveConfig, setEnv, unsetEnv, listEnv } from '../config/con
77import { getAllCredentials , setAllCredentials } from '../auth/token-store' ;
88import { CliError , handleError } from '../utils/errors' ;
99import { confirm } from '../utils/stdin' ;
10- import type { Config } from '../types/config' ;
10+ import { isInteractive , interactiveCheckbox , interactiveSelect } from '../utils/interactive' ;
11+ import type { Config , ServiceName } from '../types/config' ;
1112import type { StoredCredentials } from '../types/tokens' ;
1213
14+ interface ProfileSelection {
15+ service : ServiceName ;
16+ profile : string ;
17+ }
18+
1319const ALGORITHM = 'aes-256-gcm' ;
1420
1521interface ExportedData {
@@ -94,6 +100,7 @@ export function registerConfigCommands(program: Command): void {
94100 . description ( 'Export configuration and credentials (as environment variables by default, or to a file)' )
95101 . option ( '--key <key>' , 'Encryption key (64 hex characters). If not provided, a random key will be generated' )
96102 . option ( '--file <path>' , 'Write encrypted config to file instead of outputting AGENTIO_CONFIG' )
103+ . option ( '--all' , 'Export all profiles without prompting for selection' )
97104 . action ( async ( options ) => {
98105 try {
99106 // Validate key if provided
@@ -115,23 +122,103 @@ export function registerConfigCommands(program: Command): void {
115122 const configData = await loadConfig ( ) ;
116123 const credentials = await getAllCredentials ( ) ;
117124
125+ // Build list of all available profiles
126+ const allProfiles : ProfileSelection [ ] = [ ] ;
127+ for ( const [ service , profiles ] of Object . entries ( configData . profiles ) ) {
128+ if ( profiles ) {
129+ for ( const profile of profiles ) {
130+ allProfiles . push ( { service : service as ServiceName , profile } ) ;
131+ }
132+ }
133+ }
134+
135+ if ( allProfiles . length === 0 ) {
136+ throw new CliError (
137+ 'NOT_FOUND' ,
138+ 'No profiles configured' ,
139+ 'Add profiles first with: agentio <service> profile add'
140+ ) ;
141+ }
142+
143+ // Determine which profiles to export
144+ let selectedProfiles : ProfileSelection [ ] ;
145+
146+ if ( options . all || ! isInteractive ( ) ) {
147+ // Export all profiles
148+ selectedProfiles = allProfiles ;
149+ } else {
150+ // Interactive: ask user to select profiles
151+ const exportAll = await interactiveSelect ( {
152+ message : 'What would you like to export?' ,
153+ choices : [
154+ { name : `All profiles (${ allProfiles . length } )` , value : 'all' } ,
155+ { name : 'Select specific profiles' , value : 'select' } ,
156+ ] ,
157+ default : 'all' ,
158+ } ) ;
159+
160+ if ( exportAll === 'all' ) {
161+ selectedProfiles = allProfiles ;
162+ } else {
163+ selectedProfiles = await interactiveCheckbox ( {
164+ message : 'Select profiles to export:' ,
165+ choices : allProfiles . map ( ( p ) => ( {
166+ name : `${ p . service } : ${ p . profile } ` ,
167+ value : p ,
168+ checked : false ,
169+ } ) ) ,
170+ required : true ,
171+ } ) ;
172+ }
173+ }
174+
175+ // Filter config and credentials based on selection
176+ const filteredConfig : Config = { profiles : { } } ;
177+ const filteredCredentials : StoredCredentials = { } ;
178+
179+ for ( const { service, profile } of selectedProfiles ) {
180+ // Add to filtered config
181+ if ( ! filteredConfig . profiles [ service ] ) {
182+ ( filteredConfig . profiles as Record < string , string [ ] > ) [ service ] = [ ] ;
183+ }
184+ ( filteredConfig . profiles as Record < string , string [ ] > ) [ service ] . push ( profile ) ;
185+
186+ // Add credentials if they exist
187+ if ( credentials [ service ] ?. [ profile ] ) {
188+ if ( ! filteredCredentials [ service ] ) {
189+ filteredCredentials [ service ] = { } ;
190+ }
191+ filteredCredentials [ service ] [ profile ] = credentials [ service ] [ profile ] ;
192+ }
193+ }
194+
195+ // Include env vars if they exist
196+ if ( configData . env ) {
197+ filteredConfig . env = configData . env ;
198+ }
199+
118200 const exportData : ExportedData = {
119201 version : 1 ,
120- config : configData ,
121- credentials,
202+ config : filteredConfig ,
203+ credentials : filteredCredentials ,
122204 } ;
123205
124206 // Encrypt the data
125207 const key = deriveKeyFromPassword ( encryptionKey ) ;
126208 const encrypted = encrypt ( JSON . stringify ( exportData ) , key ) ;
127209
210+ const profileCount = selectedProfiles . length ;
211+ const profileText = profileCount === 1 ? 'profile' : 'profiles' ;
212+
128213 if ( options . file ) {
129214 // Write to file, output just the key
130215 const filePath = options . file . startsWith ( '/' ) ? options . file : join ( process . cwd ( ) , options . file ) ;
131216 await writeFile ( filePath , encrypted , { mode : 0o600 } ) ;
217+ console . error ( `Exported ${ profileCount } ${ profileText } to ${ filePath } ` ) ;
132218 console . log ( `AGENTIO_KEY=${ encryptionKey } ` ) ;
133219 } else {
134220 // Output as environment variables
221+ console . error ( `Exported ${ profileCount } ${ profileText } ` ) ;
135222 console . log ( `AGENTIO_KEY=${ encryptionKey } ` ) ;
136223 console . log ( `AGENTIO_CONFIG=${ encrypted } ` ) ;
137224 }
0 commit comments