Skip to content

Commit 17ff205

Browse files
fix: make api-name flag prompt-able and rename AfScript to Agent
1 parent 21f6f15 commit 17ff205

File tree

9 files changed

+80
-34
lines changed

9 files changed

+80
-34
lines changed

messages/agent.generate.authoring-bundle.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Generate an authoring bundle from an agent specification.
44

55
# description
66

7-
Generates an authoring bundle containing AFScript and its meta.xml file from an agent specification file.
7+
Generates an authoring bundle containing Agent and its meta.xml file from an agent specification file.
88

99
# flags.spec.summary
1010

@@ -42,6 +42,6 @@ No agent specification file found at the specified path.
4242

4343
The specified file is not a valid agent specification file.
4444

45-
# error.failed-to-create-afscript
45+
# error.failed-to-create-agent
4646

47-
Failed to create AFScript from the agent specification.
47+
Failed to create Agent from the agent specification.

messages/agent.preview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ API name of the agent you want to interact with.
2020

2121
# flags.authoring-bundle.summary
2222

23-
Preview an ephemeral afscript agent by specifying the API name of the Authoring Bundle metadata
23+
Preview an ephemeral agent by specifying the API name of the Authoring Bundle metadata
2424

2525
# flags.client-app.summary
2626

messages/agent.publish.authoring-bundle.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Publishes an Agent Authoring Bundle by compiling the AF script and creating a ne
1515

1616
API name of the Agent Authoring Bundle to publish
1717

18+
# flags.api-name.prompt
19+
20+
API name of the authoring bundle to publish
21+
1822
# flags.agent-name.summary
1923

2024
Name for the new agent to be created
@@ -32,10 +36,10 @@ Invalid bundle path. Please provide a valid path to an Agent Authoring Bundle.
3236
Failed to publish agent with the following errors:
3337
%s
3438

35-
# error.afscriptNotFound
39+
# error.agentNotFound
3640

3741
Could not find an .agent file with API name '%s' in the project.
3842

39-
# error.afscriptNotFoundAction
43+
# error.agentNotFoundAction
4044

4145
Please check that the API name is correct and that the .agent file exists in your project directory.

messages/agent.validate.authoring-bundle.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Validates an Agent Authoring Bundle by compiling the AF script and checking for
1515

1616
Path to the Agent Authoring Bundle to validate
1717

18+
# flags.api-name.prompt
19+
20+
API name of the authoring bundle to validate
21+
1822
# error.missingRequiredFlags
1923

2024
Required flag(s) missing: %s
@@ -28,10 +32,10 @@ Invalid bundle path. Please provide a valid path to an Agent Authoring Bundle.
2832
AF Script compilation failed with the following errors:
2933
%s
3034

31-
# error.afscriptNotFound
35+
# error.agentNotFound
3236

3337
Could not find an .agent file with API name '%s' in the project.
3438

35-
# error.afscriptNotFoundAction
39+
# error.agentNotFoundAction
3640

3741
Please check that the API name is correct and that the .agent file exists in your project directory.

schemas/agent-generate-authoring__bundle.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"AgentGenerateAuthoringBundleResult": {
66
"type": "object",
77
"properties": {
8-
"afScriptPath": {
8+
"agentPath": {
99
"type": "string"
1010
},
1111
"metaXmlPath": {
@@ -15,7 +15,7 @@
1515
"type": "string"
1616
}
1717
},
18-
"required": ["afScriptPath", "metaXmlPath", "outputDir"],
18+
"required": ["agentPath", "metaXmlPath", "outputDir"],
1919
"additionalProperties": false
2020
}
2121
}

src/commands/agent/generate/authoring-bundle.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2828
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.generate.authoring-bundle');
2929

3030
export type AgentGenerateAuthoringBundleResult = {
31-
afScriptPath: string;
31+
agentPath: string;
3232
metaXmlPath: string;
3333
outputDir: string;
3434
};
@@ -128,16 +128,16 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
128128
const targetOutputDir = join(outputDir ?? defaultOutputDir, 'aiAuthoringBundles', name);
129129

130130
// Generate file paths
131-
const afScriptPath = join(targetOutputDir, `${name}.agent`);
131+
const agentPath = join(targetOutputDir, `${name}.agent`);
132132
const metaXmlPath = join(targetOutputDir, `${name}.aiAuthoringBundle-meta.xml`);
133133

134-
// Write AFScript file
134+
// Write Agent file
135135
const conn = targetOrg.getConnection(flags['api-version']);
136136
const specContents = YAML.parse(readFileSync(spec, 'utf8')) as AgentJobSpec;
137-
const afScript = await Agent.createAfScript(conn, specContents);
137+
const agent = await Agent.createAfScript(conn, specContents);
138138
// Create output directory if it doesn't exist
139139
mkdirSync(targetOutputDir, { recursive: true });
140-
writeFileSync(afScriptPath, afScript);
140+
writeFileSync(agentPath, agent);
141141

142142
// Write meta.xml file
143143
const metaXml = `<?xml version="1.0" encoding="UTF-8"?>
@@ -154,15 +154,13 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
154154
this.logSuccess(`Successfully generated ${name} Authoring Bundle`);
155155

156156
return {
157-
afScriptPath,
157+
agentPath,
158158
metaXmlPath,
159159
outputDir: targetOutputDir,
160160
};
161161
} catch (error) {
162162
const err = SfError.wrap(error);
163-
throw new SfError(messages.getMessage('error.failed-to-create-afscript'), 'AfScriptGenerationError', [
164-
err.message,
165-
]);
163+
throw new SfError(messages.getMessage('error.failed-to-create-agent'), 'AgentGenerationError', [err.message]);
166164
}
167165
}
168166
}

src/commands/agent/publish/authoring-bundle.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { Messages, Lifecycle, SfError } from '@salesforce/core';
2222
import { Agent, findAuthoringBundle } from '@salesforce/agents';
2323
import { RequestStatus, type ScopedPostRetrieve } from '@salesforce/source-deploy-retrieve';
2424
import { ensureArray } from '@salesforce/kit';
25+
import { FlaggablePrompt, promptForFlag } from '../../../flags.js';
2526

2627
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2728
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.publish.authoring-bundle');
@@ -44,26 +45,45 @@ export default class AgentPublishAuthoringBundle extends SfCommand<AgentPublishA
4445
'api-name': Flags.string({
4546
char: 'n',
4647
summary: messages.getMessage('flags.api-name.summary'),
47-
required: true,
4848
}),
4949
};
5050

51+
private static readonly FLAGGABLE_PROMPTS = {
52+
'api-name': {
53+
message: messages.getMessage('flags.api-name.summary'),
54+
promptMessage: messages.getMessage('flags.api-name.prompt'),
55+
validate: (d: string): boolean | string => {
56+
if (d.length > 80) {
57+
return 'API name cannot be over 80 characters.';
58+
}
59+
const regex = /^[A-Za-z][A-Za-z0-9_]*[A-Za-z0-9]+$/;
60+
if (d.length === 0 || !regex.test(d)) {
61+
return 'Invalid API name.';
62+
}
63+
return true;
64+
},
65+
},
66+
} satisfies Record<string, FlaggablePrompt>;
67+
5168
public async run(): Promise<AgentPublishAuthoringBundleResult> {
5269
const { flags } = await this.parse(AgentPublishAuthoringBundle);
70+
// If we don't have an api name yet, prompt for it
71+
const apiName =
72+
flags['api-name'] ?? (await promptForFlag(AgentPublishAuthoringBundle.FLAGGABLE_PROMPTS['api-name']));
5373
// todo: this eslint warning can be removed once published
5474
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
55-
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), flags['api-name']);
75+
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), apiName);
5676

5777
if (!authoringBundleDir) {
58-
throw new SfError(messages.getMessage('error.afscriptNotFound', [flags['api-name']]), 'AfScriptNotFoundError', [
59-
messages.getMessage('error.afscriptNotFoundAction'),
78+
throw new SfError(messages.getMessage('error.agentNotFound', [apiName]), 'AgentNotFoundError', [
79+
messages.getMessage('error.agentNotFoundAction'),
6080
]);
6181
}
6282
// Create multi-stage output
6383
const mso = new MultiStageOutput<{ agentName: string }>({
6484
stages: ['Validate Bundle', 'Publish Agent', 'Retrieve Metadata'],
6585
title: 'Publishing Agent',
66-
data: { agentName: flags['api-name'] },
86+
data: { agentName: apiName },
6787
jsonEnabled: this.jsonEnabled(),
6888
postStagesBlock: [
6989
{
@@ -83,7 +103,7 @@ export default class AgentPublishAuthoringBundle extends SfCommand<AgentPublishA
83103
// First compile the AF script to get the Agent JSON
84104
const agentJson = await Agent.compileAfScript(
85105
conn,
86-
readFileSync(join(authoringBundleDir, `${flags['api-name']}.agent`), 'utf8')
106+
readFileSync(join(authoringBundleDir, `${apiName}.agent`), 'utf8')
87107
);
88108
mso.skipTo('Publish Agent');
89109

src/commands/agent/validate/authoring-bundle.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { join } from 'node:path';
1818
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
1919
import { Messages, SfError } from '@salesforce/core';
2020
import { Agent, findAuthoringBundle } from '@salesforce/agents';
21+
import { FlaggablePrompt, promptForFlag } from '../../../flags.js';
2122

2223
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2324
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.validate.authoring-bundle');
@@ -39,26 +40,45 @@ export default class AgentValidateAuthoringBundle extends SfCommand<AgentValidat
3940
'api-name': Flags.string({
4041
char: 'n',
4142
summary: messages.getMessage('flags.api-name.summary'),
42-
required: true,
4343
}),
4444
};
4545

46+
private static readonly FLAGGABLE_PROMPTS = {
47+
'api-name': {
48+
message: messages.getMessage('flags.api-name.summary'),
49+
promptMessage: messages.getMessage('flags.api-name.prompt'),
50+
validate: (d: string): boolean | string => {
51+
if (d.length > 80) {
52+
return 'API name cannot be over 80 characters.';
53+
}
54+
const regex = /^[A-Za-z][A-Za-z0-9_]*[A-Za-z0-9]+$/;
55+
if (d.length === 0 || !regex.test(d)) {
56+
return 'Invalid API name.';
57+
}
58+
return true;
59+
},
60+
},
61+
} satisfies Record<string, FlaggablePrompt>;
62+
4663
public async run(): Promise<AgentValidateAuthoringBundleResult> {
4764
const { flags } = await this.parse(AgentValidateAuthoringBundle);
65+
// If we don't have an api name yet, prompt for it
66+
const apiName =
67+
flags['api-name'] ?? (await promptForFlag(AgentValidateAuthoringBundle.FLAGGABLE_PROMPTS['api-name']));
4868
// todo: this eslint warning can be removed once published
4969
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
50-
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), flags['api-name']);
70+
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), apiName);
5171
if (!authoringBundleDir) {
52-
throw new SfError(messages.getMessage('error.afscriptNotFound', [flags['api-name']]), 'AfScriptNotFoundError', [
53-
messages.getMessage('error.afscriptNotFoundAction'),
72+
throw new SfError(messages.getMessage('error.agentNotFound', [apiName]), 'AgentNotFoundError', [
73+
messages.getMessage('error.agentNotFoundAction'),
5474
]);
5575
}
5676

5777
try {
5878
const targetOrg = flags['target-org'];
5979
const conn = targetOrg.getConnection(flags['api-version']);
6080
// Call Agent.compileAfScript() API
61-
await Agent.compileAfScript(conn, readFileSync(join(authoringBundleDir, `${flags['api-name']}.agent`), 'utf8'));
81+
await Agent.compileAfScript(conn, readFileSync(join(authoringBundleDir, `${!apiName}.agent`), 'utf8'));
6282
this.logSuccess('Successfully compiled');
6383
return {
6484
success: true,

test/nuts/agent.generate.authoring-bundle.nut.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,18 @@ describe.skip('agent generate authoring-bundle NUTs', () => {
6060
const result = execCmd<AgentGenerateAuthoringBundleResult>(command, { ensureExitCode: 0 }).jsonOutput?.result;
6161

6262
expect(result).to.be.ok;
63-
expect(result?.afScriptPath).to.be.ok;
63+
expect(result?.agentPath).to.be.ok;
6464
expect(result?.metaXmlPath).to.be.ok;
6565
expect(result?.outputDir).to.be.ok;
6666

6767
// Verify files exist
68-
expect(existsSync(result!.afScriptPath)).to.be.true;
68+
expect(existsSync(result!.agentPath)).to.be.true;
6969
expect(existsSync(result!.metaXmlPath)).to.be.true;
7070

7171
// Verify file contents
72-
const afScript = readFileSync(result!.afScriptPath, 'utf8');
72+
const agent = readFileSync(result!.agentPath, 'utf8');
7373
const metaXml = readFileSync(result!.metaXmlPath, 'utf8');
74-
expect(afScript).to.be.ok;
74+
expect(agent).to.be.ok;
7575
expect(metaXml).to.include('<aiAuthoringBundle>');
7676
expect(metaXml).to.include(bundleName);
7777
});

0 commit comments

Comments
 (0)