Skip to content

Commit 1dc1ee5

Browse files
authored
feat: support CAP skills plugin from commerce-apps repo (#373)
Introduce a SkillSource registry to decouple skill download strategy from installation. Adds cap-dev skill set backed by the commerce-apps repo using GitHub Contents API with sparse git checkout fallback. - Widen SkillSet to include 'cap-dev' - Add SkillSourceConfig interface and source registry (sources.ts) - Refactor github.ts into dispatcher: release-artifact vs repo-contents - Replace regex frontmatter parser with js-yaml for block scalar support - Add cap-dev to Claude Code and Codex marketplace via git-subdir - Add parser and sources unit tests
1 parent 016b3e9 commit 1dc1ee5

13 files changed

Lines changed: 568 additions & 145 deletions

File tree

.agents/plugins/marketplace.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@
2727
"authentication": "ON_INSTALL"
2828
},
2929
"category": "Productivity"
30+
},
31+
{
32+
"name": "cap-dev",
33+
"description": "Skills for scaffolding, packaging, validating, and submitting Commerce App Packages (CAPs) for Salesforce Commerce Cloud.",
34+
"source": {
35+
"source": "git-subdir",
36+
"url": "SalesforceCommerceCloud/commerce-apps",
37+
"path": ".claude",
38+
"ref": "feature/codex-copilot-plugin-docs"
39+
},
40+
"interface": {
41+
"displayName": "Commerce Apps Dev",
42+
"shortDescription": "Scaffold, validate, package, and submit Commerce App Packages.",
43+
"longDescription": "Skills for building Salesforce Commerce Cloud app packages — scaffold new apps (UI-only, backend-only, or fullstack), generate IMPEX configurations for services, custom objects, and site preferences, validate packages against registry requirements, and submit pull requests to the commerce-apps registry."
44+
},
45+
"policy": {
46+
"installation": "AVAILABLE",
47+
"authentication": "ON_INSTALL"
48+
},
49+
"category": "Productivity"
3050
}
3151
]
3252
}

.changeset/cap-plugin-support.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@salesforce/b2c-cli': minor
3+
'@salesforce/b2c-tooling-sdk': minor
4+
---
5+
6+
Add support for Commerce Apps (CAP) development skills via `b2c setup skills cap-dev`. Introduces a skill source registry to support external skill repositories alongside existing release-artifact sources.

.claude-plugin/marketplace.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,36 @@
4141
"source": "./plugins/b2c-dx-mcp",
4242
"category": "productivity",
4343
"strict": false
44+
},
45+
{
46+
"name": "cap-dev",
47+
"description": "Skills for scaffolding, packaging, validating, and submitting Commerce App Packages (CAPs) for Salesforce Commerce Cloud.",
48+
"author": {
49+
"name": "Salesforce"
50+
},
51+
"homepage": "https://github.com/SalesforceCommerceCloud/commerce-apps",
52+
"repository": "https://github.com/SalesforceCommerceCloud/commerce-apps",
53+
"license": "Apache-2.0",
54+
"source": {
55+
"source": "git-subdir",
56+
"url": "SalesforceCommerceCloud/commerce-apps",
57+
"path": ".claude",
58+
"ref": "feature/codex-copilot-plugin-docs"
59+
},
60+
"category": "productivity",
61+
"keywords": [
62+
"salesforce",
63+
"commerce-apps",
64+
"commerce-cloud",
65+
"cap",
66+
"impex"
67+
],
68+
"interface": {
69+
"displayName": "Commerce Apps Dev",
70+
"shortDescription": "Scaffold, validate, package, and submit Commerce App Packages.",
71+
"longDescription": "Skills for building Salesforce Commerce Cloud app packages — scaffold new apps (UI-only, backend-only, or fullstack), generate IMPEX configurations for services, custom objects, and site preferences, validate packages against registry requirements, and submit pull requests to the commerce-apps registry."
72+
},
73+
"strict": false
4474
}
4575
]
4676
}

packages/b2c-cli/src/commands/setup/skills.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
type SkillMetadata,
1313
type InstallSkillsResult,
1414
ALL_IDE_TYPES,
15+
ALL_SKILL_SETS,
16+
SKILL_SOURCES,
1517
detectInstalledIdes,
1618
downloadSkillsArtifact,
1719
scanSkills,
@@ -60,8 +62,8 @@ interface SetupSkillsResponse {
6062
export default class SetupSkills extends BaseCommand<typeof SetupSkills> {
6163
static args = {
6264
skillset: Args.string({
63-
description: 'Skill set to install: b2c or b2c-cli',
64-
options: ['b2c', 'b2c-cli'],
65+
description: 'Skill set to install: b2c, b2c-cli, or cap-dev',
66+
options: ALL_SKILL_SETS,
6567
}),
6668
};
6769

@@ -75,6 +77,7 @@ export default class SetupSkills extends BaseCommand<typeof SetupSkills> {
7577
static examples = [
7678
'<%= config.bin %> <%= command.id %> b2c',
7779
'<%= config.bin %> <%= command.id %> b2c-cli --ide cursor --global',
80+
'<%= config.bin %> <%= command.id %> cap-dev --ide claude-code --global',
7881
'<%= config.bin %> <%= command.id %> b2c --list',
7982
'<%= config.bin %> <%= command.id %> b2c-cli --skill b2c-code --skill b2c-webdav --ide cursor',
8083
'<%= config.bin %> <%= command.id %> b2c --global --update --force',
@@ -130,16 +133,16 @@ export default class SetupSkills extends BaseCommand<typeof SetupSkills> {
130133
this.error(
131134
t(
132135
'commands.setup.skills.skillsetRequired',
133-
'Skillset argument required in non-interactive mode. Specify b2c or b2c-cli.',
136+
'Skillset argument required in non-interactive mode. Specify b2c, b2c-cli, or cap-dev.',
134137
),
135138
);
136139
} else {
137140
skillsets = await checkbox({
138141
message: t('commands.setup.skills.selectSkillset', 'Select skill set(s) to install:'),
139-
choices: [
140-
{name: 'b2c - B2C Commerce development patterns', value: 'b2c' as SkillSet},
141-
{name: 'b2c-cli - B2C CLI commands and operations', value: 'b2c-cli' as SkillSet},
142-
],
142+
choices: ALL_SKILL_SETS.map((id) => ({
143+
name: `${id} - ${SKILL_SOURCES[id].displayName}`,
144+
value: id,
145+
})),
143146
});
144147
if (skillsets.length === 0) {
145148
ux.stdout(t('commands.setup.skills.noSkillsetsSelected', 'No skill sets selected.'));
@@ -148,11 +151,23 @@ export default class SetupSkills extends BaseCommand<typeof SetupSkills> {
148151
}
149152

150153
// Download and scan skills
151-
this.log(
152-
t('commands.setup.skills.downloading', 'Downloading skills from release {{version}}...', {
153-
version: this.flags.version || 'latest',
154-
}),
155-
);
154+
const hasReleaseArtifacts = skillsets.some((s) => SKILL_SOURCES[s].type === 'release-artifact');
155+
const hasRepoContents = skillsets.some((s) => SKILL_SOURCES[s].type === 'repo-contents');
156+
if (hasReleaseArtifacts && hasRepoContents) {
157+
this.log(t('commands.setup.skills.downloading', 'Downloading skills...'));
158+
} else if (hasRepoContents) {
159+
this.log(
160+
t('commands.setup.skills.downloadingRepo', 'Downloading skills from repository ({{ref}})...', {
161+
ref: this.flags.version || 'main',
162+
}),
163+
);
164+
} else {
165+
this.log(
166+
t('commands.setup.skills.downloadingRelease', 'Downloading skills from release {{version}}...', {
167+
version: this.flags.version || 'latest',
168+
}),
169+
);
170+
}
156171

157172
// Download skills for all skillsets in parallel
158173
const downloadResults = await Promise.all(

packages/b2c-tooling-sdk/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@
427427
"@salesforce/dev-config": "catalog:",
428428
"@types/chai": "catalog:",
429429
"@types/ejs": "^3.1.5",
430+
"@types/js-yaml": "4.0.9",
430431
"@types/mocha": "catalog:",
431432
"@types/node": "catalog:",
432433
"@types/sinon": "catalog:",
@@ -468,6 +469,7 @@
468469
"fuse.js": "7.1.0",
469470
"glob": "catalog:",
470471
"i18next": "25.7.4",
472+
"js-yaml": "4.1.1",
471473
"jsonschema": "catalog:",
472474
"jszip": "3.10.1",
473475
"minimatch": "10.1.1",

0 commit comments

Comments
 (0)