Creating new CLI commands and topics for the B2C CLI using oclif. Use when adding a new command, creating a topic, adding flags or arguments, implementing table output, or extending BaseCommand/OAuthCommand/InstanceCommand.
Creating new CLI commands and topics for the B2C CLI using oclif. Use when adding a new command, creating a topic, adding flags or arguments, implementing table output, or extending BaseCommand/OAuthCommand/InstanceCommand.
metadata
{"internal":true}
CLI Command Development
This skill covers creating new CLI commands and topics for the B2C CLI.
Command Organization
Commands live in packages/b2c-cli/src/commands/. The directory structure maps directly to command names:
Keys follow the pattern: commands.<topic>.<command>.<key>
Validation Methods
Base classes provide validation helpers:
// From OAuthCommandthis.requireOAuthCredentials(); // Ensures clientId + clientSecretthis.hasOAuthCredentials(); // Returns boolean// From InstanceCommandthis.requireServer(); // Ensures hostname is setthis.requireCodeVersion(); // Ensures code version is setthis.requireWebDavCredentials(); // Ensures WebDAV auth (Basic or OAuth)// From MrtCommandthis.requireMrtCredentials(); // Ensures MRT API credentials
// Simple error (exits with code 1)this.error('Something went wrong');
// Error with suggestionsthis.error('Config file not found', {
suggestions: ['Run b2c auth login first', 'Check your dw.json file'],
});
// Warning (continues execution)this.warn('Deprecated flag used');
// API errors - use getApiErrorMessage for clean messagesimport {getApiErrorMessage} from'@salesforce/b2c-tooling-sdk';
const {data, error, response} = awaitthis.instance.ocapi.GET('/sites', {...});
if (error) {
this.error(t('commands.topic.cmd.apiError', 'API error: {{message}}', {
message: getApiErrorMessage(error, response),
}));
}
Important: Always destructure response alongside error when making API calls. The getApiErrorMessage utility extracts clean messages from ODS, OCAPI, and SCAPI error patterns, and falls back to HTTP status (e.g., "HTTP 521 Web Server Is Down") for non-JSON responses like HTML error pages.
Command not found after creating file: Ensure the file is in the correct packages/b2c-cli/src/commands/ subdirectory matching the intended command path. Run pnpm --filter @salesforce/b2c-cli run build to regenerate the oclif manifest. For new topics, add the topic to package.json under oclif.topics.
Flag parsing errors: Check that flag names use kebab-case in the static flags definition. The char shorthand must be a single character. If using dependsOn, the referenced flag must exist in the same command's flags.
Missing i18n keys: The t() function falls back to the default string (second argument), so missing keys won't crash at runtime. However, keep key paths consistent with the commands.<topic>.<command>.<key> pattern for future localization.
"requireX" methods not available: Verify the command extends the correct base class. requireServer() is on InstanceCommand, requireOAuthCredentials() is on OAuthCommand, requireMrtCredentials() is on MrtCommand. Check the class hierarchy if a method is missing.
Creating a Command Checklist
Create file at packages/b2c-cli/src/commands/<topic>/<command>.ts
Choose appropriate base class
Define static description, examples, args, flags
Set static enableJsonFlag = true for JSON output support
Implement run() method with proper return type
Add topic to package.json if new
Add i18n keys for all user-facing strings
Update skill in skills/b2c-cli/skills/b2c-<topic>/SKILL.md if exists
Update CLI reference docs in docs/cli/<topic>.md
Build and test: pnpm run build && pnpm --filter @salesforce/b2c-cli run test