@salesforce/afv-skills 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/applying-cms-brand/SKILL.md +170 -0
- package/skills/implementing-ui-bundle-agentforce-conversation-client/SKILL.md +114 -198
- package/skills/implementing-ui-bundle-agentforce-conversation-client/references/agent-id-resolution.md +46 -0
- package/skills/implementing-ui-bundle-agentforce-conversation-client/references/style-tokens.md +18 -6
- package/skills/integrating-b2b-commerce-open-code-components/SKILL.md +166 -0
- package/skills/running-code-analyzer/SKILL.md +499 -0
- package/skills/running-code-analyzer/examples/README.md +38 -0
- package/skills/running-code-analyzer/examples/basic-scan-output.json +92 -0
- package/skills/running-code-analyzer/examples/command-variations.md +333 -0
- package/skills/running-code-analyzer/examples/fix-application-before-after.md +142 -0
- package/skills/running-code-analyzer/examples/large-scan-output.json +67 -0
- package/skills/running-code-analyzer/examples/security-focused-output.json +95 -0
- package/skills/running-code-analyzer/references/command-examples.md +27 -0
- package/skills/running-code-analyzer/references/engine-reference.md +34 -0
- package/skills/running-code-analyzer/references/error-handling.md +29 -0
- package/skills/running-code-analyzer/references/flag-reference.md +96 -0
- package/skills/running-code-analyzer/references/quick-start.md +28 -0
- package/skills/running-code-analyzer/references/special-behaviors.md +83 -0
- package/skills/running-code-analyzer/references/vendor-file-handling.md +239 -0
- package/skills/running-code-analyzer/scripts/apply-fixes.js +86 -0
- package/skills/running-code-analyzer/scripts/discover-fixes.js +34 -0
- package/skills/running-code-analyzer/scripts/filter-violations.js +405 -0
- package/skills/running-code-analyzer/scripts/parse-results.js +59 -0
- package/skills/running-code-analyzer/scripts/summarize-fixes.js +32 -0
- package/skills/running-code-analyzer/scripts/verify-execution.sh +28 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Engine Reference
|
|
2
|
+
|
|
3
|
+
## Engine File Type Support
|
|
4
|
+
|
|
5
|
+
| Engine | File Extensions |
|
|
6
|
+
|---|---|
|
|
7
|
+
| **pmd** | `.cls`, `.trigger`, `.js`, `.html`, `.htm`, `.vfp`, `.component`, `.page`, `.xml` |
|
|
8
|
+
| **eslint** | `.js`, `.ts`, `.jsx`, `.tsx` |
|
|
9
|
+
| **cpd** | `.cls`, `.trigger`, `.js`, `.ts`, `.html`, `.htm`, `.vfp`, `.component`, `.page`, `.xml` |
|
|
10
|
+
| **retire-js** | `.js`, `.ts`, `package.json`, `package-lock.json` |
|
|
11
|
+
| **regex** | Configurable per rule via `file_extensions` |
|
|
12
|
+
| **flow** | `.flow-meta.xml` |
|
|
13
|
+
| **sfge** | `.cls`, `.trigger` |
|
|
14
|
+
| **apexguru** | `.cls`, `.trigger` |
|
|
15
|
+
|
|
16
|
+
## Common Rule Tags
|
|
17
|
+
|
|
18
|
+
These tags can be used in rule selectors:
|
|
19
|
+
|
|
20
|
+
| Tag | Meaning |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `Recommended` | Default ruleset — curated for most projects |
|
|
23
|
+
| `Security` | Security vulnerabilities (CRUD, XSS, injection, crypto) |
|
|
24
|
+
| `Performance` | Performance anti-patterns (SOQL in loops, limits) |
|
|
25
|
+
| `BestPractices` | Coding standards and conventions |
|
|
26
|
+
| `CodeStyle` | Naming, formatting, braces |
|
|
27
|
+
| `Design` | Complexity, coupling, architecture |
|
|
28
|
+
| `ErrorProne` | Common bug patterns |
|
|
29
|
+
| `Documentation` | Missing docs, comments |
|
|
30
|
+
| `Apex` | Rules applying to Apex language |
|
|
31
|
+
| `JavaScript` | Rules applying to JavaScript |
|
|
32
|
+
| `TypeScript` | Rules applying to TypeScript |
|
|
33
|
+
| `HTML` | Rules applying to HTML/Visualforce |
|
|
34
|
+
| `Custom` | User-defined rules |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Error Handling Guide
|
|
2
|
+
|
|
3
|
+
Common Code Analyzer errors and their resolutions.
|
|
4
|
+
|
|
5
|
+
## Common Errors and Resolutions
|
|
6
|
+
|
|
7
|
+
| Error Pattern | Likely Cause | Resolution |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `command not found: sf` | SF CLI not installed | "Install Salesforce CLI: `npm install -g @salesforce/cli`" |
|
|
10
|
+
| `plugin-code-analyzer` not found | Plugin not installed | "Install: `sf plugins install @salesforce/plugin-code-analyzer`" |
|
|
11
|
+
| `Java not found` / `JAVA_HOME not set` | Java missing/misconfigured | "Install Java 11+. Set JAVA_HOME or add `engines.pmd.java_command` to config" |
|
|
12
|
+
| `Node.js` version error | Old Node version | "Upgrade Node.js to v18+" |
|
|
13
|
+
| `Python` not found (Flow engine) | Python not installed | "Install Python 3. Or set `engines.flow.python_command` in config" |
|
|
14
|
+
| `Config file error` / YAML parse error | Invalid code-analyzer.yml | "Your config file has a syntax error. Run `sf code-analyzer config` to validate" |
|
|
15
|
+
| `No rules matched selector` | Invalid rule selector | Check selector syntax. Run `sf code-analyzer rules --rule-selector <selector>` to verify |
|
|
16
|
+
| `Target file does not exist` | File path typo or deleted | Verify file path exists |
|
|
17
|
+
| `Org not authenticated` (ApexGuru) | No default org | "Authenticate: `sf org login web --alias myorg`" |
|
|
18
|
+
| Timeout / heap space | Large project + SFGE | "Increase heap: add `engines.sfge.java_max_heap_size: '4g'` to code-analyzer.yml" |
|
|
19
|
+
|
|
20
|
+
## Diagnosis Steps
|
|
21
|
+
|
|
22
|
+
If the scan command fails:
|
|
23
|
+
|
|
24
|
+
1. Check the error message for hints
|
|
25
|
+
2. Run `sf --version` to verify CLI
|
|
26
|
+
3. Run `sf plugins --core | grep code-analyzer` to verify plugin
|
|
27
|
+
4. Run `java -version` to verify Java
|
|
28
|
+
5. Run `sf code-analyzer rules --rule-selector <selector>` to verify the selector matches rules
|
|
29
|
+
6. If config error: run `sf code-analyzer config` to validate
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Flag Reference for `sf code-analyzer run`
|
|
2
|
+
|
|
3
|
+
Complete reference for all flags available in the `sf code-analyzer run` command (v4+).
|
|
4
|
+
|
|
5
|
+
## Valid Flags
|
|
6
|
+
|
|
7
|
+
| Flag | Short | Type | Description | Default |
|
|
8
|
+
|------|-------|------|-------------|---------|
|
|
9
|
+
| `--rule-selector` | `-r` | String | Rule selection expression (engine, category, severity, or specific rule) | `Recommended` |
|
|
10
|
+
| `--target` | `-t` | String[] | Files/folders/globs to scan (comma-separated) | Current directory |
|
|
11
|
+
| `--workspace` | `-w` | String | Workspace root directory | `.` (current directory) |
|
|
12
|
+
| `--output-file` | `-f` | String[] | Output file path(s) — format determined by extension (.json, .html, .sarif, .csv, .xml) | None (terminal only) |
|
|
13
|
+
| `--view` | `-v` | String | Terminal display format: `table` or `detail` | None |
|
|
14
|
+
| `--severity-threshold` | `-s` | Number | Exit non-zero if violations at or above this level (1-5) | None |
|
|
15
|
+
| `--config-file` | `-c` | String | Path to code-analyzer.yml configuration file | None |
|
|
16
|
+
| `--include-fixes` | | Boolean | Include fix data in results (enables auto-fix capability) | `false` |
|
|
17
|
+
| `--include-suggestions` | | Boolean | Include suggestion data in results | `false` |
|
|
18
|
+
| `--no-suppressions` | | Boolean | Ignore suppression markers in code | `false` |
|
|
19
|
+
| `--target-org` | `-o` | String | Salesforce org username or alias (required for ApexGuru engine) | None |
|
|
20
|
+
|
|
21
|
+
## Invalid Flags (DO NOT USE)
|
|
22
|
+
|
|
23
|
+
These flags existed in v3 but were removed in v4+. Using them causes errors:
|
|
24
|
+
|
|
25
|
+
| Deprecated Flag | Error Message | Replacement |
|
|
26
|
+
|----------------|---------------|-------------|
|
|
27
|
+
| `--format` | `Unknown flag: --format` | Use `--output-file <path>.<ext>` where extension determines format |
|
|
28
|
+
| `--format table` | `Unknown flag: --format` | Use `--view table` or `--view detail` |
|
|
29
|
+
| `--engine` | `Unknown flag: --engine` | Use `--rule-selector <engine>` |
|
|
30
|
+
| `--category` | `Unknown flag: --category` | Use `--rule-selector <category>` |
|
|
31
|
+
| `--json` | `Unknown flag: --json` | Use `--output-file "./results.json"` |
|
|
32
|
+
|
|
33
|
+
## Rule Selector Syntax
|
|
34
|
+
|
|
35
|
+
The `--rule-selector` flag uses a flexible expression syntax:
|
|
36
|
+
|
|
37
|
+
| Syntax | Description | Example |
|
|
38
|
+
|--------|-------------|---------|
|
|
39
|
+
| `<engine>` | Select all rules from an engine | `pmd`, `eslint`, `cpd` |
|
|
40
|
+
| `<category>` | Select rules by category | `Security`, `Performance` |
|
|
41
|
+
| `<severity>` | Select rules by severity (1-5) | `1`, `2`, `(1,2)` |
|
|
42
|
+
| `<engine>:<category>` | Engine AND category | `pmd:Security` |
|
|
43
|
+
| `<engine>:<severity>` | Engine AND severity | `eslint:2` |
|
|
44
|
+
| `(<a>,<b>)` | OR grouping | `(pmd,eslint)` for PMD OR ESLint |
|
|
45
|
+
| `<a>:<b>:<c>` | Multiple AND conditions | `pmd:Security:1` for PMD AND Security AND Severity 1 |
|
|
46
|
+
| `<engine>:<ruleName>` | Specific rule | `pmd:ApexCRUDViolation` |
|
|
47
|
+
| `all` | All available rules | `all` |
|
|
48
|
+
| `Recommended` | Default recommended rule set | `Recommended` (default) |
|
|
49
|
+
|
|
50
|
+
### Complex Rule Selector Examples
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# PMD OR ESLint, Security category, Severity 1 or 2
|
|
54
|
+
--rule-selector "(pmd,eslint):Security:(1,2)"
|
|
55
|
+
|
|
56
|
+
# All Security rules across all engines
|
|
57
|
+
--rule-selector "Security"
|
|
58
|
+
|
|
59
|
+
# Specific rule from PMD
|
|
60
|
+
--rule-selector "pmd:ApexCRUDViolation"
|
|
61
|
+
|
|
62
|
+
# All rules from CPD (duplicate detection)
|
|
63
|
+
--rule-selector "cpd"
|
|
64
|
+
|
|
65
|
+
# High and Critical severity across all engines
|
|
66
|
+
--rule-selector "(1,2)"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Output Format Extensions
|
|
70
|
+
|
|
71
|
+
The `--output-file` flag determines format by file extension:
|
|
72
|
+
|
|
73
|
+
| Extension | Format | Use Case |
|
|
74
|
+
|-----------|--------|----------|
|
|
75
|
+
| `.json` | JSON | Programmatic parsing, default for this skill |
|
|
76
|
+
| `.html` | HTML | Human-readable report for browser viewing |
|
|
77
|
+
| `.sarif` | SARIF | IDE integration (VS Code, IntelliJ) or GitHub Advanced Security |
|
|
78
|
+
| `.csv` | CSV | Spreadsheet import (Excel, Google Sheets) |
|
|
79
|
+
| `.xml` | XML | Legacy CI/CD systems |
|
|
80
|
+
|
|
81
|
+
You can specify multiple output files in a single run:
|
|
82
|
+
```bash
|
|
83
|
+
--output-file "./results.json" --output-file "./report.html"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Why These Constraints Exist
|
|
87
|
+
|
|
88
|
+
**v4+ CLI redesign:** The Code Analyzer plugin underwent a major redesign from v3 to v4+:
|
|
89
|
+
- Old flags (`--format`, `--engine`, `--category`) were removed for a more flexible `--rule-selector` expression syntax
|
|
90
|
+
- Output format is now determined by file extension rather than a separate flag
|
|
91
|
+
- Terminal display was separated into `--view` flag
|
|
92
|
+
- These changes provide more flexibility but require different syntax than v3 documentation shows
|
|
93
|
+
|
|
94
|
+
**Always use `--output-file` for results:** Terminal stdout can be truncated, interrupted, or mixed with other output. Writing to a file ensures complete, parseable results.
|
|
95
|
+
|
|
96
|
+
**Foreground execution with timeout:** SFGE (Salesforce Graph Engine) scans can take 10-20 minutes for large codebases. Running in foreground with `timeout: 1200000` (20 minutes) ensures the scan completes and output is captured.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Quick Start: Minimum Viable Commands
|
|
2
|
+
|
|
3
|
+
If you're unsure about anything, use these EXACT commands as starting points.
|
|
4
|
+
|
|
5
|
+
**IMPORTANT:** Always generate a timestamp variable FIRST, then use it in the output filename:
|
|
6
|
+
```bash
|
|
7
|
+
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Then use it:
|
|
11
|
+
```bash
|
|
12
|
+
# Simplest scan (entire workspace, recommended rules)
|
|
13
|
+
sf code-analyzer run --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
14
|
+
|
|
15
|
+
# Scan specific target
|
|
16
|
+
sf code-analyzer run --target "force-app/main/default" --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
17
|
+
|
|
18
|
+
# Scan for security
|
|
19
|
+
sf code-analyzer run --rule-selector Security --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
20
|
+
|
|
21
|
+
# Scan specific engine
|
|
22
|
+
sf code-analyzer run --rule-selector pmd --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
23
|
+
|
|
24
|
+
# Scan with HTML report (only if user explicitly asks for HTML)
|
|
25
|
+
sf code-analyzer run --output-file "./code-analyzer-results-${TIMESTAMP}.html" --include-fixes
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**After the command completes**, read the output file and present a summary to the user.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Special Behaviors
|
|
2
|
+
|
|
3
|
+
Advanced scanning scenarios and engine-specific considerations.
|
|
4
|
+
|
|
5
|
+
## SFGE (Salesforce Graph Engine) Scans
|
|
6
|
+
|
|
7
|
+
When `--rule-selector sfge` is requested:
|
|
8
|
+
- **WARN the user**: "SFGE performs deep data-flow analysis and can be resource-intensive. It may take several minutes and use significant memory. Proceed?"
|
|
9
|
+
- If project is large (>100 Apex classes), suggest increasing heap: "Consider setting `engines.sfge.java_max_heap_size: '4g'` in your code-analyzer.yml"
|
|
10
|
+
- SFGE only analyzes Apex (`.cls`, `.trigger` files)
|
|
11
|
+
|
|
12
|
+
### SFGE Workspace Compilation Behavior
|
|
13
|
+
|
|
14
|
+
**CRITICAL:** SFGE compiles ALL `.cls` and `.trigger` files found anywhere in the `--workspace` directory (default: `.` = project root), NOT just files under `--target`. The `--target` flag only controls which files are used as **entry points** for data-flow analysis, but SFGE builds a complete inter-procedural call graph from the entire workspace.
|
|
15
|
+
|
|
16
|
+
This means:
|
|
17
|
+
1. If there are invalid/template Apex files ANYWHERE in the project (e.g., `datasets/`, `scripts/`, `templates/`), SFGE will try to compile them and CRASH with compilation errors.
|
|
18
|
+
2. **The `--target` flag does NOT prevent this** — even `--target "force-app"` still causes SFGE to compile files outside `force-app/`.
|
|
19
|
+
|
|
20
|
+
**To avoid compilation failures, ALWAYS set `--workspace` explicitly for SFGE scans:**
|
|
21
|
+
```bash
|
|
22
|
+
sf code-analyzer run --rule-selector sfge --workspace "force-app" --target "force-app" --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or if the user specifies a subfolder target like `force-app/main`:
|
|
26
|
+
```bash
|
|
27
|
+
sf code-analyzer run --rule-selector sfge --workspace "force-app" --target "force-app/main" --output-file "./code-analyzer-results-${TIMESTAMP}.json" --include-fixes
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The `--workspace` flag restricts which files SFGE compiles into its graph. Set it to the narrowest directory that contains all valid, deployable Apex source code (typically `force-app` or `src`).
|
|
31
|
+
|
|
32
|
+
## ApexGuru Scans
|
|
33
|
+
|
|
34
|
+
When `--rule-selector apexguru` is requested:
|
|
35
|
+
- **Check org authentication**: Run `sf org display` first
|
|
36
|
+
- If no org authenticated: Guide user to `sf org login web` or `sf org login jwt`
|
|
37
|
+
- Add `--target-org <alias>` flag if user has specified an org
|
|
38
|
+
- ApexGuru analyzes Apex performance patterns via cloud service
|
|
39
|
+
|
|
40
|
+
## AppExchange Security Review Scans
|
|
41
|
+
|
|
42
|
+
When user mentions "AppExchange", "security review", "ISV", "partner":
|
|
43
|
+
- Use `--rule-selector all` to run comprehensive scan
|
|
44
|
+
- Output both JSON and HTML: `--output-file "./code-analyzer-results-${TIMESTAMP}.json" --output-file "./code-analyzer-results-${TIMESTAMP}.html"`
|
|
45
|
+
- In results, categorize violations as:
|
|
46
|
+
- **Blockers** (sev 1-2, Security tag): MUST fix before submission
|
|
47
|
+
- **Warnings** (sev 3, Security/BestPractices): Strongly recommended to fix
|
|
48
|
+
- **Informational** (sev 4-5): Good to fix but won't block review
|
|
49
|
+
- Highlight specific AppExchange-critical rules:
|
|
50
|
+
- `ApexCRUDViolation` (CRUD/FLS enforcement)
|
|
51
|
+
- `ApexSharingViolations` (sharing model)
|
|
52
|
+
- `ApexSOQLInjection` (injection prevention)
|
|
53
|
+
- `ApexCSRF` (CSRF protection)
|
|
54
|
+
- `ApexXSSFromEscapeFalse` / `ApexXSSFromURLParam` (XSS prevention)
|
|
55
|
+
- `ApexInsecureEndpoint` (HTTPS enforcement)
|
|
56
|
+
- `ApexBadCrypto` (crypto standards)
|
|
57
|
+
- `ApexSuggestUsingNamedCred` (credential management)
|
|
58
|
+
|
|
59
|
+
## Diff-Based Scans
|
|
60
|
+
|
|
61
|
+
When user wants to scan only changed files:
|
|
62
|
+
1. Determine the base reference:
|
|
63
|
+
- "my changes" / "what I changed" → `git diff --name-only` (unstaged) or `git diff --name-only --cached` (staged)
|
|
64
|
+
- "branch changes" / "since main" → `git diff --name-only main...HEAD`
|
|
65
|
+
- "last commit" → `git diff --name-only HEAD~1`
|
|
66
|
+
2. Filter to scannable file types:
|
|
67
|
+
```bash
|
|
68
|
+
git diff --name-only main...HEAD | grep -E '\.(cls|trigger|js|ts|html|css|xml|flow-meta\.xml)$'
|
|
69
|
+
```
|
|
70
|
+
3. If no scannable files changed: "No scannable files in your diff. Code Analyzer supports: .cls, .trigger, .js, .ts, .html, .css, .xml, .flow-meta.xml"
|
|
71
|
+
4. Pass filtered files as comma-separated `--target` value
|
|
72
|
+
|
|
73
|
+
## Large Result Sets (500+ violations)
|
|
74
|
+
|
|
75
|
+
- Summarize: top 10 rules by frequency, top 10 files by violation count
|
|
76
|
+
- Offer: "Want me to export the full results? Or focus on a specific category/file?"
|
|
77
|
+
- Don't try to display all 500+ violations inline
|
|
78
|
+
|
|
79
|
+
## Mega Result Sets (5000+ violations)
|
|
80
|
+
|
|
81
|
+
- Same as above, but also proactively suggest narrowing scope:
|
|
82
|
+
- "This is a very large number of violations. Want me to focus on just Critical/High severity, a specific category like Security, or a specific folder?"
|
|
83
|
+
- If the user originally said "scan and fix everything", still follow the full flow (scan → present → discover fixes → ask → apply → summarize) — do NOT shortcut any steps just because the result set is large
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Vendor File Handling
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Code Analyzer scans all JavaScript files, including third-party vendor libraries like jQuery, Bootstrap, Lodash, Handlebars, etc. These libraries often trigger thousands of violations, especially:
|
|
6
|
+
|
|
7
|
+
- **no-var** (legacy `var` declarations)
|
|
8
|
+
- **prefer-const** (variables that could be const)
|
|
9
|
+
- **code style** (indentation, quotes, semicolons)
|
|
10
|
+
|
|
11
|
+
A typical scan might find:
|
|
12
|
+
- **9,714 total violations**
|
|
13
|
+
- **9,089 in vendor files** (jQuery UI, Bootstrap, tablesorter)
|
|
14
|
+
- **634 in project source** (your Aura/LWC components)
|
|
15
|
+
|
|
16
|
+
## Why You Shouldn't Fix Vendor Files
|
|
17
|
+
|
|
18
|
+
| Risk | Impact |
|
|
19
|
+
|------|--------|
|
|
20
|
+
| **Breaks upgrades** | Modified vendor files can't be cleanly upgraded to newer versions |
|
|
21
|
+
| **Untested changes** | Libraries weren't designed for strict mode or modern JS patterns |
|
|
22
|
+
| **Subtle bugs** | Converting `var` to `let/const` can change scope/hoisting behavior in legacy code |
|
|
23
|
+
| **Maintainability** | Future developers won't know the file was modified and why |
|
|
24
|
+
| **Wasted effort** | The next library upgrade will overwrite your fixes anyway |
|
|
25
|
+
|
|
26
|
+
## Solutions
|
|
27
|
+
|
|
28
|
+
### Solution 1: Re-scan with --target (Fastest)
|
|
29
|
+
|
|
30
|
+
If you know your project source locations upfront:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
sf code-analyzer run --rule-selector <selector> \
|
|
34
|
+
--target "force-app/main/default/aura,force-app/main/default/lwc" \
|
|
35
|
+
--output-file "./results-project-only.json" \
|
|
36
|
+
--include-fixes
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Pros:**
|
|
40
|
+
- Only scans what you need
|
|
41
|
+
- Faster execution
|
|
42
|
+
- Cleaner results
|
|
43
|
+
|
|
44
|
+
**Cons:**
|
|
45
|
+
- Must know target directories upfront
|
|
46
|
+
- Doesn't show you what violations exist in vendor files (for awareness)
|
|
47
|
+
|
|
48
|
+
### Solution 2: Intelligent Filtering (Most Accurate)
|
|
49
|
+
|
|
50
|
+
Scan everything first, then use the intelligent filter script to separate vendor from project:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# 1. Run full scan
|
|
54
|
+
sf code-analyzer run --rule-selector <selector> \
|
|
55
|
+
--output-file "./results-all.json" --include-fixes
|
|
56
|
+
|
|
57
|
+
# 2. Filter to project files only
|
|
58
|
+
node "<skill_dir>/scripts/filter-violations.js" \
|
|
59
|
+
"./results-all.json" \
|
|
60
|
+
"./results-project.json" \
|
|
61
|
+
--report
|
|
62
|
+
|
|
63
|
+
# 3. Apply fixes to filtered results
|
|
64
|
+
node "<skill_dir>/scripts/apply-fixes.js" "./results-project.json"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Pros:**
|
|
68
|
+
- Intelligent classification using multiple heuristics
|
|
69
|
+
- Shows you vendor vs project breakdown
|
|
70
|
+
- Handles uncertain files (30-70% confidence)
|
|
71
|
+
- No manual pattern maintenance
|
|
72
|
+
|
|
73
|
+
**Cons:**
|
|
74
|
+
- Scans more files than necessary
|
|
75
|
+
- Takes longer for large codebases
|
|
76
|
+
|
|
77
|
+
## How the Intelligent Filter Works
|
|
78
|
+
|
|
79
|
+
The `filter-violations.js` script uses a **multi-heuristic confidence scoring system**:
|
|
80
|
+
|
|
81
|
+
### 1. Path-Based Signals (30% weight)
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// High confidence vendor indicators
|
|
85
|
+
node_modules/ → 100% vendor
|
|
86
|
+
bower_components/ → 100% vendor
|
|
87
|
+
vendor/ → 95% vendor
|
|
88
|
+
third-party/ → 95% vendor
|
|
89
|
+
StaticResourceSources/ → 70% vendor
|
|
90
|
+
|
|
91
|
+
// Project source indicators
|
|
92
|
+
force-app/main/default/aura/ → Project
|
|
93
|
+
force-app/main/default/lwc/ → Project
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Name-Based Signals (30% weight)
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// Filename patterns
|
|
100
|
+
*.min.js → 95% vendor (minified)
|
|
101
|
+
*-1.12.1.js → 85% vendor (version in name)
|
|
102
|
+
jquery*.js → 85% vendor (known library)
|
|
103
|
+
bootstrap*.js → 85% vendor (known library)
|
|
104
|
+
|
|
105
|
+
// Checked against package.json dependencies
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 3. Content-Based Signals (40% weight)
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
// License headers
|
|
112
|
+
MIT License, Apache, BSD, GPL → 80% vendor
|
|
113
|
+
|
|
114
|
+
// Minification indicators
|
|
115
|
+
Average line length > 500 chars → 90% vendor
|
|
116
|
+
< 10 lines but > 5KB file → 85% vendor
|
|
117
|
+
|
|
118
|
+
// Library patterns
|
|
119
|
+
UMD/AMD/CommonJS wrapper → 70% vendor
|
|
120
|
+
@version x.x.x → 65% vendor
|
|
121
|
+
@author (non-project) → 50% vendor
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Final Score
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Weighted Score = (PathScore × 0.3) + (NameScore × 0.3) + (ContentScore × 0.4)
|
|
128
|
+
|
|
129
|
+
> 70% = Vendor file
|
|
130
|
+
< 30% = Project file
|
|
131
|
+
30-70% = Uncertain (manual review)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Example Output
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
=== INTELLIGENT VENDOR FILE DETECTION ===
|
|
138
|
+
|
|
139
|
+
Original violations: 9714
|
|
140
|
+
Filtered violations: 634
|
|
141
|
+
Reduction: 9080 (93.5%)
|
|
142
|
+
|
|
143
|
+
📦 Vendor files excluded: 127
|
|
144
|
+
610 violations | 95% confidence | jquery-ui-1.12.1.js
|
|
145
|
+
located in vendor directory, version number in filename, minified file
|
|
146
|
+
525 violations | 98% confidence | jquery-ui-1.12.1.min.js
|
|
147
|
+
located in vendor directory, minified file (.min.js)
|
|
148
|
+
... and 125 more vendor files
|
|
149
|
+
|
|
150
|
+
✅ Project files included: 39
|
|
151
|
+
157 violations | CRLP_RollupHelper.js
|
|
152
|
+
103 violations | HH_ContainerHelper.js
|
|
153
|
+
84 violations | CRLP_FilterGroupHelper.js
|
|
154
|
+
...
|
|
155
|
+
|
|
156
|
+
⚠️ Uncertain files: 2
|
|
157
|
+
These files have 30-70% vendor confidence - review manually:
|
|
158
|
+
45 violations | 55% vendor | customUtility.js
|
|
159
|
+
located in vendor directory
|
|
160
|
+
|
|
161
|
+
✓ Filtered results written to: ./results-project.json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Workflow Integration
|
|
165
|
+
|
|
166
|
+
### When to Use Each Approach
|
|
167
|
+
|
|
168
|
+
| Scenario | Recommended Approach |
|
|
169
|
+
|----------|---------------------|
|
|
170
|
+
| User says "fix no-var in my code" | Use intelligent filter (excludes vendor by default) |
|
|
171
|
+
| User says "fix all no-var" | Ask: "Including vendor files (jQuery, Bootstrap)?" |
|
|
172
|
+
| User specifies path | Use --target directly |
|
|
173
|
+
| User wants report first | Full scan → intelligent filter → show breakdown |
|
|
174
|
+
|
|
175
|
+
### Step-by-Step Workflow
|
|
176
|
+
|
|
177
|
+
```markdown
|
|
178
|
+
1. Run Code Analyzer scan
|
|
179
|
+
2. Parse results
|
|
180
|
+
3. **Check violation distribution:**
|
|
181
|
+
- If 50%+ are in vendor files → offer intelligent filtering
|
|
182
|
+
- If user said "my code" or "project" → automatically filter
|
|
183
|
+
4. Discover fixes (on filtered or unfiltered results)
|
|
184
|
+
5. Apply fixes
|
|
185
|
+
6. Summarize
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Edge Cases
|
|
189
|
+
|
|
190
|
+
### Case 1: Vendored Modified Libraries
|
|
191
|
+
|
|
192
|
+
**Scenario:** Your org has modified a copy of jQuery
|
|
193
|
+
|
|
194
|
+
**Solution:** The intelligent filter will classify it as vendor, but violations may be legitimate. Options:
|
|
195
|
+
1. Fix manually after filter identifies it
|
|
196
|
+
2. Re-run with --target excluding that specific file
|
|
197
|
+
3. Add to project exceptions in filter script
|
|
198
|
+
|
|
199
|
+
### Case 2: Project Code in Static Resources
|
|
200
|
+
|
|
201
|
+
**Scenario:** Your custom JavaScript is in `staticresources/` alongside vendor libs
|
|
202
|
+
|
|
203
|
+
**Solution:** The filter checks content + name, not just path. Custom code without vendor markers scores as "project" or "uncertain" for manual review.
|
|
204
|
+
|
|
205
|
+
### Case 3: Uncertain Classifications
|
|
206
|
+
|
|
207
|
+
**Scenario:** File scores 30-70% vendor confidence
|
|
208
|
+
|
|
209
|
+
**Action:** Filter script reports these separately. Review manually:
|
|
210
|
+
- Check file purpose
|
|
211
|
+
- Look for original source/documentation
|
|
212
|
+
- Decide whether to fix or exclude
|
|
213
|
+
|
|
214
|
+
## Configuration (Future Enhancement)
|
|
215
|
+
|
|
216
|
+
The filter script could accept custom patterns:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
node filter-violations.js results.json filtered.json \
|
|
220
|
+
--exclude-patterns "*.min.js,jquery*,bootstrap*" \
|
|
221
|
+
--include-patterns "force-app/main/default/aura/**,force-app/main/default/lwc/**"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Currently uses intelligent defaults and doesn't require configuration.
|
|
225
|
+
|
|
226
|
+
## Testing the Filter
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Run with detailed report
|
|
230
|
+
node scripts/filter-violations.js \
|
|
231
|
+
./code-analyzer-results-20260519-133252.json \
|
|
232
|
+
./filtered-output.json \
|
|
233
|
+
--report
|
|
234
|
+
|
|
235
|
+
# Check the output
|
|
236
|
+
node scripts/parse-results.js ./filtered-output.json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Compare before/after violation counts to verify filtering accuracy.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Apply engine-provided auto-fixes to source files
|
|
3
|
+
// Usage: node apply-fixes.js <path-to-results.json>
|
|
4
|
+
// WARNING: This modifies files in place. Ensure you have backups or are using version control.
|
|
5
|
+
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
|
|
9
|
+
if (process.argv.length < 3) {
|
|
10
|
+
console.error("Usage: node apply-fixes.js <results-file.json>");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const filePath = process.argv[2];
|
|
15
|
+
const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
16
|
+
const runDir = data.runDir || "";
|
|
17
|
+
|
|
18
|
+
// Group fixes by file
|
|
19
|
+
const fileFixesMap = new Map();
|
|
20
|
+
data.violations.forEach(v => {
|
|
21
|
+
if (v.fixes && v.fixes.length > 0) {
|
|
22
|
+
v.fixes.forEach(fix => {
|
|
23
|
+
const loc = fix.location;
|
|
24
|
+
let filePath = loc.file;
|
|
25
|
+
if (runDir && filePath.startsWith(runDir)) filePath = filePath.substring(runDir.length + 1);
|
|
26
|
+
|
|
27
|
+
if (!fileFixesMap.has(filePath)) fileFixesMap.set(filePath, []);
|
|
28
|
+
fileFixesMap.get(filePath).push({
|
|
29
|
+
startLine: loc.startLine,
|
|
30
|
+
startColumn: loc.startColumn,
|
|
31
|
+
endLine: loc.endLine,
|
|
32
|
+
endColumn: loc.endColumn,
|
|
33
|
+
fixedCode: fix.fixedCode,
|
|
34
|
+
rule: v.rule
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Sort fixes by line/column (descending) to apply bottom-up
|
|
41
|
+
// This ensures earlier fixes don't shift line numbers for later ones
|
|
42
|
+
fileFixesMap.forEach((fixes, file) => {
|
|
43
|
+
fixes.sort((a, b) => {
|
|
44
|
+
if (b.startLine !== a.startLine) return b.startLine - a.startLine;
|
|
45
|
+
return b.startColumn - a.startColumn;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Apply fixes to each file
|
|
50
|
+
let filesModified = 0;
|
|
51
|
+
let fixesApplied = 0;
|
|
52
|
+
let fixesSkipped = 0;
|
|
53
|
+
|
|
54
|
+
fileFixesMap.forEach((fixes, filePath) => {
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
57
|
+
const lines = content.split("\n");
|
|
58
|
+
|
|
59
|
+
fixes.forEach(fix => {
|
|
60
|
+
const startIdx = fix.startLine - 1;
|
|
61
|
+
const endIdx = fix.endLine - 1;
|
|
62
|
+
if (startIdx < 0 || endIdx >= lines.length || startIdx > endIdx) {
|
|
63
|
+
fixesSkipped++;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Handle multi-line replacements: splice out old lines, insert new content
|
|
68
|
+
const firstLine = lines[startIdx];
|
|
69
|
+
const lastLine = lines[endIdx];
|
|
70
|
+
const before = firstLine.substring(0, fix.startColumn - 1);
|
|
71
|
+
const after = lastLine.substring(fix.endColumn - 1);
|
|
72
|
+
const replacement = before + fix.fixedCode + after;
|
|
73
|
+
|
|
74
|
+
// Remove the spanned lines and insert the replacement
|
|
75
|
+
lines.splice(startIdx, endIdx - startIdx + 1, replacement);
|
|
76
|
+
fixesApplied++;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
fs.writeFileSync(filePath, lines.join("\n"), "utf8");
|
|
80
|
+
filesModified++;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error("Error fixing " + filePath + ": " + err.message);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
console.log(JSON.stringify({ success: true, filesModified, fixesApplied, fixesSkipped, totalFixableFiles: fileFixesMap.size }));
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Version: v1.0 | SHA256: 19ec035f7132dc162b54a931cfdd882aa473ad80aa21a8a4be1f1127d75168e5
|
|
3
|
+
// Discover which violations have engine-provided auto-fixes
|
|
4
|
+
// Usage: node discover-fixes.js <path-to-results.json>
|
|
5
|
+
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
|
|
8
|
+
if (process.argv.length < 3) {
|
|
9
|
+
console.error("Usage: node discover-fixes.js <results-file.json>");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const filePath = process.argv[2];
|
|
14
|
+
const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
15
|
+
const runDir = data.runDir || "";
|
|
16
|
+
|
|
17
|
+
const fixesByRule = {};
|
|
18
|
+
let totalFixable = 0;
|
|
19
|
+
|
|
20
|
+
data.violations.forEach(v => {
|
|
21
|
+
if (v.fixes && v.fixes.length > 0) {
|
|
22
|
+
totalFixable++;
|
|
23
|
+
const rule = v.rule;
|
|
24
|
+
if (!fixesByRule[rule]) fixesByRule[rule] = { engine: v.engine, count: 0, severity: v.severity };
|
|
25
|
+
fixesByRule[rule].count++;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const topRules = Object.entries(fixesByRule)
|
|
30
|
+
.sort((a, b) => b[1].count - a[1].count)
|
|
31
|
+
.slice(0, 10)
|
|
32
|
+
.map(([rule, info]) => ({ rule, ...info }));
|
|
33
|
+
|
|
34
|
+
console.log(JSON.stringify({ totalFixable, totalViolations: data.violations.length, topRules }));
|