@sentriflow/cli 0.4.2 → 0.5.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/dist/index.js +121 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12323,7 +12323,7 @@ function generateSarif(results, filePath, rules, options = {}, ipSummary) {
|
|
|
12323
12323
|
tool: {
|
|
12324
12324
|
driver: {
|
|
12325
12325
|
name: "Sentriflow",
|
|
12326
|
-
version: "0.
|
|
12326
|
+
version: "0.5.0",
|
|
12327
12327
|
informationUri: "https://github.com/sentriflow/sentriflow",
|
|
12328
12328
|
rules: sarifRules,
|
|
12329
12329
|
// SEC-007: Include CWE taxonomy when rules reference it
|
|
@@ -12483,7 +12483,7 @@ function generateMultiFileSarif(fileResults, rules, options = {}) {
|
|
|
12483
12483
|
tool: {
|
|
12484
12484
|
driver: {
|
|
12485
12485
|
name: "Sentriflow",
|
|
12486
|
-
version: "0.
|
|
12486
|
+
version: "0.5.0",
|
|
12487
12487
|
informationUri: "https://github.com/sentriflow/sentriflow",
|
|
12488
12488
|
rules: sarifRules,
|
|
12489
12489
|
// SEC-007: Include CWE taxonomy when rules reference it
|
|
@@ -12527,6 +12527,103 @@ function generateMultiFileSarif(fileResults, rules, options = {}) {
|
|
|
12527
12527
|
return JSON.stringify(report, null, 2);
|
|
12528
12528
|
}
|
|
12529
12529
|
|
|
12530
|
+
// src/human.ts
|
|
12531
|
+
var COLORS = {
|
|
12532
|
+
red: "\x1B[31m",
|
|
12533
|
+
yellow: "\x1B[33m",
|
|
12534
|
+
blue: "\x1B[34m",
|
|
12535
|
+
gray: "\x1B[90m",
|
|
12536
|
+
bold: "\x1B[1m",
|
|
12537
|
+
reset: "\x1B[0m"
|
|
12538
|
+
};
|
|
12539
|
+
var SEVERITY_COLORS = {
|
|
12540
|
+
error: COLORS.red,
|
|
12541
|
+
warning: COLORS.yellow,
|
|
12542
|
+
info: COLORS.blue
|
|
12543
|
+
};
|
|
12544
|
+
function countSeverities(results) {
|
|
12545
|
+
const counts = { error: 0, warning: 0, info: 0, total: 0 };
|
|
12546
|
+
for (const r of results) {
|
|
12547
|
+
if (!r.passed) {
|
|
12548
|
+
if (r.level === "error" || r.level === "warning" || r.level === "info") {
|
|
12549
|
+
counts[r.level]++;
|
|
12550
|
+
}
|
|
12551
|
+
counts.total++;
|
|
12552
|
+
}
|
|
12553
|
+
}
|
|
12554
|
+
return counts;
|
|
12555
|
+
}
|
|
12556
|
+
function formatFinding(result, color) {
|
|
12557
|
+
const line = result.loc?.startLine ?? 0;
|
|
12558
|
+
const col = 1;
|
|
12559
|
+
const location = `${line}:${col}`.padEnd(8);
|
|
12560
|
+
const severityColor = color ? SEVERITY_COLORS[result.level] ?? "" : "";
|
|
12561
|
+
const reset = color ? COLORS.reset : "";
|
|
12562
|
+
const severityText = result.level.padEnd(7);
|
|
12563
|
+
const severity = `${severityColor}${severityText}${reset}`;
|
|
12564
|
+
const ruleColor = color ? COLORS.gray : "";
|
|
12565
|
+
const ruleId = `${ruleColor}${result.ruleId}${reset}`;
|
|
12566
|
+
return ` ${location} ${severity} ${result.message} ${ruleId}`;
|
|
12567
|
+
}
|
|
12568
|
+
function formatSummary(counts, color) {
|
|
12569
|
+
if (counts.total === 0) {
|
|
12570
|
+
const check = color ? `${COLORS.bold}\u2714${COLORS.reset}` : "\u2714";
|
|
12571
|
+
return `
|
|
12572
|
+
${check} No problems found
|
|
12573
|
+
`;
|
|
12574
|
+
}
|
|
12575
|
+
const x = color ? `${COLORS.red}\u2716${COLORS.reset}` : "\u2716";
|
|
12576
|
+
const parts = [];
|
|
12577
|
+
if (counts.error > 0) {
|
|
12578
|
+
parts.push(`${counts.error} error${counts.error !== 1 ? "s" : ""}`);
|
|
12579
|
+
}
|
|
12580
|
+
if (counts.warning > 0) {
|
|
12581
|
+
parts.push(`${counts.warning} warning${counts.warning !== 1 ? "s" : ""}`);
|
|
12582
|
+
}
|
|
12583
|
+
if (counts.info > 0) {
|
|
12584
|
+
parts.push(`${counts.info} info`);
|
|
12585
|
+
}
|
|
12586
|
+
const problemText = counts.total === 1 ? "problem" : "problems";
|
|
12587
|
+
return `
|
|
12588
|
+
${x} ${counts.total} ${problemText} (${parts.join(", ")})
|
|
12589
|
+
`;
|
|
12590
|
+
}
|
|
12591
|
+
function formatHuman(results, filePath, options) {
|
|
12592
|
+
const color = options?.color ?? false;
|
|
12593
|
+
const failures = results.filter((r) => !r.passed);
|
|
12594
|
+
const lines = [];
|
|
12595
|
+
const header = color ? `${COLORS.bold}${filePath}${COLORS.reset}` : filePath;
|
|
12596
|
+
lines.push(header);
|
|
12597
|
+
for (const result of failures) {
|
|
12598
|
+
lines.push(formatFinding(result, color));
|
|
12599
|
+
}
|
|
12600
|
+
const counts = countSeverities(results);
|
|
12601
|
+
lines.push(formatSummary(counts, color));
|
|
12602
|
+
return lines.join("\n");
|
|
12603
|
+
}
|
|
12604
|
+
function formatMultiFileHuman(files, options) {
|
|
12605
|
+
const color = options?.color ?? false;
|
|
12606
|
+
const lines = [];
|
|
12607
|
+
const totalCounts = { error: 0, warning: 0, info: 0, total: 0 };
|
|
12608
|
+
for (const { file, results } of files) {
|
|
12609
|
+
const failures = results.filter((r) => !r.passed);
|
|
12610
|
+
if (failures.length === 0) continue;
|
|
12611
|
+
const header = color ? `${COLORS.bold}${file}${COLORS.reset}` : file;
|
|
12612
|
+
lines.push(header);
|
|
12613
|
+
for (const result of failures) {
|
|
12614
|
+
lines.push(formatFinding(result, color));
|
|
12615
|
+
}
|
|
12616
|
+
lines.push("");
|
|
12617
|
+
const counts = countSeverities(results);
|
|
12618
|
+
totalCounts.error += counts.error;
|
|
12619
|
+
totalCounts.warning += counts.warning;
|
|
12620
|
+
totalCounts.info += counts.info;
|
|
12621
|
+
totalCounts.total += counts.total;
|
|
12622
|
+
}
|
|
12623
|
+
lines.push(formatSummary(totalCounts, color));
|
|
12624
|
+
return lines.join("\n");
|
|
12625
|
+
}
|
|
12626
|
+
|
|
12530
12627
|
// ../rules-default/src/common/network-rules.ts
|
|
12531
12628
|
var NoMulticastBroadcastIp = {
|
|
12532
12629
|
id: "NET-IP-001",
|
|
@@ -16510,7 +16607,7 @@ function enrichResultsWithRuleMetadata(results, rules) {
|
|
|
16510
16607
|
});
|
|
16511
16608
|
}
|
|
16512
16609
|
var program = new Command();
|
|
16513
|
-
program.name("sentriflow").description("SentriFlow Network Configuration Validator").version("0.
|
|
16610
|
+
program.name("sentriflow").description("SentriFlow Network Configuration Validator").version("0.5.0").argument("[files...]", "Path(s) to configuration file(s) (supports multiple files)").option("--ast", "Output the AST instead of rule results").option("-f, --format <format>", "Output format (json, human, sarif)", "json").option("-q, --quiet", "Only output failures (suppress passed results)").option("-c, --config <path>", "Path to config file (default: auto-detect)").option("--no-config", "Ignore config file").option("-r, --rules <path>", "Additional rules file to load (legacy)").option(
|
|
16514
16611
|
"--pack <path...>",
|
|
16515
16612
|
"Path(s) to rule pack(s) (.grx2 encrypted or unencrypted JS/TS modules)"
|
|
16516
16613
|
).option(
|
|
@@ -16937,6 +17034,13 @@ Parsing complete: ${allAsts.length} files`);
|
|
|
16937
17034
|
console.log(
|
|
16938
17035
|
generateMultiFileSarif(allFileResults, rules, sarifOptions)
|
|
16939
17036
|
);
|
|
17037
|
+
} else if (options.format === "human") {
|
|
17038
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17039
|
+
const humanFiles = allFileResults.map((fr) => ({
|
|
17040
|
+
file: fr.filePath,
|
|
17041
|
+
results: fr.results
|
|
17042
|
+
}));
|
|
17043
|
+
console.log(formatMultiFileHuman(humanFiles, { color: isColorEnabled }));
|
|
16940
17044
|
} else {
|
|
16941
17045
|
const output = {
|
|
16942
17046
|
summary: {
|
|
@@ -17054,6 +17158,9 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17054
17158
|
baseDir: process.cwd()
|
|
17055
17159
|
};
|
|
17056
17160
|
console.log(generateSarif(results2, "<stdin>", stdinRules, sarifOptions, stdinIpSummary));
|
|
17161
|
+
} else if (options.format === "human") {
|
|
17162
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17163
|
+
console.log(formatHuman(results2, "<stdin>", { color: isColorEnabled }));
|
|
17057
17164
|
} else {
|
|
17058
17165
|
const output = {
|
|
17059
17166
|
file: "<stdin>",
|
|
@@ -17153,6 +17260,13 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17153
17260
|
console.log(
|
|
17154
17261
|
generateMultiFileSarif(allFileResults, rules, sarifOptions)
|
|
17155
17262
|
);
|
|
17263
|
+
} else if (options.format === "human") {
|
|
17264
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17265
|
+
const humanFiles = allFileResults.map((fr) => ({
|
|
17266
|
+
file: fr.filePath,
|
|
17267
|
+
results: fr.results
|
|
17268
|
+
}));
|
|
17269
|
+
console.log(formatMultiFileHuman(humanFiles, { color: isColorEnabled }));
|
|
17156
17270
|
} else {
|
|
17157
17271
|
const output = {
|
|
17158
17272
|
summary: {
|
|
@@ -17271,6 +17385,9 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17271
17385
|
console.log(
|
|
17272
17386
|
generateSarif(results, filePath, singleFileRules, sarifOptions, ipSummary)
|
|
17273
17387
|
);
|
|
17388
|
+
} else if (options.format === "human") {
|
|
17389
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17390
|
+
console.log(formatHuman(results, filePath, { color: isColorEnabled }));
|
|
17274
17391
|
} else {
|
|
17275
17392
|
const output = {
|
|
17276
17393
|
vendor: {
|
|
@@ -17305,7 +17422,7 @@ async function loadLicensingExtension() {
|
|
|
17305
17422
|
licensingModulePath
|
|
17306
17423
|
);
|
|
17307
17424
|
if (licensing.registerCommands) {
|
|
17308
|
-
licensing.registerCommands(program, { cliVersion: "0.
|
|
17425
|
+
licensing.registerCommands(program, { cliVersion: "0.5.0" });
|
|
17309
17426
|
}
|
|
17310
17427
|
} catch {
|
|
17311
17428
|
const licensingMessage = `
|