Skip to content

Commit 2541254

Browse files
Merge pull request #233 from salesforcecli/er/updateSearchLogic
Er/update search logic
2 parents ac6b5d0 + 03f82de commit 2541254

File tree

11 files changed

+127
-103
lines changed

11 files changed

+127
-103
lines changed

messages/agent.publish.authoring-bundle.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Publish an Agent Authoring Bundle as a new agent
44

55
# description
66

7-
Publishes an Agent Authoring Bundle by compiling the AF script and creating a new agent in your org.
7+
Publishes an Agent Authoring Bundle by compiling the .agent file and creating a new agent in your org.
88

99
# examples
1010

@@ -13,7 +13,7 @@ Publishes an Agent Authoring Bundle by compiling the AF script and creating a ne
1313

1414
# flags.api-name.summary
1515

16-
API name of the Agent Authoring Bundle to publish
16+
API name of the Agent Authoring Bundle to publish.
1717

1818
# flags.api-name.prompt
1919

@@ -38,7 +38,7 @@ Failed to publish agent with the following errors:
3838

3939
# error.agentNotFound
4040

41-
Could not find an .agent file with API name '%s' in the project.
41+
Could not find a .bundle-meta.xml file with API name '%s' in the project.
4242

4343
# error.agentNotFoundAction
4444

messages/agent.test.run.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ By default, this command outputs test results in human-readable tables for each
1414

1515
API name of the agent test to run; corresponds to the name of the AiEvaluationDefinition metadata component that implements the agent test.
1616

17+
# flags.api-name.prompt
18+
19+
API name of the agent test to run
20+
1721
# flags.wait.summary
1822

1923
Number of minutes to wait for the command to complete and display results to the terminal window.

messages/agent.validate.authoring-bundle.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Validate an Agent Authoring Bundle
44

55
# description
66

7-
Validates an Agent Authoring Bundle by compiling the AF script and checking for errors.
7+
Validates an Agent Authoring Bundle by compiling the .agent file and checking for errors.
88

99
# examples
1010

@@ -13,7 +13,7 @@ Validates an Agent Authoring Bundle by compiling the AF script and checking for
1313

1414
# flags.api-name.summary
1515

16-
Path to the Agent Authoring Bundle to validate
16+
API name of the Agent Authoring Bundle to validate.
1717

1818
# flags.api-name.prompt
1919

@@ -29,12 +29,12 @@ Invalid bundle path. Please provide a valid path to an Agent Authoring Bundle.
2929

3030
# error.compilationFailed
3131

32-
AF Script compilation failed with the following errors:
32+
Agent compilation failed with the following errors:
3333
%s
3434

3535
# error.agentNotFound
3636

37-
Could not find an .agent file with API name '%s' in the project.
37+
Could not find a .bundle-meta.xml file with API name '%s' in the project.
3838

3939
# error.agentNotFoundAction
4040

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"@inquirer/prompts": "^7.8.6",
1010
"@oclif/core": "^4",
1111
"@oclif/multi-stage-output": "^0.8.23",
12-
"@salesforce/agents": "^0.17.11",
12+
"@salesforce/agents": "^0.18.0",
1313
"@salesforce/core": "^8.23.1",
1414
"@salesforce/kit": "^3.2.3",
1515
"@salesforce/sf-plugins-core": "^12.2.4",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export default class AgentGenerateAuthoringBundle extends SfCommand<AgentGenerat
134134
// Write Agent file
135135
const conn = targetOrg.getConnection(flags['api-version']);
136136
const specContents = YAML.parse(readFileSync(spec, 'utf8')) as AgentJobSpec;
137-
const agent = await Agent.createAfScript(conn, specContents);
137+
const agent = await Agent.createAgent(conn, specContents);
138138
// Create output directory if it doesn't exist
139139
mkdirSync(targetOutputDir, { recursive: true });
140140
writeFileSync(agentPath, agent);

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +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, promptForFileByExtensions } from '../../../flags.js';
25+
import { FlaggablePrompt, promptForAgentFiles } from '../../../flags.js';
2626

2727
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2828
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.publish.authoring-bundle');
@@ -70,10 +70,11 @@ export default class AgentPublishAuthoringBundle extends SfCommand<AgentPublishA
7070
// If api-name is not provided, prompt user to select an .agent file from the project and extract the API name from it
7171
const apiName =
7272
flags['api-name'] ??
73-
(await promptForFileByExtensions(AgentPublishAuthoringBundle.FLAGGABLE_PROMPTS['api-name'], ['.agent'], true));
74-
// todo: this eslint warning can be removed once published
75-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
76-
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), apiName);
73+
(await promptForAgentFiles(this.project!, AgentPublishAuthoringBundle.FLAGGABLE_PROMPTS['api-name']));
74+
const authoringBundleDir = findAuthoringBundle(
75+
this.project!.getPackageDirectories().map((dir) => dir.fullPath),
76+
apiName
77+
);
7778

7879
if (!authoringBundleDir) {
7980
throw new SfError(messages.getMessage('error.agentNotFound', [apiName]), 'AgentNotFoundError', [
@@ -101,8 +102,8 @@ export default class AgentPublishAuthoringBundle extends SfCommand<AgentPublishA
101102
const targetOrg = flags['target-org'];
102103
const conn = targetOrg.getConnection(flags['api-version']);
103104

104-
// First compile the AF script to get the Agent JSON
105-
const agentJson = await Agent.compileAfScript(
105+
// First compile the .agent file to get the Agent JSON
106+
const agentJson = await Agent.compileAgent(
106107
conn,
107108
readFileSync(join(authoringBundleDir, `${apiName}.agent`), 'utf8')
108109
);

src/commands/agent/test/run.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const FLAGGABLE_PROMPTS = {
4040
char: 'n',
4141
required: true,
4242
message: messages.getMessage('flags.api-name.summary'),
43+
promptMessage: messages.getMessage('flags.api-name.prompt'),
4344
validate: (d: string): boolean | string => {
4445
if (d.length === 0) {
4546
return true;

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { MultiStageOutput } from '@oclif/multi-stage-output';
2121
import { Agent, findAuthoringBundle } from '@salesforce/agents';
2222
import { Duration, sleep } from '@salesforce/kit';
2323
import { colorize } from '@oclif/core/ux';
24-
import { FlaggablePrompt, promptForFileByExtensions } from '../../../flags.js';
24+
import { FlaggablePrompt, promptForAgentFiles } from '../../../flags.js';
2525

2626
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2727
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.validate.authoring-bundle');
@@ -68,8 +68,11 @@ export default class AgentValidateAuthoringBundle extends SfCommand<AgentValidat
6868
// If api-name is not provided, prompt user to select an .agent file from the project and extract the API name from it
6969
const apiName =
7070
flags['api-name'] ??
71-
(await promptForFileByExtensions(AgentValidateAuthoringBundle.FLAGGABLE_PROMPTS['api-name'], ['.agent'], true));
72-
const authoringBundleDir = findAuthoringBundle(this.project!.getPath(), apiName);
71+
(await promptForAgentFiles(this.project!, AgentValidateAuthoringBundle.FLAGGABLE_PROMPTS['api-name']));
72+
const authoringBundleDir = findAuthoringBundle(
73+
this.project!.getPackageDirectories().map((dir) => dir.fullPath),
74+
apiName
75+
);
7376
if (!authoringBundleDir) {
7477
throw new SfError(messages.getMessage('error.agentNotFound', [apiName]), 'AgentNotFoundError', [
7578
messages.getMessage('error.agentNotFoundAction'),
@@ -100,9 +103,9 @@ export default class AgentValidateAuthoringBundle extends SfCommand<AgentValidat
100103
mso.skipTo('Validating Authoring Bundle');
101104
const targetOrg = flags['target-org'];
102105
const conn = targetOrg.getConnection(flags['api-version']);
103-
// Call Agent.compileAfScript() API
106+
// Call Agent.compileAgent() API
104107
await sleep(Duration.seconds(2));
105-
await Agent.compileAfScript(conn, readFileSync(join(authoringBundleDir, `${apiName}.agent`), 'utf8'));
108+
await Agent.compileAgent(conn, readFileSync(join(authoringBundleDir, `${apiName}.agent`), 'utf8'));
106109
mso.updateData({ status: 'COMPLETED' });
107110
mso.stop('completed');
108111
return {

src/flags.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
*/
1616

1717
import { readdir } from 'node:fs/promises';
18+
import { readdirSync } from 'node:fs';
1819
import { basename, join, relative } from 'node:path';
1920
import { Interfaces } from '@oclif/core';
2021
import { Flags } from '@salesforce/sf-plugins-core';
21-
import { Connection, Messages, SfError } from '@salesforce/core';
22+
import { Connection, Messages, SfError, SfProject } from '@salesforce/core';
2223
import { camelCaseToTitleCase } from '@salesforce/kit';
2324
import { select, input as inquirerInput } from '@inquirer/prompts';
2425
import autocomplete from 'inquirer-autocomplete-standalone';
@@ -102,18 +103,25 @@ export async function getHiddenDirs(projectRoot?: string): Promise<string[]> {
102103
}
103104
}
104105

105-
export async function traverseForFiles(dir: string, suffixes: string[], excludeDirs?: string[]): Promise<string[]> {
106-
const files = await readdir(dir, { withFileTypes: true });
106+
export function traverseForFiles(dir: string, suffixes: string[], excludeDirs?: string[]): string[];
107+
// eslint-disable-next-line @typescript-eslint/unified-signatures
108+
export function traverseForFiles(dirs: string[], suffixes: string[], excludeDirs?: string[]): string[];
109+
110+
export function traverseForFiles(dirOrDirs: string | string[], suffixes: string[], excludeDirs?: string[]): string[] {
111+
const dirs = Array.isArray(dirOrDirs) ? dirOrDirs : [dirOrDirs];
107112
const results: string[] = [];
108113

109-
for (const file of files) {
110-
const fullPath = join(dir, file.name);
114+
for (const dir of dirs) {
115+
const files = readdirSync(dir, { withFileTypes: true });
116+
117+
for (const file of files) {
118+
const fullPath = join(dir, file.name);
111119

112-
if (file.isDirectory() && !excludeDirs?.includes(file.name)) {
113-
// eslint-disable-next-line no-await-in-loop
114-
results.push(...(await traverseForFiles(fullPath, suffixes, excludeDirs)));
115-
} else if (suffixes.some((suffix) => file.name.endsWith(suffix))) {
116-
results.push(fullPath);
120+
if (file.isDirectory() && !excludeDirs?.includes(file.name)) {
121+
results.push(...traverseForFiles(fullPath, suffixes, excludeDirs));
122+
} else if (suffixes.some((suffix) => file.name.endsWith(suffix))) {
123+
results.push(fullPath);
124+
}
117125
}
118126
}
119127

@@ -135,7 +143,7 @@ export const promptForAiEvaluationDefinitionApiName = async (
135143

136144
return Promise.race([
137145
autocomplete({
138-
message: flagDef.message,
146+
message: flagDef.promptMessage ?? flagDef.message,
139147
// eslint-disable-next-line @typescript-eslint/require-await
140148
source: async (input) => {
141149
const arr = aiDefFiles.map((o) => ({ name: o.fullName, value: o.fullName }));
@@ -154,10 +162,12 @@ export const promptForAiEvaluationDefinitionApiName = async (
154162
export const promptForFileByExtensions = async (
155163
flagDef: FlaggablePrompt,
156164
extensions: string[],
157-
fileNameOnly = false
165+
fileNameOnly = false,
166+
dirs?: string[]
158167
): Promise<string> => {
159168
const hiddenDirs = await getHiddenDirs();
160-
const files = await traverseForFiles(process.cwd(), extensions, ['node_modules', ...hiddenDirs]);
169+
const dirsToTraverse = dirs ?? [process.cwd()];
170+
const files = traverseForFiles(dirsToTraverse, extensions, ['node_modules', ...hiddenDirs]);
161171
return autocomplete({
162172
message: flagDef.promptMessage ?? flagDef.message.replace(/\.$/, ''),
163173
// eslint-disable-next-line @typescript-eslint/require-await
@@ -194,6 +204,11 @@ export const promptForFlag = async (flagDef: FlaggablePrompt): Promise<string> =
194204
});
195205
};
196206

207+
export const promptForAgentFiles = (project: SfProject, flagDef: FlaggablePrompt): Promise<string> => {
208+
const dirs = project.getPackageDirectories().map((dir) => dir.fullPath);
209+
return promptForFileByExtensions(flagDef, ['.bundle-meta.xml'], true, dirs);
210+
};
211+
197212
export const validateAgentType = (agentType?: string, required = false): string | undefined => {
198213
if (required && !agentType) {
199214
throw messages.createError('error.invalidAgentType', [agentType]);

test/flags.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('traverseForFiles', () => {
4747
});
4848

4949
it('should find all yaml files when no excludeDirs is provided', async () => {
50-
const results = await traverseForFiles(testDir, ['.yml', '.yaml']);
50+
const results = traverseForFiles(testDir, ['.yml', '.yaml']);
5151
expect(results).to.have.lengthOf(6);
5252
expect(results).to.include(join(testDir, 'file1.yml'));
5353
expect(results).to.include(join(testDir, 'file2.yaml'));
@@ -58,7 +58,7 @@ describe('traverseForFiles', () => {
5858
});
5959

6060
it('should exclude specified directories', async () => {
61-
const results = await traverseForFiles(testDir, ['.yml', '.yaml'], ['node_modules', 'excluded']);
61+
const results = traverseForFiles(testDir, ['.yml', '.yaml'], ['node_modules', 'excluded']);
6262
expect(results).to.have.lengthOf(4);
6363
expect(results).to.include(join(testDir, 'file1.yml'));
6464
expect(results).to.include(join(testDir, 'file2.yaml'));
@@ -69,7 +69,7 @@ describe('traverseForFiles', () => {
6969
});
7070

7171
it('should handle empty excludeDirs array', async () => {
72-
const results = await traverseForFiles(testDir, ['.yml', '.yaml'], []);
72+
const results = traverseForFiles(testDir, ['.yml', '.yaml'], []);
7373
expect(results).to.have.lengthOf(6);
7474
});
7575
});

0 commit comments

Comments
 (0)