Skip to content

Commit 0014c3c

Browse files
committed
feat(cap): add list, tasks, and pull commands with improved UX
- cap list: export and parse commerce_feature_states for installed features - cap tasks: show config tasks with clickable BM links - cap pull: download and extract app source packages from instance or GitHub - Standardize --site-id flag across all cap commands (--site as alias) - cap uninstall: auto-resolve domain from feature state (drop --domain) - cap install: keep archive by default, upload to Impex/commerce-apps/ - Fix sites API select query (*) -> (**) and null XML parse handling - Remove stub fixture fallback from list operation - Export all CAP operations and types from SDK main index - Update CLI docs, skill, and add changeset
1 parent 7a0cb3f commit 0014c3c

14 files changed

Lines changed: 764 additions & 118 deletions

File tree

.changeset/cap-support-commands.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@salesforce/b2c-cli': minor
3+
'@salesforce/b2c-tooling-sdk': minor
4+
'@salesforce/b2c-dx-docs': patch
5+
---
6+
7+
Add `cap list`, `cap tasks`, and `cap pull` commands for managing installed Commerce Apps
8+
9+
- `cap list` exports and parses `commerce_feature_states` to show installed features with type, source, status, and version
10+
- `cap tasks` displays configuration tasks for an installed app with clickable Business Manager links
11+
- `cap pull` downloads and extracts installed app source packages for cartridge deployment or Storefront Next development
12+
- Standardize all cap commands to use `--site-id` flag (with `--site` as alias)
13+
- `cap uninstall` no longer requires `--domain` — looks it up automatically from the feature state
14+
- `cap install` now keeps the archive on the instance by default (use `--clean-archive` to remove)

docs/cli/cap.md

Lines changed: 154 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
---
2-
description: Commands for validating, packaging, installing, and uninstalling Commerce App Packages (CAPs).
2+
description: Commands for validating, packaging, installing, uninstalling, and listing Commerce App Packages (CAPs) and commerce features.
33
---
44

55
# Commerce App (CAP) Commands
66

7-
Commands for managing Commerce App Packages (CAPs) — the standard format for distributing B2C Commerce integrations.
7+
Commands for managing Commerce App Packages (CAPs) — the standard format for distributing B2C Commerce integrations — and listing commerce features installed on an instance.
88

99
## Overview
1010

1111
A Commerce App Package bundles cartridges, IMPEX data, and Storefront Next extensions into a single installable unit. See the [Commerce Apps guide](/guide/commerce-apps) for full workflow details.
1212

13+
The `cap list` and `cap tasks` commands work with the broader commerce feature state system, which tracks all installed features including ISV apps, native apps, native features, and custom features.
14+
1315
## Authentication
1416

15-
Install and uninstall commands require OAuth authentication with OCAPI permissions and WebDAV access.
17+
Install, uninstall, list, and tasks commands require OAuth authentication with OCAPI permissions and WebDAV access.
1618

1719
### Required OCAPI Permissions
1820

1921
Configure these resources in Business Manager under **Administration** > **Site Development** > **Open Commerce API Settings**:
2022

2123
| Resource | Methods | Commands |
2224
|----------|---------|----------|
23-
| `/jobs/*/executions` | POST | `cap install`, `cap uninstall` |
24-
| `/jobs/*/executions/*` | GET | `cap install`, `cap uninstall` |
25+
| `/jobs/*/executions` | POST | `cap install`, `cap uninstall`, `cap list`, `cap tasks` |
26+
| `/jobs/*/executions/*` | GET | `cap install`, `cap uninstall`, `cap list`, `cap tasks` |
27+
| `/sites` | GET | `cap list` (when no `--site-id` specified) |
2528

2629
### WebDAV Access
2730

28-
The `cap install` command uploads the CAP zip to WebDAV (`Temp/`) before triggering the install job.
31+
The `cap install` command uploads the CAP zip to WebDAV (`Impex/commerce-apps/`) before triggering the install job. The `cap list`, `cap tasks`, and `cap uninstall` commands download site archive exports via WebDAV.
2932

3033
---
3134

@@ -119,7 +122,7 @@ b2c cap package ./commerce-avalara-tax-app-v0.2.5
119122
b2c cap package ./commerce-avalara-tax-app-v0.2.5 --output ./dist
120123

121124
# Package with explicit zip filename
122-
b2c cap package ./commerce-avalara-tax-app-v0.2.5 --output ./dist/my-tax-app.zip
125+
b2c cap package ./commerce-avalara-tax-app-v0.2.5 --output ./dist/my-app.zip
123126
```
124127

125128
---
@@ -131,7 +134,7 @@ Install a Commerce App Package on a B2C Commerce instance.
131134
### Usage
132135

133136
```bash
134-
b2c cap install PATH --site SITE_ID
137+
b2c cap install PATH --site-id SITE_ID
135138
```
136139

137140
### Arguments
@@ -144,8 +147,8 @@ b2c cap install PATH --site SITE_ID
144147

145148
| Flag | Short | Description |
146149
|------|-------|-------------|
147-
| `--site SITE_ID` | `-s` | **Required.** Site ID to install the app on |
148-
| `--keep-archive` | `-k` | Keep the uploaded zip on the instance after install |
150+
| `--site-id SITE_ID` | `-s` | **Required.** Site ID to install the app on |
151+
| `--clean-archive` | | Delete the uploaded zip from the instance after install |
149152
| `--timeout SECONDS` | `-t` | Timeout in seconds (default: no timeout) |
150153
| `--skip-validate` | | Skip CAP structure validation before install |
151154
| `--json` | | Output result as JSON |
@@ -154,37 +157,37 @@ b2c cap install PATH --site SITE_ID
154157

155158
1. Validates the CAP structure (unless `--skip-validate`)
156159
2. Packages the directory into a zip if a directory is provided
157-
3. Uploads the zip to WebDAV at `Temp/{id}-v{version}.zip`
160+
3. Uploads the zip to WebDAV at `Impex/commerce-apps/{id}-v{version}.zip`
158161
4. Executes the `sfcc-install-commerce-app` system job
159162
5. Waits for job completion
160-
6. Removes the uploaded zip (unless `--keep-archive`)
163+
6. Archive is kept on the instance by default (use `--clean-archive` to remove)
161164

162165
### Examples
163166

164167
```bash
165168
# Install from a local directory
166-
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site RefArch
169+
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site-id RefArch
167170

168171
# Install from a zip
169-
b2c cap install ./commerce-avalara-tax-app-v0.2.5.zip --site RefArch
172+
b2c cap install ./commerce-avalara-tax-app-v0.2.5.zip --site-id RefArch
170173

171174
# Install without running validation first
172-
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site RefArch --skip-validate
175+
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site-id RefArch --skip-validate
173176

174-
# Keep the uploaded archive for debugging
175-
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site RefArch --keep-archive
177+
# Remove the uploaded archive after install
178+
b2c cap install ./commerce-avalara-tax-app-v0.2.5 --site-id RefArch --clean-archive
176179
```
177180

178181
---
179182

180183
## b2c cap uninstall
181184

182-
Uninstall a Commerce App from a B2C Commerce instance.
185+
Uninstall a Commerce App from a B2C Commerce instance. Looks up the app's domain automatically from the commerce feature state.
183186

184187
### Usage
185188

186189
```bash
187-
b2c cap uninstall APP_NAME --domain DOMAIN --site SITE_ID
190+
b2c cap uninstall APP_NAME --site-id SITE_ID
188191
```
189192

190193
### Arguments
@@ -197,20 +200,148 @@ b2c cap uninstall APP_NAME --domain DOMAIN --site SITE_ID
197200

198201
| Flag | Short | Description |
199202
|------|-------|-------------|
200-
| `--domain DOMAIN` | `-d` | **Required.** Commerce app domain (e.g. `tax`, `shipping`, `fraud`) |
201-
| `--site SITE_ID` | `-s` | **Required.** Site ID to uninstall the app from |
203+
| `--site-id SITE_ID` | `-s` | **Required.** Site ID to uninstall the app from |
202204
| `--timeout SECONDS` | `-t` | Timeout in seconds (default: no timeout) |
203205
| `--json` | | Output result as JSON |
204206

205207
### Examples
206208

207209
```bash
208210
# Uninstall Avalara Tax from a site
209-
b2c cap uninstall avalara-tax --domain tax --site RefArch
211+
b2c cap uninstall avalara-tax --site-id RefArch
210212
```
211213

212214
---
213215

214216
## b2c cap list
215217

216-
> **Not yet implemented.** Listing installed Commerce Apps will be available in a future release.
218+
List commerce features installed on a B2C Commerce instance. Exports the `commerce_feature_states` data unit from each site and parses the results.
219+
220+
### Usage
221+
222+
```bash
223+
b2c cap list [--site-id SITE_IDS]
224+
```
225+
226+
### Flags
227+
228+
| Flag | Short | Description |
229+
|------|-------|-------------|
230+
| `--site-id SITE_IDS` | `-s` | Site IDs to query (comma-separated). If omitted, queries all sites. |
231+
| `--timeout SECONDS` | `-t` | Timeout in seconds (default: no timeout) |
232+
| `--local` | `-l` | List locally detected Commerce App Packages (no instance required) |
233+
| `--json` | | Output result as JSON |
234+
235+
### Table Columns
236+
237+
| Column | Description |
238+
|--------|-------------|
239+
| Site ID | Site the feature is installed on (includes `Sites-` prefix) |
240+
| Name | Feature name (e.g. `avalara-tax`) |
241+
| Type | `ISV_APP`, `NATIVE_APP`, `NATIVE_FEATURE`, or `CUSTOM_FEATURE` |
242+
| Source | `CUSTOM` (uploaded via WebDAV) or `REGISTRY` (from App Registry) |
243+
| Install Status | e.g. `INSTALLED` |
244+
| Config Status | e.g. `NOT_CONFIGURED`, `CONFIGURED` |
245+
| Version | Feature version if available |
246+
| Installed At | Installation timestamp |
247+
248+
### JSON Output
249+
250+
With `--json`, returns the full feature state including `configTasks` (parsed JSON array of configuration steps) and `installationMetadata` (parsed JSON with job details, cartridge mappings, and IMPEX uninstall data).
251+
252+
### Examples
253+
254+
```bash
255+
# List all installed features across all sites
256+
b2c cap list
257+
258+
# List features for specific sites
259+
b2c cap list --site-id RefArch,SiteGenesis
260+
261+
# Machine-readable output with full details
262+
b2c cap list --json
263+
264+
# List locally detected CAP directories
265+
b2c cap list --local
266+
```
267+
268+
---
269+
270+
## b2c cap tasks
271+
272+
List configuration tasks for an installed Commerce App, with clickable links to Business Manager pages.
273+
274+
### Usage
275+
276+
```bash
277+
b2c cap tasks APP_NAME --site-id SITE_ID
278+
```
279+
280+
### Arguments
281+
282+
| Argument | Description |
283+
|----------|-------------|
284+
| `APP_NAME` | Commerce App feature name (e.g. `avalara-tax`) |
285+
286+
### Flags
287+
288+
| Flag | Short | Description |
289+
|------|-------|-------------|
290+
| `--site-id SITE_ID` | `-s` | **Required.** Site ID to query |
291+
| `--timeout SECONDS` | `-t` | Timeout in seconds (default: no timeout) |
292+
| `--json` | | Output result as JSON |
293+
294+
### Examples
295+
296+
```bash
297+
# Show configuration tasks for an installed app
298+
b2c cap tasks avalara-tax --site-id RefArch
299+
300+
# Get tasks as JSON (includes full feature state)
301+
b2c cap tasks avalara-tax --site-id RefArch --json
302+
```
303+
304+
---
305+
306+
## b2c cap pull
307+
308+
Pull installed Commerce App source packages from a B2C Commerce instance. By default, pulls all registry-sourced apps. Optionally specify a single app by name.
309+
310+
Useful for deploying cartridges to a code version or working with Storefront Next extensions locally.
311+
312+
### Usage
313+
314+
```bash
315+
b2c cap pull [APP_NAME] [--site-id SITE_ID] [--output DIR]
316+
```
317+
318+
### Arguments
319+
320+
| Argument | Description |
321+
|----------|-------------|
322+
| `APP_NAME` | *(optional)* Commerce App feature name to pull (e.g. `avalara-tax`). If omitted, pulls all registry apps. |
323+
324+
### Flags
325+
326+
| Flag | Short | Description |
327+
|------|-------|-------------|
328+
| `--site-id SITE_ID` | `-s` | Site ID to query for installed apps. If omitted, queries all sites. |
329+
| `--output DIR` | `-o` | Output directory (default: `./commerce-apps`) |
330+
| `--timeout SECONDS` | `-t` | Timeout in seconds (default: no timeout) |
331+
| `--json` | | Output result as JSON |
332+
333+
### Examples
334+
335+
```bash
336+
# Pull all registry apps to ./commerce-apps
337+
b2c cap pull
338+
339+
# Pull a specific app by name
340+
b2c cap pull avalara-tax
341+
342+
# Pull to a custom output directory
343+
b2c cap pull --output ./my-apps
344+
345+
# Pull apps installed on a specific site
346+
b2c cap pull --site-id RefArch
347+
```

packages/b2c-cli/src/commands/cap/install.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export default class CapInstall extends JobCommand<typeof CapInstall> {
3636

3737
static flags = {
3838
...JobCommand.baseFlags,
39-
site: Flags.string({
39+
'site-id': Flags.string({
4040
char: 's',
4141
description: 'Site ID to install the Commerce App on',
4242
required: true,
43+
aliases: ['site'],
4344
}),
44-
'keep-archive': Flags.boolean({
45-
char: 'k',
46-
description: 'Keep the uploaded zip on the instance after install',
45+
'clean-archive': Flags.boolean({
46+
description: 'Delete the uploaded zip from the instance after install',
4747
default: false,
4848
}),
4949
timeout: Flags.integer({
@@ -66,7 +66,7 @@ export default class CapInstall extends JobCommand<typeof CapInstall> {
6666
this.requireWebDavCredentials();
6767

6868
const {path} = this.args;
69-
const {site, 'keep-archive': keepArchive, timeout, 'skip-validate': skipValidate} = this.flags;
69+
const {'site-id': site, 'clean-archive': cleanArchive, timeout, 'skip-validate': skipValidate} = this.flags;
7070
const hostname = this.resolvedConfig.values.hostname!;
7171

7272
// Validate first unless skipped
@@ -117,16 +117,15 @@ export default class CapInstall extends JobCommand<typeof CapInstall> {
117117
try {
118118
const result = await this.operations.commerceAppInstall(this.instance, path, {
119119
siteId: site,
120-
keepArchive,
120+
keepArchive: !cleanArchive,
121121
waitOptions: {
122-
timeout: timeout ? timeout * 1000 : undefined,
123-
onProgress: (exec, elapsed) => {
122+
timeoutSeconds: timeout || undefined,
123+
onPoll: (info) => {
124124
if (!this.jsonEnabled()) {
125-
const elapsedSec = Math.floor(elapsed / 1000);
126125
this.log(
127126
t('commands.cap.install.progress', ' Status: {{status}} ({{elapsed}}s elapsed)', {
128-
status: exec.execution_status,
129-
elapsed: elapsedSec.toString(),
127+
status: info.status,
128+
elapsed: Math.floor(info.elapsedSeconds).toString(),
130129
}),
131130
);
132131
}

0 commit comments

Comments
 (0)