Skip to content

Commit 39501fb

Browse files
Merge pull request #874 from salesforcecli/sh/agent-project-template
feat: add support for creating agent project templates @W-21522177
2 parents 4ba1544 + b83b10c commit 39501fb

5 files changed

Lines changed: 71 additions & 7 deletions

File tree

messages/project.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ The analytics template provides similar files and the force-app/main/default/wav
6060

6161
The reactb2e and reactb2x templates provide React-based project scaffolding for B2E and B2X web application use cases.
6262

63+
The agent template provides project scaffolding for building Agentforce agents and includes a sample agent called Local Info Agent.
64+
6365
# flags.namespace.summary
6466

6567
Namespace associated with this project and any connected scratch orgs.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dependencies": {
1010
"@salesforce/core": "^8.27.0",
1111
"@salesforce/sf-plugins-core": "^12",
12-
"@salesforce/templates": "^66.4.1"
12+
"@salesforce/templates": "^66.5.0"
1313
},
1414
"devDependencies": {
1515
"@oclif/plugin-command-snapshot": "^5.3.12",

src/commands/template/generate/project/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default class Project extends SfCommand<CreateOutput> {
3333
summary: messages.getMessage('flags.template.summary'),
3434
description: messages.getMessage('flags.template.description'),
3535
default: 'standard',
36-
options: ['standard', 'empty', 'analytics', 'reactb2e', 'reactb2x'] as const,
36+
options: ['standard', 'empty', 'analytics', 'reactb2e', 'reactb2x', 'agent'] as const,
3737
})(),
3838
'output-dir': outputDirFlag,
3939
namespace: Flags.string({

test/commands/template/generate/project/index.nut.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,19 @@ const standardfolderarray = [
2626
'triggers',
2727
];
2828
const filestocopy = ['.forceignore', '.gitignore', '.prettierignore', '.prettierrc', 'jest.config.js', 'package.json'];
29+
const agentfilestocopy = filestocopy.filter((file) => file !== 'jest.config.js');
2930
const emptyfolderarray = ['aura', 'lwc'];
3031
const analyticsfolderarray = ['aura', 'classes', 'lwc', 'waveTemplates'];
32+
const agentfolderarray = [
33+
'aiAuthoringBundles',
34+
'bots',
35+
'classes',
36+
'flows',
37+
'genAiPlannerBundles',
38+
'genAiPromptTemplates',
39+
'permissionsetgroups',
40+
'permissionsets',
41+
];
3142
const huskyhookarray = ['pre-commit'];
3243
const vscodearray = ['extensions', 'launch', 'settings'];
3344

@@ -275,10 +286,61 @@ describe('template generate project:', () => {
275286
assert.file([webappMetaPath]);
276287
assert.fileContent(webappMetaPath, alphanumericName);
277288
});
289+
290+
it('should create project with agent template', () => {
291+
execCmd('template generate project --projectname agent1 --template agent --manifest', {
292+
ensureExitCode: 0,
293+
});
294+
const projectDir = path.join(session.project.dir, 'agent1');
295+
assert.file([path.join(projectDir, 'sfdx-project.json')]);
296+
assert.fileContent(path.join(projectDir, 'sfdx-project.json'), '"path": "force-app",');
297+
assert.fileContent(path.join(projectDir, 'sfdx-project.json'), 'sourceApiVersion');
298+
assert.file([path.join(projectDir, 'config', 'project-scratch-def.json')]);
299+
assert.fileContent(path.join(projectDir, 'config', 'project-scratch-def.json'), 'einsteinGptSettings');
300+
assert.file([path.join(projectDir, 'README.md')]);
301+
assert.fileContent(path.join(projectDir, 'README.md'), '# Agentforce Project');
302+
assert.file([path.join(projectDir, 'manifest', 'package.xml')]);
303+
assert.fileContent(path.join(projectDir, 'manifest', 'package.xml'), '<name>AiAuthoringBundle</name>');
304+
305+
const srcDir = path.join(projectDir, 'force-app', 'main', 'default');
306+
for (const folder of agentfolderarray) {
307+
const dir = path.join(srcDir, folder);
308+
assert(fs.existsSync(dir), `Missing ${dir}`);
309+
}
310+
311+
assert.file([
312+
path.join(srcDir, 'aiAuthoringBundles', 'Local_Info_Agent', 'Local_Info_Agent.bundle-meta.xml'),
313+
path.join(srcDir, 'aiAuthoringBundles', 'Local_Info_Agent', 'Local_Info_Agent.agent'),
314+
path.join(srcDir, 'classes', 'CheckWeather.cls'),
315+
path.join(srcDir, 'classes', 'CheckWeather.cls-meta.xml'),
316+
path.join(srcDir, 'classes', 'CurrentDate.cls'),
317+
path.join(srcDir, 'classes', 'CurrentDate.cls-meta.xml'),
318+
path.join(srcDir, 'classes', 'CurrentDateTest.cls'),
319+
path.join(srcDir, 'classes', 'CurrentDateTest.cls-meta.xml'),
320+
path.join(srcDir, 'classes', 'WeatherService.cls'),
321+
path.join(srcDir, 'classes', 'WeatherService.cls-meta.xml'),
322+
path.join(srcDir, 'classes', 'WeatherServiceTest.cls'),
323+
path.join(srcDir, 'classes', 'WeatherServiceTest.cls-meta.xml'),
324+
path.join(srcDir, 'flows', 'Get_Resort_Hours.flow-meta.xml'),
325+
path.join(srcDir, 'genAiPromptTemplates', 'Get_Event_Info.genAiPromptTemplate-meta.xml'),
326+
path.join(srcDir, 'permissionsets', 'Resort_Agent.permissionset-meta.xml'),
327+
path.join(srcDir, 'permissionsets', 'Resort_Admin.permissionset-meta.xml'),
328+
path.join(srcDir, 'permissionsetgroups', 'AFDX_Agent_Perms.permissionsetgroup-meta.xml'),
329+
path.join(srcDir, 'permissionsetgroups', 'AFDX_User_Perms.permissionsetgroup-meta.xml'),
330+
]);
331+
332+
for (const file of vscodearray) {
333+
assert.file(path.join(projectDir, '.vscode', `${file}.json`));
334+
}
335+
336+
for (const file of agentfilestocopy) {
337+
assert.file([path.join(projectDir, file)]);
338+
}
339+
});
278340
});
279341

280342
describe('project creation failures', () => {
281-
it('should throw invalid template name error', () => {
343+
it('should throw missing required flag error', () => {
282344
const stderr = execCmd('template generate project').shellOutput.stderr;
283345
expect(stderr).to.contain('Missing required flag');
284346
});

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,10 +1624,10 @@
16241624
cli-progress "^3.12.0"
16251625
terminal-link "^3.0.0"
16261626

1627-
"@salesforce/templates@^66.4.1":
1628-
version "66.4.1"
1629-
resolved "https://registry.yarnpkg.com/@salesforce/templates/-/templates-66.4.1.tgz#0b7470efd33935333c76e102b69d602e95717304"
1630-
integrity sha512-7ImXvg80wOQojq1Bn3PJYuMmkBB9ypgMR4usP9rst+aX43ka/fA/4jIHcThayRELkem0e2C56ougkjKr8AusyQ==
1627+
"@salesforce/templates@^66.5.0":
1628+
version "66.5.0"
1629+
resolved "https://registry.yarnpkg.com/@salesforce/templates/-/templates-66.5.0.tgz#77721c2b040b246c50c088d056a93909a8506dd8"
1630+
integrity sha512-lKnXEepqB775+hkZ0erZ+g+cLB2VA7sAirFnPjN/3PJJ/3sC9lSMB8DQfxCJOOinTFHh9fPhNfeFT/zPHTXppQ==
16311631
dependencies:
16321632
"@salesforce/kit" "^3.2.4"
16331633
ejs "^3.1.10"

0 commit comments

Comments
 (0)