@getcodesentinel/codesentinel 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +271 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -127,7 +127,12 @@ var buildExternalAnalysisSummary = (targetPath, extraction, metadataByKey, confi
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
const { depthByName, maxDepth } = computeDepths(nodeByName, directNames);
|
|
130
|
-
const centralityRanking = rankCentrality(
|
|
130
|
+
const centralityRanking = rankCentrality(
|
|
131
|
+
nodes,
|
|
132
|
+
dependentsByName,
|
|
133
|
+
directNames,
|
|
134
|
+
config.centralityTopN
|
|
135
|
+
);
|
|
131
136
|
const topCentralNames = new Set(
|
|
132
137
|
centralityRanking.slice(0, Math.max(1, Math.ceil(centralityRanking.length * 0.25))).map((entry) => entry.name)
|
|
133
138
|
);
|
|
@@ -230,8 +235,12 @@ var buildExternalAnalysisSummary = (targetPath, extraction, metadataByKey, confi
|
|
|
230
235
|
metrics: {
|
|
231
236
|
totalDependencies: allDependencies.length,
|
|
232
237
|
directDependencies: dependencies.length,
|
|
233
|
-
directProductionDependencies: dependencies.filter(
|
|
234
|
-
|
|
238
|
+
directProductionDependencies: dependencies.filter(
|
|
239
|
+
(dependency) => dependency.dependencyScope === "prod"
|
|
240
|
+
).length,
|
|
241
|
+
directDevelopmentDependencies: dependencies.filter(
|
|
242
|
+
(dependency) => dependency.dependencyScope === "dev"
|
|
243
|
+
).length,
|
|
235
244
|
transitiveDependencies: allDependencies.length - dependencies.length,
|
|
236
245
|
dependencyDepth: maxDepth,
|
|
237
246
|
lockfileKind: extraction.kind,
|
|
@@ -257,7 +266,8 @@ var DEFAULT_EXTERNAL_ANALYSIS_CONFIG = {
|
|
|
257
266
|
var mapWithConcurrency = async (values, limit, handler) => {
|
|
258
267
|
const effectiveLimit = Math.max(1, limit);
|
|
259
268
|
const workerCount = Math.min(effectiveLimit, values.length);
|
|
260
|
-
const
|
|
269
|
+
const UNSET = /* @__PURE__ */ Symbol("map_with_concurrency_unset");
|
|
270
|
+
const results = new Array(values.length).fill(UNSET);
|
|
261
271
|
let index = 0;
|
|
262
272
|
const workers = Array.from({ length: workerCount }, async () => {
|
|
263
273
|
while (true) {
|
|
@@ -267,12 +277,13 @@ var mapWithConcurrency = async (values, limit, handler) => {
|
|
|
267
277
|
return;
|
|
268
278
|
}
|
|
269
279
|
const value = values[current];
|
|
270
|
-
|
|
271
|
-
results[current] = await handler(value);
|
|
272
|
-
}
|
|
280
|
+
results[current] = await handler(value);
|
|
273
281
|
}
|
|
274
282
|
});
|
|
275
283
|
await Promise.all(workers);
|
|
284
|
+
if (results.some((value) => value === UNSET)) {
|
|
285
|
+
throw new Error("map_with_concurrency_incomplete_results");
|
|
286
|
+
}
|
|
276
287
|
return results;
|
|
277
288
|
};
|
|
278
289
|
var collectDependencyMetadata = async (extraction, metadataProvider, concurrency, onProgress) => {
|
|
@@ -473,9 +484,7 @@ var parsePnpmLockfile = (raw, directSpecs) => {
|
|
|
473
484
|
version: nodeId.slice(at + 1),
|
|
474
485
|
dependencies: [...deps].sort((a, b) => a.localeCompare(b))
|
|
475
486
|
};
|
|
476
|
-
}).sort(
|
|
477
|
-
(a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version)
|
|
478
|
-
);
|
|
487
|
+
}).sort((a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version));
|
|
479
488
|
return {
|
|
480
489
|
kind: "pnpm",
|
|
481
490
|
directDependencies: directSpecs,
|
|
@@ -579,7 +588,9 @@ var parseYarnLock = (raw, directSpecs) => {
|
|
|
579
588
|
return {
|
|
580
589
|
kind: "yarn",
|
|
581
590
|
directDependencies: directSpecs,
|
|
582
|
-
nodes: [...deduped.values()].sort(
|
|
591
|
+
nodes: [...deduped.values()].sort(
|
|
592
|
+
(a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version)
|
|
593
|
+
)
|
|
583
594
|
};
|
|
584
595
|
};
|
|
585
596
|
var parseBunLock = (_raw, _directSpecs) => {
|
|
@@ -855,7 +866,9 @@ var resolveRangeVersion = (versions, requested) => {
|
|
|
855
866
|
if (clauses.length === 0) {
|
|
856
867
|
return null;
|
|
857
868
|
}
|
|
858
|
-
const parsedVersions = versions.map((version2) => ({ version: version2, parsed: parseSemver(version2) })).filter(
|
|
869
|
+
const parsedVersions = versions.map((version2) => ({ version: version2, parsed: parseSemver(version2) })).filter(
|
|
870
|
+
(candidate) => candidate.parsed !== null
|
|
871
|
+
).sort((a, b) => compareSemver(b.parsed, a.parsed));
|
|
859
872
|
for (const candidate of parsedVersions) {
|
|
860
873
|
let clauseMatched = false;
|
|
861
874
|
let clauseUnsupported = false;
|
|
@@ -929,7 +942,9 @@ var resolveRequestedVersion = (packument, requested) => {
|
|
|
929
942
|
fallbackUsed: requested !== null
|
|
930
943
|
};
|
|
931
944
|
}
|
|
932
|
-
const semverSorted = versionKeys.map((version2) => ({ version: version2, parsed: parseSemver(version2) })).filter(
|
|
945
|
+
const semverSorted = versionKeys.map((version2) => ({ version: version2, parsed: parseSemver(version2) })).filter(
|
|
946
|
+
(candidate) => candidate.parsed !== null
|
|
947
|
+
).sort((a, b) => compareSemver(b.parsed, a.parsed)).map((candidate) => candidate.version);
|
|
933
948
|
const fallbackVersion = semverSorted[0] ?? versionKeys.sort((a, b) => b.localeCompare(a))[0];
|
|
934
949
|
if (fallbackVersion === void 0) {
|
|
935
950
|
return null;
|
|
@@ -1002,11 +1017,15 @@ var resolveRegistryGraphFromDirectSpecs = async (directSpecs, options) => {
|
|
|
1002
1017
|
continue;
|
|
1003
1018
|
}
|
|
1004
1019
|
const manifest = (packument.versions ?? {})[resolved.version] ?? {};
|
|
1005
|
-
const dependencies = Object.entries(manifest.dependencies ?? {}).filter(
|
|
1020
|
+
const dependencies = Object.entries(manifest.dependencies ?? {}).filter(
|
|
1021
|
+
([dependencyName, dependencyRange]) => dependencyName.length > 0 && dependencyRange.length > 0
|
|
1022
|
+
).sort((a, b) => a[0].localeCompare(b[0]));
|
|
1006
1023
|
nodesByKey.set(nodeKey, {
|
|
1007
1024
|
name: item.name,
|
|
1008
1025
|
version: resolved.version,
|
|
1009
|
-
dependencies: dependencies.map(
|
|
1026
|
+
dependencies: dependencies.map(
|
|
1027
|
+
([dependencyName, dependencyRange]) => `${dependencyName}@${dependencyRange}`
|
|
1028
|
+
)
|
|
1010
1029
|
});
|
|
1011
1030
|
if (item.depth >= maxDepth && dependencies.length > 0) {
|
|
1012
1031
|
truncated = true;
|
|
@@ -1183,7 +1202,8 @@ var parseDependencySpec = (value) => {
|
|
|
1183
1202
|
var mapWithConcurrency2 = async (values, limit, handler) => {
|
|
1184
1203
|
const effectiveLimit = Math.max(1, limit);
|
|
1185
1204
|
const workerCount = Math.min(effectiveLimit, values.length);
|
|
1186
|
-
const
|
|
1205
|
+
const UNSET = /* @__PURE__ */ Symbol("map_with_concurrency_unset");
|
|
1206
|
+
const results = new Array(values.length).fill(UNSET);
|
|
1187
1207
|
let index = 0;
|
|
1188
1208
|
const workers = Array.from({ length: workerCount }, async () => {
|
|
1189
1209
|
while (true) {
|
|
@@ -1193,12 +1213,13 @@ var mapWithConcurrency2 = async (values, limit, handler) => {
|
|
|
1193
1213
|
return;
|
|
1194
1214
|
}
|
|
1195
1215
|
const value = values[current];
|
|
1196
|
-
|
|
1197
|
-
results[current] = await handler(value);
|
|
1198
|
-
}
|
|
1216
|
+
results[current] = await handler(value);
|
|
1199
1217
|
}
|
|
1200
1218
|
});
|
|
1201
1219
|
await Promise.all(workers);
|
|
1220
|
+
if (results.some((value) => value === UNSET)) {
|
|
1221
|
+
throw new Error("map_with_concurrency_incomplete_results");
|
|
1222
|
+
}
|
|
1202
1223
|
return results;
|
|
1203
1224
|
};
|
|
1204
1225
|
var analyzeDependencyCandidate = async (input, metadataProvider) => {
|
|
@@ -1363,8 +1384,8 @@ var NpmRegistryMetadataProvider = class {
|
|
|
1363
1384
|
}
|
|
1364
1385
|
};
|
|
1365
1386
|
var NoopMetadataProvider = class {
|
|
1366
|
-
|
|
1367
|
-
return null;
|
|
1387
|
+
getMetadata(_name, _version, _context) {
|
|
1388
|
+
return Promise.resolve(null);
|
|
1368
1389
|
}
|
|
1369
1390
|
};
|
|
1370
1391
|
var analyzeDependencyExposureFromProject = async (input, onProgress) => {
|
|
@@ -1445,7 +1466,9 @@ var diffSets = (current, baseline) => {
|
|
|
1445
1466
|
return { added, removed };
|
|
1446
1467
|
};
|
|
1447
1468
|
var diffScoreMap = (current, baseline) => {
|
|
1448
|
-
const keys = [.../* @__PURE__ */ new Set([...current.keys(), ...baseline.keys()])].sort(
|
|
1469
|
+
const keys = [.../* @__PURE__ */ new Set([...current.keys(), ...baseline.keys()])].sort(
|
|
1470
|
+
(a, b) => a.localeCompare(b)
|
|
1471
|
+
);
|
|
1449
1472
|
return keys.map((key) => {
|
|
1450
1473
|
const before = baseline.get(key) ?? 0;
|
|
1451
1474
|
const after = current.get(key) ?? 0;
|
|
@@ -1486,17 +1509,27 @@ var compareSnapshots = (current, baseline) => {
|
|
|
1486
1509
|
singleMaintainerDependencies: [],
|
|
1487
1510
|
abandonedDependencies: []
|
|
1488
1511
|
};
|
|
1489
|
-
const highRisk = diffSets(
|
|
1512
|
+
const highRisk = diffSets(
|
|
1513
|
+
currentExternal.highRiskDependencies,
|
|
1514
|
+
baselineExternal.highRiskDependencies
|
|
1515
|
+
);
|
|
1490
1516
|
const singleMaintainer = diffSets(
|
|
1491
1517
|
currentExternal.singleMaintainerDependencies,
|
|
1492
1518
|
baselineExternal.singleMaintainerDependencies
|
|
1493
1519
|
);
|
|
1494
|
-
const abandoned = diffSets(
|
|
1520
|
+
const abandoned = diffSets(
|
|
1521
|
+
currentExternal.abandonedDependencies,
|
|
1522
|
+
baselineExternal.abandonedDependencies
|
|
1523
|
+
);
|
|
1495
1524
|
const hotspots = diffSets(currentHotspots, baselineHotspots);
|
|
1496
1525
|
const cycles = diffSets(currentCycles, baselineCycles);
|
|
1497
1526
|
return {
|
|
1498
|
-
repositoryScoreDelta: round43(
|
|
1499
|
-
|
|
1527
|
+
repositoryScoreDelta: round43(
|
|
1528
|
+
current.analysis.risk.repositoryScore - baseline.analysis.risk.repositoryScore
|
|
1529
|
+
),
|
|
1530
|
+
normalizedScoreDelta: round43(
|
|
1531
|
+
current.analysis.risk.normalizedScore - baseline.analysis.risk.normalizedScore
|
|
1532
|
+
),
|
|
1500
1533
|
fileRiskChanges: diffScoreMap(currentFileScores, baselineFileScores),
|
|
1501
1534
|
moduleRiskChanges: diffScoreMap(currentModuleScores, baselineModuleScores),
|
|
1502
1535
|
newHotspots: hotspots.added,
|
|
@@ -1586,6 +1619,32 @@ var repositoryConfidence = (snapshot) => {
|
|
|
1586
1619
|
);
|
|
1587
1620
|
return round43(weighted / weight);
|
|
1588
1621
|
};
|
|
1622
|
+
var repositoryDimensionScores = (snapshot) => {
|
|
1623
|
+
const target = findTraceTarget(snapshot, "repository", snapshot.analysis.structural.targetPath);
|
|
1624
|
+
if (target === void 0) {
|
|
1625
|
+
return {
|
|
1626
|
+
structural: null,
|
|
1627
|
+
evolution: null,
|
|
1628
|
+
external: null,
|
|
1629
|
+
interactions: null
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
const structural = target.factors.find((factor) => factor.factorId === "repository.structural");
|
|
1633
|
+
const evolution = target.factors.find((factor) => factor.factorId === "repository.evolution");
|
|
1634
|
+
const external = target.factors.find((factor) => factor.factorId === "repository.external");
|
|
1635
|
+
const interactions = target.factors.find(
|
|
1636
|
+
(factor) => factor.factorId === "repository.composite.interactions"
|
|
1637
|
+
);
|
|
1638
|
+
const interactionScore = interactions === void 0 ? null : round43(
|
|
1639
|
+
((interactions.rawMetrics["structuralEvolution"] ?? 0) + (interactions.rawMetrics["centralInstability"] ?? 0) + (interactions.rawMetrics["dependencyAmplification"] ?? 0)) * 100
|
|
1640
|
+
);
|
|
1641
|
+
return {
|
|
1642
|
+
structural: structural === void 0 ? null : round43((structural.rawMetrics["structuralDimension"] ?? 0) * 100),
|
|
1643
|
+
evolution: evolution === void 0 ? null : round43((evolution.rawMetrics["evolutionDimension"] ?? 0) * 100),
|
|
1644
|
+
external: external === void 0 ? null : round43((external.rawMetrics["externalDimension"] ?? 0) * 100),
|
|
1645
|
+
interactions: interactionScore
|
|
1646
|
+
};
|
|
1647
|
+
};
|
|
1589
1648
|
var createReport = (snapshot, diff) => {
|
|
1590
1649
|
const external = snapshot.analysis.external;
|
|
1591
1650
|
return {
|
|
@@ -1596,7 +1655,8 @@ var createReport = (snapshot, diff) => {
|
|
|
1596
1655
|
repositoryScore: snapshot.analysis.risk.repositoryScore,
|
|
1597
1656
|
normalizedScore: snapshot.analysis.risk.normalizedScore,
|
|
1598
1657
|
riskTier: toRiskTier(snapshot.analysis.risk.repositoryScore),
|
|
1599
|
-
confidence: repositoryConfidence(snapshot)
|
|
1658
|
+
confidence: repositoryConfidence(snapshot),
|
|
1659
|
+
dimensionScores: repositoryDimensionScores(snapshot)
|
|
1600
1660
|
},
|
|
1601
1661
|
hotspots: hotspotItems(snapshot),
|
|
1602
1662
|
structural: {
|
|
@@ -1616,10 +1676,18 @@ var createReport = (snapshot, diff) => {
|
|
|
1616
1676
|
reason: external.reason
|
|
1617
1677
|
} : {
|
|
1618
1678
|
available: true,
|
|
1619
|
-
highRiskDependencies: [...external.highRiskDependencies].sort(
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1679
|
+
highRiskDependencies: [...external.highRiskDependencies].sort(
|
|
1680
|
+
(a, b) => a.localeCompare(b)
|
|
1681
|
+
),
|
|
1682
|
+
highRiskDevelopmentDependencies: [...external.highRiskDevelopmentDependencies].sort(
|
|
1683
|
+
(a, b) => a.localeCompare(b)
|
|
1684
|
+
),
|
|
1685
|
+
singleMaintainerDependencies: [...external.singleMaintainerDependencies].sort(
|
|
1686
|
+
(a, b) => a.localeCompare(b)
|
|
1687
|
+
),
|
|
1688
|
+
abandonedDependencies: [...external.abandonedDependencies].sort(
|
|
1689
|
+
(a, b) => a.localeCompare(b)
|
|
1690
|
+
)
|
|
1623
1691
|
},
|
|
1624
1692
|
appendix: {
|
|
1625
1693
|
snapshotSchemaVersion: snapshot.schemaVersion,
|
|
@@ -1655,6 +1723,12 @@ var renderTextReport = (report) => {
|
|
|
1655
1723
|
lines.push(` riskTier: ${report.repository.riskTier}`);
|
|
1656
1724
|
lines.push(` confidence: ${report.repository.confidence ?? "n/a"}`);
|
|
1657
1725
|
lines.push("");
|
|
1726
|
+
lines.push("Dimension Scores (0-100)");
|
|
1727
|
+
lines.push(` structural: ${report.repository.dimensionScores.structural ?? "n/a"}`);
|
|
1728
|
+
lines.push(` evolution: ${report.repository.dimensionScores.evolution ?? "n/a"}`);
|
|
1729
|
+
lines.push(` external: ${report.repository.dimensionScores.external ?? "n/a"}`);
|
|
1730
|
+
lines.push(` interactions: ${report.repository.dimensionScores.interactions ?? "n/a"}`);
|
|
1731
|
+
lines.push("");
|
|
1658
1732
|
lines.push("Top Hotspots");
|
|
1659
1733
|
for (const hotspot of report.hotspots) {
|
|
1660
1734
|
lines.push(` - ${hotspot.target} | score=${hotspot.score}`);
|
|
@@ -1677,14 +1751,18 @@ var renderTextReport = (report) => {
|
|
|
1677
1751
|
if (!report.external.available) {
|
|
1678
1752
|
lines.push(` unavailable: ${report.external.reason}`);
|
|
1679
1753
|
} else {
|
|
1680
|
-
lines.push(
|
|
1754
|
+
lines.push(
|
|
1755
|
+
` highRiskDependencies: ${report.external.highRiskDependencies.join(", ") || "none"}`
|
|
1756
|
+
);
|
|
1681
1757
|
lines.push(
|
|
1682
1758
|
` highRiskDevelopmentDependencies: ${report.external.highRiskDevelopmentDependencies.join(", ") || "none"}`
|
|
1683
1759
|
);
|
|
1684
1760
|
lines.push(
|
|
1685
1761
|
` singleMaintainerDependencies: ${report.external.singleMaintainerDependencies.join(", ") || "none"}`
|
|
1686
1762
|
);
|
|
1687
|
-
lines.push(
|
|
1763
|
+
lines.push(
|
|
1764
|
+
` abandonedDependencies: ${report.external.abandonedDependencies.join(", ") || "none"}`
|
|
1765
|
+
);
|
|
1688
1766
|
}
|
|
1689
1767
|
lines.push("");
|
|
1690
1768
|
lines.push("Appendix");
|
|
@@ -1721,6 +1799,12 @@ var renderMarkdownReport = (report) => {
|
|
|
1721
1799
|
lines.push(`- riskTier: \`${report.repository.riskTier}\``);
|
|
1722
1800
|
lines.push(`- confidence: \`${report.repository.confidence ?? "n/a"}\``);
|
|
1723
1801
|
lines.push("");
|
|
1802
|
+
lines.push("## Dimension Scores (0-100)");
|
|
1803
|
+
lines.push(`- structural: \`${report.repository.dimensionScores.structural ?? "n/a"}\``);
|
|
1804
|
+
lines.push(`- evolution: \`${report.repository.dimensionScores.evolution ?? "n/a"}\``);
|
|
1805
|
+
lines.push(`- external: \`${report.repository.dimensionScores.external ?? "n/a"}\``);
|
|
1806
|
+
lines.push(`- interactions: \`${report.repository.dimensionScores.interactions ?? "n/a"}\``);
|
|
1807
|
+
lines.push("");
|
|
1724
1808
|
lines.push("## Top Hotspots");
|
|
1725
1809
|
for (const hotspot of report.hotspots) {
|
|
1726
1810
|
lines.push(`- **${hotspot.target}** (score: \`${hotspot.score}\`)`);
|
|
@@ -1737,21 +1821,27 @@ var renderMarkdownReport = (report) => {
|
|
|
1737
1821
|
lines.push("");
|
|
1738
1822
|
lines.push("## Structural Observations");
|
|
1739
1823
|
lines.push(`- cycles detected: \`${report.structural.cycleCount}\``);
|
|
1740
|
-
lines.push(
|
|
1824
|
+
lines.push(
|
|
1825
|
+
`- cycles: ${report.structural.cycles.map((cycle) => `\`${cycle}\``).join(", ") || "none"}`
|
|
1826
|
+
);
|
|
1741
1827
|
lines.push(`- fragile clusters: \`${report.structural.fragileClusters.length}\``);
|
|
1742
1828
|
lines.push("");
|
|
1743
1829
|
lines.push("## External Exposure Summary");
|
|
1744
1830
|
if (!report.external.available) {
|
|
1745
1831
|
lines.push(`- unavailable: \`${report.external.reason}\``);
|
|
1746
1832
|
} else {
|
|
1747
|
-
lines.push(
|
|
1833
|
+
lines.push(
|
|
1834
|
+
`- high-risk dependencies: ${report.external.highRiskDependencies.map((item) => `\`${item}\``).join(", ") || "none"}`
|
|
1835
|
+
);
|
|
1748
1836
|
lines.push(
|
|
1749
1837
|
`- high-risk development dependencies: ${report.external.highRiskDevelopmentDependencies.map((item) => `\`${item}\``).join(", ") || "none"}`
|
|
1750
1838
|
);
|
|
1751
1839
|
lines.push(
|
|
1752
1840
|
`- single maintainer dependencies: ${report.external.singleMaintainerDependencies.map((item) => `\`${item}\``).join(", ") || "none"}`
|
|
1753
1841
|
);
|
|
1754
|
-
lines.push(
|
|
1842
|
+
lines.push(
|
|
1843
|
+
`- abandoned dependencies: ${report.external.abandonedDependencies.map((item) => `\`${item}\``).join(", ") || "none"}`
|
|
1844
|
+
);
|
|
1755
1845
|
}
|
|
1756
1846
|
lines.push("");
|
|
1757
1847
|
lines.push("## Appendix");
|
|
@@ -1871,7 +1961,9 @@ var validateGateConfig = (input) => {
|
|
|
1871
1961
|
throw new GovernanceConfigurationError("max-repo-score must be a number in [0, 100]");
|
|
1872
1962
|
}
|
|
1873
1963
|
if (config.newHotspotScoreThreshold !== void 0 && (!Number.isFinite(config.newHotspotScoreThreshold) || config.newHotspotScoreThreshold < 0 || config.newHotspotScoreThreshold > 100)) {
|
|
1874
|
-
throw new GovernanceConfigurationError(
|
|
1964
|
+
throw new GovernanceConfigurationError(
|
|
1965
|
+
"new-hotspot-score-threshold must be a number in [0, 100]"
|
|
1966
|
+
);
|
|
1875
1967
|
}
|
|
1876
1968
|
};
|
|
1877
1969
|
var evaluateGates = (input) => {
|
|
@@ -2021,7 +2113,9 @@ var renderCheckMarkdown = (snapshot, result) => {
|
|
|
2021
2113
|
lines.push("## CodeSentinel CI Summary");
|
|
2022
2114
|
lines.push(`- target: \`${snapshot.analysis.structural.targetPath}\``);
|
|
2023
2115
|
lines.push(`- repositoryScore: \`${snapshot.analysis.risk.repositoryScore}\``);
|
|
2024
|
-
lines.push(
|
|
2116
|
+
lines.push(
|
|
2117
|
+
`- evaluatedGates: ${result.evaluatedGates.map((item) => `\`${item}\``).join(", ") || "none"}`
|
|
2118
|
+
);
|
|
2025
2119
|
lines.push(`- violations: \`${result.violations.length}\``);
|
|
2026
2120
|
lines.push(`- exitCode: \`${result.exitCode}\``);
|
|
2027
2121
|
const repositoryTrace = snapshot.trace?.targets.find(
|
|
@@ -2392,7 +2486,10 @@ var createSummaryShape = (summary) => ({
|
|
|
2392
2486
|
0,
|
|
2393
2487
|
10
|
|
2394
2488
|
),
|
|
2395
|
-
transitiveExposureDependenciesTop: summary.external.transitiveExposureDependencies.slice(
|
|
2489
|
+
transitiveExposureDependenciesTop: summary.external.transitiveExposureDependencies.slice(
|
|
2490
|
+
0,
|
|
2491
|
+
10
|
|
2492
|
+
)
|
|
2396
2493
|
} : {
|
|
2397
2494
|
available: false,
|
|
2398
2495
|
reason: summary.external.reason
|
|
@@ -2413,13 +2510,16 @@ var formatAnalyzeOutput = (summary, mode) => mode === "json" ? JSON.stringify(su
|
|
|
2413
2510
|
// src/application/format-explain-output.ts
|
|
2414
2511
|
var sortFactorByContribution = (left, right) => right.contribution - left.contribution || left.factorId.localeCompare(right.factorId);
|
|
2415
2512
|
var toRiskBand = (score) => {
|
|
2416
|
-
if (score <
|
|
2513
|
+
if (score < 20) {
|
|
2417
2514
|
return "low";
|
|
2418
2515
|
}
|
|
2419
|
-
if (score <
|
|
2516
|
+
if (score < 40) {
|
|
2420
2517
|
return "moderate";
|
|
2421
2518
|
}
|
|
2422
|
-
if (score <
|
|
2519
|
+
if (score < 60) {
|
|
2520
|
+
return "elevated";
|
|
2521
|
+
}
|
|
2522
|
+
if (score < 80) {
|
|
2423
2523
|
return "high";
|
|
2424
2524
|
}
|
|
2425
2525
|
return "very_high";
|
|
@@ -2444,6 +2544,7 @@ var factorLabelById2 = {
|
|
|
2444
2544
|
};
|
|
2445
2545
|
var formatFactorLabel = (factorId) => factorLabelById2[factorId] ?? factorId;
|
|
2446
2546
|
var formatNumber = (value) => value === null || value === void 0 ? "n/a" : `${value}`;
|
|
2547
|
+
var formatDimension = (value) => value === null ? "n/a" : `${value}`;
|
|
2447
2548
|
var formatFactorSummary = (factor) => `${formatFactorLabel(factor.factorId)} (+${factor.contribution}, confidence=${factor.confidence})`;
|
|
2448
2549
|
var formatFactorEvidence = (factor) => {
|
|
2449
2550
|
if (factor.factorId === "repository.structural") {
|
|
@@ -2473,6 +2574,36 @@ var formatFactorEvidence = (factor) => {
|
|
|
2473
2574
|
return "evidence available in trace";
|
|
2474
2575
|
};
|
|
2475
2576
|
var findRepositoryTarget = (targets) => targets.find((target) => target.targetType === "repository");
|
|
2577
|
+
var repositoryDimensionScores2 = (repositoryTarget) => {
|
|
2578
|
+
if (repositoryTarget === void 0) {
|
|
2579
|
+
return {
|
|
2580
|
+
structural: null,
|
|
2581
|
+
evolution: null,
|
|
2582
|
+
external: null,
|
|
2583
|
+
interactions: null
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
const structural = repositoryTarget.factors.find(
|
|
2587
|
+
(factor) => factor.factorId === "repository.structural"
|
|
2588
|
+
);
|
|
2589
|
+
const evolution = repositoryTarget.factors.find(
|
|
2590
|
+
(factor) => factor.factorId === "repository.evolution"
|
|
2591
|
+
);
|
|
2592
|
+
const external = repositoryTarget.factors.find(
|
|
2593
|
+
(factor) => factor.factorId === "repository.external"
|
|
2594
|
+
);
|
|
2595
|
+
const interactions = repositoryTarget.factors.find(
|
|
2596
|
+
(factor) => factor.factorId === "repository.composite.interactions"
|
|
2597
|
+
);
|
|
2598
|
+
return {
|
|
2599
|
+
structural: structural === void 0 ? null : Number(((structural.rawMetrics["structuralDimension"] ?? 0) * 100).toFixed(4)),
|
|
2600
|
+
evolution: evolution === void 0 ? null : Number(((evolution.rawMetrics["evolutionDimension"] ?? 0) * 100).toFixed(4)),
|
|
2601
|
+
external: external === void 0 ? null : Number(((external.rawMetrics["externalDimension"] ?? 0) * 100).toFixed(4)),
|
|
2602
|
+
interactions: interactions === void 0 ? null : Number(
|
|
2603
|
+
(((interactions.rawMetrics["structuralEvolution"] ?? 0) + (interactions.rawMetrics["centralInstability"] ?? 0) + (interactions.rawMetrics["dependencyAmplification"] ?? 0)) * 100).toFixed(4)
|
|
2604
|
+
)
|
|
2605
|
+
};
|
|
2606
|
+
};
|
|
2476
2607
|
var buildRepositoryActions = (payload, repositoryTarget) => {
|
|
2477
2608
|
if (repositoryTarget === void 0) {
|
|
2478
2609
|
return ["No repository trace available."];
|
|
@@ -2518,12 +2649,8 @@ var renderTargetText = (target) => {
|
|
|
2518
2649
|
lines.push(" top factors:");
|
|
2519
2650
|
const topFactors = [...target.factors].sort(sortFactorByContribution).slice(0, 5);
|
|
2520
2651
|
for (const factor of topFactors) {
|
|
2521
|
-
lines.push(
|
|
2522
|
-
|
|
2523
|
-
);
|
|
2524
|
-
lines.push(
|
|
2525
|
-
` evidence: ${formatFactorEvidence(factor)}`
|
|
2526
|
-
);
|
|
2652
|
+
lines.push(` - ${formatFactorSummary(factor)}`);
|
|
2653
|
+
lines.push(` evidence: ${formatFactorEvidence(factor)}`);
|
|
2527
2654
|
}
|
|
2528
2655
|
lines.push(" reduction levers:");
|
|
2529
2656
|
for (const lever of target.reductionLevers) {
|
|
@@ -2537,11 +2664,17 @@ var renderText = (payload) => {
|
|
|
2537
2664
|
const lines = [];
|
|
2538
2665
|
const repositoryTarget = findRepositoryTarget(payload.selectedTargets) ?? findRepositoryTarget(payload.trace.targets);
|
|
2539
2666
|
const repositoryTopFactors = repositoryTarget === void 0 ? [] : [...repositoryTarget.factors].sort(sortFactorByContribution).slice(0, 3);
|
|
2667
|
+
const dimensionScores = repositoryDimensionScores2(repositoryTarget);
|
|
2540
2668
|
const compositeFactors = repositoryTopFactors.filter((factor) => factor.family === "composite");
|
|
2541
2669
|
lines.push(`target: ${payload.summary.structural.targetPath}`);
|
|
2542
2670
|
lines.push(`repositoryScore: ${payload.summary.risk.repositoryScore}`);
|
|
2543
2671
|
lines.push(`riskBand: ${toRiskBand(payload.summary.risk.repositoryScore)}`);
|
|
2544
2672
|
lines.push(`selectedTargets: ${payload.selectedTargets.length}`);
|
|
2673
|
+
lines.push("dimensionScores:");
|
|
2674
|
+
lines.push(` structural: ${formatDimension(dimensionScores.structural)}`);
|
|
2675
|
+
lines.push(` evolution: ${formatDimension(dimensionScores.evolution)}`);
|
|
2676
|
+
lines.push(` external: ${formatDimension(dimensionScores.external)}`);
|
|
2677
|
+
lines.push(` interactions: ${formatDimension(dimensionScores.interactions)}`);
|
|
2545
2678
|
lines.push("");
|
|
2546
2679
|
lines.push("explanation:");
|
|
2547
2680
|
lines.push(
|
|
@@ -2570,6 +2703,7 @@ var renderMarkdown = (payload) => {
|
|
|
2570
2703
|
const lines = [];
|
|
2571
2704
|
const repositoryTarget = findRepositoryTarget(payload.selectedTargets) ?? findRepositoryTarget(payload.trace.targets);
|
|
2572
2705
|
const repositoryTopFactors = repositoryTarget === void 0 ? [] : [...repositoryTarget.factors].sort(sortFactorByContribution).slice(0, 3);
|
|
2706
|
+
const dimensionScores = repositoryDimensionScores2(repositoryTarget);
|
|
2573
2707
|
const compositeFactors = repositoryTopFactors.filter((factor) => factor.family === "composite");
|
|
2574
2708
|
lines.push(`# CodeSentinel Explanation`);
|
|
2575
2709
|
lines.push(`- target: \`${payload.summary.structural.targetPath}\``);
|
|
@@ -2577,6 +2711,12 @@ var renderMarkdown = (payload) => {
|
|
|
2577
2711
|
lines.push(`- riskBand: \`${toRiskBand(payload.summary.risk.repositoryScore)}\``);
|
|
2578
2712
|
lines.push(`- selectedTargets: \`${payload.selectedTargets.length}\``);
|
|
2579
2713
|
lines.push("");
|
|
2714
|
+
lines.push("## Dimension Scores (0-100)");
|
|
2715
|
+
lines.push(`- structural: \`${formatDimension(dimensionScores.structural)}\``);
|
|
2716
|
+
lines.push(`- evolution: \`${formatDimension(dimensionScores.evolution)}\``);
|
|
2717
|
+
lines.push(`- external: \`${formatDimension(dimensionScores.external)}\``);
|
|
2718
|
+
lines.push(`- interactions: \`${formatDimension(dimensionScores.interactions)}\``);
|
|
2719
|
+
lines.push("");
|
|
2580
2720
|
lines.push(`## Summary`);
|
|
2581
2721
|
lines.push(
|
|
2582
2722
|
`- why risky: ${repositoryTopFactors.map(formatFactorSummary).join("; ") || "insufficient data"}`
|
|
@@ -2603,9 +2743,7 @@ var renderMarkdown = (payload) => {
|
|
|
2603
2743
|
lines.push(
|
|
2604
2744
|
` - \`${formatFactorLabel(factor.factorId)}\` contribution=\`${factor.contribution}\` confidence=\`${factor.confidence}\``
|
|
2605
2745
|
);
|
|
2606
|
-
lines.push(
|
|
2607
|
-
` - evidence: \`${formatFactorEvidence(factor)}\``
|
|
2608
|
-
);
|
|
2746
|
+
lines.push(` - evidence: \`${formatFactorEvidence(factor)}\``);
|
|
2609
2747
|
}
|
|
2610
2748
|
lines.push(`- Reduction levers:`);
|
|
2611
2749
|
for (const lever of target.reductionLevers) {
|
|
@@ -3031,7 +3169,11 @@ var parseTsConfigFile = (configPath) => {
|
|
|
3031
3169
|
return parsedCommandLine;
|
|
3032
3170
|
};
|
|
3033
3171
|
var collectFilesFromTsConfigGraph = (projectRoot) => {
|
|
3034
|
-
const rootConfigPath = ts.findConfigFile(
|
|
3172
|
+
const rootConfigPath = ts.findConfigFile(
|
|
3173
|
+
projectRoot,
|
|
3174
|
+
(filePath) => ts.sys.fileExists(filePath),
|
|
3175
|
+
"tsconfig.json"
|
|
3176
|
+
);
|
|
3035
3177
|
if (rootConfigPath === void 0) {
|
|
3036
3178
|
return null;
|
|
3037
3179
|
}
|
|
@@ -3053,7 +3195,11 @@ var collectFilesFromTsConfigGraph = (projectRoot) => {
|
|
|
3053
3195
|
}
|
|
3054
3196
|
for (const reference of parsed.projectReferences ?? []) {
|
|
3055
3197
|
const referencePath = resolve2(reference.path);
|
|
3056
|
-
const referenceConfigPath = ts.sys.directoryExists(referencePath) ? ts.findConfigFile(
|
|
3198
|
+
const referenceConfigPath = ts.sys.directoryExists(referencePath) ? ts.findConfigFile(
|
|
3199
|
+
referencePath,
|
|
3200
|
+
(filePath) => ts.sys.fileExists(filePath),
|
|
3201
|
+
"tsconfig.json"
|
|
3202
|
+
) : referencePath;
|
|
3057
3203
|
if (referenceConfigPath !== void 0 && ts.sys.fileExists(referenceConfigPath)) {
|
|
3058
3204
|
visitConfig(referenceConfigPath);
|
|
3059
3205
|
}
|
|
@@ -3215,7 +3361,12 @@ var parseTypescriptProject = (projectPath, onProgress) => {
|
|
|
3215
3361
|
const cacheKey = `${sourcePath}\0${specifier}`;
|
|
3216
3362
|
let resolvedPath = resolverCache.get(cacheKey);
|
|
3217
3363
|
if (resolvedPath === void 0 && !resolverCache.has(cacheKey)) {
|
|
3218
|
-
const resolved = ts.resolveModuleName(
|
|
3364
|
+
const resolved = ts.resolveModuleName(
|
|
3365
|
+
specifier,
|
|
3366
|
+
sourcePath,
|
|
3367
|
+
options,
|
|
3368
|
+
ts.sys
|
|
3369
|
+
).resolvedModule;
|
|
3219
3370
|
if (resolved !== void 0) {
|
|
3220
3371
|
resolvedPath = normalizePath(resolve2(resolved.resolvedFileName));
|
|
3221
3372
|
}
|
|
@@ -3299,7 +3450,10 @@ var buildAuthorAliasMap = (commits) => {
|
|
|
3299
3450
|
const nameCountsByAuthorId = /* @__PURE__ */ new Map();
|
|
3300
3451
|
const commitCountByAuthorId = /* @__PURE__ */ new Map();
|
|
3301
3452
|
for (const commit of commits) {
|
|
3302
|
-
commitCountByAuthorId.set(
|
|
3453
|
+
commitCountByAuthorId.set(
|
|
3454
|
+
commit.authorId,
|
|
3455
|
+
(commitCountByAuthorId.get(commit.authorId) ?? 0) + 1
|
|
3456
|
+
);
|
|
3303
3457
|
const normalizedName = normalizeName(commit.authorName);
|
|
3304
3458
|
const names = nameCountsByAuthorId.get(commit.authorId) ?? /* @__PURE__ */ new Map();
|
|
3305
3459
|
if (normalizedName.length > 0) {
|
|
@@ -3307,19 +3461,21 @@ var buildAuthorAliasMap = (commits) => {
|
|
|
3307
3461
|
}
|
|
3308
3462
|
nameCountsByAuthorId.set(commit.authorId, names);
|
|
3309
3463
|
}
|
|
3310
|
-
const profiles = [...commitCountByAuthorId.entries()].map(
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3464
|
+
const profiles = [...commitCountByAuthorId.entries()].map(
|
|
3465
|
+
([authorId, commitCount]) => {
|
|
3466
|
+
const names = nameCountsByAuthorId.get(authorId);
|
|
3467
|
+
const primaryName = names === void 0 ? "" : [...names.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0]?.[0] ?? "";
|
|
3468
|
+
const normalizedAuthorId = authorId.toLowerCase();
|
|
3469
|
+
const isBot = normalizedAuthorId.includes("[bot]");
|
|
3470
|
+
return {
|
|
3471
|
+
authorId,
|
|
3472
|
+
commitCount,
|
|
3473
|
+
primaryName,
|
|
3474
|
+
emailStem: isBot ? null : extractEmailStem(authorId),
|
|
3475
|
+
isBot
|
|
3476
|
+
};
|
|
3477
|
+
}
|
|
3478
|
+
);
|
|
3323
3479
|
const groupsByStem = /* @__PURE__ */ new Map();
|
|
3324
3480
|
for (const profile of profiles) {
|
|
3325
3481
|
if (profile.emailStem === null || profile.emailStem.length < 4) {
|
|
@@ -3425,7 +3581,10 @@ var selectHotspots = (files, config) => {
|
|
|
3425
3581
|
const sorted = [...files].sort(
|
|
3426
3582
|
(a, b) => b.commitCount - a.commitCount || b.churnTotal - a.churnTotal || a.filePath.localeCompare(b.filePath)
|
|
3427
3583
|
);
|
|
3428
|
-
const hotspotCount = Math.max(
|
|
3584
|
+
const hotspotCount = Math.max(
|
|
3585
|
+
config.hotspotMinFiles,
|
|
3586
|
+
Math.ceil(sorted.length * config.hotspotTopPercent)
|
|
3587
|
+
);
|
|
3429
3588
|
const selected = sorted.slice(0, hotspotCount);
|
|
3430
3589
|
const hotspots = selected.map((file, index) => ({
|
|
3431
3590
|
filePath: file.filePath,
|
|
@@ -3734,7 +3893,10 @@ var GitCliHistoryProvider = class {
|
|
|
3734
3893
|
"--find-renames"
|
|
3735
3894
|
]);
|
|
3736
3895
|
onProgress?.({ stage: "git_log_received", bytes: Buffer.byteLength(output, "utf8") });
|
|
3737
|
-
const commits = parseGitLog(
|
|
3896
|
+
const commits = parseGitLog(
|
|
3897
|
+
output,
|
|
3898
|
+
(event) => onProgress?.(mapParseProgressToHistoryProgress(event))
|
|
3899
|
+
);
|
|
3738
3900
|
onProgress?.({ stage: "git_log_parsed", commits: commits.length });
|
|
3739
3901
|
return commits;
|
|
3740
3902
|
}
|
|
@@ -3920,7 +4082,10 @@ var dependencySignalWeightBudget = Object.values(dependencySignalWeights).reduce
|
|
|
3920
4082
|
0
|
|
3921
4083
|
);
|
|
3922
4084
|
var computeDependencySignalScore = (ownSignals, inheritedSignals, inheritedSignalMultiplier) => {
|
|
3923
|
-
const ownWeight = ownSignals.reduce(
|
|
4085
|
+
const ownWeight = ownSignals.reduce(
|
|
4086
|
+
(sum, signal) => sum + (dependencySignalWeights[signal] ?? 0),
|
|
4087
|
+
0
|
|
4088
|
+
);
|
|
3924
4089
|
const inheritedWeight = inheritedSignals.reduce(
|
|
3925
4090
|
(sum, signal) => sum + (dependencySignalWeights[signal] ?? 0),
|
|
3926
4091
|
0
|
|
@@ -3986,16 +4151,12 @@ var buildFactorTraces = (totalScore, inputs) => {
|
|
|
3986
4151
|
}
|
|
3987
4152
|
return traces;
|
|
3988
4153
|
};
|
|
3989
|
-
var buildReductionLevers = (factors) => factors.filter((factor) => factor.contribution > 0).sort(
|
|
3990
|
-
(a, b) => b.contribution - a.contribution || a.factorId.localeCompare(b.factorId)
|
|
3991
|
-
).slice(0, 3).map((factor) => ({
|
|
4154
|
+
var buildReductionLevers = (factors) => factors.filter((factor) => factor.contribution > 0).sort((a, b) => b.contribution - a.contribution || a.factorId.localeCompare(b.factorId)).slice(0, 3).map((factor) => ({
|
|
3992
4155
|
factorId: factor.factorId,
|
|
3993
4156
|
estimatedImpact: round45(factor.contribution)
|
|
3994
4157
|
}));
|
|
3995
4158
|
var buildTargetTrace = (targetType, targetId, totalScore, normalizedScore, factors) => {
|
|
3996
|
-
const dominantFactors = [...factors].filter((factor) => factor.contribution > 0).sort(
|
|
3997
|
-
(a, b) => b.contribution - a.contribution || a.factorId.localeCompare(b.factorId)
|
|
3998
|
-
).slice(0, 3).map((factor) => factor.factorId);
|
|
4159
|
+
const dominantFactors = [...factors].filter((factor) => factor.contribution > 0).sort((a, b) => b.contribution - a.contribution || a.factorId.localeCompare(b.factorId)).slice(0, 3).map((factor) => factor.factorId);
|
|
3999
4160
|
return {
|
|
4000
4161
|
targetType,
|
|
4001
4162
|
targetId,
|
|
@@ -4017,7 +4178,9 @@ var computeDependencyScores = (external, config) => {
|
|
|
4017
4178
|
const transitiveCounts = external.dependencies.map(
|
|
4018
4179
|
(dependency) => logScale(dependency.transitiveDependencies.length)
|
|
4019
4180
|
);
|
|
4020
|
-
const dependentCounts = external.dependencies.map(
|
|
4181
|
+
const dependentCounts = external.dependencies.map(
|
|
4182
|
+
(dependency) => logScale(dependency.dependents)
|
|
4183
|
+
);
|
|
4021
4184
|
const chainDepths = external.dependencies.map((dependency) => dependency.dependencyDepth);
|
|
4022
4185
|
const transitiveScale = buildQuantileScale(
|
|
4023
4186
|
transitiveCounts,
|
|
@@ -4312,8 +4475,14 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4312
4475
|
let busFactorRisk = 0;
|
|
4313
4476
|
const evolutionMetrics = evolutionByFile.get(filePath);
|
|
4314
4477
|
if (evolution.available && evolutionMetrics !== void 0) {
|
|
4315
|
-
frequencyRisk = normalizeWithScale(
|
|
4316
|
-
|
|
4478
|
+
frequencyRisk = normalizeWithScale(
|
|
4479
|
+
logScale(evolutionMetrics.commitCount),
|
|
4480
|
+
evolutionScales.commitCount
|
|
4481
|
+
);
|
|
4482
|
+
churnRisk = normalizeWithScale(
|
|
4483
|
+
logScale(evolutionMetrics.churnTotal),
|
|
4484
|
+
evolutionScales.churnTotal
|
|
4485
|
+
);
|
|
4317
4486
|
volatilityRisk = toUnitInterval(evolutionMetrics.recentVolatility);
|
|
4318
4487
|
ownershipConcentrationRisk = toUnitInterval(evolutionMetrics.topAuthorShare);
|
|
4319
4488
|
busFactorRisk = toUnitInterval(
|
|
@@ -4567,7 +4736,9 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4567
4736
|
externalPressure: round45(zone.externalPressure)
|
|
4568
4737
|
}));
|
|
4569
4738
|
if (collector !== void 0 && external.available) {
|
|
4570
|
-
const dependencyByName = new Map(
|
|
4739
|
+
const dependencyByName = new Map(
|
|
4740
|
+
external.dependencies.map((dependency) => [dependency.name, dependency])
|
|
4741
|
+
);
|
|
4571
4742
|
for (const dependencyScore of dependencyComputation.dependencyScores) {
|
|
4572
4743
|
const dependency = dependencyByName.get(dependencyScore.dependency);
|
|
4573
4744
|
const context = dependencyComputation.dependencyContexts.get(dependencyScore.dependency);
|
|
@@ -4598,7 +4769,9 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4598
4769
|
normalizedMetrics: { stalenessRisk: context.stalenessRisk },
|
|
4599
4770
|
weight: config.dependencyFactorWeights.staleness,
|
|
4600
4771
|
amplification: null,
|
|
4601
|
-
evidence: [
|
|
4772
|
+
evidence: [
|
|
4773
|
+
{ kind: "dependency_metric", target: dependency.name, metric: "daysSinceLastRelease" }
|
|
4774
|
+
],
|
|
4602
4775
|
confidence: hasMetadata ? 0.9 : 0.5
|
|
4603
4776
|
},
|
|
4604
4777
|
{
|
|
@@ -4611,7 +4784,9 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4611
4784
|
},
|
|
4612
4785
|
weight: config.dependencyFactorWeights.maintainerConcentration,
|
|
4613
4786
|
amplification: null,
|
|
4614
|
-
evidence: [
|
|
4787
|
+
evidence: [
|
|
4788
|
+
{ kind: "dependency_metric", target: dependency.name, metric: "maintainerCount" }
|
|
4789
|
+
],
|
|
4615
4790
|
confidence: hasMetadata ? 0.9 : 0.5
|
|
4616
4791
|
},
|
|
4617
4792
|
{
|
|
@@ -4630,7 +4805,9 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4630
4805
|
},
|
|
4631
4806
|
weight: config.dependencyFactorWeights.transitiveBurden + config.dependencyFactorWeights.centrality + config.dependencyFactorWeights.chainDepth,
|
|
4632
4807
|
amplification: null,
|
|
4633
|
-
evidence: [
|
|
4808
|
+
evidence: [
|
|
4809
|
+
{ kind: "dependency_metric", target: dependency.name, metric: "dependencyDepth" }
|
|
4810
|
+
],
|
|
4634
4811
|
confidence: 1
|
|
4635
4812
|
},
|
|
4636
4813
|
{
|
|
@@ -4652,7 +4829,9 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
|
|
|
4652
4829
|
normalizedMetrics: { popularityDampener: context.popularityDampener },
|
|
4653
4830
|
weight: config.dependencySignals.popularityMaxDampening,
|
|
4654
4831
|
amplification: null,
|
|
4655
|
-
evidence: [
|
|
4832
|
+
evidence: [
|
|
4833
|
+
{ kind: "dependency_metric", target: dependency.name, metric: "weeklyDownloads" }
|
|
4834
|
+
],
|
|
4656
4835
|
confidence: context.rawMetrics.weeklyDownloads === null ? 0.4 : 0.9
|
|
4657
4836
|
}
|
|
4658
4837
|
]);
|
|
@@ -5041,7 +5220,12 @@ var collectAnalysisInputs = async (inputPath, authorIdentityMode, options = {},
|
|
|
5041
5220
|
};
|
|
5042
5221
|
};
|
|
5043
5222
|
var runAnalyzeCommand = async (inputPath, authorIdentityMode, options = {}, logger = createSilentLogger()) => {
|
|
5044
|
-
const analysisInputs = await collectAnalysisInputs(
|
|
5223
|
+
const analysisInputs = await collectAnalysisInputs(
|
|
5224
|
+
inputPath,
|
|
5225
|
+
authorIdentityMode,
|
|
5226
|
+
options,
|
|
5227
|
+
logger
|
|
5228
|
+
);
|
|
5045
5229
|
logger.info("computing risk summary");
|
|
5046
5230
|
const risk = computeRepositoryRiskSummary(analysisInputs);
|
|
5047
5231
|
logger.info(`analysis completed (repositoryScore=${risk.repositoryScore})`);
|
|
@@ -5168,9 +5352,7 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
|
|
|
5168
5352
|
);
|
|
5169
5353
|
}
|
|
5170
5354
|
if (options.baselineSha !== void 0 && options.baselineRef !== "auto") {
|
|
5171
|
-
throw new GovernanceConfigurationError(
|
|
5172
|
-
"baseline-sha requires --baseline-ref auto"
|
|
5173
|
-
);
|
|
5355
|
+
throw new GovernanceConfigurationError("baseline-sha requires --baseline-ref auto");
|
|
5174
5356
|
}
|
|
5175
5357
|
const resolvedTargetPath = resolve4(inputPath ?? process.cwd());
|
|
5176
5358
|
logger.info("building current snapshot");
|