sf-code-analyzer-quality
Skill2 starsChanged 2 months agoMITView on GitHub
Salesforce Code Analyzer v5 and the rest of the local quality gate - sf code-analyzer run/rules/config with --workspace, --target, --rule-selector, --severity-threshold, --view, --output-file and --config-file, the pmd, eslint, regex, retire-js, flow, cpd and sfge (Salesforce Graph Engine) engines, code-analyzer.yml schema with rule overrides, ignores and suppressions, custom PMD rulesets and XPath rules, ESLint flat config with @salesforce/eslint-config-lwc, Prettier with prettier-plugin-apex, the 1-5 severity taxonomy and the analyzerFailSeverity gate, baseline and ratchet strategies for legacy code, SARIF output and CI annotation. Use when configuring or running static analysis, triaging violations, authoring or suppressing rules, or when running vf-check static, vf-check lint, vf-check format, vf-check analyzer, or vf-check local.
- Installs packages
In this repository34 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- sf-agentforce-developmentSkill
- sf-apex-developmentSkill
- sf-apex-testingSkill
- sf-async-apex-patternsSkill
- sf-cli-operationsSkill
- sf-data-cloudSkill
- sf-data-managementSkill
- sf-debugging-logsSkill
- sf-deployment-strategiesSkill
- sf-fflib-domain-service-uowSkill
- sf-fflib-foundationsSkill
- sf-fflib-operationsSkill
- sf-fflib-selector-layerSkill
- sf-fflib-testingSkill
- sf-flow-automationSkill
- sf-governor-limitsSkill
- sf-integration-patternsSkill
- sf-local-developmentSkill
- sf-lwc-developmentSkill
- sf-lwc-jest-testingSkill
- sf-minimal-changeSkill
- sf-org-security-auditSkill
- sf-packaging-releaseSkill
- sf-post-deploy-verificationSkill
- sf-process-builder-migrationSkill
- sf-project-structureSkill
- sf-scratch-orgs-sandboxesSkill
- sf-security-modelSkill
- sf-setup-automationSkill
- sf-soql-sosl-optimizationSkill
- sf-technical-debt-auditSkill
- sf-ui-test-automationSkill
- sf-workflow-orchestrationSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
If Java or Python are unavailable in an environment (a lean CI image, for example), disable those engines in code-analyzer.yml rather than …
- Very specific: line 121
Every code-analyzer command auto-discovers code-analyzer.yml or code-analyzer.yaml in the current folder.
- Very specific: line 169
Write an XPath rule (or a Java rule packaged in a JAR) in a PMD ruleset XML file.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Code Analyzer and Quality Gates
When to use
- Setting up or changing static analysis for a Salesforce project.
- Triaging a
vf-check analyzerfailure, deciding fix versus suppress, or writing a suppression with a reason and a cap. - Authoring a custom PMD rule or a regex rule for a project convention.
- Wiring Prettier/ESLint so
vf-check formatandvf-check lintare deterministic. - Introducing the gate to a legacy codebase without stopping delivery (baseline and ratchet).
- Wave 2 of the vibe-force workflow:
sf-quality-gaterunsvf-check localand reports. - Org-wide debt rather than a diff: skill
sf-technical-debt-audit(it turns recurring findings into regex rules authored here).
Toolchain and prerequisites
| Tool | Install | Requirement |
| Code Analyzer plugin | sf plugins install code-analyzer (it is also a JIT plugin: running a code-analyzer command installs it automatically) | Salesforce CLI; Node.js 20 or later if the CLI was installed via npm |
pmd, cpd, sfge engines | bundled with the plugin | JDK 11 or later |
flow engine (Flow Scanner) | bundled | Python 3.10.0 or later |
eslint, retire-js, regex engines | bundled | Node, no extra runtime |
| Prettier + Apex plugin | npm i -D prettier prettier-plugin-apex | Node 22 or later; JRE 17 or later only on platforms without a prebuilt native parser |
| LWC ESLint | npm i -D eslint @babel/core @babel/eslint-parser @salesforce/eslint-config-lwc @lwc/eslint-plugin-lwc @salesforce/eslint-plugin-lightning eslint-plugin-import eslint-plugin-jest | ESLint 9 for @salesforce/eslint-config-lwc 4.x and @lwc/eslint-plugin-lwc 3.x |
If Java or Python are unavailable in an environment (a lean CI image, for example), disable those
engines in code-analyzer.yml rather than tolerating engine errors:
engines:
flow:
disable_engine: true
cpd:
disable_engine: trueConfig files live in the plugin and are referenced by the check runner; do not duplicate them per
project: config/code-analyzer.yml, config/pmd/apex-ruleset.xml, config/eslint/eslint.config.mjs,
config/prettier/.prettierrc.
Engines
| Engine | Analyzes | Detects | Notes |
pmd | Apex, Visualforce, HTML, JavaScript, XML | security, error-prone, performance, style, documentation | JDK required; default languages apex and visualforce; AppExchange ruleset available via --rule-selector AppExchange |
eslint | JavaScript, TypeScript, LWC, Aura, CSS/SCSS (SLDS), JSX | LWC rule violations, JS correctness, SLDS 2 misuse, React/JSX when enabled | bundles @salesforce/eslint-config-lwc/recommended and @lwc/lwc-platform/recommended; supports ESLint 8 and 9 |
regex | any text file | project conventions, banned strings, trailing whitespace | custom rules need a global-modifier regex (/TODO/gi) |
retire-js | bundled JavaScript, static resources | known-vulnerable third-party libraries | |
flow | Flows, subflows | unsafe Flow patterns, data passed into without sharing Apex | Python required |
cpd | multiple languages | copy/paste duplication | JDK required; off by default in the vibe-force config |
sfge | Apex | path-based CRUD/FLS, sharing, null-pointer, loop-database, mass-schema-lookup issues | Developer Preview; JDK required; slowest engine |
Severity taxonomy and the gate
| Severity | Name | vibe-force policy |
| 1 | Critical | blocks; fix before the PR leaves wave 2 |
| 2 | High | blocks |
| 3 | Moderate | blocks (gates.analyzerFailSeverity default 3) |
| 4 | Low | reported, does not block |
| 5 | Info | reported, does not block |
--severity-threshold makes the command exit non-zero when a violation meets or exceeds the given
level; it accepts a number or its name (2 or "High"). vf-check analyzer passes
gates.analyzerFailSeverity from .vibeforce/config.json.
Core patterns
1. List the rules before running them
# recommended rules for every available engine (the default selector is Recommended)
sf code-analyzer rules
# everything the pmd engine offers, with full detail
sf code-analyzer rules --rule-selector pmd --view detail
# scope to what actually applies to this codebase
sf code-analyzer rules --rule-selector all --workspace . --target force-app/**/*.cls--rule-selector eslint is equivalent to eslint:all; append :Recommended to stay inside the
recommended set. Criteria combine with : as AND and , as OR, and parentheses group; a selector
containing parentheses must be double-quoted.
2. Run the same selectors
sf code-analyzer run --workspace . --rule-selector Recommended --severity-threshold 3 --view detail
# Apex-only path analysis, whole project as context, targeted files as entry points
sf code-analyzer run --workspace . --rule-selector sfge --target force-app/main/default/classes
# machine-readable plus human-readable in one pass
sf code-analyzer run --workspace . \
--output-file .vibeforce/reports/analyzer.json \
--output-file .vibeforce/reports/analyzer.html--workspace is the analysis context (default .); --target narrows which files produce
violations while keeping the workspace available to engines that need the whole project - Graph
Engine compiles the workspace to build its call graph.
3. Generate and evolve the configuration
# write the current effective configuration, comments included, to a file
sf code-analyzer config --config-file ./code-analyzer.yml --output-file ./code-analyzer.yml
# just the recommended rules, including their unmodified default values
sf code-analyzer config --rule-selector Recommended --include-unmodified-rules
# what is configured for one rule
sf code-analyzer config --rule-selector pmd:ApexCRUDViolationEvery code-analyzer command auto-discovers code-analyzer.yml or code-analyzer.yaml in the
current folder; --config-file overrides the location. Schema details:
references/code-analyzer-cli.md and references/config-templates.md.
4. Override severity and tags instead of deleting rules
rules:
pmd:
ApexCRUDViolation:
severity: "Critical"
tags: ["Recommended", "Security", "VibeForceBlocking"]
ApexDoc:
disabled: true
eslint:
"@lwc/lwc/no-inner-html":
severity: 1
regex:
NoTrailingWhiteSpace:
tags: ["Suggestion"]rules.<engine>.<rule>.severity accepts 1-5 or Critical|High|Moderate|Low|Info; tags
replaces the rule's tags; disabled: true switches the rule off for every file.
5. Add a project convention as a regex rule
engines:
regex:
custom_rules:
NoSeeAllData:
regex: /@IsTest\s*\(\s*seeAllData\s*=\s*true\s*\)/gi
file_extensions: [".cls"]
description: "Tests must not use seeAllData=true."
violation_message: "Replace seeAllData=true with @TestSetup-created data."
severity: 2
tags: ["Recommended", "VibeForce"]The regex must carry a global modifier (/.../g or /.../gi); without it the engine errors.
[unverified] The exact property names under custom_rules beyond regex and file_extensions
were not enumerated on the fetched configuration pages; generate a skeleton with
sf code-analyzer config --rule-selector regex --include-unmodified-rules and copy the shape it
prints.
6. Add a custom PMD rule
- Write an XPath rule (or a Java rule packaged in a JAR) in a PMD ruleset XML file; use
sf code-analyzer ast-dumpto see the AST you are matching against. - Register the ruleset:
engines:
pmd:
custom_rulesets:
- "config/pmd/apex-ruleset.xml"
java_classpath_entries: []- Confirm registration, then run it:
sf code-analyzer rules --rule-selector pmd:Custom --view detail
sf code-analyzer run --rule-selector pmd:CheckForBadVariableNames --view detailCode Analyzer tags every custom rule Custom and also adds a tag matching the <ruleset> name
attribute with spaces removed. Custom PMD severities derive from PMD priority: 1 -> 2 (High),
2 -> 3 (Moderate), 3 -> 3 (Moderate), 4 -> 4 (Low), 5 -> 4 (Low).
7. Suppress narrowly, with a reason
In-source markers (processed by Code Analyzer v5 for any text file):
// code-analyzer-suppress-next-line eslint:no-console -- deliberate build-time diagnostic
console.log('bundle built');Configuration-level bulk suppression:
suppressions:
disable_suppressions: false
"force-app/legacy/classes/":
- rule_selector: "pmd:ApexCRUDViolation,pmd:ApexSharingViolations"
max_suppressed_violations: 40
reason: "Legacy module; tracked by VF-214, migrating to user mode per quarter."Marker forms: code-analyzer-suppress, code-analyzer-suppress-line,
code-analyzer-suppress-next-line, and code-analyzer-unsuppress to restore checking. A bare
code-analyzer-suppress applies from that line to end of file or until an unsuppress marker, so
prefer the line-scoped forms. Folder paths in suppressions must end with /. --no-suppressions
ignores both marker and config suppressions, except that a suppressions.disable_suppressions
setting in the config file takes precedence over the flag. PMD's own @SuppressWarnings('PMD.RuleName')
annotation and // NOPMD comment still work for the PMD engine; vibe-force prefers the
Code Analyzer markers because they work across every engine and are greppable.
8. Formatting and linting around the analyzer
# format check (what vf-check format runs)
npx prettier --check --config config/prettier/.prettierrc --ignore-path config/prettier/.prettierignore "force-app/**/*.{cls,trigger,js,html,css,xml,json}"
# lint LWC/Aura JS (what vf-check lint runs)
npx eslint --config config/eslint/eslint.config.mjs "force-app/**/lwc/**/*.js" "force-app/**/aura/**/*.js"Prettier owns whitespace, ESLint owns JavaScript semantics, Code Analyzer owns Apex, metadata, and cross-language rules. Never encode formatting preferences as analyzer rules.
9. Composition of the vibe-force checks
vf-check | Composed of |
format | prettier --check over changed Apex, LWC, Aura, XML, JS (--fix runs prettier --write) |
lint | eslint over changed LWC/Aura JS |
analyzer | sf code-analyzer run --config-file config/code-analyzer.yml --severity-threshold <gates.analyzerFailSeverity> over the changed files as --target with the package directories as --workspace |
static | format + lint + analyzer |
local | static + jest - the full no-org gate |
Reports land in <project>/.vibeforce/reports/<check>-<ISO>.json with {check, startedAt,
durationMs, status, gates, findings[], raw}. Exit codes: 0 pass, 1 gate failed, 2
misconfiguration or missing tool, 3 org/network error.
Anti-patterns
| Anti-pattern | Consequence | Instead |
--rule-selector eslint when you meant the recommended set | runs every ESLint rule, floods the report | eslint:Recommended |
--target without --workspace on Graph Engine runs | Graph Engine cannot build the call graph and misses or misreports paths | pass the whole project as --workspace |
| Deleting a rule from the ruleset to silence it | loses the signal everywhere, silently | rules.<engine>.<rule>.disabled with a comment, or a scoped suppression |
Bare code-analyzer-suppress at the top of a file | suppresses to end of file | code-analyzer-suppress-next-line <selector> -- reason |
Suppression without max_suppressed_violations | debt grows invisibly | set a cap; new violations beyond it are reported normally |
Running --rule-selector all in the PR gate | noisy, slow, unstable across plugin upgrades | Recommended plus explicitly added rules |
Turning off the whole sfge engine because it is slow | loses path-based CRUD/FLS detection | keep it in the nightly or pre-deploy run, raise java_thread_count, java_max_heap_size |
auto_discover_eslint_config: true plus a conflicting local config | plugin-version conflicts and engine errors | pin eslint_config_file to config/eslint/eslint.config.mjs |
| Formatting rules enabled in both Prettier and ESLint | fight each other on every save | Prettier formats, ESLint lints |
Using v4 syntax (sf scanner run --category Security) | removed command surface | see the migration table in references/code-analyzer-cli.md |
Verification
# does the configuration resolve and are the intended rules selected?
sf code-analyzer config --config-file config/code-analyzer.yml --rule-selector Recommended
sf code-analyzer rules --config-file config/code-analyzer.yml --workspace . --view table
# the gate itself, on changed files only
node "${CLAUDE_PLUGIN_ROOT}/scripts/checks/vf-check.mjs" analyzer --changed
# the full local gate before any deploy
node "${CLAUDE_PLUGIN_ROOT}/scripts/checks/vf-check.mjs" local
# CI: SARIF for code scanning upload
sf code-analyzer run --workspace . --rule-selector Recommended \
--severity-threshold 3 --output-file analyzer.sarifA configuration change is proven by a before/after sf code-analyzer rules --rule-selector <rule>
pair showing the new severity or tags, plus a run that exits 0 on clean code and 1 on a
deliberately seeded violation.
References
references/code-analyzer-cli.md- command, flag, and engine tables; output file formats; v4 to v5 migration.references/rule-catalogue.md- highest-value PMD Apex, ESLint LWC, Graph Engine, regex, and retire-js rules with fixes.references/config-templates.md- the content expected inconfig/code-analyzer.yml,config/pmd/apex-ruleset.xml,config/eslint/eslint.config.mjs,config/prettier/.prettierrc,.prettierignore.references/quality-gates-and-baselines.md- gate policy, legacy baselines, ratchets, CI integration, suppression review.- Code Analyzer: Use CLI Commands, Customize the Configuration, Top-Level Customization Reference, PMD engine, ESLint engine, Graph Engine, Graph Engine rules, Suppress Violations, Output Schemas
- CLI reference: code-analyzer commands
- PMD Apex rules, PMD rulesets
- @lwc/eslint-plugin-lwc, @salesforce/eslint-config-lwc, prettier-plugin-apex
- Sibling skills:
sf-apex-development,sf-apex-testing,sf-lwc-development,sf-lwc-jest-testing,sf-security-model,sf-debugging-logs,sf-deployment-strategies,sf-post-deploy-verification.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

