eslint-plugin-ai-guard 1.2.4 → 1.2.6
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/cli/index.js +191 -93
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -414,19 +414,19 @@ function addIgnoresToLegacyConfig(existing) {
|
|
|
414
414
|
function getConfigFilePath(configType, cwd = process.cwd()) {
|
|
415
415
|
switch (configType) {
|
|
416
416
|
case "flat-js":
|
|
417
|
-
return
|
|
417
|
+
return import_path7.default.join(cwd, "eslint.config.js");
|
|
418
418
|
case "flat-mjs":
|
|
419
|
-
return
|
|
419
|
+
return import_path7.default.join(cwd, "eslint.config.mjs");
|
|
420
420
|
case "flat-cjs":
|
|
421
|
-
return
|
|
421
|
+
return import_path7.default.join(cwd, "eslint.config.cjs");
|
|
422
422
|
case "eslintrc-js":
|
|
423
|
-
return
|
|
423
|
+
return import_path7.default.join(cwd, ".eslintrc.js");
|
|
424
424
|
case "eslintrc-cjs":
|
|
425
|
-
return
|
|
425
|
+
return import_path7.default.join(cwd, ".eslintrc.cjs");
|
|
426
426
|
case "eslintrc-json":
|
|
427
|
-
return
|
|
427
|
+
return import_path7.default.join(cwd, ".eslintrc.json");
|
|
428
428
|
default:
|
|
429
|
-
return
|
|
429
|
+
return import_path7.default.join(cwd, ".eslintrc.js");
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
function validateFlatConfigText(content) {
|
|
@@ -461,12 +461,12 @@ function validateLegacyConfigText(content) {
|
|
|
461
461
|
}
|
|
462
462
|
return problems;
|
|
463
463
|
}
|
|
464
|
-
var import_fs7,
|
|
464
|
+
var import_fs7, import_path7, AI_GUARD_MARKER, DEFAULT_FLAT_IGNORES, DEFAULT_LEGACY_IGNORES;
|
|
465
465
|
var init_config_manager = __esm({
|
|
466
466
|
"cli/utils/config-manager.ts"() {
|
|
467
467
|
"use strict";
|
|
468
468
|
import_fs7 = __toESM(require("fs"));
|
|
469
|
-
|
|
469
|
+
import_path7 = __toESM(require("path"));
|
|
470
470
|
AI_GUARD_MARKER = "eslint-plugin-ai-guard";
|
|
471
471
|
DEFAULT_FLAT_IGNORES = [
|
|
472
472
|
"node_modules/**",
|
|
@@ -490,7 +490,7 @@ var init_config_manager = __esm({
|
|
|
490
490
|
// cli/index.ts
|
|
491
491
|
var import_commander = require("commander");
|
|
492
492
|
var import_fs12 = __toESM(require("fs"));
|
|
493
|
-
var
|
|
493
|
+
var import_path15 = __toESM(require("path"));
|
|
494
494
|
|
|
495
495
|
// cli/commands/run.ts
|
|
496
496
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -1205,6 +1205,9 @@ async function runEslint(options) {
|
|
|
1205
1205
|
};
|
|
1206
1206
|
}
|
|
1207
1207
|
|
|
1208
|
+
// cli/utils/sarif.ts
|
|
1209
|
+
var import_path3 = __toESM(require("path"));
|
|
1210
|
+
|
|
1208
1211
|
// cli/utils/version.ts
|
|
1209
1212
|
var import_module = require("module");
|
|
1210
1213
|
var import_url2 = require("url");
|
|
@@ -1353,8 +1356,24 @@ function confidenceToRank(confidence) {
|
|
|
1353
1356
|
return 30;
|
|
1354
1357
|
}
|
|
1355
1358
|
}
|
|
1356
|
-
function
|
|
1357
|
-
|
|
1359
|
+
function normalizeSarifPath(filePath, repoRoot) {
|
|
1360
|
+
let normalized = filePath;
|
|
1361
|
+
normalized = normalized.replace(/\\/g, "/");
|
|
1362
|
+
normalized = normalized.replace(/^[A-Za-z]:\//, "/");
|
|
1363
|
+
if (repoRoot && import_path3.default.isAbsolute(filePath)) {
|
|
1364
|
+
const posixRoot = repoRoot.replace(/\\/g, "/").replace(/^[A-Za-z]:\//, "/").replace(/\/$/, "");
|
|
1365
|
+
if (normalized.startsWith(posixRoot + "/")) {
|
|
1366
|
+
normalized = normalized.slice(posixRoot.length + 1);
|
|
1367
|
+
} else if (normalized.startsWith(posixRoot)) {
|
|
1368
|
+
normalized = normalized.slice(posixRoot.length);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
normalized = normalized.replace(/^\/+/, "");
|
|
1372
|
+
normalized = normalized.replace(/^\.\//, "");
|
|
1373
|
+
if (!normalized || normalized === ".") {
|
|
1374
|
+
normalized = filePath.replace(/\\/g, "/");
|
|
1375
|
+
}
|
|
1376
|
+
return normalized;
|
|
1358
1377
|
}
|
|
1359
1378
|
function collectUsedRuleIds(result) {
|
|
1360
1379
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1405,10 +1424,11 @@ function buildRuleDescriptors(ruleIds) {
|
|
|
1405
1424
|
});
|
|
1406
1425
|
});
|
|
1407
1426
|
}
|
|
1408
|
-
function buildSarifResult(issue, file) {
|
|
1427
|
+
function buildSarifResult(issue, file, repoRoot) {
|
|
1409
1428
|
const confidence = ISSUE_CONFIDENCE[issue.ruleId];
|
|
1410
1429
|
const asyncRiskType = ISSUE_ASYNC_RISK_TYPE[issue.ruleId];
|
|
1411
1430
|
const category = ISSUE_CATEGORY[issue.ruleId];
|
|
1431
|
+
const sarifUri = normalizeSarifPath(file.filePath, repoRoot);
|
|
1412
1432
|
return {
|
|
1413
1433
|
ruleId: issue.ruleId,
|
|
1414
1434
|
level: confidenceToSarifLevel(confidence),
|
|
@@ -1419,8 +1439,8 @@ function buildSarifResult(issue, file) {
|
|
|
1419
1439
|
{
|
|
1420
1440
|
physicalLocation: {
|
|
1421
1441
|
artifactLocation: {
|
|
1422
|
-
|
|
1423
|
-
|
|
1442
|
+
// Repository-relative POSIX path — no uriBaseId
|
|
1443
|
+
uri: sarifUri
|
|
1424
1444
|
},
|
|
1425
1445
|
region: {
|
|
1426
1446
|
startLine: Math.max(1, issue.line),
|
|
@@ -1515,13 +1535,13 @@ function normalizeSarifForGitHub(log2) {
|
|
|
1515
1535
|
runs: normalizedRuns
|
|
1516
1536
|
};
|
|
1517
1537
|
}
|
|
1518
|
-
function buildSarifLog(result, version = PKG_VERSION) {
|
|
1538
|
+
function buildSarifLog(result, version = PKG_VERSION, repoRoot) {
|
|
1519
1539
|
const usedRuleIds = collectUsedRuleIds(result);
|
|
1520
1540
|
const rules = buildRuleDescriptors(usedRuleIds);
|
|
1521
1541
|
const sarifResults = [];
|
|
1522
1542
|
for (const file of result.files) {
|
|
1523
1543
|
for (const issue of file.issues) {
|
|
1524
|
-
sarifResults.push(buildSarifResult(issue, file));
|
|
1544
|
+
sarifResults.push(buildSarifResult(issue, file, repoRoot));
|
|
1525
1545
|
}
|
|
1526
1546
|
}
|
|
1527
1547
|
const log2 = {
|
|
@@ -1553,7 +1573,19 @@ function buildSarifLog(result, version = PKG_VERSION) {
|
|
|
1553
1573
|
function sarifToJson(log2) {
|
|
1554
1574
|
return JSON.stringify(log2, null, 2);
|
|
1555
1575
|
}
|
|
1556
|
-
function
|
|
1576
|
+
function debugSarifPath(filePath, repoRoot) {
|
|
1577
|
+
const normalizedUri = normalizeSarifPath(filePath, repoRoot);
|
|
1578
|
+
return {
|
|
1579
|
+
originalPath: filePath,
|
|
1580
|
+
normalizedUri,
|
|
1581
|
+
isRepositoryRelative: !import_path3.default.isAbsolute(normalizedUri) && !normalizedUri.startsWith("/"),
|
|
1582
|
+
hasLeadingSlash: normalizedUri.startsWith("/"),
|
|
1583
|
+
hasDriveLetter: /^[A-Za-z]:/.test(normalizedUri),
|
|
1584
|
+
hasBackslashes: normalizedUri.includes("\\"),
|
|
1585
|
+
hasLeadingDotSlash: normalizedUri.startsWith("./")
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
function buildSarifDebugInfo(result, repoRoot) {
|
|
1557
1589
|
const usedRuleIds = collectUsedRuleIds(result);
|
|
1558
1590
|
const rulesEmitted = usedRuleIds.map((id) => {
|
|
1559
1591
|
const meta = RULE_DOCS[id];
|
|
@@ -1575,7 +1607,13 @@ function buildSarifDebugInfo(result) {
|
|
|
1575
1607
|
};
|
|
1576
1608
|
});
|
|
1577
1609
|
const resultsEmitted = [];
|
|
1610
|
+
const pathsDebug = [];
|
|
1611
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
1578
1612
|
for (const file of result.files) {
|
|
1613
|
+
if (!seenPaths.has(file.filePath)) {
|
|
1614
|
+
seenPaths.add(file.filePath);
|
|
1615
|
+
pathsDebug.push(debugSarifPath(file.filePath, repoRoot));
|
|
1616
|
+
}
|
|
1579
1617
|
for (const issue of file.issues) {
|
|
1580
1618
|
const confidence = ISSUE_CONFIDENCE[issue.ruleId];
|
|
1581
1619
|
resultsEmitted.push({
|
|
@@ -1585,6 +1623,7 @@ function buildSarifDebugInfo(result) {
|
|
|
1585
1623
|
securitySeverity: confidenceToSecuritySeverity(confidence),
|
|
1586
1624
|
precision: confidenceToPrecision(confidence),
|
|
1587
1625
|
filePath: file.filePath,
|
|
1626
|
+
normalizedUri: normalizeSarifPath(file.filePath, repoRoot),
|
|
1588
1627
|
line: issue.line
|
|
1589
1628
|
});
|
|
1590
1629
|
}
|
|
@@ -1592,6 +1631,7 @@ function buildSarifDebugInfo(result) {
|
|
|
1592
1631
|
return {
|
|
1593
1632
|
rulesEmitted,
|
|
1594
1633
|
resultsEmitted,
|
|
1634
|
+
pathsDebug,
|
|
1595
1635
|
totalResults: result.files.reduce((n, f) => n + f.issues.length, 0),
|
|
1596
1636
|
version: PKG_VERSION
|
|
1597
1637
|
};
|
|
@@ -1824,7 +1864,7 @@ function writeGitHubOutputs(result, sarifPath) {
|
|
|
1824
1864
|
|
|
1825
1865
|
// cli/utils/git-diff.ts
|
|
1826
1866
|
var import_child_process = require("child_process");
|
|
1827
|
-
var
|
|
1867
|
+
var import_path4 = __toESM(require("path"));
|
|
1828
1868
|
var import_fs3 = __toESM(require("fs"));
|
|
1829
1869
|
var DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
1830
1870
|
var IGNORE_PREFIXES = [
|
|
@@ -1934,7 +1974,7 @@ function filterFiles(rawFiles, extensions, workingDirectory, cwd, debugInfo) {
|
|
|
1934
1974
|
for (const rel of rawFiles) {
|
|
1935
1975
|
const normalized = rel.replace(/\\/g, "/").trim();
|
|
1936
1976
|
if (!normalized) continue;
|
|
1937
|
-
const ext =
|
|
1977
|
+
const ext = import_path4.default.extname(normalized).toLowerCase();
|
|
1938
1978
|
if (!extensions.includes(ext)) {
|
|
1939
1979
|
debugInfo.droppedByExtension++;
|
|
1940
1980
|
continue;
|
|
@@ -1950,7 +1990,7 @@ function filterFiles(rawFiles, extensions, workingDirectory, cwd, debugInfo) {
|
|
|
1950
1990
|
continue;
|
|
1951
1991
|
}
|
|
1952
1992
|
}
|
|
1953
|
-
const abs =
|
|
1993
|
+
const abs = import_path4.default.resolve(cwd, normalized);
|
|
1954
1994
|
if (!import_fs3.default.existsSync(abs)) {
|
|
1955
1995
|
debugInfo.droppedMissing++;
|
|
1956
1996
|
continue;
|
|
@@ -2073,7 +2113,7 @@ function registerRunCommand(program2) {
|
|
|
2073
2113
|
"--max-warnings <n>",
|
|
2074
2114
|
"Fail with exit code 1 if warnings exceed this count",
|
|
2075
2115
|
(value) => Number.parseInt(value, 10)
|
|
2076
|
-
).option("--verbose", "Show all issues \u2014 disable grouping of repeated warnings").option("--quiet", "Only show errors \u2014 suppress warnings and informational hints").option("--debug-timing", "Print per-phase timing diagnostics").option("--debug-sarif", "Print SARIF tag normalization trace \u2014 diagnose
|
|
2116
|
+
).option("--verbose", "Show all issues \u2014 disable grouping of repeated warnings").option("--quiet", "Only show errors \u2014 suppress warnings and informational hints").option("--debug-timing", "Print per-phase timing diagnostics").option("--debug-sarif", "Print SARIF tag/level normalization trace \u2014 diagnose schema issues").option("--debug-sarif-paths", "Print path normalization trace \u2014 diagnose GitHub Code Scanning path resolution").option("--sarif-output <file>", "Write SARIF to this file instead of stdout").action(async (opts) => {
|
|
2077
2117
|
if (opts.maxWarnings !== void 0 && (!Number.isInteger(opts.maxWarnings) || opts.maxWarnings < 0)) {
|
|
2078
2118
|
log.blank();
|
|
2079
2119
|
log.error("--max-warnings must be a non-negative integer.");
|
|
@@ -2126,10 +2166,11 @@ function registerRunCommand(program2) {
|
|
|
2126
2166
|
writeGitHubOutputs(result);
|
|
2127
2167
|
}
|
|
2128
2168
|
if (opts.sarif || opts.sarifOutput) {
|
|
2129
|
-
const
|
|
2169
|
+
const repoRoot = process.env.GITHUB_WORKSPACE ?? void 0;
|
|
2170
|
+
const sarifLog = buildSarifLog(result, void 0, repoRoot);
|
|
2130
2171
|
const sarifJson = sarifToJson(sarifLog);
|
|
2131
2172
|
if (opts.debugSarif) {
|
|
2132
|
-
const debugInfo = buildSarifDebugInfo(result);
|
|
2173
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2133
2174
|
process.stderr.write("\n[debug-sarif] SARIF GitHub Compatibility Trace\n");
|
|
2134
2175
|
process.stderr.write("[debug-sarif] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
2135
2176
|
process.stderr.write("[debug-sarif] Rules Emitted:\n");
|
|
@@ -2167,11 +2208,39 @@ function registerRunCommand(program2) {
|
|
|
2167
2208
|
process.stderr.write(`[debug-sarif] security-severity: ${res.securitySeverity}
|
|
2168
2209
|
`);
|
|
2169
2210
|
process.stderr.write(`[debug-sarif] precision: ${res.precision}
|
|
2211
|
+
`);
|
|
2212
|
+
process.stderr.write(`[debug-sarif] artifact uri: ${res.normalizedUri}
|
|
2170
2213
|
`);
|
|
2171
2214
|
}
|
|
2172
2215
|
}
|
|
2173
2216
|
process.stderr.write("[debug-sarif] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
|
|
2174
2217
|
}
|
|
2218
|
+
if (opts.debugSarifPaths) {
|
|
2219
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2220
|
+
process.stderr.write("\n[debug-sarif-paths] Path Normalization Trace\n");
|
|
2221
|
+
process.stderr.write("[debug-sarif-paths] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
2222
|
+
process.stderr.write(`[debug-sarif-paths] GITHUB_WORKSPACE: ${repoRoot ?? "(not set \u2014 local run)"}
|
|
2223
|
+
|
|
2224
|
+
`);
|
|
2225
|
+
if (debugInfo.pathsDebug.length === 0) {
|
|
2226
|
+
process.stderr.write("[debug-sarif-paths] (no files in results)\n");
|
|
2227
|
+
} else {
|
|
2228
|
+
for (const p of debugInfo.pathsDebug) {
|
|
2229
|
+
process.stderr.write(`[debug-sarif-paths] original path: ${p.originalPath}
|
|
2230
|
+
`);
|
|
2231
|
+
process.stderr.write(`[debug-sarif-paths] artifact uri: ${p.normalizedUri}
|
|
2232
|
+
`);
|
|
2233
|
+
process.stderr.write(`[debug-sarif-paths] repo-relative: ${p.isRepositoryRelative ? "\u2705 yes" : "\u274C NO (GitHub may miss this)"}
|
|
2234
|
+
`);
|
|
2235
|
+
if (p.hasBackslashes) process.stderr.write("[debug-sarif-paths] \u26A0 had backslashes \u2014 converted\n");
|
|
2236
|
+
if (p.hasDriveLetter) process.stderr.write("[debug-sarif-paths] \u26A0 had drive letter \u2014 stripped\n");
|
|
2237
|
+
if (p.hasLeadingSlash) process.stderr.write("[debug-sarif-paths] \u26A0 had leading slash \u2014 stripped\n");
|
|
2238
|
+
if (p.hasLeadingDotSlash) process.stderr.write("[debug-sarif-paths] \u26A0 had leading ./ \u2014 stripped\n");
|
|
2239
|
+
process.stderr.write("\n");
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
process.stderr.write("[debug-sarif-paths] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
|
|
2243
|
+
}
|
|
2175
2244
|
if (opts.sarifOutput) {
|
|
2176
2245
|
import_fs4.default.writeFileSync(opts.sarifOutput, sarifJson, "utf-8");
|
|
2177
2246
|
if (opts.debugSarif) {
|
|
@@ -2514,7 +2583,7 @@ function resolveExitCode(result, failOn, maxWarnings) {
|
|
|
2514
2583
|
}
|
|
2515
2584
|
|
|
2516
2585
|
// cli/commands/changed.ts
|
|
2517
|
-
var
|
|
2586
|
+
var import_path5 = __toESM(require("path"));
|
|
2518
2587
|
var import_fs5 = __toESM(require("fs"));
|
|
2519
2588
|
var import_ora2 = __toESM(require("ora"));
|
|
2520
2589
|
var import_chalk5 = __toESM(require("chalk"));
|
|
@@ -2523,7 +2592,7 @@ function registerChangedCommand(program2) {
|
|
|
2523
2592
|
"--max-warnings <n>",
|
|
2524
2593
|
"Fail if warnings exceed this count",
|
|
2525
2594
|
(v) => Number.parseInt(v, 10)
|
|
2526
|
-
).option("--verbose", "Expand all findings (disable grouping)").option("--quiet", "Show errors only").option("--debug-timing", "Print per-phase timing diagnostics").option("--debug-git", "Print full git resolution trace (useful for diagnosing zero-file issues)").option("--debug-ci", "Print CI environment state (GITHUB_* vars, SARIF path, summary path)").option("--debug-sarif", "Print SARIF tag normalization trace \u2014 diagnose
|
|
2595
|
+
).option("--verbose", "Expand all findings (disable grouping)").option("--quiet", "Show errors only").option("--debug-timing", "Print per-phase timing diagnostics").option("--debug-git", "Print full git resolution trace (useful for diagnosing zero-file issues)").option("--debug-ci", "Print CI environment state (GITHUB_* vars, SARIF path, summary path)").option("--debug-sarif", "Print SARIF tag/level normalization trace \u2014 diagnose schema issues").option("--debug-sarif-paths", "Print path normalization trace \u2014 diagnose GitHub Code Scanning path resolution").action(async (opts) => {
|
|
2527
2596
|
const preset = opts.strict ? "strict" : opts.security ? "security" : "recommended";
|
|
2528
2597
|
const inCI = isGitHubActions();
|
|
2529
2598
|
const baseRef = opts.base ?? (opts.pr || inCI ? getGitHubBaseRef() : void 0);
|
|
@@ -2552,7 +2621,7 @@ function registerChangedCommand(program2) {
|
|
|
2552
2621
|
});
|
|
2553
2622
|
}
|
|
2554
2623
|
const cwd = process.cwd();
|
|
2555
|
-
const resolvedPath =
|
|
2624
|
+
const resolvedPath = import_path5.default.resolve(opts.path);
|
|
2556
2625
|
const workingDirectory = opts.path !== "." ? opts.path : void 0;
|
|
2557
2626
|
const spinner = opts.json || opts.sarif ? null : (0, import_ora2.default)({ text: import_chalk5.default.dim("Detecting changed files\u2026"), color: "cyan" }).start();
|
|
2558
2627
|
const changedResult = getChangedFiles({
|
|
@@ -2633,10 +2702,11 @@ function handleResults(result, opts, preset, scanMode, changedFilesCount, inCI,
|
|
|
2633
2702
|
emitGitHubAnnotations(result);
|
|
2634
2703
|
}
|
|
2635
2704
|
if (opts.sarif) {
|
|
2636
|
-
const
|
|
2705
|
+
const repoRoot = process.env.GITHUB_WORKSPACE ?? void 0;
|
|
2706
|
+
const sarifLog = buildSarifLog(result, void 0, repoRoot);
|
|
2637
2707
|
const sarifJson = sarifToJson(sarifLog);
|
|
2638
2708
|
if (opts.debugSarif) {
|
|
2639
|
-
const debugInfo = buildSarifDebugInfo(result);
|
|
2709
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2640
2710
|
process.stderr.write("\n[debug-sarif] SARIF GitHub Compatibility Trace\n");
|
|
2641
2711
|
process.stderr.write("[debug-sarif] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
2642
2712
|
process.stderr.write("[debug-sarif] Rules Emitted:\n");
|
|
@@ -2674,11 +2744,39 @@ function handleResults(result, opts, preset, scanMode, changedFilesCount, inCI,
|
|
|
2674
2744
|
process.stderr.write(`[debug-sarif] security-severity: ${res.securitySeverity}
|
|
2675
2745
|
`);
|
|
2676
2746
|
process.stderr.write(`[debug-sarif] precision: ${res.precision}
|
|
2747
|
+
`);
|
|
2748
|
+
process.stderr.write(`[debug-sarif] artifact uri: ${res.normalizedUri}
|
|
2677
2749
|
`);
|
|
2678
2750
|
}
|
|
2679
2751
|
}
|
|
2680
2752
|
process.stderr.write("[debug-sarif] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
|
|
2681
2753
|
}
|
|
2754
|
+
if (opts.debugSarifPaths) {
|
|
2755
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2756
|
+
process.stderr.write("\n[debug-sarif-paths] Path Normalization Trace\n");
|
|
2757
|
+
process.stderr.write("[debug-sarif-paths] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
2758
|
+
process.stderr.write(`[debug-sarif-paths] GITHUB_WORKSPACE: ${repoRoot ?? "(not set \u2014 local run)"}
|
|
2759
|
+
|
|
2760
|
+
`);
|
|
2761
|
+
if (debugInfo.pathsDebug.length === 0) {
|
|
2762
|
+
process.stderr.write("[debug-sarif-paths] (no files in results)\n");
|
|
2763
|
+
} else {
|
|
2764
|
+
for (const p of debugInfo.pathsDebug) {
|
|
2765
|
+
process.stderr.write(`[debug-sarif-paths] original path: ${p.originalPath}
|
|
2766
|
+
`);
|
|
2767
|
+
process.stderr.write(`[debug-sarif-paths] artifact uri: ${p.normalizedUri}
|
|
2768
|
+
`);
|
|
2769
|
+
process.stderr.write(`[debug-sarif-paths] repo-relative: ${p.isRepositoryRelative ? "\u2705 yes" : "\u274C NO (GitHub may miss this)"}
|
|
2770
|
+
`);
|
|
2771
|
+
if (p.hasBackslashes) process.stderr.write("[debug-sarif-paths] \u26A0 had backslashes \u2014 converted\n");
|
|
2772
|
+
if (p.hasDriveLetter) process.stderr.write("[debug-sarif-paths] \u26A0 had drive letter \u2014 stripped\n");
|
|
2773
|
+
if (p.hasLeadingSlash) process.stderr.write("[debug-sarif-paths] \u26A0 had leading slash \u2014 stripped\n");
|
|
2774
|
+
if (p.hasLeadingDotSlash) process.stderr.write("[debug-sarif-paths] \u26A0 had leading ./ \u2014 stripped\n");
|
|
2775
|
+
process.stderr.write("\n");
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
process.stderr.write("[debug-sarif-paths] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
|
|
2779
|
+
}
|
|
2682
2780
|
if (resolvedSarifPath) {
|
|
2683
2781
|
import_fs5.default.writeFileSync(resolvedSarifPath, sarifJson, "utf-8");
|
|
2684
2782
|
if (opts.debugSarif) {
|
|
@@ -2814,12 +2912,12 @@ function getFailOnExitCode(result, failOn, maxWarnings) {
|
|
|
2814
2912
|
|
|
2815
2913
|
// cli/commands/init.ts
|
|
2816
2914
|
var import_chalk6 = __toESM(require("chalk"));
|
|
2817
|
-
var
|
|
2915
|
+
var import_path8 = __toESM(require("path"));
|
|
2818
2916
|
var import_fs8 = __toESM(require("fs"));
|
|
2819
2917
|
|
|
2820
2918
|
// cli/utils/detector.ts
|
|
2821
2919
|
var import_fs6 = __toESM(require("fs"));
|
|
2822
|
-
var
|
|
2920
|
+
var import_path6 = __toESM(require("path"));
|
|
2823
2921
|
var import_module2 = require("module");
|
|
2824
2922
|
var FLAT_CONFIG_FILES = [
|
|
2825
2923
|
{ file: "eslint.config.js", type: "flat-js" },
|
|
@@ -2836,11 +2934,11 @@ var LEGACY_CONFIG_FILES = [
|
|
|
2836
2934
|
var ALL_CONFIG_FILES = [...FLAT_CONFIG_FILES, ...LEGACY_CONFIG_FILES];
|
|
2837
2935
|
function isPackageInstalled(pkgName, cwd = process.cwd()) {
|
|
2838
2936
|
try {
|
|
2839
|
-
const pkgPath =
|
|
2937
|
+
const pkgPath = import_path6.default.join(cwd, "node_modules", pkgName, "package.json");
|
|
2840
2938
|
if (import_fs6.default.existsSync(pkgPath)) {
|
|
2841
2939
|
return true;
|
|
2842
2940
|
}
|
|
2843
|
-
const req = (0, import_module2.createRequire)(
|
|
2941
|
+
const req = (0, import_module2.createRequire)(import_path6.default.join(cwd, "package.json"));
|
|
2844
2942
|
req.resolve(`${pkgName}/package.json`);
|
|
2845
2943
|
return true;
|
|
2846
2944
|
} catch {
|
|
@@ -2849,8 +2947,8 @@ function isPackageInstalled(pkgName, cwd = process.cwd()) {
|
|
|
2849
2947
|
}
|
|
2850
2948
|
function getPackageVersion(pkgName, cwd = process.cwd()) {
|
|
2851
2949
|
try {
|
|
2852
|
-
const pkgPath =
|
|
2853
|
-
const resolvedPath = import_fs6.default.existsSync(pkgPath) ? pkgPath : (0, import_module2.createRequire)(
|
|
2950
|
+
const pkgPath = import_path6.default.join(cwd, "node_modules", pkgName, "package.json");
|
|
2951
|
+
const resolvedPath = import_fs6.default.existsSync(pkgPath) ? pkgPath : (0, import_module2.createRequire)(import_path6.default.join(cwd, "package.json")).resolve(`${pkgName}/package.json`);
|
|
2854
2952
|
const raw = import_fs6.default.readFileSync(resolvedPath, "utf-8");
|
|
2855
2953
|
const json = JSON.parse(raw);
|
|
2856
2954
|
return json.version ?? null;
|
|
@@ -2867,7 +2965,7 @@ function detectConfigType(cwd = process.cwd()) {
|
|
|
2867
2965
|
const found = [];
|
|
2868
2966
|
let first = null;
|
|
2869
2967
|
for (const { file, type } of ALL_CONFIG_FILES) {
|
|
2870
|
-
const fullPath =
|
|
2968
|
+
const fullPath = import_path6.default.join(cwd, file);
|
|
2871
2969
|
if (import_fs6.default.existsSync(fullPath)) {
|
|
2872
2970
|
found.push(fullPath);
|
|
2873
2971
|
if (!first) first = { type, path: fullPath };
|
|
@@ -2947,7 +3045,7 @@ async function verifyConfigLoads(configPath, cwd) {
|
|
|
2947
3045
|
overrideConfigFile: configPath
|
|
2948
3046
|
});
|
|
2949
3047
|
await eslint.lintText("", {
|
|
2950
|
-
filePath:
|
|
3048
|
+
filePath: import_path8.default.join(cwd, "_ai_guard_probe_.js")
|
|
2951
3049
|
});
|
|
2952
3050
|
return null;
|
|
2953
3051
|
} catch (err) {
|
|
@@ -2983,7 +3081,7 @@ function registerInitCommand(program2) {
|
|
|
2983
3081
|
log.warn("eslint-plugin-ai-guard not found");
|
|
2984
3082
|
}
|
|
2985
3083
|
if (env.configType !== "none") {
|
|
2986
|
-
log.success(`ESLint config found: ${import_chalk6.default.white(
|
|
3084
|
+
log.success(`ESLint config found: ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath ?? env.configType))}`);
|
|
2987
3085
|
} else {
|
|
2988
3086
|
log.info("No ESLint config found \u2014 will generate one");
|
|
2989
3087
|
}
|
|
@@ -2992,7 +3090,7 @@ function registerInitCommand(program2) {
|
|
|
2992
3090
|
log.blank();
|
|
2993
3091
|
log.warn("Conflicting configs detected:");
|
|
2994
3092
|
for (const p of env.allConfigPaths) {
|
|
2995
|
-
log.print(` ${import_chalk6.default.yellow("\u2192")} ${import_chalk6.default.white(
|
|
3093
|
+
log.print(` ${import_chalk6.default.yellow("\u2192")} ${import_chalk6.default.white(import_path8.default.relative(cwd, p))}`);
|
|
2996
3094
|
}
|
|
2997
3095
|
log.print(` ${import_chalk6.default.gray("Multiple config formats found \u2014 this can cause unpredictable behavior.")}`);
|
|
2998
3096
|
}
|
|
@@ -3020,7 +3118,7 @@ function registerInitCommand(program2) {
|
|
|
3020
3118
|
try {
|
|
3021
3119
|
const { createRequire: createRequire3 } = await import("module");
|
|
3022
3120
|
const { pathToFileURL: pathToFileURL2 } = await import("url");
|
|
3023
|
-
const req = createRequire3(
|
|
3121
|
+
const req = createRequire3(import_path8.default.join(cwd, "_probe.js"));
|
|
3024
3122
|
const resolvedPath = req.resolve("eslint-plugin-ai-guard");
|
|
3025
3123
|
const aiGuard = await import(pathToFileURL2(resolvedPath).href);
|
|
3026
3124
|
const plugin = aiGuard.default || aiGuard;
|
|
@@ -3039,7 +3137,7 @@ function registerInitCommand(program2) {
|
|
|
3039
3137
|
if (eslintNeedsFlat && existingIsLegacy) {
|
|
3040
3138
|
log.section("Config Migration Required");
|
|
3041
3139
|
log.warn(`ESLint v${env.eslintMajor} requires flat config, but a legacy config was found:`);
|
|
3042
|
-
log.print(` ${import_chalk6.default.white(
|
|
3140
|
+
log.print(` ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
3043
3141
|
log.blank();
|
|
3044
3142
|
log.print(` ${import_chalk6.default.bold("ai-guard will create a new flat config.")}`);
|
|
3045
3143
|
log.blank();
|
|
@@ -3051,7 +3149,7 @@ function registerInitCommand(program2) {
|
|
|
3051
3149
|
const raw = readConfig(env.configPath);
|
|
3052
3150
|
const { content: fixed, changed } = removeNukeIgnore(raw);
|
|
3053
3151
|
if (changed) {
|
|
3054
|
-
log.warn(`Removed "**/*" ignore pattern from ${
|
|
3152
|
+
log.warn(`Removed "**/*" ignore pattern from ${import_path8.default.relative(cwd, env.configPath)}`);
|
|
3055
3153
|
if (!isDryRun) {
|
|
3056
3154
|
backupConfig(env.configPath);
|
|
3057
3155
|
writeConfig(env.configPath, fixed);
|
|
@@ -3063,7 +3161,7 @@ function registerInitCommand(program2) {
|
|
|
3063
3161
|
}
|
|
3064
3162
|
if (env.configType === "none" || eslintNeedsFlat && existingIsLegacy) {
|
|
3065
3163
|
const targetName = useFlat ? "eslint.config.mjs" : ".eslintrc.js";
|
|
3066
|
-
finalConfigPath =
|
|
3164
|
+
finalConfigPath = import_path8.default.join(cwd, targetName);
|
|
3067
3165
|
const content2 = useFlat ? generateFlatConfig(preset) : generateLegacyConfig(preset);
|
|
3068
3166
|
if (isDryRun) {
|
|
3069
3167
|
log.print(` ${import_chalk6.default.gray(`[dry-run] would create: ${targetName}`)}`);
|
|
@@ -3091,15 +3189,15 @@ function registerInitCommand(program2) {
|
|
|
3091
3189
|
finalConfigPath = env.configPath;
|
|
3092
3190
|
} else if (isDryRun) {
|
|
3093
3191
|
finalConfigPath = env.configPath;
|
|
3094
|
-
log.print(` ${import_chalk6.default.gray(`[dry-run] would patch: ${
|
|
3192
|
+
log.print(` ${import_chalk6.default.gray(`[dry-run] would patch: ${import_path8.default.relative(cwd, env.configPath)}`)}`);
|
|
3095
3193
|
} else {
|
|
3096
3194
|
const bak = backupConfig(env.configPath);
|
|
3097
|
-
log.info(`Backed up \u2192 ${import_chalk6.default.gray(
|
|
3195
|
+
log.info(`Backed up \u2192 ${import_chalk6.default.gray(import_path8.default.relative(cwd, bak))}`);
|
|
3098
3196
|
writeConfig(env.configPath, patched);
|
|
3099
3197
|
if (isInvalid) {
|
|
3100
|
-
log.success(`Detected invalid ai-guard config \u2014 repairing ${import_chalk6.default.white(
|
|
3198
|
+
log.success(`Detected invalid ai-guard config \u2014 repairing ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
3101
3199
|
} else {
|
|
3102
|
-
log.success(`Patched ${import_chalk6.default.white(
|
|
3200
|
+
log.success(`Patched ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
3103
3201
|
}
|
|
3104
3202
|
finalConfigPath = env.configPath;
|
|
3105
3203
|
configWritten = true;
|
|
@@ -3112,12 +3210,12 @@ function registerInitCommand(program2) {
|
|
|
3112
3210
|
finalConfigPath = env.configPath;
|
|
3113
3211
|
} else if (isDryRun) {
|
|
3114
3212
|
finalConfigPath = env.configPath;
|
|
3115
|
-
log.print(` ${import_chalk6.default.gray(`[dry-run] would patch: ${
|
|
3213
|
+
log.print(` ${import_chalk6.default.gray(`[dry-run] would patch: ${import_path8.default.relative(cwd, env.configPath)}`)}`);
|
|
3116
3214
|
} else {
|
|
3117
3215
|
const bak = backupConfig(env.configPath);
|
|
3118
|
-
log.info(`Backed up \u2192 ${import_chalk6.default.gray(
|
|
3216
|
+
log.info(`Backed up \u2192 ${import_chalk6.default.gray(import_path8.default.relative(cwd, bak))}`);
|
|
3119
3217
|
writeConfig(env.configPath, patched);
|
|
3120
|
-
log.success(`Patched ${import_chalk6.default.white(
|
|
3218
|
+
log.success(`Patched ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
3121
3219
|
finalConfigPath = env.configPath;
|
|
3122
3220
|
configWritten = true;
|
|
3123
3221
|
}
|
|
@@ -3133,11 +3231,11 @@ function registerInitCommand(program2) {
|
|
|
3133
3231
|
cleanedUp = true;
|
|
3134
3232
|
} catch (err) {
|
|
3135
3233
|
const reason = err instanceof Error ? err.message : String(err);
|
|
3136
|
-
log.warn(`Could not back up ${
|
|
3234
|
+
log.warn(`Could not back up ${import_path8.default.relative(cwd, p)}: ${reason}`);
|
|
3137
3235
|
}
|
|
3138
3236
|
} else {
|
|
3139
3237
|
cleanedUp = true;
|
|
3140
|
-
log.print(` ${import_chalk6.default.gray(`[dry-run] would rename ${
|
|
3238
|
+
log.print(` ${import_chalk6.default.gray(`[dry-run] would rename ${import_path8.default.relative(cwd, p)} to ${import_path8.default.basename(p)}.bak`)}`);
|
|
3141
3239
|
}
|
|
3142
3240
|
}
|
|
3143
3241
|
}
|
|
@@ -3156,7 +3254,7 @@ function registerInitCommand(program2) {
|
|
|
3156
3254
|
log.blank();
|
|
3157
3255
|
log.section("Validation");
|
|
3158
3256
|
if (!import_fs8.default.existsSync(finalConfigPath)) {
|
|
3159
|
-
log.error(`Config file not found after write: ${
|
|
3257
|
+
log.error(`Config file not found after write: ${import_path8.default.relative(cwd, finalConfigPath)}`);
|
|
3160
3258
|
log.blank();
|
|
3161
3259
|
log.print(` ${import_chalk6.default.bold("Problem:")} File write may have failed.`);
|
|
3162
3260
|
log.print(` ${import_chalk6.default.bold("Fix:")} Check disk space and file permissions, then re-run.`);
|
|
@@ -3172,7 +3270,7 @@ function registerInitCommand(program2) {
|
|
|
3172
3270
|
log.print(` ${import_chalk6.default.red("\u2716")} ${e}`);
|
|
3173
3271
|
}
|
|
3174
3272
|
} else {
|
|
3175
|
-
log.success(`Config structure valid: ${import_chalk6.default.white(
|
|
3273
|
+
log.success(`Config structure valid: ${import_chalk6.default.white(import_path8.default.relative(cwd, finalConfigPath))}`);
|
|
3176
3274
|
}
|
|
3177
3275
|
log.info("Verifying ESLint can load the config\u2026");
|
|
3178
3276
|
const loadError = await verifyConfigLoads(finalConfigPath, cwd);
|
|
@@ -3196,7 +3294,7 @@ function registerInitCommand(program2) {
|
|
|
3196
3294
|
}
|
|
3197
3295
|
log.blank();
|
|
3198
3296
|
log.print(` ${import_chalk6.default.bold("Fix:")}`);
|
|
3199
|
-
log.print(` 1. Check the syntax in ${import_chalk6.default.cyan(
|
|
3297
|
+
log.print(` 1. Check the syntax in ${import_chalk6.default.cyan(import_path8.default.relative(cwd, finalConfigPath))}`);
|
|
3200
3298
|
log.print(` 2. Make sure ${import_chalk6.default.cyan("eslint-plugin-ai-guard")} is installed`);
|
|
3201
3299
|
log.print(` 3. Run ${import_chalk6.default.cyan("ai-guard doctor")} for full diagnostics`);
|
|
3202
3300
|
log.blank();
|
|
@@ -3218,7 +3316,7 @@ function registerInitCommand(program2) {
|
|
|
3218
3316
|
if (loadError === null && !lingeringConflicts) {
|
|
3219
3317
|
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold.green("Configuration validated successfully")}`);
|
|
3220
3318
|
}
|
|
3221
|
-
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold("ESLint config:")} ${import_chalk6.default.cyan(
|
|
3319
|
+
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold("ESLint config:")} ${import_chalk6.default.cyan(import_path8.default.relative(cwd, finalConfigPath))}`);
|
|
3222
3320
|
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold("Mode:")} ${import_chalk6.default.cyan(useFlat ? `Flat config (ESLint v${env.eslintMajor ?? 9})` : `Legacy config (ESLint v${env.eslintMajor ?? 8})`)}`);
|
|
3223
3321
|
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold("Preset:")} ${import_chalk6.default.cyan(preset)}`);
|
|
3224
3322
|
log.blank();
|
|
@@ -3232,14 +3330,14 @@ function registerInitCommand(program2) {
|
|
|
3232
3330
|
|
|
3233
3331
|
// cli/commands/doctor.ts
|
|
3234
3332
|
var import_chalk7 = __toESM(require("chalk"));
|
|
3235
|
-
var
|
|
3333
|
+
var import_path9 = __toESM(require("path"));
|
|
3236
3334
|
init_config_manager();
|
|
3237
3335
|
var import_meta2 = {};
|
|
3238
3336
|
async function probeConfigLoad(configPath, cwd) {
|
|
3239
3337
|
try {
|
|
3240
3338
|
const { ESLint } = await import("eslint");
|
|
3241
3339
|
const eslint = new ESLint({ cwd, overrideConfigFile: configPath });
|
|
3242
|
-
await eslint.lintText("", { filePath:
|
|
3340
|
+
await eslint.lintText("", { filePath: import_path9.default.join(cwd, "_probe_.js") });
|
|
3243
3341
|
return { ok: true, error: null };
|
|
3244
3342
|
} catch (err) {
|
|
3245
3343
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -3274,7 +3372,7 @@ function registerDoctorCommand(program2) {
|
|
|
3274
3372
|
checks.push({
|
|
3275
3373
|
label: "ESLint config present",
|
|
3276
3374
|
pass: hasConfig,
|
|
3277
|
-
detail: hasConfig ? `${
|
|
3375
|
+
detail: hasConfig ? `${import_path9.default.relative(cwd, env.configPath ?? "")} (${env.configType})` : "No eslint.config.* or .eslintrc.* found",
|
|
3278
3376
|
fix: hasConfig ? void 0 : "ai-guard init",
|
|
3279
3377
|
note: hasConfig ? void 0 : "This will generate the correct config format for your ESLint version"
|
|
3280
3378
|
});
|
|
@@ -3306,7 +3404,7 @@ function registerDoctorCommand(program2) {
|
|
|
3306
3404
|
checks.push({
|
|
3307
3405
|
label: "Plugin wired in config",
|
|
3308
3406
|
pass: pluginWired && !isInvalidConfig,
|
|
3309
|
-
detail: readError ? `Could not read config: ${readError}` : isInvalidConfig ? "Invalid ai-guard config detected (wrong export usage)" : pluginWired ? "eslint-plugin-ai-guard referenced in config" : `Config exists but ai-guard plugin not found in ${
|
|
3407
|
+
detail: readError ? `Could not read config: ${readError}` : isInvalidConfig ? "Invalid ai-guard config detected (wrong export usage)" : pluginWired ? "eslint-plugin-ai-guard referenced in config" : `Config exists but ai-guard plugin not found in ${import_path9.default.relative(cwd, env.configPath)}`,
|
|
3310
3408
|
fix: isInvalidConfig || !pluginWired && !readError ? "ai-guard init (will patch/repair your existing config)" : void 0
|
|
3311
3409
|
});
|
|
3312
3410
|
}
|
|
@@ -3314,7 +3412,7 @@ function registerDoctorCommand(program2) {
|
|
|
3314
3412
|
label: "No conflicting config files",
|
|
3315
3413
|
pass: !env.hasConflictingConfigs,
|
|
3316
3414
|
detail: env.hasConflictingConfigs ? `Conflicting config detected:
|
|
3317
|
-
${env.allConfigPaths.map((p) => ` ${
|
|
3415
|
+
${env.allConfigPaths.map((p) => ` ${import_path9.default.relative(cwd, p)}`).join("\n")}` : "Only one config format detected",
|
|
3318
3416
|
fix: env.hasConflictingConfigs ? "Remove or backup legacy config" : void 0,
|
|
3319
3417
|
note: env.hasConflictingConfigs ? "ESLint v9 silently ignores .eslintrc.* when a flat config exists. This can cause confusion." : void 0
|
|
3320
3418
|
});
|
|
@@ -3341,7 +3439,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3341
3439
|
label: "ESLint config loads without errors",
|
|
3342
3440
|
pass: probe.ok,
|
|
3343
3441
|
detail: probe.ok ? "ESLint loaded config successfully" : probe.error ?? "Unknown error",
|
|
3344
|
-
fix: probe.ok ? void 0 : `Check syntax in ${
|
|
3442
|
+
fix: probe.ok ? void 0 : `Check syntax in ${import_path9.default.relative(cwd, env.configPath)}`,
|
|
3345
3443
|
note: probe.ok ? void 0 : "Run: ai-guard init --dry-run to preview a fresh config"
|
|
3346
3444
|
});
|
|
3347
3445
|
}
|
|
@@ -3350,7 +3448,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3350
3448
|
let utilsVersion = null;
|
|
3351
3449
|
try {
|
|
3352
3450
|
const { createRequire: createRequire3 } = await import("module");
|
|
3353
|
-
const req = createRequire3(
|
|
3451
|
+
const req = createRequire3(import_path9.default.join(cwd, "package.json"));
|
|
3354
3452
|
const pkgPath = req.resolve("@typescript-eslint/utils/package.json");
|
|
3355
3453
|
const pkg = JSON.parse(
|
|
3356
3454
|
(await import("fs")).readFileSync(pkgPath, "utf-8")
|
|
@@ -3361,10 +3459,10 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3361
3459
|
}
|
|
3362
3460
|
if (!utilsOk) {
|
|
3363
3461
|
try {
|
|
3364
|
-
const selfDir =
|
|
3462
|
+
const selfDir = import_path9.default.dirname(
|
|
3365
3463
|
new URL(import_meta2.url).pathname.replace(/^\/([A-Za-z]:)/, "$1")
|
|
3366
3464
|
);
|
|
3367
|
-
const pkgPath =
|
|
3465
|
+
const pkgPath = import_path9.default.join(selfDir, "../../node_modules/@typescript-eslint/utils/package.json");
|
|
3368
3466
|
if ((await import("fs")).existsSync(pkgPath)) {
|
|
3369
3467
|
utilsOk = true;
|
|
3370
3468
|
}
|
|
@@ -3384,7 +3482,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3384
3482
|
let parserVersion = null;
|
|
3385
3483
|
try {
|
|
3386
3484
|
const { createRequire: createRequire3 } = await import("module");
|
|
3387
|
-
const req = createRequire3(
|
|
3485
|
+
const req = createRequire3(import_path9.default.join(cwd, "package.json"));
|
|
3388
3486
|
const pkgPath = req.resolve("@typescript-eslint/parser/package.json");
|
|
3389
3487
|
const pkg = JSON.parse(
|
|
3390
3488
|
(await import("fs")).readFileSync(pkgPath, "utf-8")
|
|
@@ -3472,7 +3570,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3472
3570
|
var import_prompts = require("@inquirer/prompts");
|
|
3473
3571
|
var import_chalk8 = __toESM(require("chalk"));
|
|
3474
3572
|
init_config_manager();
|
|
3475
|
-
var
|
|
3573
|
+
var import_path10 = __toESM(require("path"));
|
|
3476
3574
|
function registerPresetCommand(program2) {
|
|
3477
3575
|
program2.command("preset").description("Interactively select and apply an ai-guard preset to your ESLint config").action(async () => {
|
|
3478
3576
|
const cwd = process.cwd();
|
|
@@ -3500,14 +3598,14 @@ function registerPresetCommand(program2) {
|
|
|
3500
3598
|
const env = detect(cwd);
|
|
3501
3599
|
const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9 || isFlat(env.configType);
|
|
3502
3600
|
if (env.configType === "none") {
|
|
3503
|
-
const configPath = useFlat ?
|
|
3601
|
+
const configPath = useFlat ? import_path10.default.join(cwd, "eslint.config.mjs") : import_path10.default.join(cwd, ".eslintrc.js");
|
|
3504
3602
|
const content = useFlat ? generateFlatConfig(preset) : generateLegacyConfig(preset);
|
|
3505
3603
|
writeConfig(configPath, content);
|
|
3506
|
-
log.success(`Created ${import_chalk8.default.white(
|
|
3604
|
+
log.success(`Created ${import_chalk8.default.white(import_path10.default.relative(cwd, configPath))} with ${import_chalk8.default.cyan(preset)} preset`);
|
|
3507
3605
|
} else {
|
|
3508
3606
|
const configPath = env.configPath;
|
|
3509
3607
|
const backupPath = backupConfig(configPath);
|
|
3510
|
-
log.info(`Backed up \u2192 ${import_chalk8.default.gray(
|
|
3608
|
+
log.info(`Backed up \u2192 ${import_chalk8.default.gray(import_path10.default.relative(cwd, backupPath))}`);
|
|
3511
3609
|
const existing = readConfig(configPath);
|
|
3512
3610
|
const withPlugin = isFlat(env.configType) ? patchFlatConfig(existing, preset) : patchLegacyConfig(existing, preset);
|
|
3513
3611
|
const patched = isFlat(env.configType) ? switchFlatPreset(withPlugin, preset) : switchLegacyPreset(withPlugin, preset);
|
|
@@ -3515,7 +3613,7 @@ function registerPresetCommand(program2) {
|
|
|
3515
3613
|
log.warn("No preset changes needed. Config already matches selected preset.");
|
|
3516
3614
|
} else {
|
|
3517
3615
|
writeConfig(configPath, patched);
|
|
3518
|
-
log.success(`Updated ${import_chalk8.default.white(
|
|
3616
|
+
log.success(`Updated ${import_chalk8.default.white(import_path10.default.relative(cwd, configPath))} to ${import_chalk8.default.cyan(preset)} preset`);
|
|
3519
3617
|
}
|
|
3520
3618
|
}
|
|
3521
3619
|
log.blank();
|
|
@@ -3555,7 +3653,7 @@ function registerPresetCommand(program2) {
|
|
|
3555
3653
|
// cli/commands/ignore.ts
|
|
3556
3654
|
var import_chalk9 = __toESM(require("chalk"));
|
|
3557
3655
|
init_config_manager();
|
|
3558
|
-
var
|
|
3656
|
+
var import_path11 = __toESM(require("path"));
|
|
3559
3657
|
var DEFAULT_IGNORES = [
|
|
3560
3658
|
".next/",
|
|
3561
3659
|
"dist/",
|
|
@@ -3577,21 +3675,21 @@ function registerIgnoreCommand(program2) {
|
|
|
3577
3675
|
const env = detect(cwd);
|
|
3578
3676
|
if (env.configType === "none") {
|
|
3579
3677
|
const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9;
|
|
3580
|
-
const configPath = useFlat ?
|
|
3678
|
+
const configPath = useFlat ? import_path11.default.join(cwd, "eslint.config.mjs") : import_path11.default.join(cwd, ".eslintrc.js");
|
|
3581
3679
|
const content = useFlat ? generateFlatConfig("recommended") : generateLegacyConfig("recommended");
|
|
3582
3680
|
writeConfig(configPath, content);
|
|
3583
|
-
log.success(`No config found \u2014 generated ${import_chalk9.default.white(
|
|
3681
|
+
log.success(`No config found \u2014 generated ${import_chalk9.default.white(import_path11.default.relative(cwd, configPath))} with ignores included`);
|
|
3584
3682
|
} else {
|
|
3585
3683
|
const configPath = env.configPath;
|
|
3586
3684
|
const backupPath = backupConfig(configPath);
|
|
3587
|
-
log.info(`Backed up \u2192 ${import_chalk9.default.gray(
|
|
3685
|
+
log.info(`Backed up \u2192 ${import_chalk9.default.gray(import_path11.default.relative(cwd, backupPath))}`);
|
|
3588
3686
|
const existing = readConfig(configPath);
|
|
3589
3687
|
const patched = isFlat(env.configType) ? addIgnoresToFlatConfig(existing) : addIgnoresToLegacyConfig(existing);
|
|
3590
3688
|
if (patched === existing) {
|
|
3591
3689
|
log.warn("Ignore patterns already present in config \u2014 no changes made.");
|
|
3592
3690
|
} else {
|
|
3593
3691
|
writeConfig(configPath, patched);
|
|
3594
|
-
log.success(`Patched ${import_chalk9.default.white(
|
|
3692
|
+
log.success(`Patched ${import_chalk9.default.white(import_path11.default.relative(cwd, configPath))} with ignore patterns`);
|
|
3595
3693
|
}
|
|
3596
3694
|
}
|
|
3597
3695
|
log.blank();
|
|
@@ -3603,7 +3701,7 @@ function registerIgnoreCommand(program2) {
|
|
|
3603
3701
|
|
|
3604
3702
|
// cli/commands/baseline.ts
|
|
3605
3703
|
var import_fs9 = __toESM(require("fs"));
|
|
3606
|
-
var
|
|
3704
|
+
var import_path12 = __toESM(require("path"));
|
|
3607
3705
|
var import_chalk10 = __toESM(require("chalk"));
|
|
3608
3706
|
var import_ora3 = __toESM(require("ora"));
|
|
3609
3707
|
var BASELINE_FILE = ".ai-guard-baseline.json";
|
|
@@ -3624,12 +3722,12 @@ function saveBaseline(result, preset, mode, cwd) {
|
|
|
3624
3722
|
totalIssues: result.totalIssues,
|
|
3625
3723
|
entries
|
|
3626
3724
|
};
|
|
3627
|
-
const baselinePath =
|
|
3725
|
+
const baselinePath = import_path12.default.join(cwd, BASELINE_FILE);
|
|
3628
3726
|
import_fs9.default.writeFileSync(baselinePath, JSON.stringify(baseline, null, 2), "utf-8");
|
|
3629
3727
|
return baselinePath;
|
|
3630
3728
|
}
|
|
3631
3729
|
function loadBaseline(cwd) {
|
|
3632
|
-
const baselinePath =
|
|
3730
|
+
const baselinePath = import_path12.default.join(cwd, BASELINE_FILE);
|
|
3633
3731
|
if (!import_fs9.default.existsSync(baselinePath)) return null;
|
|
3634
3732
|
try {
|
|
3635
3733
|
const raw = import_fs9.default.readFileSync(baselinePath, "utf-8");
|
|
@@ -3716,7 +3814,7 @@ function registerBaselineCommand(program2) {
|
|
|
3716
3814
|
}
|
|
3717
3815
|
const baselinePath = saveBaseline(result, preset, mode, cwd);
|
|
3718
3816
|
log.success(
|
|
3719
|
-
`Baseline saved \u2192 ${import_chalk10.default.white(
|
|
3817
|
+
`Baseline saved \u2192 ${import_chalk10.default.white(import_path12.default.relative(cwd, baselinePath))}`
|
|
3720
3818
|
);
|
|
3721
3819
|
log.info(` ${result.totalIssues} issues recorded (${result.totalErrors} errors, ${result.totalWarnings} warnings)`);
|
|
3722
3820
|
log.info(` Preset: ${import_chalk10.default.cyan(preset)}`);
|
|
@@ -3800,7 +3898,7 @@ function registerBaselineCommand(program2) {
|
|
|
3800
3898
|
|
|
3801
3899
|
// cli/commands/init-context.ts
|
|
3802
3900
|
var import_fs10 = __toESM(require("fs"));
|
|
3803
|
-
var
|
|
3901
|
+
var import_path13 = __toESM(require("path"));
|
|
3804
3902
|
var import_chalk11 = __toESM(require("chalk"));
|
|
3805
3903
|
var import_prompts2 = require("@inquirer/prompts");
|
|
3806
3904
|
var RULE_CATEGORIES = {
|
|
@@ -4164,13 +4262,13 @@ var AGENTS = [
|
|
|
4164
4262
|
{
|
|
4165
4263
|
id: "copilot",
|
|
4166
4264
|
label: "GitHub Copilot",
|
|
4167
|
-
filePath:
|
|
4265
|
+
filePath: import_path13.default.join(".github", "copilot-instructions.md"),
|
|
4168
4266
|
generate: generateCopilotFile
|
|
4169
4267
|
}
|
|
4170
4268
|
];
|
|
4171
4269
|
function getPackageVersion2(cwd) {
|
|
4172
4270
|
try {
|
|
4173
|
-
const pkgPath =
|
|
4271
|
+
const pkgPath = import_path13.default.join(cwd, "node_modules", "eslint-plugin-ai-guard", "package.json");
|
|
4174
4272
|
if (import_fs10.default.existsSync(pkgPath)) {
|
|
4175
4273
|
const pkg = JSON.parse(import_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
4176
4274
|
if (pkg.version) return pkg.version;
|
|
@@ -4178,7 +4276,7 @@ function getPackageVersion2(cwd) {
|
|
|
4178
4276
|
} catch {
|
|
4179
4277
|
}
|
|
4180
4278
|
try {
|
|
4181
|
-
const pkgPath =
|
|
4279
|
+
const pkgPath = import_path13.default.join(cwd, "package.json");
|
|
4182
4280
|
if (import_fs10.default.existsSync(pkgPath)) {
|
|
4183
4281
|
const pkg = JSON.parse(import_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
4184
4282
|
if (pkg.version) return pkg.version;
|
|
@@ -4247,7 +4345,7 @@ function registerInitContextCommand(program2) {
|
|
|
4247
4345
|
log.blank();
|
|
4248
4346
|
const results = [];
|
|
4249
4347
|
for (const agent of selectedAgents) {
|
|
4250
|
-
const fullPath =
|
|
4348
|
+
const fullPath = import_path13.default.join(cwd, agent.filePath);
|
|
4251
4349
|
const exists = import_fs10.default.existsSync(fullPath);
|
|
4252
4350
|
if (exists && !isForce && !isDryRun) {
|
|
4253
4351
|
const overwrite = await (0, import_prompts2.confirm)({
|
|
@@ -4272,7 +4370,7 @@ function registerInitContextCommand(program2) {
|
|
|
4272
4370
|
results.push({ file: agent.filePath, status: "dry-run" });
|
|
4273
4371
|
continue;
|
|
4274
4372
|
}
|
|
4275
|
-
const parentDir =
|
|
4373
|
+
const parentDir = import_path13.default.dirname(fullPath);
|
|
4276
4374
|
if (!import_fs10.default.existsSync(parentDir)) {
|
|
4277
4375
|
import_fs10.default.mkdirSync(parentDir, { recursive: true });
|
|
4278
4376
|
}
|
|
@@ -4311,7 +4409,7 @@ function registerInitContextCommand(program2) {
|
|
|
4311
4409
|
|
|
4312
4410
|
// cli/commands/report.ts
|
|
4313
4411
|
var import_fs11 = __toESM(require("fs"));
|
|
4314
|
-
var
|
|
4412
|
+
var import_path14 = __toESM(require("path"));
|
|
4315
4413
|
var import_ora4 = __toESM(require("ora"));
|
|
4316
4414
|
var RULE_META = {
|
|
4317
4415
|
"ai-guard/no-empty-catch": { description: "Empty catch blocks silently swallow errors", category: "Reliability" },
|
|
@@ -4335,18 +4433,18 @@ var RULE_META = {
|
|
|
4335
4433
|
};
|
|
4336
4434
|
function getProjectName(cwd) {
|
|
4337
4435
|
try {
|
|
4338
|
-
const pkgPath =
|
|
4436
|
+
const pkgPath = import_path14.default.join(cwd, "package.json");
|
|
4339
4437
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4340
4438
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4341
4439
|
if (pkg.name) return pkg.name;
|
|
4342
4440
|
}
|
|
4343
4441
|
} catch {
|
|
4344
4442
|
}
|
|
4345
|
-
return
|
|
4443
|
+
return import_path14.default.basename(cwd);
|
|
4346
4444
|
}
|
|
4347
4445
|
function getPluginVersion(cwd) {
|
|
4348
4446
|
try {
|
|
4349
|
-
const pkgPath =
|
|
4447
|
+
const pkgPath = import_path14.default.resolve(__dirname, "../../package.json");
|
|
4350
4448
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4351
4449
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4352
4450
|
if (pkg.version) return pkg.version;
|
|
@@ -4354,7 +4452,7 @@ function getPluginVersion(cwd) {
|
|
|
4354
4452
|
} catch {
|
|
4355
4453
|
}
|
|
4356
4454
|
try {
|
|
4357
|
-
const pkgPath =
|
|
4455
|
+
const pkgPath = import_path14.default.join(cwd, "node_modules", "eslint-plugin-ai-guard", "package.json");
|
|
4358
4456
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4359
4457
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4360
4458
|
if (pkg.version) return pkg.version;
|
|
@@ -4733,7 +4831,7 @@ function registerReportCommand(program2) {
|
|
|
4733
4831
|
log.banner("AI GUARD REPORT");
|
|
4734
4832
|
log.blank();
|
|
4735
4833
|
const html = generateHtml(reportData);
|
|
4736
|
-
const outputPath =
|
|
4834
|
+
const outputPath = import_path14.default.resolve(cwd, opts.output);
|
|
4737
4835
|
import_fs11.default.writeFileSync(outputPath, html, "utf-8");
|
|
4738
4836
|
log.success(`Report saved: ${opts.output}`);
|
|
4739
4837
|
log.info(
|
|
@@ -4767,7 +4865,7 @@ function registerReportCommand(program2) {
|
|
|
4767
4865
|
// cli/index.ts
|
|
4768
4866
|
function getVersion() {
|
|
4769
4867
|
try {
|
|
4770
|
-
const pkgPath =
|
|
4868
|
+
const pkgPath = import_path15.default.resolve(__dirname, "../../package.json");
|
|
4771
4869
|
const raw = import_fs12.default.readFileSync(pkgPath, "utf-8");
|
|
4772
4870
|
const pkg = JSON.parse(raw);
|
|
4773
4871
|
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|