eslint-plugin-ai-guard 1.2.3 → 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 +399 -118
- 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");
|
|
@@ -1259,11 +1262,13 @@ function sanitizeSarifTags(tags) {
|
|
|
1259
1262
|
);
|
|
1260
1263
|
}
|
|
1261
1264
|
function sanitizeSarifProperties(props) {
|
|
1265
|
+
const confidence = props.confidence ?? "low";
|
|
1262
1266
|
return {
|
|
1263
1267
|
tags: sanitizeSarifTags(props.tags),
|
|
1264
|
-
confidence
|
|
1268
|
+
confidence,
|
|
1265
1269
|
category: props.category ?? "AI Patterns",
|
|
1266
|
-
"
|
|
1270
|
+
"security-severity": confidenceToSecuritySeverity(confidence),
|
|
1271
|
+
precision: confidenceToPrecision(confidence)
|
|
1267
1272
|
};
|
|
1268
1273
|
}
|
|
1269
1274
|
function sanitizeSarifRule(rule) {
|
|
@@ -1295,6 +1300,34 @@ function sanitizeSarifLog(log2) {
|
|
|
1295
1300
|
}))
|
|
1296
1301
|
};
|
|
1297
1302
|
}
|
|
1303
|
+
function confidenceToSecuritySeverity(confidence) {
|
|
1304
|
+
switch (confidence) {
|
|
1305
|
+
case "high":
|
|
1306
|
+
return "8.0";
|
|
1307
|
+
case "medium":
|
|
1308
|
+
return "5.0";
|
|
1309
|
+
case "low":
|
|
1310
|
+
return "3.0";
|
|
1311
|
+
case "informational":
|
|
1312
|
+
return "1.0";
|
|
1313
|
+
default:
|
|
1314
|
+
return "3.0";
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
function confidenceToPrecision(confidence) {
|
|
1318
|
+
switch (confidence) {
|
|
1319
|
+
case "high":
|
|
1320
|
+
return "high";
|
|
1321
|
+
case "medium":
|
|
1322
|
+
return "medium";
|
|
1323
|
+
case "low":
|
|
1324
|
+
return "low";
|
|
1325
|
+
case "informational":
|
|
1326
|
+
return "low";
|
|
1327
|
+
default:
|
|
1328
|
+
return "low";
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1298
1331
|
function confidenceToSarifLevel(confidence) {
|
|
1299
1332
|
switch (confidence) {
|
|
1300
1333
|
case "high":
|
|
@@ -1323,22 +1356,24 @@ function confidenceToRank(confidence) {
|
|
|
1323
1356
|
return 30;
|
|
1324
1357
|
}
|
|
1325
1358
|
}
|
|
1326
|
-
function
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
return "low";
|
|
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
|
+
}
|
|
1338
1370
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1371
|
+
normalized = normalized.replace(/^\/+/, "");
|
|
1372
|
+
normalized = normalized.replace(/^\.\//, "");
|
|
1373
|
+
if (!normalized || normalized === ".") {
|
|
1374
|
+
normalized = filePath.replace(/\\/g, "/");
|
|
1375
|
+
}
|
|
1376
|
+
return normalized;
|
|
1342
1377
|
}
|
|
1343
1378
|
function collectUsedRuleIds(result) {
|
|
1344
1379
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1384,16 +1419,16 @@ function buildRuleDescriptors(ruleIds) {
|
|
|
1384
1419
|
properties: sanitizeSarifProperties({
|
|
1385
1420
|
tags: rawTags,
|
|
1386
1421
|
confidence,
|
|
1387
|
-
category
|
|
1388
|
-
problemSeverity: confidenceToGitHubSeverity(confidence)
|
|
1422
|
+
category
|
|
1389
1423
|
})
|
|
1390
1424
|
});
|
|
1391
1425
|
});
|
|
1392
1426
|
}
|
|
1393
|
-
function buildSarifResult(issue, file) {
|
|
1427
|
+
function buildSarifResult(issue, file, repoRoot) {
|
|
1394
1428
|
const confidence = ISSUE_CONFIDENCE[issue.ruleId];
|
|
1395
1429
|
const asyncRiskType = ISSUE_ASYNC_RISK_TYPE[issue.ruleId];
|
|
1396
1430
|
const category = ISSUE_CATEGORY[issue.ruleId];
|
|
1431
|
+
const sarifUri = normalizeSarifPath(file.filePath, repoRoot);
|
|
1397
1432
|
return {
|
|
1398
1433
|
ruleId: issue.ruleId,
|
|
1399
1434
|
level: confidenceToSarifLevel(confidence),
|
|
@@ -1404,8 +1439,8 @@ function buildSarifResult(issue, file) {
|
|
|
1404
1439
|
{
|
|
1405
1440
|
physicalLocation: {
|
|
1406
1441
|
artifactLocation: {
|
|
1407
|
-
|
|
1408
|
-
|
|
1442
|
+
// Repository-relative POSIX path — no uriBaseId
|
|
1443
|
+
uri: sarifUri
|
|
1409
1444
|
},
|
|
1410
1445
|
region: {
|
|
1411
1446
|
startLine: Math.max(1, issue.line),
|
|
@@ -1419,18 +1454,94 @@ function buildSarifResult(issue, file) {
|
|
|
1419
1454
|
],
|
|
1420
1455
|
properties: {
|
|
1421
1456
|
confidence: confidence ?? "low",
|
|
1457
|
+
"security-severity": confidenceToSecuritySeverity(confidence),
|
|
1458
|
+
precision: confidenceToPrecision(confidence),
|
|
1422
1459
|
...asyncRiskType && { asyncRiskType },
|
|
1423
1460
|
...category && { category }
|
|
1424
1461
|
}
|
|
1425
1462
|
};
|
|
1426
1463
|
}
|
|
1427
|
-
function
|
|
1464
|
+
function enhanceTagsWithGitHubSemantics(ruleId, baseTags) {
|
|
1465
|
+
const category = ISSUE_CATEGORY[ruleId];
|
|
1466
|
+
const tags = [...baseTags];
|
|
1467
|
+
if (category === "Security" || ruleId.includes("secret") || ruleId.includes("eval") || ruleId.includes("sql") || ruleId.includes("deserialize") || ruleId.includes("auth")) {
|
|
1468
|
+
tags.push("security", "correctness", "reliability");
|
|
1469
|
+
} else {
|
|
1470
|
+
tags.push("correctness", "reliability");
|
|
1471
|
+
}
|
|
1472
|
+
return sanitizeSarifTags(tags);
|
|
1473
|
+
}
|
|
1474
|
+
function normalizeSarifForGitHub(log2) {
|
|
1475
|
+
const normalizedRuns = log2.runs.map((run) => {
|
|
1476
|
+
const rules = run.tool.driver.rules.map((rule) => {
|
|
1477
|
+
const confidence = ISSUE_CONFIDENCE[rule.id];
|
|
1478
|
+
const properties = rule.properties || {};
|
|
1479
|
+
properties["security-severity"] = confidenceToSecuritySeverity(confidence);
|
|
1480
|
+
properties["precision"] = confidenceToPrecision(confidence);
|
|
1481
|
+
const currentTags = properties.tags || [];
|
|
1482
|
+
properties.tags = enhanceTagsWithGitHubSemantics(rule.id, currentTags);
|
|
1483
|
+
delete properties["problem.severity"];
|
|
1484
|
+
const defaultConfiguration = rule.defaultConfiguration || { level: "warning" };
|
|
1485
|
+
let normalizedConfigLevel = defaultConfiguration.level;
|
|
1486
|
+
if (!["error", "warning", "note", "none"].includes(normalizedConfigLevel)) {
|
|
1487
|
+
normalizedConfigLevel = confidenceToSarifLevel(confidence);
|
|
1488
|
+
}
|
|
1489
|
+
if (normalizedConfigLevel === "none") {
|
|
1490
|
+
normalizedConfigLevel = "note";
|
|
1491
|
+
}
|
|
1492
|
+
return {
|
|
1493
|
+
...rule,
|
|
1494
|
+
defaultConfiguration: {
|
|
1495
|
+
...defaultConfiguration,
|
|
1496
|
+
level: normalizedConfigLevel
|
|
1497
|
+
},
|
|
1498
|
+
properties
|
|
1499
|
+
};
|
|
1500
|
+
});
|
|
1501
|
+
const results = run.results.map((result) => {
|
|
1502
|
+
const confidence = ISSUE_CONFIDENCE[result.ruleId];
|
|
1503
|
+
const properties = result.properties || {};
|
|
1504
|
+
properties["security-severity"] = confidenceToSecuritySeverity(confidence);
|
|
1505
|
+
properties["precision"] = confidenceToPrecision(confidence);
|
|
1506
|
+
let normalizedLevel = result.level;
|
|
1507
|
+
if (!["error", "warning", "note", "none"].includes(normalizedLevel)) {
|
|
1508
|
+
normalizedLevel = confidenceToSarifLevel(confidence);
|
|
1509
|
+
}
|
|
1510
|
+
if (normalizedLevel === "none") {
|
|
1511
|
+
normalizedLevel = "note";
|
|
1512
|
+
}
|
|
1513
|
+
const kind = confidence === "informational" ? "informational" : "fail";
|
|
1514
|
+
return {
|
|
1515
|
+
...result,
|
|
1516
|
+
level: normalizedLevel,
|
|
1517
|
+
kind,
|
|
1518
|
+
properties
|
|
1519
|
+
};
|
|
1520
|
+
});
|
|
1521
|
+
return {
|
|
1522
|
+
...run,
|
|
1523
|
+
tool: {
|
|
1524
|
+
...run.tool,
|
|
1525
|
+
driver: {
|
|
1526
|
+
...run.tool.driver,
|
|
1527
|
+
rules
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
results
|
|
1531
|
+
};
|
|
1532
|
+
});
|
|
1533
|
+
return {
|
|
1534
|
+
...log2,
|
|
1535
|
+
runs: normalizedRuns
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
function buildSarifLog(result, version = PKG_VERSION, repoRoot) {
|
|
1428
1539
|
const usedRuleIds = collectUsedRuleIds(result);
|
|
1429
1540
|
const rules = buildRuleDescriptors(usedRuleIds);
|
|
1430
1541
|
const sarifResults = [];
|
|
1431
1542
|
for (const file of result.files) {
|
|
1432
1543
|
for (const issue of file.issues) {
|
|
1433
|
-
sarifResults.push(buildSarifResult(issue, file));
|
|
1544
|
+
sarifResults.push(buildSarifResult(issue, file, repoRoot));
|
|
1434
1545
|
}
|
|
1435
1546
|
}
|
|
1436
1547
|
const log2 = {
|
|
@@ -1457,12 +1568,24 @@ function buildSarifLog(result, version = PKG_VERSION) {
|
|
|
1457
1568
|
}
|
|
1458
1569
|
]
|
|
1459
1570
|
};
|
|
1460
|
-
return sanitizeSarifLog(log2);
|
|
1571
|
+
return normalizeSarifForGitHub(sanitizeSarifLog(log2));
|
|
1461
1572
|
}
|
|
1462
1573
|
function sarifToJson(log2) {
|
|
1463
1574
|
return JSON.stringify(log2, null, 2);
|
|
1464
1575
|
}
|
|
1465
|
-
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) {
|
|
1466
1589
|
const usedRuleIds = collectUsedRuleIds(result);
|
|
1467
1590
|
const rulesEmitted = usedRuleIds.map((id) => {
|
|
1468
1591
|
const meta = RULE_DOCS[id];
|
|
@@ -1470,7 +1593,7 @@ function buildSarifDebugInfo(result) {
|
|
|
1470
1593
|
const category = ISSUE_CATEGORY[id] ?? "AI Patterns";
|
|
1471
1594
|
const categorySlug = category.toLowerCase().replace(/\s+/g, "-");
|
|
1472
1595
|
const rawTags = [...meta?.tags ?? ["ai-guard"], categorySlug];
|
|
1473
|
-
const sanitizedTags =
|
|
1596
|
+
const sanitizedTags = enhanceTagsWithGitHubSemantics(id, rawTags);
|
|
1474
1597
|
return {
|
|
1475
1598
|
id,
|
|
1476
1599
|
rawTags,
|
|
@@ -1478,11 +1601,37 @@ function buildSarifDebugInfo(result) {
|
|
|
1478
1601
|
hasDuplicatesInRaw: rawTags.length !== new Set(rawTags).size,
|
|
1479
1602
|
confidence: confidence ?? "low",
|
|
1480
1603
|
category,
|
|
1481
|
-
level: confidenceToSarifLevel(confidence)
|
|
1604
|
+
level: confidenceToSarifLevel(confidence),
|
|
1605
|
+
securitySeverity: confidenceToSecuritySeverity(confidence),
|
|
1606
|
+
precision: confidenceToPrecision(confidence)
|
|
1482
1607
|
};
|
|
1483
1608
|
});
|
|
1609
|
+
const resultsEmitted = [];
|
|
1610
|
+
const pathsDebug = [];
|
|
1611
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
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
|
+
}
|
|
1617
|
+
for (const issue of file.issues) {
|
|
1618
|
+
const confidence = ISSUE_CONFIDENCE[issue.ruleId];
|
|
1619
|
+
resultsEmitted.push({
|
|
1620
|
+
ruleId: issue.ruleId,
|
|
1621
|
+
level: confidenceToSarifLevel(confidence),
|
|
1622
|
+
kind: confidence === "informational" ? "informational" : "fail",
|
|
1623
|
+
securitySeverity: confidenceToSecuritySeverity(confidence),
|
|
1624
|
+
precision: confidenceToPrecision(confidence),
|
|
1625
|
+
filePath: file.filePath,
|
|
1626
|
+
normalizedUri: normalizeSarifPath(file.filePath, repoRoot),
|
|
1627
|
+
line: issue.line
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1484
1631
|
return {
|
|
1485
1632
|
rulesEmitted,
|
|
1633
|
+
resultsEmitted,
|
|
1634
|
+
pathsDebug,
|
|
1486
1635
|
totalResults: result.files.reduce((n, f) => n + f.issues.length, 0),
|
|
1487
1636
|
version: PKG_VERSION
|
|
1488
1637
|
};
|
|
@@ -1715,7 +1864,7 @@ function writeGitHubOutputs(result, sarifPath) {
|
|
|
1715
1864
|
|
|
1716
1865
|
// cli/utils/git-diff.ts
|
|
1717
1866
|
var import_child_process = require("child_process");
|
|
1718
|
-
var
|
|
1867
|
+
var import_path4 = __toESM(require("path"));
|
|
1719
1868
|
var import_fs3 = __toESM(require("fs"));
|
|
1720
1869
|
var DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
1721
1870
|
var IGNORE_PREFIXES = [
|
|
@@ -1825,7 +1974,7 @@ function filterFiles(rawFiles, extensions, workingDirectory, cwd, debugInfo) {
|
|
|
1825
1974
|
for (const rel of rawFiles) {
|
|
1826
1975
|
const normalized = rel.replace(/\\/g, "/").trim();
|
|
1827
1976
|
if (!normalized) continue;
|
|
1828
|
-
const ext =
|
|
1977
|
+
const ext = import_path4.default.extname(normalized).toLowerCase();
|
|
1829
1978
|
if (!extensions.includes(ext)) {
|
|
1830
1979
|
debugInfo.droppedByExtension++;
|
|
1831
1980
|
continue;
|
|
@@ -1841,7 +1990,7 @@ function filterFiles(rawFiles, extensions, workingDirectory, cwd, debugInfo) {
|
|
|
1841
1990
|
continue;
|
|
1842
1991
|
}
|
|
1843
1992
|
}
|
|
1844
|
-
const abs =
|
|
1993
|
+
const abs = import_path4.default.resolve(cwd, normalized);
|
|
1845
1994
|
if (!import_fs3.default.existsSync(abs)) {
|
|
1846
1995
|
debugInfo.droppedMissing++;
|
|
1847
1996
|
continue;
|
|
@@ -1964,7 +2113,7 @@ function registerRunCommand(program2) {
|
|
|
1964
2113
|
"--max-warnings <n>",
|
|
1965
2114
|
"Fail with exit code 1 if warnings exceed this count",
|
|
1966
2115
|
(value) => Number.parseInt(value, 10)
|
|
1967
|
-
).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) => {
|
|
1968
2117
|
if (opts.maxWarnings !== void 0 && (!Number.isInteger(opts.maxWarnings) || opts.maxWarnings < 0)) {
|
|
1969
2118
|
log.blank();
|
|
1970
2119
|
log.error("--max-warnings must be a non-negative integer.");
|
|
@@ -2017,25 +2166,80 @@ function registerRunCommand(program2) {
|
|
|
2017
2166
|
writeGitHubOutputs(result);
|
|
2018
2167
|
}
|
|
2019
2168
|
if (opts.sarif || opts.sarifOutput) {
|
|
2020
|
-
const
|
|
2169
|
+
const repoRoot = process.env.GITHUB_WORKSPACE ?? void 0;
|
|
2170
|
+
const sarifLog = buildSarifLog(result, void 0, repoRoot);
|
|
2021
2171
|
const sarifJson = sarifToJson(sarifLog);
|
|
2022
2172
|
if (opts.debugSarif) {
|
|
2023
|
-
const debugInfo = buildSarifDebugInfo(result);
|
|
2024
|
-
process.stderr.write("\n[debug-sarif] SARIF
|
|
2173
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2174
|
+
process.stderr.write("\n[debug-sarif] SARIF GitHub Compatibility Trace\n");
|
|
2025
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");
|
|
2176
|
+
process.stderr.write("[debug-sarif] Rules Emitted:\n");
|
|
2026
2177
|
for (const r of debugInfo.rulesEmitted) {
|
|
2027
|
-
process.stderr.write(`[debug-sarif] ${r.id}
|
|
2178
|
+
process.stderr.write(`[debug-sarif] - ${r.id}:
|
|
2179
|
+
`);
|
|
2180
|
+
process.stderr.write(`[debug-sarif] confidence: ${r.confidence}
|
|
2181
|
+
`);
|
|
2182
|
+
process.stderr.write(`[debug-sarif] level: ${r.level}
|
|
2183
|
+
`);
|
|
2184
|
+
process.stderr.write(`[debug-sarif] security-severity: ${r.securitySeverity}
|
|
2028
2185
|
`);
|
|
2029
|
-
process.stderr.write(`[debug-sarif]
|
|
2186
|
+
process.stderr.write(`[debug-sarif] precision: ${r.precision}
|
|
2030
2187
|
`);
|
|
2031
|
-
process.stderr.write(`[debug-sarif]
|
|
2188
|
+
process.stderr.write(`[debug-sarif] raw tags: ${JSON.stringify(r.rawTags)}
|
|
2189
|
+
`);
|
|
2190
|
+
process.stderr.write(`[debug-sarif] normalized tags: ${JSON.stringify(r.sanitizedTags)}
|
|
2032
2191
|
`);
|
|
2033
2192
|
if (r.hasDuplicatesInRaw) {
|
|
2034
|
-
process.stderr.write(`[debug-sarif]
|
|
2193
|
+
process.stderr.write(`[debug-sarif] \u26A0 had duplicates \u2014 deduplicated
|
|
2194
|
+
`);
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
process.stderr.write("\n[debug-sarif] Results Emitted:\n");
|
|
2198
|
+
if (debugInfo.resultsEmitted.length === 0) {
|
|
2199
|
+
process.stderr.write("[debug-sarif] (none)\n");
|
|
2200
|
+
} else {
|
|
2201
|
+
for (const res of debugInfo.resultsEmitted) {
|
|
2202
|
+
process.stderr.write(`[debug-sarif] - ${res.ruleId} (${res.filePath}:${res.line}):
|
|
2203
|
+
`);
|
|
2204
|
+
process.stderr.write(`[debug-sarif] level: ${res.level}
|
|
2205
|
+
`);
|
|
2206
|
+
process.stderr.write(`[debug-sarif] kind: ${res.kind}
|
|
2207
|
+
`);
|
|
2208
|
+
process.stderr.write(`[debug-sarif] security-severity: ${res.securitySeverity}
|
|
2209
|
+
`);
|
|
2210
|
+
process.stderr.write(`[debug-sarif] precision: ${res.precision}
|
|
2211
|
+
`);
|
|
2212
|
+
process.stderr.write(`[debug-sarif] artifact uri: ${res.normalizedUri}
|
|
2213
|
+
`);
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
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");
|
|
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)"}
|
|
2035
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");
|
|
2036
2240
|
}
|
|
2037
2241
|
}
|
|
2038
|
-
process.stderr.write("\n");
|
|
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");
|
|
2039
2243
|
}
|
|
2040
2244
|
if (opts.sarifOutput) {
|
|
2041
2245
|
import_fs4.default.writeFileSync(opts.sarifOutput, sarifJson, "utf-8");
|
|
@@ -2379,7 +2583,7 @@ function resolveExitCode(result, failOn, maxWarnings) {
|
|
|
2379
2583
|
}
|
|
2380
2584
|
|
|
2381
2585
|
// cli/commands/changed.ts
|
|
2382
|
-
var
|
|
2586
|
+
var import_path5 = __toESM(require("path"));
|
|
2383
2587
|
var import_fs5 = __toESM(require("fs"));
|
|
2384
2588
|
var import_ora2 = __toESM(require("ora"));
|
|
2385
2589
|
var import_chalk5 = __toESM(require("chalk"));
|
|
@@ -2388,7 +2592,7 @@ function registerChangedCommand(program2) {
|
|
|
2388
2592
|
"--max-warnings <n>",
|
|
2389
2593
|
"Fail if warnings exceed this count",
|
|
2390
2594
|
(v) => Number.parseInt(v, 10)
|
|
2391
|
-
).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)").action(async (opts) => {
|
|
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) => {
|
|
2392
2596
|
const preset = opts.strict ? "strict" : opts.security ? "security" : "recommended";
|
|
2393
2597
|
const inCI = isGitHubActions();
|
|
2394
2598
|
const baseRef = opts.base ?? (opts.pr || inCI ? getGitHubBaseRef() : void 0);
|
|
@@ -2417,7 +2621,7 @@ function registerChangedCommand(program2) {
|
|
|
2417
2621
|
});
|
|
2418
2622
|
}
|
|
2419
2623
|
const cwd = process.cwd();
|
|
2420
|
-
const resolvedPath =
|
|
2624
|
+
const resolvedPath = import_path5.default.resolve(opts.path);
|
|
2421
2625
|
const workingDirectory = opts.path !== "." ? opts.path : void 0;
|
|
2422
2626
|
const spinner = opts.json || opts.sarif ? null : (0, import_ora2.default)({ text: import_chalk5.default.dim("Detecting changed files\u2026"), color: "cyan" }).start();
|
|
2423
2627
|
const changedResult = getChangedFiles({
|
|
@@ -2498,10 +2702,87 @@ function handleResults(result, opts, preset, scanMode, changedFilesCount, inCI,
|
|
|
2498
2702
|
emitGitHubAnnotations(result);
|
|
2499
2703
|
}
|
|
2500
2704
|
if (opts.sarif) {
|
|
2501
|
-
const
|
|
2705
|
+
const repoRoot = process.env.GITHUB_WORKSPACE ?? void 0;
|
|
2706
|
+
const sarifLog = buildSarifLog(result, void 0, repoRoot);
|
|
2502
2707
|
const sarifJson = sarifToJson(sarifLog);
|
|
2708
|
+
if (opts.debugSarif) {
|
|
2709
|
+
const debugInfo = buildSarifDebugInfo(result, repoRoot);
|
|
2710
|
+
process.stderr.write("\n[debug-sarif] SARIF GitHub Compatibility Trace\n");
|
|
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");
|
|
2712
|
+
process.stderr.write("[debug-sarif] Rules Emitted:\n");
|
|
2713
|
+
for (const r of debugInfo.rulesEmitted) {
|
|
2714
|
+
process.stderr.write(`[debug-sarif] - ${r.id}:
|
|
2715
|
+
`);
|
|
2716
|
+
process.stderr.write(`[debug-sarif] confidence: ${r.confidence}
|
|
2717
|
+
`);
|
|
2718
|
+
process.stderr.write(`[debug-sarif] level: ${r.level}
|
|
2719
|
+
`);
|
|
2720
|
+
process.stderr.write(`[debug-sarif] security-severity: ${r.securitySeverity}
|
|
2721
|
+
`);
|
|
2722
|
+
process.stderr.write(`[debug-sarif] precision: ${r.precision}
|
|
2723
|
+
`);
|
|
2724
|
+
process.stderr.write(`[debug-sarif] raw tags: ${JSON.stringify(r.rawTags)}
|
|
2725
|
+
`);
|
|
2726
|
+
process.stderr.write(`[debug-sarif] normalized tags: ${JSON.stringify(r.sanitizedTags)}
|
|
2727
|
+
`);
|
|
2728
|
+
if (r.hasDuplicatesInRaw) {
|
|
2729
|
+
process.stderr.write(`[debug-sarif] \u26A0 had duplicates \u2014 deduplicated
|
|
2730
|
+
`);
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
process.stderr.write("\n[debug-sarif] Results Emitted:\n");
|
|
2734
|
+
if (debugInfo.resultsEmitted.length === 0) {
|
|
2735
|
+
process.stderr.write("[debug-sarif] (none)\n");
|
|
2736
|
+
} else {
|
|
2737
|
+
for (const res of debugInfo.resultsEmitted) {
|
|
2738
|
+
process.stderr.write(`[debug-sarif] - ${res.ruleId} (${res.filePath}:${res.line}):
|
|
2739
|
+
`);
|
|
2740
|
+
process.stderr.write(`[debug-sarif] level: ${res.level}
|
|
2741
|
+
`);
|
|
2742
|
+
process.stderr.write(`[debug-sarif] kind: ${res.kind}
|
|
2743
|
+
`);
|
|
2744
|
+
process.stderr.write(`[debug-sarif] security-severity: ${res.securitySeverity}
|
|
2745
|
+
`);
|
|
2746
|
+
process.stderr.write(`[debug-sarif] precision: ${res.precision}
|
|
2747
|
+
`);
|
|
2748
|
+
process.stderr.write(`[debug-sarif] artifact uri: ${res.normalizedUri}
|
|
2749
|
+
`);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
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");
|
|
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
|
+
}
|
|
2503
2780
|
if (resolvedSarifPath) {
|
|
2504
2781
|
import_fs5.default.writeFileSync(resolvedSarifPath, sarifJson, "utf-8");
|
|
2782
|
+
if (opts.debugSarif) {
|
|
2783
|
+
process.stderr.write(`[debug-sarif] SARIF written to: ${resolvedSarifPath}
|
|
2784
|
+
`);
|
|
2785
|
+
}
|
|
2505
2786
|
} else {
|
|
2506
2787
|
console.log(sarifJson);
|
|
2507
2788
|
}
|
|
@@ -2631,12 +2912,12 @@ function getFailOnExitCode(result, failOn, maxWarnings) {
|
|
|
2631
2912
|
|
|
2632
2913
|
// cli/commands/init.ts
|
|
2633
2914
|
var import_chalk6 = __toESM(require("chalk"));
|
|
2634
|
-
var
|
|
2915
|
+
var import_path8 = __toESM(require("path"));
|
|
2635
2916
|
var import_fs8 = __toESM(require("fs"));
|
|
2636
2917
|
|
|
2637
2918
|
// cli/utils/detector.ts
|
|
2638
2919
|
var import_fs6 = __toESM(require("fs"));
|
|
2639
|
-
var
|
|
2920
|
+
var import_path6 = __toESM(require("path"));
|
|
2640
2921
|
var import_module2 = require("module");
|
|
2641
2922
|
var FLAT_CONFIG_FILES = [
|
|
2642
2923
|
{ file: "eslint.config.js", type: "flat-js" },
|
|
@@ -2653,11 +2934,11 @@ var LEGACY_CONFIG_FILES = [
|
|
|
2653
2934
|
var ALL_CONFIG_FILES = [...FLAT_CONFIG_FILES, ...LEGACY_CONFIG_FILES];
|
|
2654
2935
|
function isPackageInstalled(pkgName, cwd = process.cwd()) {
|
|
2655
2936
|
try {
|
|
2656
|
-
const pkgPath =
|
|
2937
|
+
const pkgPath = import_path6.default.join(cwd, "node_modules", pkgName, "package.json");
|
|
2657
2938
|
if (import_fs6.default.existsSync(pkgPath)) {
|
|
2658
2939
|
return true;
|
|
2659
2940
|
}
|
|
2660
|
-
const req = (0, import_module2.createRequire)(
|
|
2941
|
+
const req = (0, import_module2.createRequire)(import_path6.default.join(cwd, "package.json"));
|
|
2661
2942
|
req.resolve(`${pkgName}/package.json`);
|
|
2662
2943
|
return true;
|
|
2663
2944
|
} catch {
|
|
@@ -2666,8 +2947,8 @@ function isPackageInstalled(pkgName, cwd = process.cwd()) {
|
|
|
2666
2947
|
}
|
|
2667
2948
|
function getPackageVersion(pkgName, cwd = process.cwd()) {
|
|
2668
2949
|
try {
|
|
2669
|
-
const pkgPath =
|
|
2670
|
-
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`);
|
|
2671
2952
|
const raw = import_fs6.default.readFileSync(resolvedPath, "utf-8");
|
|
2672
2953
|
const json = JSON.parse(raw);
|
|
2673
2954
|
return json.version ?? null;
|
|
@@ -2684,7 +2965,7 @@ function detectConfigType(cwd = process.cwd()) {
|
|
|
2684
2965
|
const found = [];
|
|
2685
2966
|
let first = null;
|
|
2686
2967
|
for (const { file, type } of ALL_CONFIG_FILES) {
|
|
2687
|
-
const fullPath =
|
|
2968
|
+
const fullPath = import_path6.default.join(cwd, file);
|
|
2688
2969
|
if (import_fs6.default.existsSync(fullPath)) {
|
|
2689
2970
|
found.push(fullPath);
|
|
2690
2971
|
if (!first) first = { type, path: fullPath };
|
|
@@ -2764,7 +3045,7 @@ async function verifyConfigLoads(configPath, cwd) {
|
|
|
2764
3045
|
overrideConfigFile: configPath
|
|
2765
3046
|
});
|
|
2766
3047
|
await eslint.lintText("", {
|
|
2767
|
-
filePath:
|
|
3048
|
+
filePath: import_path8.default.join(cwd, "_ai_guard_probe_.js")
|
|
2768
3049
|
});
|
|
2769
3050
|
return null;
|
|
2770
3051
|
} catch (err) {
|
|
@@ -2800,7 +3081,7 @@ function registerInitCommand(program2) {
|
|
|
2800
3081
|
log.warn("eslint-plugin-ai-guard not found");
|
|
2801
3082
|
}
|
|
2802
3083
|
if (env.configType !== "none") {
|
|
2803
|
-
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))}`);
|
|
2804
3085
|
} else {
|
|
2805
3086
|
log.info("No ESLint config found \u2014 will generate one");
|
|
2806
3087
|
}
|
|
@@ -2809,7 +3090,7 @@ function registerInitCommand(program2) {
|
|
|
2809
3090
|
log.blank();
|
|
2810
3091
|
log.warn("Conflicting configs detected:");
|
|
2811
3092
|
for (const p of env.allConfigPaths) {
|
|
2812
|
-
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))}`);
|
|
2813
3094
|
}
|
|
2814
3095
|
log.print(` ${import_chalk6.default.gray("Multiple config formats found \u2014 this can cause unpredictable behavior.")}`);
|
|
2815
3096
|
}
|
|
@@ -2837,7 +3118,7 @@ function registerInitCommand(program2) {
|
|
|
2837
3118
|
try {
|
|
2838
3119
|
const { createRequire: createRequire3 } = await import("module");
|
|
2839
3120
|
const { pathToFileURL: pathToFileURL2 } = await import("url");
|
|
2840
|
-
const req = createRequire3(
|
|
3121
|
+
const req = createRequire3(import_path8.default.join(cwd, "_probe.js"));
|
|
2841
3122
|
const resolvedPath = req.resolve("eslint-plugin-ai-guard");
|
|
2842
3123
|
const aiGuard = await import(pathToFileURL2(resolvedPath).href);
|
|
2843
3124
|
const plugin = aiGuard.default || aiGuard;
|
|
@@ -2856,7 +3137,7 @@ function registerInitCommand(program2) {
|
|
|
2856
3137
|
if (eslintNeedsFlat && existingIsLegacy) {
|
|
2857
3138
|
log.section("Config Migration Required");
|
|
2858
3139
|
log.warn(`ESLint v${env.eslintMajor} requires flat config, but a legacy config was found:`);
|
|
2859
|
-
log.print(` ${import_chalk6.default.white(
|
|
3140
|
+
log.print(` ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
2860
3141
|
log.blank();
|
|
2861
3142
|
log.print(` ${import_chalk6.default.bold("ai-guard will create a new flat config.")}`);
|
|
2862
3143
|
log.blank();
|
|
@@ -2868,7 +3149,7 @@ function registerInitCommand(program2) {
|
|
|
2868
3149
|
const raw = readConfig(env.configPath);
|
|
2869
3150
|
const { content: fixed, changed } = removeNukeIgnore(raw);
|
|
2870
3151
|
if (changed) {
|
|
2871
|
-
log.warn(`Removed "**/*" ignore pattern from ${
|
|
3152
|
+
log.warn(`Removed "**/*" ignore pattern from ${import_path8.default.relative(cwd, env.configPath)}`);
|
|
2872
3153
|
if (!isDryRun) {
|
|
2873
3154
|
backupConfig(env.configPath);
|
|
2874
3155
|
writeConfig(env.configPath, fixed);
|
|
@@ -2880,7 +3161,7 @@ function registerInitCommand(program2) {
|
|
|
2880
3161
|
}
|
|
2881
3162
|
if (env.configType === "none" || eslintNeedsFlat && existingIsLegacy) {
|
|
2882
3163
|
const targetName = useFlat ? "eslint.config.mjs" : ".eslintrc.js";
|
|
2883
|
-
finalConfigPath =
|
|
3164
|
+
finalConfigPath = import_path8.default.join(cwd, targetName);
|
|
2884
3165
|
const content2 = useFlat ? generateFlatConfig(preset) : generateLegacyConfig(preset);
|
|
2885
3166
|
if (isDryRun) {
|
|
2886
3167
|
log.print(` ${import_chalk6.default.gray(`[dry-run] would create: ${targetName}`)}`);
|
|
@@ -2908,15 +3189,15 @@ function registerInitCommand(program2) {
|
|
|
2908
3189
|
finalConfigPath = env.configPath;
|
|
2909
3190
|
} else if (isDryRun) {
|
|
2910
3191
|
finalConfigPath = env.configPath;
|
|
2911
|
-
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)}`)}`);
|
|
2912
3193
|
} else {
|
|
2913
3194
|
const bak = backupConfig(env.configPath);
|
|
2914
|
-
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))}`);
|
|
2915
3196
|
writeConfig(env.configPath, patched);
|
|
2916
3197
|
if (isInvalid) {
|
|
2917
|
-
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))}`);
|
|
2918
3199
|
} else {
|
|
2919
|
-
log.success(`Patched ${import_chalk6.default.white(
|
|
3200
|
+
log.success(`Patched ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
2920
3201
|
}
|
|
2921
3202
|
finalConfigPath = env.configPath;
|
|
2922
3203
|
configWritten = true;
|
|
@@ -2929,12 +3210,12 @@ function registerInitCommand(program2) {
|
|
|
2929
3210
|
finalConfigPath = env.configPath;
|
|
2930
3211
|
} else if (isDryRun) {
|
|
2931
3212
|
finalConfigPath = env.configPath;
|
|
2932
|
-
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)}`)}`);
|
|
2933
3214
|
} else {
|
|
2934
3215
|
const bak = backupConfig(env.configPath);
|
|
2935
|
-
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))}`);
|
|
2936
3217
|
writeConfig(env.configPath, patched);
|
|
2937
|
-
log.success(`Patched ${import_chalk6.default.white(
|
|
3218
|
+
log.success(`Patched ${import_chalk6.default.white(import_path8.default.relative(cwd, env.configPath))}`);
|
|
2938
3219
|
finalConfigPath = env.configPath;
|
|
2939
3220
|
configWritten = true;
|
|
2940
3221
|
}
|
|
@@ -2950,11 +3231,11 @@ function registerInitCommand(program2) {
|
|
|
2950
3231
|
cleanedUp = true;
|
|
2951
3232
|
} catch (err) {
|
|
2952
3233
|
const reason = err instanceof Error ? err.message : String(err);
|
|
2953
|
-
log.warn(`Could not back up ${
|
|
3234
|
+
log.warn(`Could not back up ${import_path8.default.relative(cwd, p)}: ${reason}`);
|
|
2954
3235
|
}
|
|
2955
3236
|
} else {
|
|
2956
3237
|
cleanedUp = true;
|
|
2957
|
-
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`)}`);
|
|
2958
3239
|
}
|
|
2959
3240
|
}
|
|
2960
3241
|
}
|
|
@@ -2973,7 +3254,7 @@ function registerInitCommand(program2) {
|
|
|
2973
3254
|
log.blank();
|
|
2974
3255
|
log.section("Validation");
|
|
2975
3256
|
if (!import_fs8.default.existsSync(finalConfigPath)) {
|
|
2976
|
-
log.error(`Config file not found after write: ${
|
|
3257
|
+
log.error(`Config file not found after write: ${import_path8.default.relative(cwd, finalConfigPath)}`);
|
|
2977
3258
|
log.blank();
|
|
2978
3259
|
log.print(` ${import_chalk6.default.bold("Problem:")} File write may have failed.`);
|
|
2979
3260
|
log.print(` ${import_chalk6.default.bold("Fix:")} Check disk space and file permissions, then re-run.`);
|
|
@@ -2989,7 +3270,7 @@ function registerInitCommand(program2) {
|
|
|
2989
3270
|
log.print(` ${import_chalk6.default.red("\u2716")} ${e}`);
|
|
2990
3271
|
}
|
|
2991
3272
|
} else {
|
|
2992
|
-
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))}`);
|
|
2993
3274
|
}
|
|
2994
3275
|
log.info("Verifying ESLint can load the config\u2026");
|
|
2995
3276
|
const loadError = await verifyConfigLoads(finalConfigPath, cwd);
|
|
@@ -3013,7 +3294,7 @@ function registerInitCommand(program2) {
|
|
|
3013
3294
|
}
|
|
3014
3295
|
log.blank();
|
|
3015
3296
|
log.print(` ${import_chalk6.default.bold("Fix:")}`);
|
|
3016
|
-
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))}`);
|
|
3017
3298
|
log.print(` 2. Make sure ${import_chalk6.default.cyan("eslint-plugin-ai-guard")} is installed`);
|
|
3018
3299
|
log.print(` 3. Run ${import_chalk6.default.cyan("ai-guard doctor")} for full diagnostics`);
|
|
3019
3300
|
log.blank();
|
|
@@ -3035,7 +3316,7 @@ function registerInitCommand(program2) {
|
|
|
3035
3316
|
if (loadError === null && !lingeringConflicts) {
|
|
3036
3317
|
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold.green("Configuration validated successfully")}`);
|
|
3037
3318
|
}
|
|
3038
|
-
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))}`);
|
|
3039
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})`)}`);
|
|
3040
3321
|
log.print(` ${import_chalk6.default.green("\u2714")} ${import_chalk6.default.bold("Preset:")} ${import_chalk6.default.cyan(preset)}`);
|
|
3041
3322
|
log.blank();
|
|
@@ -3049,14 +3330,14 @@ function registerInitCommand(program2) {
|
|
|
3049
3330
|
|
|
3050
3331
|
// cli/commands/doctor.ts
|
|
3051
3332
|
var import_chalk7 = __toESM(require("chalk"));
|
|
3052
|
-
var
|
|
3333
|
+
var import_path9 = __toESM(require("path"));
|
|
3053
3334
|
init_config_manager();
|
|
3054
3335
|
var import_meta2 = {};
|
|
3055
3336
|
async function probeConfigLoad(configPath, cwd) {
|
|
3056
3337
|
try {
|
|
3057
3338
|
const { ESLint } = await import("eslint");
|
|
3058
3339
|
const eslint = new ESLint({ cwd, overrideConfigFile: configPath });
|
|
3059
|
-
await eslint.lintText("", { filePath:
|
|
3340
|
+
await eslint.lintText("", { filePath: import_path9.default.join(cwd, "_probe_.js") });
|
|
3060
3341
|
return { ok: true, error: null };
|
|
3061
3342
|
} catch (err) {
|
|
3062
3343
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -3091,7 +3372,7 @@ function registerDoctorCommand(program2) {
|
|
|
3091
3372
|
checks.push({
|
|
3092
3373
|
label: "ESLint config present",
|
|
3093
3374
|
pass: hasConfig,
|
|
3094
|
-
detail: hasConfig ? `${
|
|
3375
|
+
detail: hasConfig ? `${import_path9.default.relative(cwd, env.configPath ?? "")} (${env.configType})` : "No eslint.config.* or .eslintrc.* found",
|
|
3095
3376
|
fix: hasConfig ? void 0 : "ai-guard init",
|
|
3096
3377
|
note: hasConfig ? void 0 : "This will generate the correct config format for your ESLint version"
|
|
3097
3378
|
});
|
|
@@ -3123,7 +3404,7 @@ function registerDoctorCommand(program2) {
|
|
|
3123
3404
|
checks.push({
|
|
3124
3405
|
label: "Plugin wired in config",
|
|
3125
3406
|
pass: pluginWired && !isInvalidConfig,
|
|
3126
|
-
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)}`,
|
|
3127
3408
|
fix: isInvalidConfig || !pluginWired && !readError ? "ai-guard init (will patch/repair your existing config)" : void 0
|
|
3128
3409
|
});
|
|
3129
3410
|
}
|
|
@@ -3131,7 +3412,7 @@ function registerDoctorCommand(program2) {
|
|
|
3131
3412
|
label: "No conflicting config files",
|
|
3132
3413
|
pass: !env.hasConflictingConfigs,
|
|
3133
3414
|
detail: env.hasConflictingConfigs ? `Conflicting config detected:
|
|
3134
|
-
${env.allConfigPaths.map((p) => ` ${
|
|
3415
|
+
${env.allConfigPaths.map((p) => ` ${import_path9.default.relative(cwd, p)}`).join("\n")}` : "Only one config format detected",
|
|
3135
3416
|
fix: env.hasConflictingConfigs ? "Remove or backup legacy config" : void 0,
|
|
3136
3417
|
note: env.hasConflictingConfigs ? "ESLint v9 silently ignores .eslintrc.* when a flat config exists. This can cause confusion." : void 0
|
|
3137
3418
|
});
|
|
@@ -3158,7 +3439,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3158
3439
|
label: "ESLint config loads without errors",
|
|
3159
3440
|
pass: probe.ok,
|
|
3160
3441
|
detail: probe.ok ? "ESLint loaded config successfully" : probe.error ?? "Unknown error",
|
|
3161
|
-
fix: probe.ok ? void 0 : `Check syntax in ${
|
|
3442
|
+
fix: probe.ok ? void 0 : `Check syntax in ${import_path9.default.relative(cwd, env.configPath)}`,
|
|
3162
3443
|
note: probe.ok ? void 0 : "Run: ai-guard init --dry-run to preview a fresh config"
|
|
3163
3444
|
});
|
|
3164
3445
|
}
|
|
@@ -3167,7 +3448,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3167
3448
|
let utilsVersion = null;
|
|
3168
3449
|
try {
|
|
3169
3450
|
const { createRequire: createRequire3 } = await import("module");
|
|
3170
|
-
const req = createRequire3(
|
|
3451
|
+
const req = createRequire3(import_path9.default.join(cwd, "package.json"));
|
|
3171
3452
|
const pkgPath = req.resolve("@typescript-eslint/utils/package.json");
|
|
3172
3453
|
const pkg = JSON.parse(
|
|
3173
3454
|
(await import("fs")).readFileSync(pkgPath, "utf-8")
|
|
@@ -3178,10 +3459,10 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3178
3459
|
}
|
|
3179
3460
|
if (!utilsOk) {
|
|
3180
3461
|
try {
|
|
3181
|
-
const selfDir =
|
|
3462
|
+
const selfDir = import_path9.default.dirname(
|
|
3182
3463
|
new URL(import_meta2.url).pathname.replace(/^\/([A-Za-z]:)/, "$1")
|
|
3183
3464
|
);
|
|
3184
|
-
const pkgPath =
|
|
3465
|
+
const pkgPath = import_path9.default.join(selfDir, "../../node_modules/@typescript-eslint/utils/package.json");
|
|
3185
3466
|
if ((await import("fs")).existsSync(pkgPath)) {
|
|
3186
3467
|
utilsOk = true;
|
|
3187
3468
|
}
|
|
@@ -3201,7 +3482,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3201
3482
|
let parserVersion = null;
|
|
3202
3483
|
try {
|
|
3203
3484
|
const { createRequire: createRequire3 } = await import("module");
|
|
3204
|
-
const req = createRequire3(
|
|
3485
|
+
const req = createRequire3(import_path9.default.join(cwd, "package.json"));
|
|
3205
3486
|
const pkgPath = req.resolve("@typescript-eslint/parser/package.json");
|
|
3206
3487
|
const pkg = JSON.parse(
|
|
3207
3488
|
(await import("fs")).readFileSync(pkgPath, "utf-8")
|
|
@@ -3289,7 +3570,7 @@ ${env.allConfigPaths.map((p) => ` ${import_path8.default.relative(cwd, p)}
|
|
|
3289
3570
|
var import_prompts = require("@inquirer/prompts");
|
|
3290
3571
|
var import_chalk8 = __toESM(require("chalk"));
|
|
3291
3572
|
init_config_manager();
|
|
3292
|
-
var
|
|
3573
|
+
var import_path10 = __toESM(require("path"));
|
|
3293
3574
|
function registerPresetCommand(program2) {
|
|
3294
3575
|
program2.command("preset").description("Interactively select and apply an ai-guard preset to your ESLint config").action(async () => {
|
|
3295
3576
|
const cwd = process.cwd();
|
|
@@ -3317,14 +3598,14 @@ function registerPresetCommand(program2) {
|
|
|
3317
3598
|
const env = detect(cwd);
|
|
3318
3599
|
const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9 || isFlat(env.configType);
|
|
3319
3600
|
if (env.configType === "none") {
|
|
3320
|
-
const configPath = useFlat ?
|
|
3601
|
+
const configPath = useFlat ? import_path10.default.join(cwd, "eslint.config.mjs") : import_path10.default.join(cwd, ".eslintrc.js");
|
|
3321
3602
|
const content = useFlat ? generateFlatConfig(preset) : generateLegacyConfig(preset);
|
|
3322
3603
|
writeConfig(configPath, content);
|
|
3323
|
-
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`);
|
|
3324
3605
|
} else {
|
|
3325
3606
|
const configPath = env.configPath;
|
|
3326
3607
|
const backupPath = backupConfig(configPath);
|
|
3327
|
-
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))}`);
|
|
3328
3609
|
const existing = readConfig(configPath);
|
|
3329
3610
|
const withPlugin = isFlat(env.configType) ? patchFlatConfig(existing, preset) : patchLegacyConfig(existing, preset);
|
|
3330
3611
|
const patched = isFlat(env.configType) ? switchFlatPreset(withPlugin, preset) : switchLegacyPreset(withPlugin, preset);
|
|
@@ -3332,7 +3613,7 @@ function registerPresetCommand(program2) {
|
|
|
3332
3613
|
log.warn("No preset changes needed. Config already matches selected preset.");
|
|
3333
3614
|
} else {
|
|
3334
3615
|
writeConfig(configPath, patched);
|
|
3335
|
-
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`);
|
|
3336
3617
|
}
|
|
3337
3618
|
}
|
|
3338
3619
|
log.blank();
|
|
@@ -3372,7 +3653,7 @@ function registerPresetCommand(program2) {
|
|
|
3372
3653
|
// cli/commands/ignore.ts
|
|
3373
3654
|
var import_chalk9 = __toESM(require("chalk"));
|
|
3374
3655
|
init_config_manager();
|
|
3375
|
-
var
|
|
3656
|
+
var import_path11 = __toESM(require("path"));
|
|
3376
3657
|
var DEFAULT_IGNORES = [
|
|
3377
3658
|
".next/",
|
|
3378
3659
|
"dist/",
|
|
@@ -3394,21 +3675,21 @@ function registerIgnoreCommand(program2) {
|
|
|
3394
3675
|
const env = detect(cwd);
|
|
3395
3676
|
if (env.configType === "none") {
|
|
3396
3677
|
const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9;
|
|
3397
|
-
const configPath = useFlat ?
|
|
3678
|
+
const configPath = useFlat ? import_path11.default.join(cwd, "eslint.config.mjs") : import_path11.default.join(cwd, ".eslintrc.js");
|
|
3398
3679
|
const content = useFlat ? generateFlatConfig("recommended") : generateLegacyConfig("recommended");
|
|
3399
3680
|
writeConfig(configPath, content);
|
|
3400
|
-
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`);
|
|
3401
3682
|
} else {
|
|
3402
3683
|
const configPath = env.configPath;
|
|
3403
3684
|
const backupPath = backupConfig(configPath);
|
|
3404
|
-
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))}`);
|
|
3405
3686
|
const existing = readConfig(configPath);
|
|
3406
3687
|
const patched = isFlat(env.configType) ? addIgnoresToFlatConfig(existing) : addIgnoresToLegacyConfig(existing);
|
|
3407
3688
|
if (patched === existing) {
|
|
3408
3689
|
log.warn("Ignore patterns already present in config \u2014 no changes made.");
|
|
3409
3690
|
} else {
|
|
3410
3691
|
writeConfig(configPath, patched);
|
|
3411
|
-
log.success(`Patched ${import_chalk9.default.white(
|
|
3692
|
+
log.success(`Patched ${import_chalk9.default.white(import_path11.default.relative(cwd, configPath))} with ignore patterns`);
|
|
3412
3693
|
}
|
|
3413
3694
|
}
|
|
3414
3695
|
log.blank();
|
|
@@ -3420,7 +3701,7 @@ function registerIgnoreCommand(program2) {
|
|
|
3420
3701
|
|
|
3421
3702
|
// cli/commands/baseline.ts
|
|
3422
3703
|
var import_fs9 = __toESM(require("fs"));
|
|
3423
|
-
var
|
|
3704
|
+
var import_path12 = __toESM(require("path"));
|
|
3424
3705
|
var import_chalk10 = __toESM(require("chalk"));
|
|
3425
3706
|
var import_ora3 = __toESM(require("ora"));
|
|
3426
3707
|
var BASELINE_FILE = ".ai-guard-baseline.json";
|
|
@@ -3441,12 +3722,12 @@ function saveBaseline(result, preset, mode, cwd) {
|
|
|
3441
3722
|
totalIssues: result.totalIssues,
|
|
3442
3723
|
entries
|
|
3443
3724
|
};
|
|
3444
|
-
const baselinePath =
|
|
3725
|
+
const baselinePath = import_path12.default.join(cwd, BASELINE_FILE);
|
|
3445
3726
|
import_fs9.default.writeFileSync(baselinePath, JSON.stringify(baseline, null, 2), "utf-8");
|
|
3446
3727
|
return baselinePath;
|
|
3447
3728
|
}
|
|
3448
3729
|
function loadBaseline(cwd) {
|
|
3449
|
-
const baselinePath =
|
|
3730
|
+
const baselinePath = import_path12.default.join(cwd, BASELINE_FILE);
|
|
3450
3731
|
if (!import_fs9.default.existsSync(baselinePath)) return null;
|
|
3451
3732
|
try {
|
|
3452
3733
|
const raw = import_fs9.default.readFileSync(baselinePath, "utf-8");
|
|
@@ -3533,7 +3814,7 @@ function registerBaselineCommand(program2) {
|
|
|
3533
3814
|
}
|
|
3534
3815
|
const baselinePath = saveBaseline(result, preset, mode, cwd);
|
|
3535
3816
|
log.success(
|
|
3536
|
-
`Baseline saved \u2192 ${import_chalk10.default.white(
|
|
3817
|
+
`Baseline saved \u2192 ${import_chalk10.default.white(import_path12.default.relative(cwd, baselinePath))}`
|
|
3537
3818
|
);
|
|
3538
3819
|
log.info(` ${result.totalIssues} issues recorded (${result.totalErrors} errors, ${result.totalWarnings} warnings)`);
|
|
3539
3820
|
log.info(` Preset: ${import_chalk10.default.cyan(preset)}`);
|
|
@@ -3617,7 +3898,7 @@ function registerBaselineCommand(program2) {
|
|
|
3617
3898
|
|
|
3618
3899
|
// cli/commands/init-context.ts
|
|
3619
3900
|
var import_fs10 = __toESM(require("fs"));
|
|
3620
|
-
var
|
|
3901
|
+
var import_path13 = __toESM(require("path"));
|
|
3621
3902
|
var import_chalk11 = __toESM(require("chalk"));
|
|
3622
3903
|
var import_prompts2 = require("@inquirer/prompts");
|
|
3623
3904
|
var RULE_CATEGORIES = {
|
|
@@ -3981,13 +4262,13 @@ var AGENTS = [
|
|
|
3981
4262
|
{
|
|
3982
4263
|
id: "copilot",
|
|
3983
4264
|
label: "GitHub Copilot",
|
|
3984
|
-
filePath:
|
|
4265
|
+
filePath: import_path13.default.join(".github", "copilot-instructions.md"),
|
|
3985
4266
|
generate: generateCopilotFile
|
|
3986
4267
|
}
|
|
3987
4268
|
];
|
|
3988
4269
|
function getPackageVersion2(cwd) {
|
|
3989
4270
|
try {
|
|
3990
|
-
const pkgPath =
|
|
4271
|
+
const pkgPath = import_path13.default.join(cwd, "node_modules", "eslint-plugin-ai-guard", "package.json");
|
|
3991
4272
|
if (import_fs10.default.existsSync(pkgPath)) {
|
|
3992
4273
|
const pkg = JSON.parse(import_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
3993
4274
|
if (pkg.version) return pkg.version;
|
|
@@ -3995,7 +4276,7 @@ function getPackageVersion2(cwd) {
|
|
|
3995
4276
|
} catch {
|
|
3996
4277
|
}
|
|
3997
4278
|
try {
|
|
3998
|
-
const pkgPath =
|
|
4279
|
+
const pkgPath = import_path13.default.join(cwd, "package.json");
|
|
3999
4280
|
if (import_fs10.default.existsSync(pkgPath)) {
|
|
4000
4281
|
const pkg = JSON.parse(import_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
4001
4282
|
if (pkg.version) return pkg.version;
|
|
@@ -4064,7 +4345,7 @@ function registerInitContextCommand(program2) {
|
|
|
4064
4345
|
log.blank();
|
|
4065
4346
|
const results = [];
|
|
4066
4347
|
for (const agent of selectedAgents) {
|
|
4067
|
-
const fullPath =
|
|
4348
|
+
const fullPath = import_path13.default.join(cwd, agent.filePath);
|
|
4068
4349
|
const exists = import_fs10.default.existsSync(fullPath);
|
|
4069
4350
|
if (exists && !isForce && !isDryRun) {
|
|
4070
4351
|
const overwrite = await (0, import_prompts2.confirm)({
|
|
@@ -4089,7 +4370,7 @@ function registerInitContextCommand(program2) {
|
|
|
4089
4370
|
results.push({ file: agent.filePath, status: "dry-run" });
|
|
4090
4371
|
continue;
|
|
4091
4372
|
}
|
|
4092
|
-
const parentDir =
|
|
4373
|
+
const parentDir = import_path13.default.dirname(fullPath);
|
|
4093
4374
|
if (!import_fs10.default.existsSync(parentDir)) {
|
|
4094
4375
|
import_fs10.default.mkdirSync(parentDir, { recursive: true });
|
|
4095
4376
|
}
|
|
@@ -4128,7 +4409,7 @@ function registerInitContextCommand(program2) {
|
|
|
4128
4409
|
|
|
4129
4410
|
// cli/commands/report.ts
|
|
4130
4411
|
var import_fs11 = __toESM(require("fs"));
|
|
4131
|
-
var
|
|
4412
|
+
var import_path14 = __toESM(require("path"));
|
|
4132
4413
|
var import_ora4 = __toESM(require("ora"));
|
|
4133
4414
|
var RULE_META = {
|
|
4134
4415
|
"ai-guard/no-empty-catch": { description: "Empty catch blocks silently swallow errors", category: "Reliability" },
|
|
@@ -4152,18 +4433,18 @@ var RULE_META = {
|
|
|
4152
4433
|
};
|
|
4153
4434
|
function getProjectName(cwd) {
|
|
4154
4435
|
try {
|
|
4155
|
-
const pkgPath =
|
|
4436
|
+
const pkgPath = import_path14.default.join(cwd, "package.json");
|
|
4156
4437
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4157
4438
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4158
4439
|
if (pkg.name) return pkg.name;
|
|
4159
4440
|
}
|
|
4160
4441
|
} catch {
|
|
4161
4442
|
}
|
|
4162
|
-
return
|
|
4443
|
+
return import_path14.default.basename(cwd);
|
|
4163
4444
|
}
|
|
4164
4445
|
function getPluginVersion(cwd) {
|
|
4165
4446
|
try {
|
|
4166
|
-
const pkgPath =
|
|
4447
|
+
const pkgPath = import_path14.default.resolve(__dirname, "../../package.json");
|
|
4167
4448
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4168
4449
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4169
4450
|
if (pkg.version) return pkg.version;
|
|
@@ -4171,7 +4452,7 @@ function getPluginVersion(cwd) {
|
|
|
4171
4452
|
} catch {
|
|
4172
4453
|
}
|
|
4173
4454
|
try {
|
|
4174
|
-
const pkgPath =
|
|
4455
|
+
const pkgPath = import_path14.default.join(cwd, "node_modules", "eslint-plugin-ai-guard", "package.json");
|
|
4175
4456
|
if (import_fs11.default.existsSync(pkgPath)) {
|
|
4176
4457
|
const pkg = JSON.parse(import_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
4177
4458
|
if (pkg.version) return pkg.version;
|
|
@@ -4550,7 +4831,7 @@ function registerReportCommand(program2) {
|
|
|
4550
4831
|
log.banner("AI GUARD REPORT");
|
|
4551
4832
|
log.blank();
|
|
4552
4833
|
const html = generateHtml(reportData);
|
|
4553
|
-
const outputPath =
|
|
4834
|
+
const outputPath = import_path14.default.resolve(cwd, opts.output);
|
|
4554
4835
|
import_fs11.default.writeFileSync(outputPath, html, "utf-8");
|
|
4555
4836
|
log.success(`Report saved: ${opts.output}`);
|
|
4556
4837
|
log.info(
|
|
@@ -4584,7 +4865,7 @@ function registerReportCommand(program2) {
|
|
|
4584
4865
|
// cli/index.ts
|
|
4585
4866
|
function getVersion() {
|
|
4586
4867
|
try {
|
|
4587
|
-
const pkgPath =
|
|
4868
|
+
const pkgPath = import_path15.default.resolve(__dirname, "../../package.json");
|
|
4588
4869
|
const raw = import_fs12.default.readFileSync(pkgPath, "utf-8");
|
|
4589
4870
|
const pkg = JSON.parse(raw);
|
|
4590
4871
|
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|