This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Salesforce CLI plugin (@salesforce/lwc-dev-mobile) providing mobile extensions for Lightning Web Components Local Development. It manages iOS simulators and Android emulators for mobile app development through the sf CLI.
# Install dependencies
yarn install
# Build (compile + lint via wireit)
yarn build
# Compile TypeScript only
yarn compile
# Lint
yarn lint
# Format code
yarn format
# Check formatting
yarn format:check
# Run unit tests with coverage
yarn test
# Run a single test file
npx mocha 'test/unit/cli/commands/force/lightning/local/device/create.test.ts'
# Run tests matching a pattern
npx mocha --grep "should create" 'test/unit/**/*.test.ts'
# Run during development (ts-node, no compilation needed)
./bin/dev.js force lightning local device list --platform androidThis is an oclif CLI plugin. Commands are discovered by oclif from dist/cli/commands/ based on directory structure — the file path maps directly to the CLI command name.
Commands (under src/cli/commands/force/lightning/):
local/setup.ts— Environment setuplocal/device/create.ts,list.ts,start.ts— Device managementlocal/app/install.ts,launch.ts— App deploymentlwc/test/ui/mobile/configure.ts,run.ts— UI test automation
All commands are re-exported from src/index.ts.
Every command extends BaseCommand from @salesforce/lwc-dev-mobile-core and follows this structure:
- Messages: Loaded from markdown files in
messages/viaMessages.importMessagesDirectoryFromMetaUrl - Flags: Defined as static using
CommandLineUtils.createFlag()for common flags (platform, json, log-level) andFlags.*from@salesforce/sf-plugins-corefor command-specific flags - Command name:
protected _commandNameis abstract inBaseCommand— every command must set it (e.g.,'force:lightning:local:device:list'). Used for telemetry event names. - Requirements:
populateCommandRequirements()sets up pre-flight checks (e.g., environment validation, device name availability) processed byRequirementProcessor - Execution:
run()handles both CLI mode (with spinner viaCommonUtils.startCliAction) and JSON mode (returns typed data validated by Zod schemas) - Platform branching: Android vs iOS is determined by
CommandLineUtils.platformFlagIsAndroid(), delegating toAndroidDeviceManager/AppleDeviceManagerorAndroidUtils/IOSUtils
Product Feature Tracking is handled automatically by BaseCommand.init() — it emits a {commandName}.executed event via Lifecycle.emitTelemetry() in a .finally() block. No per-command code needed. O11y config (enableO11y, o11yUploadEndpoint, productFeatureId) lives in package.json. Requires @salesforce/cli >= 2.126.0.
@salesforce/lwc-dev-mobile-core: ProvidesBaseCommand, device managers, platform utilities, requirement system, and environment checks. This is where most platform-specific logic lives.zod: Runtime schema validation for JSON output (schemas insrc/cli/schema/)@salesforce/core:Messages(i18n),Logger@salesforce/sf-plugins-core:Flagsdefinitions
CLI text (summaries, flag descriptions, examples, error messages) lives in messages/*.md files, not in source code. Each command loads its own message file by name (e.g., device-create.md).
- Module system: ESM (
"type": "module"in package.json). Use.jsextensions in import paths even for TypeScript files. - Formatting: Prettier — 4-space indent, single quotes, no trailing commas, 120 char width.
- Linting: ESLint with
eslint-config-salesforce-typescript+plugin:sf-plugin/recommended. - Conventional commits: Enforced via commitlint + husky hooks.
- Framework: Mocha + Chai assertions + Sinon/ts-sinon for mocking
- Test location:
test/unit/mirrorssrc/structure, files named*.test.ts - Test isolation: Uses
TestContextfrom@salesforce/corefor sandbox management - Coverage thresholds: 75% lines, 80% statements, 75% branches, 75% functions (enforced by c8)
- Pattern: Stub external dependencies from
@salesforce/lwc-dev-mobile-core(device managers, utils) and test both CLI and JSON output modes - Telemetry testing: Stub
Lifecycle.getInstance().emitTelemetryand assert the payload has correcteventNameandcommandName
Wireit orchestrates builds. yarn build runs both compile and lint. TypeScript compiles to dist/ with incremental builds. Node.js >=20 required (Volta pins to 20.18.0, Yarn 1.22.22).