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:

  1. Runs various available linters across the project
  2. Generating comprehensive analysis reports
  3. Integration with CI/CD pipelines for automated checks

Available Linters

The analyzer runs the following linters on an analysis:

LinterWhat It ChecksDefault State
complianceSalesforce metadata rules (hardcoded IDs, permissions, missing docs, etc.)Enabled
code-analyzerStatic analysis via Salesforce Code Analyzer (PMD, ESLint, CPD)Enabled
duplicatesDuplicate metadata components across packagesEnabled
architectureAI-powered architectural review of changed codeDisabled
version-assistAI-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

FlagDescriptionRequiredDefault
--package, -pThe name of the package to analyzeNo-
--domain, -dThe domain to analyzeNo-
--source-path, -sThe path to analyzeNo-
--exclude-lintersComma-separated list of linters to excludeNo[]
--fail-onLinters that should cause command failure if issues foundNo[]
--show-aliasfy-notesShow notes for aliasified packagesNotrue
--fail-on-unclaimedFail when duplicates are found in unclaimed packagesNofalse
--output-formatOutput format (markdown, json, github)Nomarkdown
--report-dirDirectory for analysis reportsNo-
--compliance-rulesPath to compliance rules YAML fileNoconfig/compliance-rules.yaml
--code-analyzer-configPath to Salesforce Code Analyzer config fileNoconfig/code-analyzer.yml
--duplicates-configPath to duplicates exclusion config fileNoconfig/duplicates.yaml
--generate-compliance-configGenerate sample compliance rules configurationNofalse

Scoping Analysis

The command provides three mutually exclusive ways to scope your analysis:

  1. By Package: Analyze specific packages

    sfp project:analyze -p core,utils
  2. By Domain: Analyze all packages in a domain

    sfp project:analyze -d sales
  3. 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:

  1. Creates GitHub Check runs for each analysis
  2. Adds annotations to the code for identified issues
  3. Provides detailed summaries in the GitHub UI

Examples

  1. Basic analysis of all packages:

    sfp project:analyze
  2. Analyze specific packages with JSON output:

    sfp project:analyze -p core,utils --output-format json
  3. Analyze with strict validation:

    sfp project:analyze --fail-on duplicates --fail-on-unclaimed
  4. Generate reports in a specific directory:

    sfp project:analyze --report-dir ./analysis-reports
  5. Generate compliance configuration:

    sfp project:analyze --generate-compliance-config
  6. 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:

  1. CLI flags (--exclude-linters, --fail-on) — highest priority, always wins
  2. config/analyze.yaml — local file in the repo
  3. Server project config (analyzeConfig field on the project) — fallback when no local file exists
  4. 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
      - duplicates

Field Reference

FieldTypeDefaultDescription
excludeLintersstring[][]Linter names to skip. All run by default.
failOnstring[][]Linters whose results fail the check. Informational by default.
changeSignificanceEnabledbooleanfalseSkip architecture AI when changes are trivial.
branchRulesBranchRule[][]Target-branch-specific overrides.
branchRules[].patternstringGlob pattern matched against the PR target branch.
branchRules[].excludeLintersstring[]inheritsOverride excludeLinters for this branch pattern.
branchRules[].failOnstring[]inheritsOverride failOn for this branch pattern.
branchRules[].changeSignificanceEnabledbooleaninheritsOverride 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.

FilePurposeRequired
config/analyze.yamlOrchestration: which linters run, what causes failureNo
config/compliance-rules.yamlRules for the compliance linterNo
config/code-analyzer.ymlConfig for Salesforce Code Analyzer (PMD/ESLint/CPD)No
config/ai-assist.yamlConfig for the AI architecture linter (preferred name)No
config/ai-architecture.yamlConfig for the AI architecture linter (legacy name, still supported)No
config/duplicates.yamlExclusion config for the duplicates linterNo
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 thresholds

When 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:
  - compliance

Strict release branches, lenient feature branches

# config/analyze.yaml
excludeLinters:
  - architecture
failOn: []

branchRules:
  - pattern: "release/*"
    failOn:
      - compliance
      - code-analyzer
      - duplicates
  - pattern: "main"
    failOn:
      - compliance
      - code-analyzer

Use 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"

On this page