From 21f47c8afd9d0e1475015be220a28582d4333968 Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Fri, 20 Feb 2026 14:12:57 -0700 Subject: [PATCH 1/5] fix: error on missing info for --json --- messages/agent.generate.authoring-bundle.md | 12 ++ messages/agent.test.run.md | 4 + .../agent/generate/authoring-bundle.ts | 49 ++++++-- .../agent/publish/authoring-bundle.ts | 5 + src/commands/agent/test/run.ts | 5 + .../agent/validate/authoring-bundle.ts | 5 + .../agent/generate/authoring-bundle.test.ts | 112 ++++++++++++++++++ 7 files changed, 183 insertions(+), 9 deletions(-) diff --git a/messages/agent.generate.authoring-bundle.md b/messages/agent.generate.authoring-bundle.md index 13f2764..2333fdb 100644 --- a/messages/agent.generate.authoring-bundle.md +++ b/messages/agent.generate.authoring-bundle.md @@ -139,3 +139,15 @@ Canceled authoring bundle generation. # warning.noSpecDir No agent spec directory found at %s. + +# error.jsonRequiresName + +When using --json, you must specify --name. + +# error.jsonRequiresSpecOrNoSpec + +When using --json, you must specify either --spec or --no-spec. + +# error.jsonAabExists + +An authoring bundle with the API name "%s" already exists in the project. Use --force-overwrite to overwrite it, or specify a different --api-name. diff --git a/messages/agent.test.run.md b/messages/agent.test.run.md index 65ed2f4..bb5158a 100644 --- a/messages/agent.test.run.md +++ b/messages/agent.test.run.md @@ -35,3 +35,7 @@ Number of minutes to wait for the command to complete and display results to the - Start an agent test and write the JSON-formatted results into a directory called "test-results": <%= config.bin %> <%= command.id %> --api-name Resort_Manager_Test --wait 10 --output-dir ./test-results --result-format json + +# error.missingRequiredFlags + +When using --json, you must specify the required flag(s): %s. diff --git a/src/commands/agent/generate/authoring-bundle.ts b/src/commands/agent/generate/authoring-bundle.ts index 8f97722..1fba5f8 100644 --- a/src/commands/agent/generate/authoring-bundle.ts +++ b/src/commands/agent/generate/authoring-bundle.ts @@ -106,6 +106,19 @@ async function resolveUniqueBundle( return resolveUniqueBundle(baseOutputDir, false); } +function resolveNameAndApiNameForJson( + flags: { name: string; 'api-name'?: string; 'force-overwrite'?: boolean }, + baseOutputDir: string +): { name: string; bundleApiName: string } { + const name = flags.name; + const bundleApiName = flags['api-name'] ?? generateApiName(name); + const bundleDir = join(baseOutputDir, 'aiAuthoringBundles', bundleApiName); + if (existsSync(bundleDir) && !flags['force-overwrite']) { + throw messages.createError('error.jsonAabExists', [bundleApiName]); + } + return { name, bundleApiName }; +} + export default class AgentGenerateAuthoringBundle extends SfCommand { public static readonly summary = messages.getMessage('summary'); public static readonly description = messages.getMessage('description'); @@ -138,6 +151,7 @@ export default class AgentGenerateAuthoringBundle extends SfCommand { const { flags } = await this.parse(AgentGenerateAuthoringBundle); const { 'output-dir': outputDir } = flags; @@ -146,6 +160,16 @@ export default class AgentGenerateAuthoringBundle extends SfCommand undefined, --spec => path, missing => wizard prompts let spec: string | undefined; if (flags['no-spec']) { @@ -207,19 +231,26 @@ export default class AgentGenerateAuthoringBundle extends SfCommand { const { flags } = await this.parse(AgentPublishAuthoringBundle); + + if (this.jsonEnabled() && !flags['api-name']) { + throw messages.createError('error.missingRequiredFlags', ['api-name']); + } + // If api-name is not provided, prompt user to select an .agent file from the project and extract the API name from it const aabName = flags['api-name'] ?? diff --git a/src/commands/agent/test/run.ts b/src/commands/agent/test/run.ts index 91e482d..9376965 100644 --- a/src/commands/agent/test/run.ts +++ b/src/commands/agent/test/run.ts @@ -84,6 +84,11 @@ export default class AgentTestRun extends SfCommand { public async run(): Promise { const { flags } = await this.parse(AgentTestRun); const connection = flags['target-org'].getConnection(flags['api-version']); + + if (this.jsonEnabled() && !flags['api-name']) { + throw messages.createError('error.missingRequiredFlags', ['api-name']); + } + const apiName = flags['api-name'] ?? (await promptForAiEvaluationDefinitionApiName(FLAGGABLE_PROMPTS['api-name'], connection)); diff --git a/src/commands/agent/validate/authoring-bundle.ts b/src/commands/agent/validate/authoring-bundle.ts index c402eef..823d5fd 100644 --- a/src/commands/agent/validate/authoring-bundle.ts +++ b/src/commands/agent/validate/authoring-bundle.ts @@ -63,6 +63,11 @@ export default class AgentValidateAuthoringBundle extends SfCommand { const { flags } = await this.parse(AgentValidateAuthoringBundle); + + if (this.jsonEnabled() && !flags['api-name']) { + throw messages.createError('error.missingRequiredFlags', ['api-name']); + } + // If api-name is not provided, prompt user to select an .agent file from the project and extract the API name from it const aabName = flags['api-name'] ?? diff --git a/test/commands/agent/generate/authoring-bundle.test.ts b/test/commands/agent/generate/authoring-bundle.test.ts index b5dfc41..0db9c8b 100644 --- a/test/commands/agent/generate/authoring-bundle.test.ts +++ b/test/commands/agent/generate/authoring-bundle.test.ts @@ -459,4 +459,116 @@ describe('agent generate authoring-bundle', () => { expect(result.agentPath).to.include('BrandNewAgent.agent'); }); }); + + describe('when --json is used', () => { + it('should throw when --name is not specified', async () => { + try { + await AgentGenerateAuthoringBundle.run([ + '--json', + '--no-spec', + '--api-name', + 'MyAgent', + '--target-org', + 'test@org.com', + ]); + expect.fail('Expected error'); + } catch (error) { + expect((error as Error).message).to.include('you must specify --name'); + } + }); + + it('should throw when neither --spec nor --no-spec is specified', async () => { + try { + await AgentGenerateAuthoringBundle.run([ + '--json', + '--name', + 'My Agent', + '--api-name', + 'MyAgent', + '--target-org', + 'test@org.com', + ]); + expect.fail('Expected error'); + } catch (error) { + expect((error as Error).message).to.include('you must specify either --spec or --no-spec'); + } + }); + + it('should throw when existing AAB matches api-name and --force-overwrite is not set', async () => { + const EXISTING_BUNDLE_API_NAME = 'Willie_Resort_Manager'; + try { + await AgentGenerateAuthoringBundle.run([ + '--json', + '--no-spec', + '--name', + 'Willie Resort Manager', + '--api-name', + EXISTING_BUNDLE_API_NAME, + '--target-org', + 'test@org.com', + ]); + expect.fail('Expected error'); + } catch (error) { + expect((error as Error).message).to.include(EXISTING_BUNDLE_API_NAME); + expect((error as Error).message).to.include('--force-overwrite'); + } + }); + + it('should use generateApiName(name) as api-name when --api-name is omitted and not prompt', async () => { + const result = await AgentGenerateAuthoringBundle.run([ + '--json', + '--no-spec', + '--name', + 'My Custom Agent', + '--target-org', + 'test@org.com', + ]); + + expect(inputStub.called).to.be.false; + const expectedApiName = generateApiName('My Custom Agent'); + expect(result.outputDir).to.include(expectedApiName); + expect(createAuthoringBundleStub.calledOnce).to.be.true; + const callArgs = createAuthoringBundleStub.firstCall.args[0] as CreateAuthoringBundleArgs; + expect(callArgs.bundleApiName).to.equal(expectedApiName); + expect(callArgs.agentSpec.name).to.equal('My Custom Agent'); + }); + + it('should succeed with --json when all required flags provided and no existing AAB', async () => { + const result = await AgentGenerateAuthoringBundle.run([ + '--json', + '--no-spec', + '--name', + 'Json Agent', + '--api-name', + 'JsonAgent', + '--target-org', + 'test@org.com', + ]); + + expect(selectStub.called).to.be.false; + expect(inputStub.called).to.be.false; + expect(yesNoOrCancelStub.called).to.be.false; + expect(result.agentPath).to.include('JsonAgent.agent'); + expect(createAuthoringBundleStub.calledOnce).to.be.true; + }); + + it('should succeed with --json and --force-overwrite when existing AAB matches', async () => { + const EXISTING_BUNDLE_API_NAME = 'Willie_Resort_Manager'; + const result = await AgentGenerateAuthoringBundle.run([ + '--json', + '--no-spec', + '--name', + 'Willie Resort Manager', + '--api-name', + EXISTING_BUNDLE_API_NAME, + '--force-overwrite', + '--target-org', + 'test@org.com', + ]); + + expect(yesNoOrCancelStub.called).to.be.false; + expect(createAuthoringBundleStub.calledOnce).to.be.true; + expect(result.agentPath).to.include(`${EXISTING_BUNDLE_API_NAME}.agent`); + }); + }); }); From 62897d1628100db5959b032d6e84d1c6a23f5799 Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Mon, 23 Feb 2026 09:53:19 -0700 Subject: [PATCH 2/5] Update messages/agent.generate.authoring-bundle.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/agent.generate.authoring-bundle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/agent.generate.authoring-bundle.md b/messages/agent.generate.authoring-bundle.md index 2333fdb..d245ee7 100644 --- a/messages/agent.generate.authoring-bundle.md +++ b/messages/agent.generate.authoring-bundle.md @@ -142,7 +142,7 @@ No agent spec directory found at %s. # error.jsonRequiresName -When using --json, you must specify --name. +When using --json, you must also specify --name. # error.jsonRequiresSpecOrNoSpec From e767b25cc81fa9fe9ee80dd7de15d42f1be78d41 Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Mon, 23 Feb 2026 09:53:24 -0700 Subject: [PATCH 3/5] Update messages/agent.generate.authoring-bundle.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/agent.generate.authoring-bundle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/agent.generate.authoring-bundle.md b/messages/agent.generate.authoring-bundle.md index d245ee7..62af41e 100644 --- a/messages/agent.generate.authoring-bundle.md +++ b/messages/agent.generate.authoring-bundle.md @@ -146,7 +146,7 @@ When using --json, you must also specify --name. # error.jsonRequiresSpecOrNoSpec -When using --json, you must specify either --spec or --no-spec. +When using --json, you must also specify either --spec or --no-spec. # error.jsonAabExists From 3b9df4be03afa72b89ae1740bdbedf0cd303a87d Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Mon, 23 Feb 2026 09:53:29 -0700 Subject: [PATCH 4/5] Update messages/agent.generate.authoring-bundle.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/agent.generate.authoring-bundle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/agent.generate.authoring-bundle.md b/messages/agent.generate.authoring-bundle.md index 62af41e..f98ff2f 100644 --- a/messages/agent.generate.authoring-bundle.md +++ b/messages/agent.generate.authoring-bundle.md @@ -150,4 +150,4 @@ When using --json, you must also specify either --spec or --no-spec. # error.jsonAabExists -An authoring bundle with the API name "%s" already exists in the project. Use --force-overwrite to overwrite it, or specify a different --api-name. +An authoring bundle with the API name "%s" already exists in the project. Use --force-overwrite to overwrite it or specify a different authoring bundle using the --api-name flag. From 0f1c99176ab024ae60e6fe0fb3e95aa37d06378e Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Mon, 23 Feb 2026 09:53:34 -0700 Subject: [PATCH 5/5] Update messages/agent.test.run.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/agent.test.run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/agent.test.run.md b/messages/agent.test.run.md index bb5158a..09adc43 100644 --- a/messages/agent.test.run.md +++ b/messages/agent.test.run.md @@ -38,4 +38,4 @@ Number of minutes to wait for the command to complete and display results to the # error.missingRequiredFlags -When using --json, you must specify the required flag(s): %s. +When using --json, you must also specify the required flag(s): %s.