Help us improve
Share bugs, ideas, or general feedback.
From sf-skills
Runs Salesforce Code Analyzer to scan Apex, LWC, and JS code for security, performance, style, and duplicate violations. Supports all engines (PMD, ESLint, CPD, RetireJS, Flow, SFGE, ApexGuru) and targets including git diff.
npx claudepluginhub ccmalcom/sf-skills-plugin --plugin sf-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/sf-skills:running-code-analyzerThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**BEFORE DOING ANYTHING ELSE:**
examples/README.mdexamples/basic-scan-output.jsonexamples/command-variations.mdexamples/fix-application-before-after.mdexamples/large-scan-output.jsonexamples/security-focused-output.jsonreferences/command-examples.mdreferences/engine-reference.mdreferences/error-handling.mdreferences/flag-reference.mdreferences/quick-start.mdreferences/special-behaviors.mdreferences/vendor-file-handling.mdscripts/apply-fixes.jsscripts/discover-fixes.jsscripts/filter-violations.jsscripts/parse-results.jsscripts/summarize-fixes.jsscripts/verify-execution.shScans code for vulnerabilities, bugs, and code smells using Semgrep (default) and CodeQL. Use before releases, on large PRs, or when investigating recurring bug classes.
Runs Semgrep static analysis scans in parallel subagents with two modes: full coverage and high-confidence security vulnerabilities. Detects Semgrep Pro for cross-file taint analysis. Use for security audits and finding bugs.
Runs Semgrep static analysis scan using parallel subagents. Supports full ruleset coverage or high-confidence security vulnerabilities. Use for security audits or bug finding.
Share bugs, ideas, or general feedback.
BEFORE DOING ANYTHING ELSE:
This skill MUST use the Bash tool to execute sf code-analyzer run and Node.js scripts.
DO NOT use these tools under any circumstances:
run_code_analyzer (MCP tool)mcp__* (any MCP tool)mcp in its nameIf you see a run_code_analyzer tool available, ignore it completely. Use only the Bash tool with sf code-analyzer run.
This skill translates natural language requests ("scan for security issues", "check my changes") into the correct sf code-analyzer run command, executes scans with any combination of engines/targets/severities, and presents actionable results. When engine-provided fixes are available, it discovers them, asks for user confirmation, applies them safely, and offers verification. Use this skill for static analysis, security reviews, AppExchange certification, code quality checks, or finding duplicates/vulnerabilities in Salesforce projects.
In scope:
sf code-analyzer run with any combination of engines, targets, categories, severitiesOut of scope:
The following rules are ABSOLUTE and override any prior knowledge:
sf code-analyzer run — NOT sf scanner run (deprecated v3 command)--format flag — use --output-file <path>.<ext> instead (extension determines format)--output-file to write results to a file — do NOT rely on terminal stdout--output-file with a timestamped filename (e.g., ./code-analyzer-results-20260512-143022.json)--format, --engine, --category, --json — these cause errors, use --rule-selector and --output-file insteadsf code-analyzer runnode <skill_dir>/scripts/*.js using the Bash toolWhy: The v4+ CLI redesigned the flag interface. Old v3 flags cause "unknown flag" errors.
For complete flag reference and rule selector syntax, see <skill_dir>/references/flag-reference.md.
User must have: Salesforce CLI (sf), @salesforce/plugin-code-analyzer (v5.x+), Java 11+ (PMD/CPD/SFGE), Node.js 18+ (ESLint/RetireJS), Python 3 (Flow), authenticated org (ApexGuru).
If a scan fails, read <skill_dir>/references/error-handling.md. For quick command examples, see <skill_dir>/references/quick-start.md.
Allowed: Bash (sf code-analyzer, node, git, date), Read, Write, Edit
Forbidden: MCP tools, Agent tool, Web tools, other skills
This skill owns the complete scan-fix-verify workflow. Using MCP tools bypasses the validated script workflow.
Use this decision tree for fast pattern matching before going to Step 1 detailed parsing:
| User Says | Action | Rule Selector | Notes |
|---|---|---|---|
| "scan my code" / "run code analyzer" | Default scan | Recommended | Curated rule set, all file types |
| "check for security issues" / "security review" | Security scan | all:Security:(1,2) | All engines, Critical+High only |
| "scan my changes" / "check the diff" | Diff-based scan | Get changed files via git diff, filter to scannable types, use --target | See Step 1.5 for filtering logic |
| "run PMD" / "check my Apex" | PMD only | pmd | Apex classes and triggers |
| "lint my LWC" / "check my JavaScript" | ESLint only | eslint | JavaScript/TypeScript/LWC |
| "find duplicates" / "check for copy-paste" | CPD (Copy-Paste Detector) | cpd | Detects code clones |
| "check for vulnerabilities" / "scan libraries" | RetireJS | retire-js | JavaScript library CVEs |
| "deep analysis" / "data flow analysis" | SFGE (Graph Engine) | sfge | Requires Java 11+, 10-20min, use --workspace "force-app" |
| "performance analysis" / "governor limits" | ApexGuru | apexguru | Requires authenticated org |
| "analyze my Flows" | Flow engine | flow | Target: **/*.flow-meta.xml, requires Python 3 |
| "AppExchange security review" | AppExchange scan | all:Security:(1,2) | Read <skill_dir>/references/special-behaviors.md → AppExchange section |
If the pattern matches above, proceed directly to Step 3 (Build Command). Otherwise, continue to Step 1 for detailed parsing.
Analyze the user's request along these 7 dimensions. Any can be combined freely:
Map user keywords to --rule-selector values:
pmdeslintflowcpdretire-jssfgeapexgururegexallRecommended (default)Map user keywords to category tags:
SecurityPerformanceBestPracticesCodeStyleDesignErrorProneDocumentationSeverity levels: 1=Critical (must fix), 2=High (should fix), 3=Moderate (recommended), 4=Low (nice to fix), 5=Info (FYI)
Map user keywords:
1(1,2)(1,2,3)If the user mentions a specific rule by name (e.g., "ApexCRUDViolation", "no-unused-vars"):
--rule-selector <engine>:<ruleName>--rule-selector <ruleName>⚠️ IMPORTANT — Partial Rule Names: The --rule-selector flag requires the EXACT full rule name (e.g., @salesforce-ux/slds/no-hardcoded-values-slds2, not no-hardcoded-values). It does NOT support wildcards or partial matches.
When you are NOT 100% certain of the full rule name:
sf code-analyzer rules command with grep:
sf code-analyzer rules --rule-selector all 2>&1 | grep -i "USER_KEYWORD"
Map user keywords:
--target <path>--target **/*.cls,**/*.triggergit diff --name-only [base]...HEAD, filter to scannable types, pass as --target--target **/lwc/**--target **/*.flow-meta.xml--target)For diff filtering details: See <skill_dir>/references/special-behaviors.md.
DEFAULT: Always JSON. Only change if user EXPLICITLY requests another format.
Naming: ./code-analyzer-results-<YYYYMMDD-HHmmss>.<ext> (timestamp via TIMESTAMP=$(date +%Y%m%d-%H%M%S))
Formats: .json (default), .html (report), .sarif (GitHub/IDE), .csv (spreadsheet), .xml
Map user keywords:
git diff --name-only main...HEAD → scan those filesgit diff --name-only HEAD~1git diff --name-only develop...HEADSyntax: : = AND, , = OR, () = grouping
Examples:
pmdpmd:Securitypmd:2(pmd,eslint):Security:(1,2) = (PMD or ESLint) AND Security AND (sev 1 or 2)pmd:ApexCRUDViolationallMore examples: <skill_dir>/references/command-examples.md
Generate timestamp: TIMESTAMP=$(date +%Y%m%d-%H%M%S)
Build command:
sf code-analyzer run \
--rule-selector <selector> \
--target <targets> \ # optional
--output-file "./code-analyzer-results-${TIMESTAMP}.json" \ # DEFAULT: JSON
--include-fixes \ # always
--workspace <path> # optional
Key decisions:
.json). Only change format if user explicitly requests HTML/SARIF/CSV/XML.--include-fixes (enables Step 6 auto-fix)--target to scan entire workspacegit diff --name-only, filter to scannable types, pass as --targetSpecial cases: See <skill_dir>/references/special-behaviors.md for SFGE/ApexGuru/AppExchange/diff filtering.
⚠️ TOOL REQUIREMENT: Use Bash tool ONLY. DO NOT use run_code_analyzer (MCP tool) or any MCP tool.
Rules: Foreground only (no run_in_background), hardcoded filename (not $TIMESTAMP), timeout 1200000ms, no sleep, log output to timestamped file.
Steps:
Generate timestamp: date +%Y%m%d-%H%M%S → capture output (e.g., 20260512-143022) using Bash tool
Tell user:
Starting scan...
Results: ./code-analyzer-results-20260512-143022.json
Log: ./code-analyzer-results-20260512-143022.log
May take several minutes for large codebases.
Run command with literal timestamp in filename and tee to capture log (timeout: 1200000):
⚠️ IMPORTANT: Use the Bash tool, NOT the run_code_analyzer MCP tool.
sf code-analyzer run --rule-selector Recommended --output-file "./code-analyzer-results-20260512-143022.json" --include-fixes 2>&1 | tee "./code-analyzer-results-20260512-143022.log"
After completion: Exit 0 = success. Error output → check both the log file and <skill_dir>/references/error-handling.md.
IMMEDIATELY parse results (Step 5). Do NOT ask user what they want.
<skill_dir> — see belowjq to parse results — jq one-liners WILL fail due to shell quoting issuesAll scripts are bundled in the scripts/ subdirectory of the same directory that contains this SKILL.md file. Use the absolute path to that directory — do NOT use ./scripts/ as that resolves relative to the current working directory, not the skill directory.
node <skill_dir>/scripts/parse-results.js "./code-analyzer-results-TIMESTAMP.json"
⚠️ DO NOT:
node scripts/parse-results.js (won't resolve from user's CWD)jq as a substitute for the parse scriptALWAYS present a concise summary, then point to the output file for full details.
## Scan Complete
**Found X violations** across Y files.
| Severity | Count |
|----------|-------|
| Critical (1) | X |
| High (2) | X |
| Moderate (3) | X |
| Low (4) | X |
| Info (5) | X |
### Top Issues
| # | Rule | Engine | Sev | File | Line |
|---|------|--------|-----|------|------|
| 1 | ApexCRUDViolation | pmd | 2 | AccountService.cls | 42 |
| 2 | ApexSOQLInjection | pmd | 1 | QueryHelper.cls | 18 |
| ... (show up to 10 most critical) |
### Top Rules by Frequency
| Rule | Engine | Count |
|------|--------|-------|
| no-var | eslint | 170 |
| ApexDoc | pmd | 165 |
| ... |
Full results: `./code-analyzer-results-20260512-143022.json`
<path>"Always end with: Output file path + next-action offers (explain rules / apply fixes)
For large result sets: See <skill_dir>/references/special-behaviors.md.
After presenting results, check if violations have engine-provided fixes (deterministic, not AI-generated).
Rules: NEVER apply without confirmation. Use EXACT scripts from <skill_dir>/scripts/. Filter vendor files if needed, then: Discover → Apply → Summarize.
Flow: Filter vendor (6.1 if needed) → discover (6.2) → present (6.3) → ASK user → apply (6.4) → summarize (6.5) → present results.
If user said "fix my code" or "project source", or if top files by violation count are vendor libraries (jQuery, Bootstrap, *.min.js), run:
node "<skill_dir>/scripts/filter-violations.js" \
"./code-analyzer-results-TIMESTAMP.json" \
"./code-analyzer-results-TIMESTAMP-filtered.json" \
--report
Present: "Excluded X vendor files (Y violations) - jQuery, Bootstrap, etc. Applying fixes to Z project files only."
Use filtered file for Step 6.3+. See: <skill_dir>/references/vendor-file-handling.md for detailed logic.
node "<skill_dir>/scripts/discover-fixes.js" "./code-analyzer-results-TIMESTAMP.json"
(Use filtered file from Step 6.1 if created.)
After running the discovery script, present results:
### Engine-Provided Fixes Available
**X of Y violations** have auto-fixes provided by the analysis engine:
| Rule | Engine | Sev | Fixable Count |
|------|--------|-----|---------------|
| no-var | eslint | 3 | 170 |
| no-hardcoded-values-slds2 | eslint | 4 | 76 |
| ... |
These are safe, deterministic fixes generated by the engines (not AI-generated).
Would you like me to apply these fixes? (yes / no / select specific rules)
Even if the user originally said "scan and fix everything", you MUST still stop here and wait. Present the table, ask the question, and WAIT for a response in the NEXT turn.
Only proceed after user says "yes", "apply", "go ahead" IN A SEPARATE RESPONSE.
node "<skill_dir>/scripts/apply-fixes.js" "./code-analyzer-results-TIMESTAMP.json"
(Use filtered file if Step 6.1 created one.)
⚠️ MANDATORY: After the apply script completes, you MUST run the summary script as your VERY NEXT action.
node "<skill_dir>/scripts/summarize-fixes.js" "./code-analyzer-results-TIMESTAMP.json"
Then present to the user:
### Engine-Provided Fixes Applied Successfully ✓
**Applied X auto-fixes across Y files.**
| Severity | Fixes Applied |
|----------|---------------|
| Critical (1) | X |
| High (2) | X |
| ... |
| Rule | Fixes Applied |
|------|---------------|
| no-var | 169 |
| ... |
Want me to re-run the scan to verify the fixes resolved the violations?
| Constraint | Rationale |
|---|---|
| Timestamped output (JSON + log) | Prevents overwrite; enables history tracking |
Use tee for logs | Keeps logs in working dir with matching timestamp |
Never use --format flag | Removed in v4+; use --output-file <path>.<ext> instead |
| Foreground scans, 1200000ms timeout | SFGE takes 10-20min; backgrounding loses output |
Execute scripts from <skill_dir>/scripts/ | Never write inline scripts or heredocs |
| Never apply fixes without confirmation | User must explicitly approve code modifications |
| Check for vendor files before fixes | If 50%+ vendor (jQuery, Bootstrap), filter first |
| Run fix scripts in order | Filter (if needed) → Discover → Apply → Summarize |
SFGE needs explicit --workspace | Prevents template file compilation errors |
| Look up partial rule names first | Guessing fails; use sf code-analyzer rules to find exact name |
| ONLY Bash tool, never MCP | run_code_analyzer MCP tool bypasses script workflow |
| Never invoke other skills for fixes | This skill owns complete workflow end-to-end |
| Issue | Why It Happens | Solution |
|---|---|---|
--format flag error | Removed in v4+ | Use --output-file <path>.<ext> |
| Scan returns 0 results | Invalid rule selector | Run sf code-analyzer rules --rule-selector <selector> to verify |
| SFGE compilation error | Template files in workspace | Set --workspace "force-app" |
| jq parsing fails | Shell quoting issues | Use node "<skill_dir>/scripts/parse-results.js" |
| Inline scripts written | LLM generates custom code | NEVER write scripts — use existing from <skill_dir>/scripts/ |
| Scan times out | Large SFGE | Increase timeout to 1200000ms |
| run_code_analyzer MCP used | LLM prefers MCP over Bash | Use Bash tool ONLY |
| Other skills invoked | LLM delegates to other skills | Use apply-fixes.js from this skill only |
| Most violations are vendor | Includes jQuery, Bootstrap, *.min.js | Run filter-violations.js before applying fixes |
Every scan produces: timestamped JSON file, concise summary (severity/top violations/rules/files), next-action offers. If fixes applied: summary by severity/rule, offer verification.
<skill_dir> is the absolute path to the directory containing this SKILL.md file.
| File | When to use |
|---|---|
<skill_dir>/scripts/parse-results.js | Step 5 — extract summary from scan JSON |
<skill_dir>/scripts/filter-violations.js | Step 6.1 — exclude vendor files (jQuery, Bootstrap) from fixes |
<skill_dir>/scripts/discover-fixes.js | Step 6.2 — identify fixable violations |
<skill_dir>/scripts/apply-fixes.js | Step 6.4 — apply engine fixes after user confirms |
<skill_dir>/scripts/summarize-fixes.js | Step 6.5 — summarize applied changes |
| File | When to read |
|---|---|
<skill_dir>/references/quick-start.md | Command syntax templates |
<skill_dir>/references/flag-reference.md | Flag docs, rule selector syntax |
<skill_dir>/references/error-handling.md | Scan failure diagnosis |
<skill_dir>/references/engine-reference.md | Engine capabilities, file types, rule tags |
<skill_dir>/references/command-examples.md | Uncommon command scenarios |
<skill_dir>/references/special-behaviors.md | SFGE/ApexGuru/AppExchange/diff/large scans |
<skill_dir>/references/vendor-file-handling.md | Vendor file detection and filtering logic |
Examples in <skill_dir>/examples/ show output structure validation and command patterns (basic/large/security scans, fix workflows).