When running sf code-analyzer run using the latest v5.x CLI with a valid Salesforce DX project, the tool reports “0 violations across 0 files”, even though multiple .cls and .trigger files exist in the specified --target directory.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Code Analyzer Report</title>
<link
rel="icon"
href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjI4MzEgNy4zOTk0QzEzLjg5MjUgNi43Njk3MyAxNC42NDQ1IDYuMjkwNiAxNS40Nzc5IDYuMDAxMDRDMTYuMzExMiA1LjcxMTQ5IDE3LjIwMjIgNS42MTk3IDE4LjA3ODQgNS43MzMxM0MxOC45NTQ2IDUuODQ2NTcgMTkuNzkxMiA2LjE2MjAzIDIwLjUyIDYuNjUzODNDMjEuMjQ4OSA3LjE0NTYzIDIxLjg0OTMgNy43OTk4NSAyMi4yNzI1IDguNTYzMjJDMjMuMTQ4MSA4LjE3OTUxIDI0LjA5NiA3Ljk4MTI1IDI1LjA1NDUgNy45ODEzMUMyNi44OTY2IDcuOTgxMzEgMjguNjYzMiA4LjcwMTMyIDI5Ljk2NTggOS45ODI5M0MzMS4yNjgzIDExLjI2NDUgMzIgMTMuMDAyOCAzMiAxNC44MTUzQzMyIDE2LjYyNzcgMzEuMjY4MyAxOC4zNjYgMjkuOTY1OCAxOS42NDc2QzI4LjY2MzIgMjAuOTI5MiAyNi44OTY2IDIxLjY0OTIgMjUuMDU0NSAyMS42NDkyQzI0LjYgMjEuNjQ5NSAyNC4xNDY2IDIxLjYwNDMgMjMuNzAxNCAyMS41MTQyQzIzLjI2NDggMjIuMjg0IDIyLjYyNzIgMjIuOTI1IDIxLjg1NDQgMjMuMzcxQzIxLjA4MTcgMjMuODE3MSAyMC4yMDE5IDI0LjA1MTkgMTkuMzA2IDI0LjA1MTNDMTguNTQzNSAyNC4wNTM4IDE3Ljc5MDYgMjMuODgzMyAxNy4xMDU5IDIzLjU1MzJDMTYuNjU3MiAyNC41OTY3IDE1Ljg5OTkgMjUuNDgzMyAxNC45MzI0IDI2LjA5NzdDMTMuOTY0OCAyNi43MTIxIDEyLjgzMTggMjcuMDI1OSAxMS42ODA1IDI2Ljk5ODNDMTAuNTI5MyAyNi45NzA3IDkuNDEzMTQgMjYuNjAzIDguNDc3MTQgMjUuOTQyOUM3LjU0MTE1IDI1LjI4MjggNi44Mjg2IDI0LjM2MSA2LjQzMjE2IDIzLjI5NzJDNi4wNzEyNSAyMy4zNzIxIDUuNzAzMzIgMjMuNDA5NSA1LjMzNDQ2IDIzLjQwODlDNC4xNTQ4NSAyMy4zOTYyIDMuMDEyMDUgMjMuMDAzMyAyLjA4MTA3IDIyLjI5MDRDMS4xNTAwOSAyMS41Nzc1IDAuNDgyMzE5IDIwLjU4MzkgMC4xODAwNjMgMTkuNDYyQy0wLjEyMjE5NCAxOC4zNCAtMC4wNDIzMDg3IDE3LjE1MTQgMC40MDc1NTkgMTYuMDc4NEMwLjg1NzQyOCAxNS4wMDU0IDEuNjUyNDIgMTQuMTA3MSAyLjY3MDc1IDEzLjUyMTFDMi4zMzIyOSAxMi43NTU5IDIuMTU4MzQgMTEuOTMwMiAyLjE1OTc5IDExLjA5NTdDMi4xNjEzNiA5LjgxOTg4IDIuNTY5MjMgOC41NzY2MSAzLjMyNjA5IDcuNTQwNjlDNC4wODI5NSA2LjUwNDc3IDUuMTUwNzIgNS43MjgyNyA2LjM3OTMxIDUuMzIwMzVDNy42MDc5IDQuOTEyNDQgOC45MzU1MiA0Ljg5MzYyIDEwLjE3NTUgNS4yNjY1NEMxMS40MTU2IDUuNjM5NDYgMTIuNTA1NiA2LjM4NTM2IDEzLjI5MjUgNy4zOTk0SDEzLjI4MzFaIiBmaWxsPSIjMEQ5RERBIi8+Cjwvc3ZnPgo="
/>
<script type="module" crossorigin>
(function () {
const relList = document.createElement("link").relList;
if (
!(relList && relList.supports && relList.supports("modulepreload"))
) {
for (const link of document.querySelectorAll(
'link[rel="modulepreload"]',
))
processPreload(link);
new MutationObserver((mutations) => {
for (const mutation of mutations)
if ("childList" === mutation.type)
for (const node of mutation.addedNodes)
"LINK" === node.tagName &&
"modulepreload" === node.rel &&
processPreload(node);
}).observe(document, { childList: true, subtree: true });
}
function processPreload(link) {
if (link.ep) return;
link.ep = true;
const fetchOpts = (function (link2) {
const fetchOpts2 = {};
return (
link2.integrity && (fetchOpts2.integrity = link2.integrity),
link2.referrerPolicy &&
(fetchOpts2.referrerPolicy = link2.referrerPolicy),
"use-credentials" === link2.crossOrigin
? (fetchOpts2.credentials = "include")
: "anonymous" === link2.crossOrigin
? (fetchOpts2.credentials = "omit")
: (fetchOpts2.credentials = "same-origin"),
fetchOpts2
);
})(link);
fetch(link.href, fetchOpts);
}
})();
// ==== START OF VIOLATIONS ====
const data = {"runDir":"C:\\Users\\samee\\OneDrive\\Desktop\\2gpManagedPackageV2\\","violationCounts":{"total":0,"sev1":0,"sev2":0,"sev3":0,"sev4":0,"sev5":0},"versions":{"code-analyzer":"0.30.0","regex":"0.23.0","pmd":"0.26.1"},"violations":[]};
// ==== END OF VIOLATIONS ====
class Model {
constructor(data2) {
(this.violations = this.processViolations(data2)),
(this.fileCache = /* @__PURE__ */ new Map());
}
sanitize(obj, path, defaultValue = "") {
return path
.split(".")
.reduce(
(acc, part) =>
acc && void 0 !== acc[part] ? acc[part] : defaultValue,
obj,
);
}
getFile(fullPath) {
return (
this.fileCache.has(fullPath) ||
this.fileCache.set(fullPath, fullPath.split("/").pop()),
this.fileCache.get(fullPath)
);
}
getEngines() {
return [...new Set(this.violations.map((v) => v.engine))];
}
getVersions() {
return this.sanitize(data, "versions", {});
}
processViolations(data2) {
return (Array.isArray(data2) ? data2 : data2.violations || []).map(
(violation) => {
const primaryLocationIndex = violation.primaryLocationIndex || 0,
primaryLocation =
Array.isArray(violation.locations) &&
violation.locations.length > 0
? violation.locations[primaryLocationIndex]
: {};
return {
file: this.sanitize(primaryLocation, "file", ""),
severity: this.sanitize(violation, "severity", ""),
rule: this.sanitize(violation, "rule", ""),
engine: this.sanitize(violation, "engine", ""),
message: this.sanitize(violation, "message", ""),
tags: Array.isArray(violation.tags) ? violation.tags : [],
startLine: this.sanitize(primaryLocation, "startLine", ""),
startColumn: this.sanitize(primaryLocation, "startColumn", ""),
endLine: this.sanitize(primaryLocation, "endLine", ""),
endColumn: this.sanitize(primaryLocation, "endColumn", ""),
resources: Array.isArray(violation.resources)
? violation.resources
: [],
primaryLocationIndex,
locations: Array.isArray(violation.locations)
? violation.locations
: [],
};
},
);
}
filterViolations(severityFilter, engineFilter, searchTerm) {
const searchRegex = searchTerm ? new RegExp(searchTerm, "i") : null;
return this.violations.filter(
(violation) =>
(!severityFilter ||
violation.severity.toString() === severityFilter) &&
(!engineFilter || violation.engine === engineFilter) &&
(!searchRegex ||
searchRegex.test(violation.file) ||
searchRegex.test(violation.rule) ||
searchRegex.test(violation.tags.join(", ")) ||
searchRegex.test(violation.message)),
);
}
sortViolations(data2, sortColumn, sortDirection) {
return [...data2].sort((a, b) => {
let aValue, bValue;
if ("file" === sortColumn)
(aValue = this.getFile(a[sortColumn])),
(bValue = this.getFile(b[sortColumn]));
else if ("tags" === sortColumn)
(aValue = a[sortColumn].join(", ")),
(bValue = b[sortColumn].join(", "));
else if (
"startLine" === sortColumn ||
"startColumn" === sortColumn
) {
if (
((aValue = a[sortColumn]),
(bValue = b[sortColumn]),
aValue === bValue)
) {
const endColumn =
"startLine" === sortColumn ? "endLine" : "endColumn";
(aValue = a[endColumn] || a[sortColumn]),
(bValue = b[endColumn] || b[sortColumn]);
}
} else (aValue = a[sortColumn]), (bValue = b[sortColumn]);
return "string" == typeof aValue && "string" == typeof bValue
? "asc" === sortDirection
? aValue.localeCompare(bValue, void 0, { sensitivity: "base" })
: bValue.localeCompare(aValue, void 0, { sensitivity: "base" })
: "asc" === sortDirection
? aValue - bValue
: bValue - aValue;
});
}
groupBy(data2, key) {
return data2.reduce((acc, item) => {
const group = acc.get(item[key]) || [];
return group.push(item), acc.set(item[key], group), acc;
}, /* @__PURE__ */ new Map());
}
groupByfile(data2) {
return this.groupBy(data2, "file");
}
groupBySeverity(data2) {
return this.groupBy(data2, "severity");
}
groupByEngine(data2) {
return this.groupBy(data2, "engine");
}
groupByRule(data2) {
return this.groupBy(data2, "rule");
}
}
class View {
constructor(model) {
(this.model = model),
(this.defaultSort = { column: "file", direction: "asc" }),
(this.currentViolations = []),
(this.currentViolationIndex = -1),
(this.summary = document.getElementById("summary")),
(this.violationsTable = document.getElementById("violationsTable")),
(this.tableBody = this.violationsTable.querySelector("tbody")),
(this.resetButton = document.getElementById("resetButton")),
(this.overlay = document.querySelector(".overlay")),
(this.panel = document.querySelector(".panel")),
(this.panelContent = document.querySelector(".panel-content")),
(this.panelPrev = document.getElementById("prev")),
(this.panelNext = document.getElementById("next")),
(this.panelClose = document.getElementById("panelClose"));
}
getSeverityText(severity) {
return (
{
1: "Severity 1: Critical",
2: "Severity 2: High",
3: "Severity 3: Moderate",
4: "Severity 4: Low",
5: "Severity 5: Info",
}[severity] || ""
);
}
getSeverityValue(severity) {
const severityNum = Number(severity);
return severityNum >= 1 && severityNum <= 5 ? severityNum : "";
}
getSeverityContent(severity) {
const severityValue = this.getSeverityValue(severity),
severityText = this.getSeverityText(severity);
return severityValue && severityText
? `<span class="dot sev${severityValue}"></span> ${severityText}`
: "";
}
getResourcesList(resources) {
if (!resources || 0 === resources.length) return "";
return `<ul>${resources.map((resource) => `<li><a href="${resource}" target="_blank">${resource}</a></li>`).join("")}</ul>`;
}
getLineDisplay(violation) {
return violation.startLine.toString();
}
getColumnDisplay(violation) {
return violation.startColumn.toString();
}
getPosition(violation) {
if (!violation.startLine || !violation.startColumn) return "";
let position = `${violation.startLine}:${violation.startColumn}`;
return (
violation.endLine &&
violation.endColumn &&
(position += `-${violation.endLine}:${violation.endColumn}`),
position
);
}
getLocation(violation) {
const position = this.getPosition(violation);
return `<ul class="locations"><li><span class="file">${position ? `${violation.file} (${position})` : violation.file}</span></li></ul>`;
}
getLocationsList(violation) {
var _a;
if (!((_a = violation.locations) == null ? void 0 : _a.length))
return "";
return `<ul class="locations">${violation.locations
.map((location, index) => {
const position = this.getPosition(location);
return `<li>
<span class="file">
${index == violation.primaryLocationIndex ? "<span class='tag'>Main</span> " : ""}
${location.file} (${position})
</span>
${location.comment ? `<span class="comment">${location.comment}</span>` : ""}
</li>`;
})
.join("")}</ul>`;
}
updateSummary(data2) {
const uniqueFiles = new Set(data2.map((v) => v.file));
(this.summary.textContent = `Found ${data2.length} violation${1 !== data2.length ? "s" : ""} across ${uniqueFiles.size} file${1 !== uniqueFiles.size ? "s" : ""}`),
this.violationsTable.classList.toggle("hidden", 0 === data2.length);
}
updateBoxes(data2) {
const counts = data2.reduce(
(acc, v) => ((acc[v.severity] = (acc[v.severity] || 0) + 1), acc),
{},
);
for (let i = 1; i <= 5; i++)
document.getElementById(`sev${i}`).textContent = counts[i] || 0;
}
toggleBoxes(severity) {
document.querySelectorAll(".box").forEach((box) => {
box.classList.toggle("selected", box.dataset.severity === severity);
});
}
updateReset() {
const severityFilter =
document.getElementById("severityFilter").value,
engineFilter = document.getElementById("engineFilter").value,
searchTerm = document.getElementById("searchInput").value;
this.resetButton.disabled = !(
severityFilter ||
engineFilter ||
searchTerm
);
}
clearFilters() {
(document.getElementById("severityFilter").value = ""),
(document.getElementById("engineFilter").value = ""),
(document.getElementById("searchInput").value = ""),
this.updateReset(),
this.updateTable();
}
populateEngine(engines) {
document.getElementById("engineFilter").innerHTML = `
<option value="">All Engines</option>
<option disabled>───</option>
${engines
.filter((engine) => "" !== engine.trim())
.sort()
.map((engine) => `<option value="${engine}">${engine}</option>`)
.join("")}
`;
}
populateRow(violation) {
const row = this.tableBody.insertRow();
(row.dataset.index = this.model.violations.indexOf(violation)),
(row.innerHTML = `
<td class="file">${this.model.getFile(violation.file)}</td>
<td class="severity">
<span class="dot sev${this.getSeverityValue(violation.severity)}"></span>
${this.getSeverityText(violation.severity)}
</td>
<td class="rule">${violation.rule}</td>
<td class="engine">${violation.engine}</td>
<td class="message">${violation.message}</td>
<td class="tags">${violation.tags.sort().join(", ")}</td>
<td class="startLine">${this.getLineDisplay(violation)}</td>
<td class="startColumn">${this.getColumnDisplay(violation)}</td>
`);
}
populateTable(data2, groupBy) {
(this.tableBody.innerHTML = ""),
this.violationsTable.classList.toggle("ungrouped", "" === groupBy),
"file" === groupBy
? this.populateGroupedTable(this.model.groupByfile(data2), false)
: "severity" === groupBy
? this.populateGroupedTable(
this.model.groupBySeverity(data2),
true,
)
: "engine" === groupBy
? this.populateGroupedTable(
this.model.groupByEngine(data2),
false,
)
: "rule" === groupBy
? this.populateGroupedTable(
this.model.groupByRule(data2),
false,
)
: data2.forEach((violation) => this.populateRow(violation)),
this.updateSummary(data2);
}
populateGroupedTable(groupedData, isSeverity) {
groupedData.forEach((violations, groupKey) => {
(this.tableBody.insertRow().innerHTML = `<td colspan="8" class="group">
${isSeverity ? `<span class="dot sev${this.getSeverityValue(parseInt(groupKey))}"></span>` : ""}
${isSeverity ? this.getSeverityText(parseInt(groupKey)) : groupKey}
<span class="count">(${violations.length})</span>
</td>`),
violations.forEach((violation) => this.populateRow(violation));
});
}
updateTable() {
const severityFilter =
document.getElementById("severityFilter").value,
engineFilter = document.getElementById("engineFilter").value,
searchTerm = document
.getElementById("searchInput")
.value.toLowerCase(),
groupBy = document.getElementById("groupBy").value,
filteredViolations = this.model.filterViolations(
severityFilter,
engineFilter,
searchTerm,
),
sortedViolations = this.model.sortViolations(
filteredViolations,
this.defaultSort.column,
this.defaultSort.direction,
);
(this.currentViolations = sortedViolations),
this.populateTable(sortedViolations, groupBy),
this.updateSummary(sortedViolations),
this.toggleBoxes(severityFilter),
this.updateReset();
}
updateSorting(column) {
this.defaultSort.column === column
? (this.defaultSort.direction =
"asc" === this.defaultSort.direction ? "desc" : "asc")
: ((this.defaultSort.column = column),
(this.defaultSort.direction = "asc")),
this.updateArrow();
}
updateArrow() {
document.querySelectorAll("#violationsTable th").forEach((th) => {
th.classList.remove("asc", "desc"),
th.dataset.sort === this.defaultSort.column &&
th.classList.add(this.defaultSort.direction);
});
}
updatePagination() {
(this.panelPrev.disabled = this.currentViolationIndex <= 0),
(this.panelNext.disabled =
this.currentViolationIndex >= this.currentViolations.length - 1);
}
populatePanel(violation) {
const panelFields = [
{ label: "Rule", content: violation.rule },
{
label: "Severity",
content: this.getSeverityContent(violation.severity),
},
{ label: "Engine", content: violation.engine },
{ label: "Message", content: violation.message },
{
label:
violation.locations.length <= 1 ? "Location" : "Locations",
content:
violation.locations.length <= 1
? this.getLocation(violation)
: this.getLocationsList(violation),
},
{
label: "Tags",
content:
violation.tags.length > 0 ? violation.tags.join(", ") : "",
},
{
label: "Resources",
content: this.getResourcesList(violation.resources),
},
],
dl = document.createElement("dl");
panelFields.forEach(({ label, content }) => {
content && (dl.innerHTML += `<dt>${label}</dt><dd>${content}</dd>`);
}),
(this.panelContent.innerHTML = ""),
this.panelContent.appendChild(dl);
}
showPanel(violation) {
(this.currentViolationIndex = this.currentViolations.findIndex(
(v) => v === violation,
)),
this.populatePanel(violation),
this.overlay.classList.add("visible"),
this.panel.classList.add("visible"),
this.updatePagination(),
(document.body.style.overflow = "hidden");
}
paginatePanel(direction) {
const newIndex = this.currentViolationIndex + direction;
if (newIndex >= 0 && newIndex < this.currentViolations.length) {
this.currentViolationIndex = newIndex;
const violation =
this.currentViolations[this.currentViolationIndex];
this.populatePanel(violation), this.updatePagination();
}
}
hidePanel() {
this.overlay.classList.remove("visible"),
this.panel.classList.remove("visible"),
setTimeout(() => {
document.body.style.overflow = "";
}, 300);
}
populateVersions(versions) {
if (!versions || 0 === Object.keys(versions).length) return;
const footer = document.querySelector(".footer");
footer.innerHTML =
`<p>Versions: <span class="versions">${Object.entries(versions)
.map(
([key, value]) => `<span class="version">
<span class="version-name">${key}</span>
<span class="version-number">v${value}</span>
</span>`,
)
.join("")}</p>` + footer.innerHTML;
}
}
new (class {
constructor(data2) {
const parsedData =
"string" == typeof data2 ? JSON.parse(data2) : data2;
(this.model = new Model(parsedData)),
(this.view = new View(this.model));
const engines = this.model.getEngines();
this.view.populateEngine(engines);
const violations = this.model.violations;
this.view.updateSummary(violations),
this.view.updateBoxes(violations),
this.view.toggleBoxes(""),
this.view.updateTable(),
this.view.updateArrow(),
this.view.updateReset(),
this.view.populateVersions(this.model.getVersions()),
this.eventListeners();
}
handleSeverityBoxClick(event) {
const severity = event.currentTarget.dataset.severity,
severityFilter = document.getElementById("severityFilter");
(severityFilter.value =
severityFilter.value === severity ? "" : severity),
this.view.updateTable();
}
handleResetClick() {
this.view.updateTable(), this.view.clearFilters();
}
handleTableHeaderClick(event) {
const th = event.target.closest("th");
th &&
th.dataset.sort &&
(this.view.updateSorting(th.dataset.sort), this.view.updateTable());
}
handleTableRowClick(event) {
const row = event.target.closest("tr");
if (row) {
const violationIndex = row.dataset.index,
violation = this.model.violations[violationIndex];
this.view.showPanel(violation);
}
}
handleGroupBy(value) {
(document.getElementById("groupBy").value = value),
this.view.updateTable();
}
handleShortcuts(event) {
if ("INPUT" === document.activeElement.tagName) return;
const action = {
n: () => this.handleGroupBy("file"),
e: () => this.handleGroupBy("engine"),
s: () => this.handleGroupBy("severity"),
r: () => this.handleGroupBy("rule"),
u: () => this.handleGroupBy(""),
escape: () => this.handleEscapeKey(),
arrowup: () => this.handleArrowKey(-1),
arrowleft: () => this.handleArrowKey(-1),
arrowdown: () => this.handleArrowKey(1),
arrowright: () => this.handleArrowKey(1),
}[event.key.toLowerCase()];
action && (event.preventDefault(), action());
}
handleEscapeKey() {
this.view.overlay.classList.contains("visible")
? this.view.hidePanel()
: this.view.clearFilters();
}
handleArrowKey(direction) {
this.view.overlay.classList.contains("visible") &&
this.view.paginatePanel(direction);
}
eventListeners() {
document.querySelectorAll(".box").forEach((box) => {
box.addEventListener(
"click",
this.handleSeverityBoxClick.bind(this),
);
}),
["severityFilter", "engineFilter", "groupBy"].forEach((id) => {
document
.getElementById(id)
.addEventListener(
"change",
this.view.updateTable.bind(this.view),
);
}),
document
.getElementById("searchInput")
.addEventListener("input", this.view.updateTable.bind(this.view)),
this.view.resetButton.addEventListener(
"click",
this.handleResetClick.bind(this),
),
document
.querySelector("#violationsTable thead")
.addEventListener(
"click",
this.handleTableHeaderClick.bind(this),
),
document
.querySelector("#violationsTable tbody")
.addEventListener("click", this.handleTableRowClick.bind(this)),
this.view.overlay.addEventListener("click", (e) => {
e.target === this.view.overlay && this.view.hidePanel();
}),
this.view.panelPrev.addEventListener("click", () =>
this.view.paginatePanel(-1),
),
this.view.panelNext.addEventListener("click", () =>
this.view.paginatePanel(1),
),
this.view.panelClose.addEventListener("click", (e) => {
e.preventDefault(), this.view.hidePanel();
}),
document.addEventListener(
"keydown",
this.handleShortcuts.bind(this),
);
}
})(data);
</script>
<style rel="stylesheet" crossorigin>
/* Light Theme */
:root {
--color-text: #181818;
--color-link: #0176d3;
--color-link-hover: #014486;
--color-shade-1: #ffffff;
--color-shade-2: #fbfbfb;
--color-shade-3: #f3f3f3;
--color-shade-4: #e5e5e5;
--color-shade-5: #c9c9c9;
--color-shade-6: #999999;
--color-shade-7: #747474;
--color-severity-1: #aa3001;
--color-severity-2: #ea001e;
--color-severity-3: #f38303;
--color-severity-4: #fcc003;
--color-severity-5: #41b658;
--color-focus: rgba(0, 119, 204, 0.2);
--color-shadow: rgba(0, 0, 0, 0.1);
--color-overlay: rgba(0, 0, 0, 0.25);
--font-body: system-ui, sans-serif;
--font-code: monospace, sans-serif;
}
.hidden {
display: none;
}
body {
font-family: var(--font-body);
background-color: var(--color-shade-1);
margin: 0;
transition: color 1s ease;
}
.page {
min-width: 980px;
margin: 0 auto;
background-color: var(--color-shade-1);
}
.page a {
color: var(--color-link);
text-decoration: none;
}
.page a:hover {
text-decoration: underline;
color: var(--color-link-hover);
}
.page .filter-link {
color: var(--color-text);
cursor: help;
}
.page .filter-link:hover {
text-decoration: none;
border-bottom: 1px dotted var(--color-text);
color: var(--color-text);
}
.header {
margin: 0;
border-bottom: 1px solid var(--color-shade-4);
display: flex;
justify-content: space-between;
margin: 0;
padding: 0 20px;
background-color: var(--color-shade-2);
}
.header h1.logo {
background-position: left center;
background-repeat: no-repeat;
background-size: 35px 24px;
color: var(--color-text);
font-size: 16px;
font-weight: normal;
margin: 0;
padding: 20px 20px 20px 36px;
text-align: center;
}
.header h2.title {
background-position: left center;
background-repeat: no-repeat;
background-size: 26px 26px;
color: var(--color-text);
font-size: 16px;
font-weight: normal;
margin: 0;
padding: 20px 20px 20px 36px;
text-align: center;
}
.header p.help {
font-size: 16px;
margin: 0;
padding: 20px 0 20px 20px;
}
.boxes {
display: flex;
gap: 20px;
justify-content: space-between;
margin: 50px 20px;
}
.box {
align-items: center;
background: var(--color-shade-1);
border-radius: 8px;
border: 1px solid var(--color-shade-5);
box-shadow: 0px 2px 2px 0px var(--color-shade-4);
cursor: pointer;
display: flex;
flex-direction: row-reverse;
flex: 1 1 0;
gap: 10px;
justify-content: space-evenly;
padding: 20px;
transition: all 0.1s ease;
}
.box:hover {
border: 1px solid var(--color-shade-7);
background-color: var(--color-shade-2);
}
.box:active,
.box.selected {
border: 1px solid var(--color-link);
box-shadow: 0px 0px 0px 2px var(--color-focus);
}
.box h4 {
color: var(--color-text);
line-height: 24px;
padding: 0;
margin: 0;
min-width: 80px;
}
.box h4 span {
display: flex;
flex-direction: column;
}
.box h4 span:first-child {
font-size: 14px;
font-weight: bold;
}
.box h4 span:last-child {
font-size: 16px;
font-weight: normal;
}
.box p {
font-size: 44px;
margin: 0;
padding: 0;
}
.box .sev1 {
color: var(--color-severity-1);
}
.box .sev2 {
color: var(--color-severity-2);
}
.box .sev3 {
color: var(--color-severity-3);
}
.box .sev4 {
color: var(--color-severity-4);
}
.box .sev5 {
color: var(--color-severity-5);
}
#summary {
color: var(--color-text);
font-size: 18px;
font-weight: bold;
margin: 20px 20px;
}
.toolbar {
display: flex;
justify-content: space-between;
margin: 20px 20px;
}
.toolbar h3 {
color: var(--color-text);
font-size: 14px;
}
@media screen and (max-width: 1200px) {
.toolbar h3 {
display: none;
}
}
.toolbar form {
display: flex;
gap: 20px;
}
.toolbar .filter {
display: flex;
align-items: center;
gap: 20px;
margin-right: 20px;
}
.toolbar .view {
display: flex;
align-items: center;
gap: 20px;
}
.toolbar input,
.toolbar select,
.toolbar button {
font-size: 16px;
}
.toolbar select {
appearance: none;
background-color: var(--color-shade-1);
background-position: right 10px top 50%;
background-repeat: no-repeat;
background-size: 10px auto;
border-radius: 4px;
border: 1px solid var(--color-shade-7);
color: var(--color-text);
cursor: pointer;
font-size: 14px;
padding: 8px 30px 8px 10px;
transition: all 0.1s ease;
min-width: 160px;
}
.toolbar select:hover {
border-color: var(--color-text);
}
.toolbar select:focus {
outline: none;
border-color: var(--color-link);
box-shadow: 0 0 0 2px var(--color-focus);
}
.toolbar input {
appearance: none;
background-color: var(--color-shade-1);
background-position: left 10px top 50%;
background-repeat: no-repeat;
background-size: 16px auto;
border-radius: 4px;
border: 1px solid var(--color-shade-7);
color: var(--color-text);
cursor: pointer;
font-size: 14px;
padding: 8px 8px 8px 34px;
transition: all 0.1s ease;
min-width: 260px;
}
.toolbar input::placeholder {
color: var(--color-shade-6);
}
.toolbar input:hover {
border-color: var(--color-text);
}
.toolbar input:focus {
outline: none;
border-color: var(--color-link);
box-shadow: 0 0 0 2px var(--color-focus);
}
.toolbar button,
.panel button {
position: relative;
display: inline-flex;
align-items: center;
padding: 0;
background-color: transparent;
background-clip: border-box;
border: 1px solid var(--color-shade-7);
border-radius: 4px;
box-shadow: none;
text-decoration: none;
color: var(--color-link);
appearance: none;
white-space: normal;
user-select: none;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
}
.toolbar button:hover,
.panel button:hover {
background-color: var(--color-shade-3);
border-color: var(--color-text);
}
.toolbar button:active,
.panel button:active {
background-color: var(--color-shade-3);
border-color: var(--color-link-hover);
box-shadow: 0 0 0 2px var(--color-focus);
color: var(--color-link-hover);
outline: none;
}
.toolbar button:focus,
.panel button:focus {
outline: none;
border-color: var(--color-link);
box-shadow: 0 0 0 2px var(--color-focus);
}
.toolbar button:disabled,
.toolbar button[disabled],
.panel button:disabled,
.panel button[disabled] {
background-color: transparent;
border-color: transparent;
color: var(--color-shade-5);
cursor: default;
border: 1px solid var(--color-shade-5);
}
.toolbar button:disabled *,
.toolbar button[disabled] *,
.panel button:disabled *,
.panel button[disabled] * {
pointer-events: none;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
table th,
table td {
text-align: left;
padding: 8px 14px;
height: 16px;
}
table th {
background-color: var(--color-shade-4);
border-top: 1px solid var(--color-shade-5);
border-bottom: 1px solid var(--color-shade-5);
cursor: pointer;
}
table.ungrouped th {
background-color: var(--color-shade-3);
}
table th.asc::after,
table th.desc::after {
content: "";
display: inline-block;
width: 12px;
height: 12px;
margin-left: 5px;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
opacity: 1;
}
table th.asc::after {
transform: rotate(180deg);
}
table tr {
background-color: var(--color-shade-1);
border-top: 1px solid var(--color-shade-5);
border-bottom: 1px solid var(--color-shade-5);
}
table tr:hover {
background-color: var(--color-shade-2);
cursor: pointer;
}
table td.group {
background-color: var(--color-shade-3);
font-size: 14px;
cursor: default;
}
table .severity {
min-width: 160px;
}
table .engine,
table .rule,
table .tags {
min-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
table .message {
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
table .count {
color: var(--color-shade-7);
}
table .startLine,
table .startColumn {
min-width: 80px;
}
@media screen and (max-width: 1600px) {
table .tags {
display: none;
}
}
@media screen and (max-width: 1400px) {
table .engine {
display: none;
}
}
@media screen and (max-width: 1300px) {
table .message {
display: none;
}
}
.footer {
font-family: var(--font-body);
font-size: 14px;
padding: 20px 0 40px 0;
text-align: center;
}
.footer p {
display: flex;
flex-direction: row;
gap: 0;
justify-content: center;
align-items: center;
color: var(--color-shade-7);
padding-bottom: 10px;
font-size: 12px;
}
.versions {
display: flex;
flex-direction: row;
gap: 10px;
justify-content: center;
align-items: center;
margin-left: 10px;
}
.version {
display: flex;
vertical-align: middle;
border: 1px solid var(--color-shade-5);
border-radius: 20px;
font-size: 12px;
line-height: 1.8;
padding: 0 10px;
margin: 0;
}
.version .version-name {
font-weight: 500;
color: var(--color-shade-7);
border-right: 1px solid var(--color-shade-5);
padding: 0 8px 0 0;
}
.version .version-number {
color: var(--color-shade-7);
padding: 0 0 0 8px;
}
.rundir {
margin-left: 5px;
font-weight: 500;
}
.dot {
font-weight: bold;
border-radius: 50%;
margin-right: 4px;
color: var(--color-shade-1);
text-align: center;
font-size: 12px;
display: inline-block;
width: 10px;
height: 10px;
}
.dot.sev {
display: none;
}
.dot.sev1 {
background-color: var(--color-severity-1);
}
.dot.sev2 {
background-color: var(--color-severity-2);
}
.dot.sev3 {
background-color: var(--color-severity-3);
}
.dot.sev4 {
background-color: var(--color-severity-4);
}
.dot.sev5 {
background-color: var(--color-severity-5);
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--color-overlay);
z-index: 1000;
opacity: 0;
visibility: hidden;
transition:
opacity 0.3s ease,
visibility 0.3s ease;
}
.overlay.visible {
opacity: 1;
visibility: visible;
}
.panel {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
right: -800px;
width: 800px;
height: 100%;
background-color: var(--color-shade-1);
border-left: 1px solid var(--color-shade-5);
box-shadow: -2px 0 5px var(--color-shadow);
transition: all 0.3s ease;
}
@media screen and (max-width: 1400px) {
.panel {
right: -600px;
width: 600px;
}
}
@media screen and (max-width: 800px) {
.panel {
right: -100%;
width: 100%;
}
}
.panel.visible {
right: 0;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid var(--color-shade-4);
background-color: var(--color-shade-2);
}
.panel-header h3 {
margin: 0;
font-size: 16px;
}
.panel-header a {
display: block;
width: 12px;
height: 12px;
background-color: transparent;
background-repeat: no-repeat;
background-position: center;
background-size: 12px 12px;
}
.panel-content {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
}
.panel-content dl {
margin: 0;
}
.panel-content dt {
font-size: 14px;
font-weight: bold;
line-height: 1.5;
margin-bottom: 5px;
}
.panel-content dd {
font-size: 14px;
margin-left: 0;
margin-bottom: 25px;
}
.panel-content dd#panelFile,
.panel-content dd#panelResources {
word-break: break-all;
}
.panel-content ul,
.panel-content ol {
padding-left: 20px;
}
.panel-content li {
padding-left: 5px;
margin-bottom: 10px;
}
.panel-content .severity {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}
.panel-content .locations {
list-style: none;
padding: 0;
margin: 0;
}
.panel-content .locations li {
margin: 15px 0 0 0;
padding: 0;
background: var(--color-shade-1);
border-radius: 6px;
border: 1px solid var(--color-shade-5);
box-shadow: 0px 2px 2px 0px var(--color-shade-4);
}
.panel-content .tag {
text-transform: uppercase;
font-family: var(--font-mono);
font-weight: 400;
padding: 2px 8px;
border-radius: 10px;
font-size: 10px;
margin-right: 2px;
border: 1px solid var(--color-shade-5);
letter-spacing: 0.5px;
}
.panel-content .file {
display: block;
font-family: var(--font-code);
font-size: 12px;
padding: 8px 10px;
line-height: 1.6;
border-radius: 6px;
}
.panel-content .comment {
display: block;
border-top: 1px solid var(--color-shade-5);
padding: 8px 10px;
background-color: var(--color-shade-2);
border-radius: 0 0 6px 6px;
line-height: 1.6;
}
.panel-footer {
padding: 20px;
background-color: var(--color-shade-1);
border-top: 1px solid var(--color-shade-4);
display: flex;
justify-content: space-between;
}
/* Images */
.header h1.logo {
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjI4MzEgNy4zOTk0QzEzLjg5MjUgNi43Njk3MyAxNC42NDQ1IDYuMjkwNiAxNS40Nzc5IDYuMDAxMDRDMTYuMzExMiA1LjcxMTQ5IDE3LjIwMjIgNS42MTk3IDE4LjA3ODQgNS43MzMxM0MxOC45NTQ2IDUuODQ2NTcgMTkuNzkxMiA2LjE2MjAzIDIwLjUyIDYuNjUzODNDMjEuMjQ4OSA3LjE0NTYzIDIxLjg0OTMgNy43OTk4NSAyMi4yNzI1IDguNTYzMjJDMjMuMTQ4MSA4LjE3OTUxIDI0LjA5NiA3Ljk4MTI1IDI1LjA1NDUgNy45ODEzMUMyNi44OTY2IDcuOTgxMzEgMjguNjYzMiA4LjcwMTMyIDI5Ljk2NTggOS45ODI5M0MzMS4yNjgzIDExLjI2NDUgMzIgMTMuMDAyOCAzMiAxNC44MTUzQzMyIDE2LjYyNzcgMzEuMjY4MyAxOC4zNjYgMjkuOTY1OCAxOS42NDc2QzI4LjY2MzIgMjAuOTI5MiAyNi44OTY2IDIxLjY0OTIgMjUuMDU0NSAyMS42NDkyQzI0LjYgMjEuNjQ5NSAyNC4xNDY2IDIxLjYwNDMgMjMuNzAxNCAyMS41MTQyQzIzLjI2NDggMjIuMjg0IDIyLjYyNzIgMjIuOTI1IDIxLjg1NDQgMjMuMzcxQzIxLjA4MTcgMjMuODE3MSAyMC4yMDE5IDI0LjA1MTkgMTkuMzA2IDI0LjA1MTNDMTguNTQzNSAyNC4wNTM4IDE3Ljc5MDYgMjMuODgzMyAxNy4xMDU5IDIzLjU1MzJDMTYuNjU3MiAyNC41OTY3IDE1Ljg5OTkgMjUuNDgzMyAxNC45MzI0IDI2LjA5NzdDMTMuOTY0OCAyNi43MTIxIDEyLjgzMTggMjcuMDI1OSAxMS42ODA1IDI2Ljk5ODNDMTAuNTI5MyAyNi45NzA3IDkuNDEzMTQgMjYuNjAzIDguNDc3MTQgMjUuOTQyOUM3LjU0MTE1IDI1LjI4MjggNi44Mjg2IDI0LjM2MSA2LjQzMjE2IDIzLjI5NzJDNi4wNzEyNSAyMy4zNzIxIDUuNzAzMzIgMjMuNDA5NSA1LjMzNDQ2IDIzLjQwODlDNC4xNTQ4NSAyMy4zOTYyIDMuMDEyMDUgMjMuMDAzMyAyLjA4MTA3IDIyLjI5MDRDMS4xNTAwOSAyMS41Nzc1IDAuNDgyMzE5IDIwLjU4MzkgMC4xODAwNjMgMTkuNDYyQy0wLjEyMjE5NCAxOC4zNCAtMC4wNDIzMDg3IDE3LjE1MTQgMC40MDc1NTkgMTYuMDc4NEMwLjg1NzQyOCAxNS4wMDU0IDEuNjUyNDIgMTQuMTA3MSAyLjY3MDc1IDEzLjUyMTFDMi4zMzIyOSAxMi43NTU5IDIuMTU4MzQgMTEuOTMwMiAyLjE1OTc5IDExLjA5NTdDMi4xNjEzNiA5LjgxOTg4IDIuNTY5MjMgOC41NzY2MSAzLjMyNjA5IDcuNTQwNjlDNC4wODI5NSA2LjUwNDc3IDUuMTUwNzIgNS43MjgyNyA2LjM3OTMxIDUuMzIwMzVDNy42MDc5IDQuOTEyNDQgOC45MzU1MiA0Ljg5MzYyIDEwLjE3NTUgNS4yNjY1NEMxMS40MTU2IDUuNjM5NDYgMTIuNTA1NiA2LjM4NTM2IDEzLjI5MjUgNy4zOTk0SDEzLjI4MzFaIiBmaWxsPSIjMEQ5RERBIi8+Cjwvc3ZnPgo=");
}
.header h2.title {
background-image: url('data:image/svg+xml,<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="26" height="26" rx="4" fill="%23107CAD"/><path fill-rule="evenodd" clip-rule="evenodd" d="M18.1096 5.37199C16.5949 5.37199 15.3626 6.61286 15.3626 8.13812C15.3626 9.66337 16.5949 10.904 18.1096 10.904C19.6245 10.904 20.8568 9.66337 20.8568 8.13812C20.8568 6.61286 19.6245 5.37199 18.1096 5.37199ZM21.4798 10.4994L22.8004 11.829C23.0665 12.097 23.0665 12.5311 22.8004 12.7991C22.6675 12.933 22.4931 13 22.3188 13C22.1444 13 21.9699 12.933 21.837 12.7991L20.5252 11.4782C19.8463 11.9775 19.0128 12.276 18.1096 12.276C15.8435 12.276 14 10.4196 14 8.13812C14 5.85632 15.8435 4 18.1096 4C20.3757 4 22.2194 5.85632 22.2194 8.13812C22.2194 9.01581 21.9445 9.82904 21.4798 10.4994ZM12.7757 18.3979H15.7174C16.202 18.3979 16.595 18.021 16.595 17.5561C16.595 17.0912 16.202 16.7143 15.7174 16.7143H12.7757C12.2911 16.7143 11.8981 17.0912 11.8981 17.5561C11.8981 18.021 12.2911 18.3979 12.7757 18.3979ZM7.31383 13.8826C7.31383 14.3475 7.70683 14.7245 8.1915 14.7245H11.3624C11.8471 14.7245 12.24 14.3475 12.24 13.8826C12.24 13.4178 11.8471 13.0408 11.3624 13.0408H8.1915C7.70683 13.0408 7.31383 13.4178 7.31383 13.8826ZM8.1915 18.3979H9.6328C10.1174 18.3979 10.5105 18.021 10.5105 17.5561C10.5105 17.0912 10.1174 16.7143 9.6328 16.7143H8.1915C7.70683 16.7143 7.31383 17.0912 7.31383 17.5561C7.31383 18.021 7.70683 18.3979 8.1915 18.3979ZM11.8114 11.051C12.7963 13.426 15.2094 15.1071 18.0363 15.1071C18.7198 15.1071 19.3788 15.0077 20 14.8254V19.7755C20 20.4517 19.4284 21 18.7234 21H6.2766C5.5716 21 5 20.4517 5 19.7755V7.22451C5 6.54821 5.5716 6 6.2766 6H11.9494C11.5583 6.8163 11.3342 7.72136 11.3342 8.67858C11.3342 8.91145 11.3487 9.14087 11.3738 9.36739H8.1915C7.70683 9.36739 7.31383 9.74429 7.31383 10.2092C7.31383 10.674 7.70683 11.051 8.1915 11.051H11.8114Z" fill="white"/></svg>');
}
.toolbar select {
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAxMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEuNTk2MzIgMTIuNjkyNEg4LjQwNDAxQzguNTk2MzEgMTIuNjkyNCA4LjczMDkzIDEyLjk0MjQgOC41NzcwOCAxMy4xMTU1TDUuMjUwMTYgMTcuMTkyNEM1LjEzNDc4IDE3LjM0NjIgNC44ODQ3OCAxNy4zNDYyIDQuNzY5MzkgMTcuMTkyNEwxLjQwNDAxIDEzLjExNTVDMS4yNjkzOSAxMi45NDI0IDEuMzg0NzggMTIuNjkyNCAxLjU5NjMyIDEyLjY5MjRaIiBmaWxsPSIjNzQ3NDc0Ii8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik04LjQwMzY4IDcuMzA3NjJMMS41OTU5OSA3LjMwNzYyQzEuNDAzNjggNy4zMDc2MiAxLjI2OTA3IDcuMDU3NjIgMS40MjI5MiA2Ljg4NDU0TDQuNzQ5ODQgMi44MDc2MkM0Ljg2NTIyIDIuNjUzNzcgNS4xMTUyMiAyLjY1Mzc3IDUuMjMwNjEgMi44MDc2Mkw4LjU5NTk5IDYuODg0NTRDOC43MzA2MSA3LjA1NzYyIDguNjE1MjIgNy4zMDc2MiA4LjQwMzY4IDcuMzA3NjJaIiBmaWxsPSIjNzQ3NDc0Ii8+PC9zdmc+");
}
.toolbar input {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15.26 13.94l-4.12-4.1a6.43 6.43 0 001.05-4.23c-.37-2.65-2.52-4.75-5.19-5A6.43 6.43 0 00.67 7c.25 2.65 2.34 4.84 4.98 5.21a6.43 6.43 0 004.21-1.05l4.08 4.11c.18.19.46.19.65 0l.64-.65c.18-.18.18-.49.03-.67zM2.49 6.41a3.96 3.96 0 117.92 0 3.96 3.96 0 01-7.92 0z' fill='%23747474'/%3E%3C/svg%3E");
}
table th.asc::after,
table th.desc::after {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.554 4.85a.4.4 0 000-.623L6.092.837a.4.4 0 00-.646 0L1.985 4.227a.4.4 0 000 .623l.646.623a.4.4 0 00.554 0l1.085-1.06c.184-.185.507-.046.507.207v6.227c0 .23.208.46.462.46h.923c.254 0 .461-.253.461-.46V4.619c0-.276.323-.392.508-.207l1.084 1.06a.4.4 0 00.554 0l.6-.622z' fill='%23747474'/%3E%3C/svg%3E");
}
.panel-header a {
background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7.53863 5.81555L11.5386 1.78478C11.7232 1.60017 11.7232 1.32324 11.5386 1.13863L10.9232 0.492473C10.7386 0.307858 10.4617 0.307858 10.2771 0.492473L6.24632 4.52324C6.12324 4.64632 5.93863 4.64632 5.81555 4.52324L1.78478 0.461704C1.60017 0.277088 1.32324 0.277088 1.13863 0.461704L0.492473 1.10786C0.307858 1.29247 0.307858 1.5694 0.492473 1.75401L4.52324 5.78478C4.64632 5.90786 4.64632 6.09247 4.52324 6.21555L0.461704 10.2771C0.277088 10.4617 0.277088 10.7386 0.461704 10.9232L1.10786 11.5694C1.29247 11.754 1.5694 11.754 1.75401 11.5694L5.78478 7.53863C5.90786 7.41555 6.09247 7.41555 6.21555 7.53863L10.2463 11.5694C10.4309 11.754 10.7079 11.754 10.8925 11.5694L11.5386 10.9232C11.7232 10.7386 11.7232 10.4617 11.5386 10.2771L7.53863 6.24632C7.41555 6.12324 7.41555 5.93863 7.53863 5.81555Z' fill='%23747474'/%3E%3C/svg%3E");
}
/* Dark Theme */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #bbbbbb;
--color-link: #0099ee;
--color-link-hover: #55bbee;
--color-shade-1: #0a0a0a;
--color-shade-2: #161616;
--color-shade-3: #202020;
--color-shade-4: #2e2e2e;
--color-shade-5: #424242;
--color-shade-6: #666666;
--color-shade-7: #969696;
--color-severity-1: #ff3355;
--color-severity-2: #ff5533;
--color-severity-3: #ff9933;
--color-severity-4: #ffd633;
--color-severity-5: #55cc66;
--color-focus: rgba(77, 184, 255, 0.4);
--color-shadow: rgba(0, 0, 0, 0.5);
--color-overlay: rgba(0, 0, 0, 0.6);
}
body {
background-color: var(--color-shade-1);
color: var(--color-text);
}
.page {
background-color: var(--color-shade-1);
}
.header {
background-color: var(--color-shade-2);
border-bottom-color: var(--color-shade-4);
}
.box {
background-color: var(--color-shade-2);
border-color: var(--color-shade-5);
box-shadow: 0px 2px 2px 0px var(--color-shadow);
}
.box:hover {
background-color: var(--color-shade-3);
border-color: var(--color-link);
}
.box:active,
.box.selected {
background-color: var(--color-shade-3);
border-color: var(--color-link);
box-shadow: none;
}
.toolbar select,
.toolbar input {
background-color: var(--color-shade-2);
border-color: var(--color-shade-5);
color: var(--color-text);
}
.toolbar select:hover,
.toolbar input:hover {
border-color: var(--color-link);
}
.toolbar select:focus,
.toolbar input:focus {
border-color: var(--color-link);
box-shadow: 0 0 0 1px var(--color-link);
}
.toolbar button,
.panel button {
background-color: var(--color-shade-3);
border-color: var(--color-shade-6);
color: var(--color-link);
}
.toolbar button:hover,
.panel button:hover {
background-color: var(--color-shade-4);
border-color: var(--color-shade-7);
}
.toolbar button:active,
.panel button:active,
.toolbar button:focus,
.panel button:focus {
background-color: var(--color-shade-4);
border-color: var(--color-link);
box-shadow: 0 0 0 2px var(--color-focus);
color: var(--color-link-hover);
}
table th {
background-color: var(--color-shade-4);
border-color: var(--color-shade-5);
}
table.ungrouped th {
background-color: var(--color-shade-3);
}
table tr {
background-color: var(--color-shade-2);
border-color: var(--color-shade-4);
}
table tr:hover {
background-color: var(--color-shade-3);
}
table td.group {
background-color: var(--color-shade-3);
}
.panel {
background-color: var(--color-shade-2);
border-left-color: var(--color-shade-5);
box-shadow: -2px 0 5px var(--color-shadow);
}
.panel-header {
background-color: var(--color-shade-3);
border-bottom-color: var(--color-shade-5);
}
.panel-content .locations li {
background-color: var(--color-shade-2);
border-color: var(--color-shade-5);
box-shadow: 0px 2px 2px 0px var(--color-shadow);
}
.panel-content .locations .file {
background-color: var(--color-shade-3);
}
.panel-footer {
background-color: var(--color-shade-2);
border-top-color: var(--color-shade-4);
}
.toolbar input::placeholder {
color: var(--color-shade-6);
}
.footer {
color: var(--color-shade-7);
}
.toolbar button:disabled,
.toolbar button[disabled],
.panel button:disabled,
.panel button[disabled] {
background-color: var(--color-shade-2);
border-color: var(--color-shade-4);
color: var(--color-shade-6);
}
}
</style>
</head>
<body>
<div class="page">
<div class="overlay">
<div class="panel" role="dialog">
<div class="panel-header">
<h3>Details</h3>
<a href="#" id="panelClose" class="panel-close"></a>
</div>
<div class="panel-content"></div>
<div class="panel-footer">
<button id="prev">← Prev</button>
<button id="next">Next →</button>
</div>
</div>
</div>
<header class="header">
<h1 class="logo">Salesforce</h1>
<h2 class="title">
<strong class="text">Code Analyzer Report</strong> –
<!-- START OF TIMESTAMP -->
<span class="timestamp">Jul 31, 2025, 3:45 PM</span>
<!-- END OF TIMESTAMP -->
</h2>
<p class="help" aria-label="documentation">
<a
href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview"
>Developer Docs</a
>
</p>
</header>
<div class="boxes">
<div class="box" data-severity="1">
<h4><span>Severity 1</span> <span>Critical</span></h4>
<p class="sev1" id="sev1">0</p>
</div>
<div class="box" data-severity="2">
<h4><span>Severity 2</span> <span>High</span></h4>
<p class="sev2" id="sev2">0</p>
</div>
<div class="box" data-severity="3">
<h4><span>Severity 3</span> <span>Moderate</span></h4>
<p class="sev3" id="sev3">0</p>
</div>
<div class="box" data-severity="4">
<h4><span>Severity 4</span> <span>Low</span></h4>
<p class="sev4" id="sev4">0</p>
</div>
<div class="box" data-severity="5">
<h4><span>Severity 5</span> <span>Info</span></h4>
<p class="sev5" id="sev5">0</p>
</div>
</div>
<main class="content" role="main">
<h3 id="summary">Found 0 violations across 0 files</h3>
<div class="toolbar">
<div class="filter">
<h3>Filter</h3>
<form role="search" aria-label="Filter violations">
<select id="severityFilter" aria-label="Filter by severity">
<option value="">All Severities</option>
<option disabled>───</option>
<option value="1">Severity 1: Critical</option>
<option value="2">Severity 2: High</option>
<option value="3">Severity 3: Moderate</option>
<option value="4">Severity 4: Low</option>
<option value="5">Severity 5: Info</option>
</select>
<select id="engineFilter" aria-label="Filter by engine">
<option value="">All Engines</option>
</select>
<input
type="text"
id="searchInput"
placeholder="Filter files, rules, tags & messages"
aria-label="Filter files, rules, tags & messages"
/>
<button id="resetButton" aria-label="Reset filters" disabled>
Reset
</button>
</form>
</div>
<div class="view">
<h3>Group</h3>
<select id="groupBy">
<option value="">Ungrouped</option>
<option disabled>───</option>
<option value="engine">Engine</option>
<option value="file">Filename</option>
<option value="rule">Rule</option>
<option value="severity">Severity</option>
</select>
</div>
</div>
<table id="violationsTable">
<thead>
<tr>
<th data-sort="file" class="file">Filename</th>
<th data-sort="severity" class="severity">Severity</th>
<th data-sort="rule" class="rule">Rule</th>
<th data-sort="engine" class="engine">Engine</th>
<th data-sort="message" class="message">Message</th>
<th data-sort="tags" class="tags">Tags</th>
<th data-sort="startLine" class="startLine">Line</th>
<th data-sort="startColumn" class="startColumn">Column</th>
</tr>
</thead>
<tbody></tbody>
</table>
</main>
<footer class="footer" role="contentinfo">
<p>
Generated by Code Analyzer from path:
<!-- START OF RUNDIR -->
<span class="rundir">C:\Users\samee\OneDrive\Desktop\2gpManagedPackageV2\</span>
<!-- END OF RUNDIR -->
</p>
</footer>
</div>
</body>
</html>
3.Observe the output or HTML report.
Have you tried to resolve this issue yourself first?
Bug Description
When running sf code-analyzer run using the latest v5.x CLI with a valid Salesforce DX project, the tool reports “0 violations across 0 files”, even though multiple .cls and .trigger files exist in the specified --target directory.
Output / Logs
Steps To Reproduce
Steps to Reproduce:
1.Create a valid SFDX project with Apex classes and triggers under force-app/main/default.
2.Run the command:
sf code-analyzer run --rule-selector AppExchange --output-file=CodeAnalyzerReport.html --target force-app/main/default
3.Observe the output or HTML report.
✅Expected Result:
The analyzer scans all .cls and .trigger files under the target path and produces results (even if 0 violations).
❌ Actual Result:
The analyzer outputs:
Found 0 violations across 0 files
Even though valid files like ChatterCreateTaskOperations.cls and ChatterPostTrigger.trigger exist.
Expected Behavior
✅Expected Result:
The analyzer scans all .cls and .trigger files under the target path and produces results (even if 0 violations).
Operating System
Windows 11 Home Single Language, version 24H2 (64-bit), OS build 26100.4652
Salesforce CLI Version
@salesforce/cli/2.98.6 win32-x64 node-v22.17.0
Code Analyzer Plugin (code-analyzer) Version
code-analyzer 5.2.2 (5.2.2)
Node Version
v22.17.0
Java Version
openjdk version "23.0.1"
Python Version
Python 3.13.5
Additional Context (Screenshots, Files, etc)
No response
Workaround
No response
Urgency
Critical