1414 * limitations under the License.
1515 */
1616
17- import { join } from 'node:path' ;
18- import { mkdirSync , writeFileSync , readFileSync } from 'node:fs' ;
17+ import { join , resolve } from 'node:path' ;
18+ import { mkdirSync , writeFileSync , readFileSync , existsSync } from 'node:fs' ;
1919import { SfCommand , Flags } from '@salesforce/sf-plugins-core' ;
20- import { Messages , SfError } from '@salesforce/core' ;
20+ import { generateApiName , Messages , SfError } from '@salesforce/core' ;
2121import { Agent , AgentJobSpec } from '@salesforce/agents' ;
2222import YAML from 'yaml' ;
23- import { FlaggablePrompt , promptForFlag } from '../../../flags.js' ;
23+ import { input as inquirerInput } from '@inquirer/prompts' ;
24+ import { theme } from '../../../inquirer-theme.js' ;
25+ import { FlaggablePrompt , promptForFlag , promptForYamlFile } from '../../../flags.js' ;
2426
2527Messages . importMessagesDirectoryFromMetaUrl ( import . meta. url ) ;
2628const messages = Messages . loadMessages ( '@salesforce/plugin-agent' , 'agent.generate.authoring-bundle' ) ;
@@ -39,6 +41,9 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
3941
4042 public static readonly flags = {
4143 'target-org' : Flags . requiredOrg ( ) ,
44+ 'api-name' : Flags . string ( {
45+ summary : messages . getMessage ( 'flags.api-name.summary' ) ,
46+ } ) ,
4247 'api-version' : Flags . orgApiVersion ( ) ,
4348 spec : Flags . file ( {
4449 summary : messages . getMessage ( 'flags.spec.summary' ) ,
@@ -58,13 +63,35 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
5863 private static readonly FLAGGABLE_PROMPTS = {
5964 name : {
6065 message : messages . getMessage ( 'flags.name.summary' ) ,
61- promptMessage : messages . getMessage ( 'flags.name.prompt' ) ,
6266 validate : ( d : string ) : boolean | string => d . length > 0 || 'Name cannot be empty' ,
6367 required : true ,
6468 } ,
69+ 'api-name' : {
70+ message : messages . getMessage ( 'flags.api-name.summary' ) ,
71+ promptMessage : messages . getMessage ( 'flags.api-name.prompt' ) ,
72+ validate : ( d : string ) : boolean | string => {
73+ if ( d . length === 0 ) {
74+ return true ;
75+ }
76+ if ( d . length > 80 ) {
77+ return 'API name cannot be over 80 characters.' ;
78+ }
79+ const regex = / ^ [ A - Z a - z ] [ A - Z a - z 0 - 9 _ ] * [ A - Z a - z 0 - 9 ] + $ / ;
80+ if ( ! regex . test ( d ) ) {
81+ return 'Invalid API name.' ;
82+ }
83+ return true ;
84+ } ,
85+ } ,
6586 spec : {
6687 message : messages . getMessage ( 'flags.spec.summary' ) ,
67- validate : ( d : string ) : boolean | string => d . length > 0 || 'Spec file path cannot be empty' ,
88+ validate : ( d : string ) : boolean | string => {
89+ const specPath = resolve ( d ) ;
90+ if ( ! existsSync ( specPath ) ) {
91+ return 'Please enter an existing agent spec (yaml) file' ;
92+ }
93+ return true ;
94+ } ,
6895 required : true ,
6996 } ,
7097 } satisfies Record < string , FlaggablePrompt > ;
@@ -74,12 +101,25 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
74101 const { 'output-dir' : outputDir , 'target-org' : targetOrg } = flags ;
75102
76103 // If we don't have a spec yet, prompt for it
77- const spec = flags [ ' spec' ] ?? ( await promptForFlag ( AgentGenerateAuthoringBundle . FLAGGABLE_PROMPTS [ 'spec' ] ) ) ;
104+ const spec = flags . spec ?? ( await promptForYamlFile ( AgentGenerateAuthoringBundle . FLAGGABLE_PROMPTS [ 'spec' ] ) ) ;
78105
79106 // If we don't have a name yet, prompt for it
80- const name = (
81- flags [ 'name' ] ?? ( await promptForFlag ( AgentGenerateAuthoringBundle . FLAGGABLE_PROMPTS [ 'name' ] ) )
82- ) . replaceAll ( ' ' , '_' ) ;
107+ const name = flags [ 'name' ] ?? ( await promptForFlag ( AgentGenerateAuthoringBundle . FLAGGABLE_PROMPTS [ 'name' ] ) ) ;
108+
109+ // If we don't have an api name yet, prompt for it
110+ let bundleApiName = flags [ 'api-name' ] ;
111+ if ( ! bundleApiName ) {
112+ bundleApiName = generateApiName ( name ) ;
113+ const promptedValue = await inquirerInput ( {
114+ message : messages . getMessage ( 'flags.api-name.prompt' ) ,
115+ validate : AgentGenerateAuthoringBundle . FLAGGABLE_PROMPTS [ 'api-name' ] . validate ,
116+ default : bundleApiName ,
117+ theme,
118+ } ) ;
119+ if ( promptedValue ?. length ) {
120+ bundleApiName = promptedValue ;
121+ }
122+ }
83123
84124 try {
85125 // Get default output directory if not specified
0 commit comments