Overview
Project analysis is available in sfp-pro.
The project analysis command helps you analyze your Salesforce project for potential issues and provides detailed reports in various formats. This command is particularly useful for identifying issues such as duplicate components, compliance violations, hardcoded IDs and URLs, and other code quality concerns.
Usage
sfp project:analyze [flags]Common Use Cases
The analyze command serves several key purposes:
- Runs various available linters across the project
- Generating comprehensive analysis reports
- Integration with CI/CD pipelines for automated checks
Available Linters
The analyzer runs the following linters on an analysis:
| Linter | What It Checks | Default State |
|---|---|---|
compliance | Salesforce metadata rules (hardcoded IDs, permissions, missing docs, etc.) | Enabled |
code-analyzer | Static analysis via Salesforce Code Analyzer (PMD, ESLint, CPD) | Enabled |
duplicates | Duplicate metadata components across packages | Enabled |
architecture | AI-powered architectural review of changed code | Disabled |
version-assist | AI-decided semantic version intent for server-managed packages (posts a /version comment) | Disabled (opt-in addon) |
The version-assist addon is enabled differently from the other linters — it is gated by the project's versionManagement.enabled and analyzeConfig.versionAssistEnabled settings rather than by excludeLinters, and only runs when the PR impacts a server-managed package. See AI Assisted Version Intent.
Available Flags
| Flag | Description | Required | Default |
|---|---|---|---|
--package, -p | The name of the package to analyze | No | - |
--domain, -d | The domain to analyze | No | - |
--source-path, -s | The path to analyze | No | - |
--exclude-linters | Comma-separated list of linters to exclude | No | [] |
--fail-on | Linters that should cause command failure if issues found | No | [] |
--show-aliasfy-notes | Show notes for aliasified packages | No | true |
--fail-on-unclaimed | Fail when duplicates are found in unclaimed packages | No | false |
--output-format | Output format (markdown, json, github) | No | markdown |
--report-dir | Directory for analysis reports | No | - |
--compliance-rules | Path to compliance rules YAML file | No | config/compliance-rules.yaml |
--code-analyzer-config | Path to Salesforce Code Analyzer config file | No | config/code-analyzer.yml |
--duplicates-config | Path to duplicates exclusion config file | No | config/duplicates.yaml |
--generate-compliance-config | Generate sample compliance rules configuration | No | false |
Scoping Analysis
The command provides three mutually exclusive ways to scope your analysis:
-
By Package: Analyze specific packages
sfp project:analyze -p core,utils -
By Domain: Analyze all packages in a domain
sfp project:analyze -d sales -
By Source Path: Analyze a specific directory
sfp project:analyze -s ./force-app/main/default
Output Formats
The command supports multiple output formats:
- Markdown: Human-readable documentation format
- JSON: Machine-readable format for integration with other tools
- GitHub: Special format for GitHub Checks API integration
GitHub Integration
When running in GitHub Actions, the command automatically:
- Creates GitHub Check runs for each analysis
- Adds annotations to the code for identified issues
- Provides detailed summaries in the GitHub UI
Examples
-
Basic analysis of all packages:
sfp project:analyze -
Analyze specific packages with JSON output:
sfp project:analyze -p core,utils --output-format json -
Analyze with strict validation:
sfp project:analyze --fail-on duplicates --fail-on-unclaimed -
Generate reports in a specific directory:
sfp project:analyze --report-dir ./analysis-reports -
Generate compliance configuration:
sfp project:analyze --generate-compliance-config -
Run compliance checks with custom rules:
sfp project:analyze --compliance-rules config/compliance-rules.yaml --fail-on compliance
Analyzer Orchestration — config/analyze.yaml
The config/analyze.yaml file controls which linters are enabled and which ones cause a non-zero exit code (failing the CI check). This is the first file the analyzer reads before it invokes any linter.
Config Source Priority
The analyzer resolves its orchestration config in this order:
- CLI flags (
--exclude-linters,--fail-on) — highest priority, always wins config/analyze.yaml— local file in the repo- Server project config (
analyzeConfigfield on the project) — fallback when no local file exists - Defaults — all linters enabled, none fail the check
Schema
# config/analyze.yaml
# Linter names to disable entirely for all PRs.
# Valid values: duplicates, compliance, code-analyzer, architecture
excludeLinters:
- architecture
# Linters whose findings cause the check to fail (non-zero exit).
# Only linters that actually ran can appear here.
failOn:
- compliance
- code-analyzer
# When true, the architecture linter skips PRs whose diffs are
# below the significance thresholds defined in ai-assist.yaml.
# Has no effect when the architecture linter is excluded.
changeSignificanceEnabled: false
# Optional: per-target-branch overrides.
# Matched against the PR's target (base) branch using glob patterns.
# First matching rule wins; if nothing matches, the top-level values apply.
branchRules:
- pattern: "release/*"
failOn:
- compliance
- code-analyzer
- duplicates
changeSignificanceEnabled: false
- pattern: "hotfix/*"
excludeLinters:
- architecture
- duplicates
failOn:
- compliance
- pattern: "main"
failOn:
- compliance
- code-analyzer
- duplicatesField Reference
| Field | Type | Default | Description |
|---|---|---|---|
excludeLinters | string[] | [] | Linter names to skip. All run by default. |
failOn | string[] | [] | Linters whose results fail the check. Informational by default. |
changeSignificanceEnabled | boolean | false | Skip architecture AI when changes are trivial. |
branchRules | BranchRule[] | [] | Target-branch-specific overrides. |
branchRules[].pattern | string | — | Glob pattern matched against the PR target branch. |
branchRules[].excludeLinters | string[] | inherits | Override excludeLinters for this branch pattern. |
branchRules[].failOn | string[] | inherits | Override failOn for this branch pattern. |
branchRules[].changeSignificanceEnabled | boolean | inherits | Override changeSignificanceEnabled for this branch pattern. |
Configuration Files
All configuration files live inside the repository root under config/. If a file is absent the linter falls back to safe defaults.
| File | Purpose | Required |
|---|---|---|
config/analyze.yaml | Orchestration: which linters run, what causes failure | No |
config/compliance-rules.yaml | Rules for the compliance linter | No |
config/code-analyzer.yml | Config for Salesforce Code Analyzer (PMD/ESLint/CPD) | No |
config/ai-assist.yaml | Config for the AI architecture linter (preferred name) | No |
config/ai-architecture.yaml | Config for the AI architecture linter (legacy name, still supported) | No |
config/duplicates.yaml | Exclusion config for the duplicates linter | No |
Recommended Repository Layout
config/
├── analyze.yaml # Orchestration (which linters run, what fails)
├── compliance-rules.yaml # Compliance rule definitions
├── code-analyzer.yml # Salesforce Code Analyzer engine config
├── ai-assist.yaml # AI architecture linter config
└── duplicates.yaml # Duplicates linter exclusions (optional)How Configuration Is Loaded at Runtime
sfp project:analyze
│
├─ 1. Resolve orchestration config (analyze.yaml / server / CLI flags)
│ └─ Determines: which linters run, which can fail the check
│
├─ 2. Compliance linter
│ └─ Loads config/compliance-rules.yaml
│ └─ If extends: default → merges with built-in preset
│
├─ 3. Code Analyzer linter
│ └─ Finds config/code-analyzer.yml (or variants)
│ └─ If not found → uses engine defaults
│
├─ 4. Duplicates linter
│ └─ Loads config/duplicates.yaml (optional exclusions)
│
└─ 5. Architecture linter (if not excluded)
└─ Loads config/ai-assist.yaml (or config/ai-architecture.yaml)
└─ Determines provider, patterns, significance thresholdsWhen run in PR context (triggered by a webhook or --pr-number), all linters restrict their analysis to the changed files in the PR diff. When run standalone (no PR context), linters scan the full project.
Common Scenarios
Fail the PR check on compliance errors only
# config/analyze.yaml
excludeLinters:
- architecture
failOn:
- complianceStrict release branches, lenient feature branches
# config/analyze.yaml
excludeLinters:
- architecture
failOn: []
branchRules:
- pattern: "release/*"
failOn:
- compliance
- code-analyzer
- duplicates
- pattern: "main"
failOn:
- compliance
- code-analyzerUse architecture linter with significance filtering
# config/analyze.yaml
changeSignificanceEnabled: true# config/ai-assist.yaml
provider: anthropic
changeSignificance:
fileTypeThresholds:
apex:
lines: 30
files: 2
default:
lines: 100
files: 3
ignoredFilePatterns:
- "**/__tests__/**"
- "**/*.test.js"