@vibgrate/cli 2026.730.1 → 2026.731.1
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/baseline-4FBHW2X2.js +9 -0
- package/dist/{baseline-V6MYDEMS.js.map → baseline-4FBHW2X2.js.map} +1 -1
- package/dist/chunk-2XTPGYR2.js +6 -0
- package/dist/{chunk-Q4UQ73NA.js.map → chunk-2XTPGYR2.js.map} +1 -1
- package/dist/{chunk-CQDCZQFV.js → chunk-3NP2DO4G.js} +3 -3
- package/dist/{chunk-CQDCZQFV.js.map → chunk-3NP2DO4G.js.map} +1 -1
- package/dist/{chunk-VOEYUAER.js → chunk-476KWSFM.js} +3 -3
- package/dist/{chunk-VOEYUAER.js.map → chunk-476KWSFM.js.map} +1 -1
- package/dist/{chunk-6D4BCGRQ.js → chunk-C22ZY3FV.js} +3 -3
- package/dist/{chunk-6D4BCGRQ.js.map → chunk-C22ZY3FV.js.map} +1 -1
- package/dist/{chunk-TJ3WIJ7H.js → chunk-CWB6H553.js} +3 -3
- package/dist/{chunk-TJ3WIJ7H.js.map → chunk-CWB6H553.js.map} +1 -1
- package/dist/{chunk-5G7C6H2G.js → chunk-DXSEG6SZ.js} +3 -3
- package/dist/{chunk-5G7C6H2G.js.map → chunk-DXSEG6SZ.js.map} +1 -1
- package/dist/{chunk-6WNJJXFY.js → chunk-GPDJOCUI.js} +23 -6
- package/dist/chunk-GPDJOCUI.js.map +1 -0
- package/dist/{chunk-CFL3QQQZ.js → chunk-J3BQ7FIT.js} +7 -7
- package/dist/{chunk-CFL3QQQZ.js.map → chunk-J3BQ7FIT.js.map} +1 -1
- package/dist/{chunk-IDAQV3NQ.js → chunk-NJT4CA6K.js} +42 -11
- package/dist/chunk-NJT4CA6K.js.map +1 -0
- package/dist/{chunk-DBMYWNLC.js → chunk-SE4JMB4W.js} +3 -3
- package/dist/{chunk-DBMYWNLC.js.map → chunk-SE4JMB4W.js.map} +1 -1
- package/dist/{chunk-GLT3N7T2.js → chunk-SKIMUFCI.js} +6 -6
- package/dist/{chunk-GLT3N7T2.js.map → chunk-SKIMUFCI.js.map} +1 -1
- package/dist/{chunk-EKCNSRNJ.js → chunk-T7OFJS3X.js} +7 -7
- package/dist/{chunk-EKCNSRNJ.js.map → chunk-T7OFJS3X.js.map} +1 -1
- package/dist/{chunk-ON7PZNYV.js → chunk-UVMP7DFF.js} +12 -12
- package/dist/{chunk-ON7PZNYV.js.map → chunk-UVMP7DFF.js.map} +1 -1
- package/dist/cli.js +354 -88
- package/dist/cli.js.map +1 -1
- package/dist/{fs-HNR6LAI7.js → fs-HF5DOHYR.js} +3 -3
- package/dist/fs-HF5DOHYR.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/{interactive-NJG6467J.js → interactive-V6IRYZTA.js} +13 -13
- package/dist/{interactive-NJG6467J.js.map → interactive-V6IRYZTA.js.map} +1 -1
- package/dist/load-KPHH26ND.js +10 -0
- package/dist/{load-YPSEDYIW.js.map → load-KPHH26ND.js.map} +1 -1
- package/dist/{run-outcome-5FQWHWYK.js → run-outcome-TZ53G67B.js} +5 -5
- package/dist/{run-outcome-5FQWHWYK.js.map → run-outcome-TZ53G67B.js.map} +1 -1
- package/dist/{runtime-session-Y4ZD3QDO.js → runtime-session-PZKXBDJT.js} +7 -7
- package/dist/{runtime-session-Y4ZD3QDO.js.map → runtime-session-PZKXBDJT.js.map} +1 -1
- package/dist/{vg-mcp-bridge-PZFGTZSA.js → vg-mcp-bridge-7NNVIVO7.js} +6 -6
- package/dist/{vg-mcp-bridge-PZFGTZSA.js.map → vg-mcp-bridge-7NNVIVO7.js.map} +1 -1
- package/dist/{vgd-DH7AHQ23.js → vgd-Y2YCN75V.js} +6 -6
- package/dist/vgd-Y2YCN75V.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-V6MYDEMS.js +0 -9
- package/dist/chunk-6WNJJXFY.js.map +0 -1
- package/dist/chunk-IDAQV3NQ.js.map +0 -1
- package/dist/chunk-Q4UQ73NA.js +0 -6
- package/dist/fs-HNR6LAI7.js.map +0 -1
- package/dist/load-YPSEDYIW.js +0 -10
- package/dist/vgd-DH7AHQ23.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-
|
|
3
|
-
export { runBuild } from './chunk-
|
|
4
|
-
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-
|
|
5
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
2
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-T7OFJS3X.js';
|
|
3
|
+
export { runBuild } from './chunk-T7OFJS3X.js';
|
|
4
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-CWB6H553.js';
|
|
5
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-GPDJOCUI.js';
|
|
6
6
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
7
7
|
import { runCodeSession } from './chunk-WBMMRERH.js';
|
|
8
8
|
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
9
|
-
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-
|
|
9
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-3NP2DO4G.js';
|
|
10
10
|
import './chunk-5I4VSBWQ.js';
|
|
11
11
|
import './chunk-IS7VTH2Q.js';
|
|
12
12
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
|
|
@@ -23,11 +23,11 @@ import './chunk-RGEVBSLK.js';
|
|
|
23
23
|
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
|
|
24
24
|
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
25
25
|
import './chunk-7AVYKZEM.js';
|
|
26
|
-
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-
|
|
27
|
-
import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-
|
|
28
|
-
import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-
|
|
26
|
+
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-J3BQ7FIT.js';
|
|
27
|
+
import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-SKIMUFCI.js';
|
|
28
|
+
import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-C22ZY3FV.js';
|
|
29
29
|
import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
|
|
30
|
-
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-
|
|
30
|
+
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift } from './chunk-UVMP7DFF.js';
|
|
31
31
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
32
32
|
import './chunk-IPICO2RV.js';
|
|
33
33
|
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-FHJBGPJZ.js';
|
|
@@ -39,14 +39,14 @@ import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
|
39
39
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
40
40
|
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
|
|
41
41
|
import './chunk-RXP66R2E.js';
|
|
42
|
-
import { loadGraph, SCHEMA_VERSION } from './chunk-
|
|
43
|
-
import { resolveGraphPath, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-
|
|
44
|
-
import { VERSION } from './chunk-
|
|
42
|
+
import { loadGraph, SCHEMA_VERSION } from './chunk-476KWSFM.js';
|
|
43
|
+
import { resolveGraphPath, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-DXSEG6SZ.js';
|
|
44
|
+
import { VERSION } from './chunk-2XTPGYR2.js';
|
|
45
45
|
import { cacheDir, serializeGraph, stableStringify } from './chunk-ZKNB4YH4.js';
|
|
46
46
|
import './chunk-BWPBB45M.js';
|
|
47
47
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
48
48
|
import './chunk-BPF3YX2U.js';
|
|
49
|
-
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-
|
|
49
|
+
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-NJT4CA6K.js';
|
|
50
50
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
51
51
|
import * as fs7 from 'fs';
|
|
52
52
|
import fs7__default, { realpathSync } from 'fs';
|
|
@@ -2009,6 +2009,30 @@ function runTree(graph, params) {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
|
|
2011
2011
|
// src/lsp/enrich.ts
|
|
2012
|
+
var REACH_RANK = {
|
|
2013
|
+
reached: 3,
|
|
2014
|
+
potentially_reachable: 2,
|
|
2015
|
+
unknown: 1,
|
|
2016
|
+
"not-observed": 0
|
|
2017
|
+
};
|
|
2018
|
+
function mergeReachability(a, b) {
|
|
2019
|
+
const left = a ?? "unknown";
|
|
2020
|
+
const right = b ?? "unknown";
|
|
2021
|
+
return REACH_RANK[right] > REACH_RANK[left] ? right : left;
|
|
2022
|
+
}
|
|
2023
|
+
function mergeReachSites(a, b) {
|
|
2024
|
+
const out2 = [];
|
|
2025
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2026
|
+
for (const site of [...a ?? [], ...b ?? []]) {
|
|
2027
|
+
if (!site?.file) continue;
|
|
2028
|
+
const k = `${site.file}::${site.line ?? ""}::${site.symbol ?? ""}`;
|
|
2029
|
+
if (seen.has(k)) continue;
|
|
2030
|
+
seen.add(k);
|
|
2031
|
+
out2.push(site);
|
|
2032
|
+
if (out2.length >= 10) break;
|
|
2033
|
+
}
|
|
2034
|
+
return out2;
|
|
2035
|
+
}
|
|
2012
2036
|
var OSV_QUERY_URL = "https://api.osv.dev/v1/query";
|
|
2013
2037
|
var KEV_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json";
|
|
2014
2038
|
var cache = /* @__PURE__ */ new Map();
|
|
@@ -2171,10 +2195,11 @@ async function scanWorkspaceVulns(targets, opts = { offline: false }) {
|
|
|
2171
2195
|
existing.locations.push(loc);
|
|
2172
2196
|
}
|
|
2173
2197
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
existing.
|
|
2198
|
+
existing.reachability = mergeReachability(existing.reachability, t.reachability);
|
|
2199
|
+
if (t.reachSites?.length) {
|
|
2200
|
+
existing.reachSites = mergeReachSites(existing.reachSites, t.reachSites);
|
|
2177
2201
|
}
|
|
2202
|
+
if (!existing.reachEvidence && t.reachEvidence) existing.reachEvidence = t.reachEvidence;
|
|
2178
2203
|
if (!existing.latestStable && t.latestStable) existing.latestStable = t.latestStable;
|
|
2179
2204
|
if (!existing.section && t.section) existing.section = t.section;
|
|
2180
2205
|
}
|
|
@@ -2211,6 +2236,8 @@ async function scanWorkspaceVulns(targets, opts = { offline: false }) {
|
|
|
2211
2236
|
published: v.published,
|
|
2212
2237
|
kev: kevHit,
|
|
2213
2238
|
reachability: t.reachability ?? "unknown",
|
|
2239
|
+
reachSites: t.reachSites ?? [],
|
|
2240
|
+
reachEvidence: t.reachEvidence ?? null,
|
|
2214
2241
|
file: locations[0]?.file ?? t.file ?? null,
|
|
2215
2242
|
line: locations[0]?.line ?? t.line ?? null,
|
|
2216
2243
|
locations,
|
|
@@ -2334,6 +2361,8 @@ var VibgrateLanguageServer = class {
|
|
|
2334
2361
|
this.conn.onRequest("textDocument/codeLens", (_m, params) => this.onCodeLens(params));
|
|
2335
2362
|
this.conn.onRequest("vibgrate/graph/query", (_m, params) => this.onGraphQuery(params));
|
|
2336
2363
|
this.conn.onRequest("vibgrate/score/forFile", (_m, params) => this.onScoreForFile(params));
|
|
2364
|
+
this.conn.onRequest("vibgrate/score/forProject", (_m, params) => this.onScoreForProject(params));
|
|
2365
|
+
this.conn.onRequest("vibgrate/architecture", (_m, params) => this.onArchitecture(params));
|
|
2337
2366
|
this.conn.onRequest("vibgrate/score/history", (_m, params) => {
|
|
2338
2367
|
const p = params;
|
|
2339
2368
|
const days = typeof p?.days === "number" && p.days > 0 && p.days <= 365 ? p.days : 90;
|
|
@@ -2454,7 +2483,8 @@ var VibgrateLanguageServer = class {
|
|
|
2454
2483
|
scannedAt: a.timestamp,
|
|
2455
2484
|
...delta !== void 0 ? { delta } : {},
|
|
2456
2485
|
...buildBreakdown(a.drift, a.projects ?? []) ? { breakdown: buildBreakdown(a.drift, a.projects ?? []) } : {},
|
|
2457
|
-
...buildEolHorizon(a.projects ?? []) ? { eolHorizon: buildEolHorizon(a.projects ?? []) } : {}
|
|
2486
|
+
...buildEolHorizon(a.projects ?? []) ? { eolHorizon: buildEolHorizon(a.projects ?? []) } : {},
|
|
2487
|
+
...buildProjectRefs(this.opts.root, a.projects ?? []) ? { projects: buildProjectRefs(this.opts.root, a.projects ?? []) } : {}
|
|
2458
2488
|
};
|
|
2459
2489
|
this.conn.notify("vibgrate/score", payload);
|
|
2460
2490
|
}
|
|
@@ -2637,7 +2667,7 @@ var VibgrateLanguageServer = class {
|
|
|
2637
2667
|
kevSource: "skipped"
|
|
2638
2668
|
};
|
|
2639
2669
|
}
|
|
2640
|
-
const
|
|
2670
|
+
const importMap = packageImportMap(this.graph);
|
|
2641
2671
|
const targets = [];
|
|
2642
2672
|
for (const proj of a.projects ?? []) {
|
|
2643
2673
|
if (isPrunedWorkspacePath(proj.path) || isPrunedWorkspacePath(manifestRelativePath(proj))) {
|
|
@@ -2662,8 +2692,22 @@ var VibgrateLanguageServer = class {
|
|
|
2662
2692
|
if (l >= 0) line = l + 1;
|
|
2663
2693
|
}
|
|
2664
2694
|
let reachability = "unknown";
|
|
2665
|
-
|
|
2666
|
-
|
|
2695
|
+
let reachSites = [];
|
|
2696
|
+
let reachEvidence = null;
|
|
2697
|
+
if (importMap) {
|
|
2698
|
+
const files = lookupImportFiles(importMap, dep.package);
|
|
2699
|
+
if (files.length > 0) {
|
|
2700
|
+
reachability = "reached";
|
|
2701
|
+
reachSites = files.slice(0, 10).map((file) => ({
|
|
2702
|
+
file,
|
|
2703
|
+
// Best-effort first line that mentions the package name (import site).
|
|
2704
|
+
line: firstPackageMentionLine(this.opts.root, file, dep.package)
|
|
2705
|
+
}));
|
|
2706
|
+
reachEvidence = `${dep.package} is imported by ${files.length} file${files.length === 1 ? "" : "s"} in the code map`;
|
|
2707
|
+
} else {
|
|
2708
|
+
reachability = "not-observed";
|
|
2709
|
+
reachEvidence = `no import of ${dep.package} was found in the code map`;
|
|
2710
|
+
}
|
|
2667
2711
|
}
|
|
2668
2712
|
targets.push({
|
|
2669
2713
|
ecosystem,
|
|
@@ -2673,7 +2717,9 @@ var VibgrateLanguageServer = class {
|
|
|
2673
2717
|
line,
|
|
2674
2718
|
section: dep.section ?? null,
|
|
2675
2719
|
latestStable: dep.latestStable ?? null,
|
|
2676
|
-
reachability
|
|
2720
|
+
reachability,
|
|
2721
|
+
reachSites,
|
|
2722
|
+
reachEvidence
|
|
2677
2723
|
});
|
|
2678
2724
|
}
|
|
2679
2725
|
}
|
|
@@ -2684,7 +2730,53 @@ var VibgrateLanguageServer = class {
|
|
|
2684
2730
|
const a = this.artifact;
|
|
2685
2731
|
if (!a || !p.uri) return null;
|
|
2686
2732
|
const project = projectForFile(this.opts.root, a, uriToPath(p.uri));
|
|
2687
|
-
return project ? scoreForProject(a, project) : null;
|
|
2733
|
+
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
2734
|
+
}
|
|
2735
|
+
/**
|
|
2736
|
+
* `vibgrate/score/forProject` — monorepo scope picker. Returns the same
|
|
2737
|
+
* shape as the whole-repo score, scoped to one scanned project path.
|
|
2738
|
+
*/
|
|
2739
|
+
onScoreForProject(params) {
|
|
2740
|
+
const p = params;
|
|
2741
|
+
const a = this.artifact;
|
|
2742
|
+
if (!a || typeof p.path !== "string") return null;
|
|
2743
|
+
const project = projectByPath(a, p.path);
|
|
2744
|
+
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
2745
|
+
}
|
|
2746
|
+
/**
|
|
2747
|
+
* `vibgrate/architecture` — the Architecture panel. `path` absent or
|
|
2748
|
+
* `'__repo__'` returns the whole-workspace aggregate (`extended.architecture`);
|
|
2749
|
+
* a project path returns that project's own detection (`ProjectScan.architecture`).
|
|
2750
|
+
* Returns `null` when the scanner hasn't produced architecture data yet (still
|
|
2751
|
+
* scanning, or the archetype/layer scanner is disabled) rather than an empty
|
|
2752
|
+
* shape a client might mistake for "no layers detected".
|
|
2753
|
+
*/
|
|
2754
|
+
onArchitecture(params) {
|
|
2755
|
+
const p = params;
|
|
2756
|
+
const a = this.artifact;
|
|
2757
|
+
if (!a) return null;
|
|
2758
|
+
if (!p?.path || p.path === "__repo__") {
|
|
2759
|
+
const arch = a.extended?.architecture;
|
|
2760
|
+
if (!arch) return null;
|
|
2761
|
+
return {
|
|
2762
|
+
archetype: arch.archetype,
|
|
2763
|
+
archetypeConfidence: arch.archetypeConfidence,
|
|
2764
|
+
layers: arch.layers,
|
|
2765
|
+
totalClassified: arch.totalClassified,
|
|
2766
|
+
unclassified: arch.unclassified
|
|
2767
|
+
};
|
|
2768
|
+
}
|
|
2769
|
+
const project = projectByPath(a, p.path);
|
|
2770
|
+
if (!project?.architecture) return null;
|
|
2771
|
+
return {
|
|
2772
|
+
archetype: project.architecture.archetype,
|
|
2773
|
+
archetypeConfidence: project.architecture.archetypeConfidence,
|
|
2774
|
+
layers: project.architecture.layers,
|
|
2775
|
+
totalClassified: project.architecture.totalClassified,
|
|
2776
|
+
unclassified: project.architecture.unclassified,
|
|
2777
|
+
manifestPath: manifestRelativePath(project),
|
|
2778
|
+
lockfilePath: lockfileRelativePath(this.opts.root, project)
|
|
2779
|
+
};
|
|
2688
2780
|
}
|
|
2689
2781
|
};
|
|
2690
2782
|
function uriToPath(uri) {
|
|
@@ -2712,6 +2804,33 @@ function pruneArtifactProjects(a) {
|
|
|
2712
2804
|
const findings = (a.findings ?? []).filter((f) => !isPrunedWorkspacePath(f.location));
|
|
2713
2805
|
return { ...a, projects, findings };
|
|
2714
2806
|
}
|
|
2807
|
+
function projectByPath(a, projectPath) {
|
|
2808
|
+
const want = path37.normalize(projectPath === "" ? "." : projectPath);
|
|
2809
|
+
for (const proj of a.projects ?? []) {
|
|
2810
|
+
const got = path37.normalize(proj.path === "" ? "." : proj.path);
|
|
2811
|
+
if (got === want) return proj;
|
|
2812
|
+
}
|
|
2813
|
+
return void 0;
|
|
2814
|
+
}
|
|
2815
|
+
function buildProjectRefs(rootDir, projects) {
|
|
2816
|
+
if (projects.length === 0) return void 0;
|
|
2817
|
+
return projects.map((p) => {
|
|
2818
|
+
const rel = p.path === "" ? "." : p.path;
|
|
2819
|
+
const base = rel === "." ? "." : path37.basename(rel);
|
|
2820
|
+
const lockfilePath = lockfileRelativePath(rootDir, p);
|
|
2821
|
+
return {
|
|
2822
|
+
path: rel,
|
|
2823
|
+
name: p.name || base,
|
|
2824
|
+
manifestPath: manifestRelativePath(p),
|
|
2825
|
+
...lockfilePath ? { lockfilePath } : {},
|
|
2826
|
+
...p.drift ? {
|
|
2827
|
+
score: p.drift.score,
|
|
2828
|
+
band: p.drift.riskLevel ?? "low",
|
|
2829
|
+
mode: p.drift.mode ?? "verified"
|
|
2830
|
+
} : {}
|
|
2831
|
+
};
|
|
2832
|
+
}).sort((a, b) => a.path.localeCompare(b.path));
|
|
2833
|
+
}
|
|
2715
2834
|
function projectForFile(root2, a, filePath) {
|
|
2716
2835
|
const dir = path37.dirname(path37.resolve(filePath));
|
|
2717
2836
|
let best;
|
|
@@ -2736,7 +2855,7 @@ function hasReleaseDates(a) {
|
|
|
2736
2855
|
}
|
|
2737
2856
|
return false;
|
|
2738
2857
|
}
|
|
2739
|
-
function scoreForProject(a, proj) {
|
|
2858
|
+
function scoreForProject(rootDir, a, proj) {
|
|
2740
2859
|
if (!proj.drift) return null;
|
|
2741
2860
|
let behind = 0;
|
|
2742
2861
|
let total = 0;
|
|
@@ -2757,10 +2876,11 @@ function scoreForProject(a, proj) {
|
|
|
2757
2876
|
methodology: proj.drift.methodologyVersion ?? a.drift.methodologyVersion ?? "unknown",
|
|
2758
2877
|
scale: "0 best, 100 worst",
|
|
2759
2878
|
counts: { behind, eol, unmaintained, total },
|
|
2760
|
-
rootPath: proj.path,
|
|
2879
|
+
rootPath: proj.path === "" ? "." : proj.path,
|
|
2761
2880
|
scannedAt: a.timestamp,
|
|
2762
2881
|
...buildBreakdown(proj.drift, [proj]) ? { breakdown: buildBreakdown(proj.drift, [proj]) } : {},
|
|
2763
|
-
...buildEolHorizon([proj]) ? { eolHorizon: buildEolHorizon([proj]) } : {}
|
|
2882
|
+
...buildEolHorizon([proj]) ? { eolHorizon: buildEolHorizon([proj]) } : {},
|
|
2883
|
+
...buildProjectRefs(rootDir, a.projects ?? []) ? { projects: buildProjectRefs(rootDir, a.projects ?? []) } : {}
|
|
2764
2884
|
};
|
|
2765
2885
|
}
|
|
2766
2886
|
function runtimeHorizonLabel(project) {
|
|
@@ -2789,34 +2909,40 @@ function bandForScore(n) {
|
|
|
2789
2909
|
if (n <= 60) return "moderate";
|
|
2790
2910
|
return "high";
|
|
2791
2911
|
}
|
|
2792
|
-
function buildBreakdown(
|
|
2793
|
-
const top = drift.dependencyDrift?.top;
|
|
2794
|
-
if (!top || top.length === 0) return void 0;
|
|
2912
|
+
function buildBreakdown(_drift, projects) {
|
|
2795
2913
|
const byPkg = /* @__PURE__ */ new Map();
|
|
2796
2914
|
for (const p of projects) {
|
|
2797
2915
|
const ecosystem = osvEcosystem(p.type);
|
|
2798
|
-
for (const d of p.dependencies ?? [])
|
|
2916
|
+
for (const d of p.dependencies ?? []) {
|
|
2917
|
+
if (!byPkg.has(d.package)) byPkg.set(d.package, { row: d, ecosystem });
|
|
2918
|
+
}
|
|
2799
2919
|
}
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2920
|
+
if (byPkg.size === 0) return void 0;
|
|
2921
|
+
const items = [];
|
|
2922
|
+
for (const [, { row, ecosystem }] of byPkg) {
|
|
2923
|
+
const scored = perDependencyDrift(row, {
|
|
2924
|
+
unsupported: row.unsupported === true,
|
|
2925
|
+
abandoned: row.abandoned === true
|
|
2926
|
+
});
|
|
2927
|
+
if (scored.excluded) continue;
|
|
2928
|
+
items.push({
|
|
2929
|
+
package: row.package,
|
|
2930
|
+
section: row.section ?? "dependencies",
|
|
2931
|
+
ecosystem,
|
|
2932
|
+
drift: scored.drift,
|
|
2933
|
+
band: bandForScore(scored.drift),
|
|
2934
|
+
currentSpec: row.currentSpec ?? "",
|
|
2935
|
+
resolvedVersion: row.resolvedVersion ?? null,
|
|
2936
|
+
latestStable: row.latestStable ?? null,
|
|
2937
|
+
majorsBehind: row.majorsBehind ?? null,
|
|
2938
|
+
ageDays: row.ageDays ?? null,
|
|
2939
|
+
mode: scored.mode,
|
|
2940
|
+
unsupported: scored.unsupported || row.unsupported === true,
|
|
2941
|
+
abandoned: scored.flags.includes("abandoned-floor") || row.abandoned === true,
|
|
2942
|
+
flags: scored.flags
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
items.sort((a, b) => b.drift - a.drift || a.package.localeCompare(b.package));
|
|
2820
2946
|
return items.length > 0 ? items : void 0;
|
|
2821
2947
|
}
|
|
2822
2948
|
function manifestRelativePath(proj) {
|
|
@@ -2851,30 +2977,129 @@ function manifestRelativePath(proj) {
|
|
|
2851
2977
|
return join27("package.json");
|
|
2852
2978
|
}
|
|
2853
2979
|
}
|
|
2854
|
-
function
|
|
2980
|
+
function lockfileRelativePath(rootDir, proj) {
|
|
2981
|
+
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
2982
|
+
const candidateNames = (() => {
|
|
2983
|
+
switch (proj.type) {
|
|
2984
|
+
case "node":
|
|
2985
|
+
case "typescript":
|
|
2986
|
+
return ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "bun.lockb"];
|
|
2987
|
+
case "python":
|
|
2988
|
+
return ["poetry.lock", "uv.lock", "Pipfile.lock"];
|
|
2989
|
+
case "go":
|
|
2990
|
+
return ["go.sum"];
|
|
2991
|
+
case "rust":
|
|
2992
|
+
return ["Cargo.lock"];
|
|
2993
|
+
case "ruby":
|
|
2994
|
+
return ["Gemfile.lock"];
|
|
2995
|
+
case "php":
|
|
2996
|
+
return ["composer.lock"];
|
|
2997
|
+
case "dotnet":
|
|
2998
|
+
return ["packages.lock.json"];
|
|
2999
|
+
case "dart":
|
|
3000
|
+
return ["pubspec.lock"];
|
|
3001
|
+
default:
|
|
3002
|
+
return [];
|
|
3003
|
+
}
|
|
3004
|
+
})();
|
|
3005
|
+
const dirsToTry = base ? [base, ""] : [""];
|
|
3006
|
+
for (const dir of dirsToTry) {
|
|
3007
|
+
for (const name of candidateNames) {
|
|
3008
|
+
const rel = dir ? path37.join(dir, name) : name;
|
|
3009
|
+
try {
|
|
3010
|
+
if (fs7.existsSync(path37.join(rootDir, rel))) return rel;
|
|
3011
|
+
} catch {
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
return void 0;
|
|
3016
|
+
}
|
|
3017
|
+
function packageImportMap(graph) {
|
|
2855
3018
|
if (!graph?.nodes?.length) return null;
|
|
2856
|
-
const
|
|
3019
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
3020
|
+
const map = /* @__PURE__ */ new Map();
|
|
3021
|
+
const addPkg = (raw, file) => {
|
|
3022
|
+
if (!file) return;
|
|
3023
|
+
const cleaned = raw.replace(/^node_modules\//, "").replace(/\\/g, "/");
|
|
3024
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3025
|
+
keys.add(cleaned.toLowerCase());
|
|
3026
|
+
if (cleaned.startsWith("@")) {
|
|
3027
|
+
const parts = cleaned.split("/");
|
|
3028
|
+
if (parts.length >= 2) keys.add(`${parts[0]}/${parts[1]}`.toLowerCase());
|
|
3029
|
+
} else {
|
|
3030
|
+
keys.add(cleaned.split("/")[0].toLowerCase());
|
|
3031
|
+
}
|
|
3032
|
+
for (const k of keys) {
|
|
3033
|
+
let set = map.get(k);
|
|
3034
|
+
if (!set) {
|
|
3035
|
+
set = /* @__PURE__ */ new Set();
|
|
3036
|
+
map.set(k, set);
|
|
3037
|
+
}
|
|
3038
|
+
set.add(file);
|
|
3039
|
+
}
|
|
3040
|
+
};
|
|
3041
|
+
for (const e of graph.edges ?? []) {
|
|
3042
|
+
if (e.kind !== "import") continue;
|
|
3043
|
+
const src = byId.get(e.src);
|
|
3044
|
+
const dst = byId.get(e.dst);
|
|
3045
|
+
if (!src?.file || !dst) continue;
|
|
3046
|
+
if (dst.kind !== "external" && dst.kind !== "package" && dst.kind !== "module") continue;
|
|
3047
|
+
for (const raw of [dst.name, dst.qualifiedName].filter(Boolean)) {
|
|
3048
|
+
addPkg(raw, src.file);
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
2857
3051
|
for (const n of graph.nodes) {
|
|
2858
3052
|
if (n.kind !== "external" && n.kind !== "package" && n.kind !== "module") continue;
|
|
2859
|
-
const
|
|
2860
|
-
|
|
2861
|
-
|
|
3053
|
+
for (const raw of [n.name, n.qualifiedName].filter(Boolean)) {
|
|
3054
|
+
const cleaned = raw.replace(/^node_modules\//, "").replace(/\\/g, "/").toLowerCase();
|
|
3055
|
+
if (!map.has(cleaned)) map.set(cleaned, /* @__PURE__ */ new Set());
|
|
2862
3056
|
if (cleaned.startsWith("@")) {
|
|
2863
3057
|
const parts = cleaned.split("/");
|
|
2864
|
-
if (parts.length >= 2
|
|
2865
|
-
|
|
2866
|
-
|
|
3058
|
+
if (parts.length >= 2 && !map.has(`${parts[0]}/${parts[1]}`)) {
|
|
3059
|
+
map.set(`${parts[0]}/${parts[1]}`, /* @__PURE__ */ new Set());
|
|
3060
|
+
}
|
|
2867
3061
|
}
|
|
2868
|
-
set.add(cleaned.toLowerCase());
|
|
2869
3062
|
}
|
|
2870
3063
|
}
|
|
2871
|
-
|
|
3064
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
3065
|
+
for (const [k, files] of map) {
|
|
3066
|
+
out2.set(k, [...files].sort());
|
|
3067
|
+
}
|
|
3068
|
+
return out2;
|
|
2872
3069
|
}
|
|
2873
|
-
function
|
|
3070
|
+
function lookupImportFiles(map, pkg) {
|
|
2874
3071
|
const p = pkg.toLowerCase();
|
|
2875
|
-
if (
|
|
2876
|
-
if (!p.startsWith("@")
|
|
2877
|
-
|
|
3072
|
+
if (map.has(p)) return map.get(p);
|
|
3073
|
+
if (!p.startsWith("@")) {
|
|
3074
|
+
const root2 = p.split("/")[0];
|
|
3075
|
+
if (map.has(root2)) return map.get(root2);
|
|
3076
|
+
}
|
|
3077
|
+
return [];
|
|
3078
|
+
}
|
|
3079
|
+
function firstPackageMentionLine(root2, relFile, pkg) {
|
|
3080
|
+
try {
|
|
3081
|
+
const abs = path37.resolve(root2, relFile);
|
|
3082
|
+
const stat2 = fs7.statSync(abs);
|
|
3083
|
+
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3084
|
+
const text = fs7.readFileSync(abs, "utf8");
|
|
3085
|
+
const tokens = [pkg];
|
|
3086
|
+
if (pkg.startsWith("@")) {
|
|
3087
|
+
const parts = pkg.split("/");
|
|
3088
|
+
if (parts[1]) tokens.push(parts[1]);
|
|
3089
|
+
} else if (pkg.includes("/")) {
|
|
3090
|
+
tokens.push(pkg.split("/")[0]);
|
|
3091
|
+
}
|
|
3092
|
+
const lines = text.split(/\r?\n/);
|
|
3093
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3094
|
+
const line = lines[i];
|
|
3095
|
+
if (!/import|require|from|use |include/.test(line) && !line.includes(pkg)) continue;
|
|
3096
|
+
for (const t of tokens) {
|
|
3097
|
+
if (t && line.includes(t)) return i + 1;
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3100
|
+
} catch {
|
|
3101
|
+
}
|
|
3102
|
+
return null;
|
|
2878
3103
|
}
|
|
2879
3104
|
function osvEcosystem(type) {
|
|
2880
3105
|
switch (type) {
|
|
@@ -6064,7 +6289,7 @@ function registerCode(program) {
|
|
|
6064
6289
|
try {
|
|
6065
6290
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6066
6291
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6067
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6292
|
+
const { loadGraph: loadGraph2 } = await import('./load-KPHH26ND.js');
|
|
6068
6293
|
const state = readOrchestratorState2();
|
|
6069
6294
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6070
6295
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -6148,7 +6373,7 @@ function registerCode(program) {
|
|
|
6148
6373
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
6149
6374
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
6150
6375
|
}
|
|
6151
|
-
const { runInteractive } = await import('./interactive-
|
|
6376
|
+
const { runInteractive } = await import('./interactive-V6IRYZTA.js');
|
|
6152
6377
|
await runInteractive(
|
|
6153
6378
|
rootOf(global),
|
|
6154
6379
|
global,
|
|
@@ -6229,7 +6454,7 @@ function registerCode(program) {
|
|
|
6229
6454
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
6230
6455
|
};
|
|
6231
6456
|
try {
|
|
6232
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
6457
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-TZ53G67B.js');
|
|
6233
6458
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
6234
6459
|
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-3YOPU3LF.js');
|
|
6235
6460
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
@@ -6238,11 +6463,11 @@ function registerCode(program) {
|
|
|
6238
6463
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
6239
6464
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6240
6465
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6241
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6466
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-PZKXBDJT.js');
|
|
6242
6467
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6243
6468
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6244
6469
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6245
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6470
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-Y2YCN75V.js');
|
|
6246
6471
|
const federation = loadOrDiscoverFederation(root2);
|
|
6247
6472
|
const modelProfile = mergeModelExecutionProfile(
|
|
6248
6473
|
resolveModelExecutionProfile({
|
|
@@ -6300,7 +6525,7 @@ ${res.stderr}` : ""),
|
|
|
6300
6525
|
exitCode: res.status ?? 1
|
|
6301
6526
|
};
|
|
6302
6527
|
};
|
|
6303
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6528
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-7NNVIVO7.js');
|
|
6304
6529
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6305
6530
|
getGraph: () => graph,
|
|
6306
6531
|
root: root2,
|
|
@@ -6536,7 +6761,7 @@ ${res.stderr}` : ""),
|
|
|
6536
6761
|
if (!autonomous && !tty) {
|
|
6537
6762
|
throw usageError("the agent approves each edit/command \u2014 run in a terminal to approve interactively, or pass --auto to run autonomously (or --single for a one-shot diff).");
|
|
6538
6763
|
}
|
|
6539
|
-
const { agentTask } = await import('./interactive-
|
|
6764
|
+
const { agentTask } = await import('./interactive-V6IRYZTA.js');
|
|
6540
6765
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
6541
6766
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
6542
6767
|
let priorSummary;
|
|
@@ -6546,7 +6771,7 @@ ${res.stderr}` : ""),
|
|
|
6546
6771
|
if (prev) priorSummary = summarizeSession(prev);
|
|
6547
6772
|
}
|
|
6548
6773
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
6549
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6774
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-7NNVIVO7.js');
|
|
6550
6775
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6551
6776
|
getGraph: () => graph,
|
|
6552
6777
|
root: root2,
|
|
@@ -6570,11 +6795,11 @@ ${res.stderr}` : ""),
|
|
|
6570
6795
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
6571
6796
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6572
6797
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6573
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6798
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-PZKXBDJT.js');
|
|
6574
6799
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6575
6800
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6576
6801
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6577
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6802
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-Y2YCN75V.js');
|
|
6578
6803
|
const federation = loadFederation(root2);
|
|
6579
6804
|
const modelProfile = mergeModelExecutionProfile(
|
|
6580
6805
|
resolveModelExecutionProfile({
|
|
@@ -7464,7 +7689,7 @@ function registerDaemon(program) {
|
|
|
7464
7689
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
7465
7690
|
}
|
|
7466
7691
|
if (!loaded.ok) {
|
|
7467
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
7692
|
+
const { loadGraph: loadGraph2 } = await import('./load-KPHH26ND.js');
|
|
7468
7693
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7469
7694
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7470
7695
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -7869,7 +8094,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
7869
8094
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
7870
8095
|
}
|
|
7871
8096
|
if (opts.baseline) {
|
|
7872
|
-
const { runBaseline } = await import('./baseline-
|
|
8097
|
+
const { runBaseline } = await import('./baseline-4FBHW2X2.js');
|
|
7873
8098
|
await runBaseline(rootDir);
|
|
7874
8099
|
}
|
|
7875
8100
|
console.log("");
|
|
@@ -7971,11 +8196,42 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
7971
8196
|
importingFiles: [...files].sort()
|
|
7972
8197
|
};
|
|
7973
8198
|
}
|
|
7974
|
-
async function
|
|
8199
|
+
async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
|
|
7975
8200
|
const content = await readFile3(path37.join(rootDir, relFile));
|
|
7976
|
-
if (!content) return
|
|
8201
|
+
if (!content) return null;
|
|
7977
8202
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7978
|
-
|
|
8203
|
+
const re = new RegExp(`\\b${escaped}\\b`);
|
|
8204
|
+
const lines = content.split(/\r?\n/);
|
|
8205
|
+
for (let i = 0; i < lines.length; i++) {
|
|
8206
|
+
if (re.test(lines[i])) return i + 1;
|
|
8207
|
+
}
|
|
8208
|
+
return null;
|
|
8209
|
+
}
|
|
8210
|
+
function formatSitePath(site) {
|
|
8211
|
+
return site.line != null && site.line > 0 ? `${site.file}:${site.line}` : site.file;
|
|
8212
|
+
}
|
|
8213
|
+
function enclosingFunctionName(graph, relFile, line) {
|
|
8214
|
+
if (line == null || line < 1) return null;
|
|
8215
|
+
let best = null;
|
|
8216
|
+
let bestSpan = Number.POSITIVE_INFINITY;
|
|
8217
|
+
for (const node2 of graph.nodes) {
|
|
8218
|
+
if (node2.file !== relFile) continue;
|
|
8219
|
+
if (node2.kind !== "function" && node2.kind !== "method") continue;
|
|
8220
|
+
const start = node2.span?.start;
|
|
8221
|
+
const end = node2.span?.end;
|
|
8222
|
+
if (start == null || end == null) continue;
|
|
8223
|
+
if (line < start || line > end) continue;
|
|
8224
|
+
const span = end - start;
|
|
8225
|
+
if (span < bestSpan) {
|
|
8226
|
+
bestSpan = span;
|
|
8227
|
+
best = node2;
|
|
8228
|
+
}
|
|
8229
|
+
}
|
|
8230
|
+
return best?.name ?? null;
|
|
8231
|
+
}
|
|
8232
|
+
function sitesFromImportFiles(files, limit = 10) {
|
|
8233
|
+
const sites = files.slice(0, limit).map((file) => ({ file }));
|
|
8234
|
+
return { callPath: sites.map(formatSitePath), sites };
|
|
7979
8235
|
}
|
|
7980
8236
|
async function defaultReadFile(absPath) {
|
|
7981
8237
|
try {
|
|
@@ -8058,6 +8314,7 @@ async function analyzeReachability(input) {
|
|
|
8058
8314
|
}
|
|
8059
8315
|
const matchableSymbols = entry.symbols.map((s) => ({ symbol: s.symbol, identifier: symbolIdentifier(s.symbol) })).filter((s) => isMatchableIdentifier(s.identifier));
|
|
8060
8316
|
if (entry.symbolCoverage !== "function" || matchableSymbols.length === 0) {
|
|
8317
|
+
const { callPath, sites } = sitesFromImportFiles(evidence.importingFiles, 10);
|
|
8061
8318
|
findings.push({
|
|
8062
8319
|
advisoryId: entry.advisoryId,
|
|
8063
8320
|
ecosystem: entry.ecosystem,
|
|
@@ -8065,7 +8322,8 @@ async function analyzeReachability(input) {
|
|
|
8065
8322
|
version: entry.version,
|
|
8066
8323
|
tier: "potentially_reachable",
|
|
8067
8324
|
evidence: `${entry.package} is imported by ${evidence.importingFiles.length} file${evidence.importingFiles.length === 1 ? "" : "s"}; vulnerable symbols unresolved (coverage: ${entry.symbolCoverage})`,
|
|
8068
|
-
callPath
|
|
8325
|
+
callPath,
|
|
8326
|
+
sites,
|
|
8069
8327
|
graphConfidence: Math.min(baseConfidence, 0.6)
|
|
8070
8328
|
});
|
|
8071
8329
|
continue;
|
|
@@ -8073,14 +8331,19 @@ async function analyzeReachability(input) {
|
|
|
8073
8331
|
const filesToCheck = evidence.importingFiles.slice(0, MAX_FILES_PER_PACKAGE);
|
|
8074
8332
|
let anySymbolFound = false;
|
|
8075
8333
|
for (const { symbol, identifier } of matchableSymbols) {
|
|
8076
|
-
const
|
|
8334
|
+
const sites = [];
|
|
8077
8335
|
for (const relFile of filesToCheck) {
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8336
|
+
const line = await firstReferenceLine(input.rootDir, relFile, identifier, readFile3);
|
|
8337
|
+
if (line == null) continue;
|
|
8338
|
+
sites.push({
|
|
8339
|
+
file: relFile,
|
|
8340
|
+
line,
|
|
8341
|
+
symbol,
|
|
8342
|
+
function: enclosingFunctionName(input.graph, relFile, line)
|
|
8343
|
+
});
|
|
8344
|
+
if (sites.length >= 5) break;
|
|
8082
8345
|
}
|
|
8083
|
-
if (
|
|
8346
|
+
if (sites.length > 0) {
|
|
8084
8347
|
anySymbolFound = true;
|
|
8085
8348
|
findings.push({
|
|
8086
8349
|
advisoryId: entry.advisoryId,
|
|
@@ -8089,13 +8352,15 @@ async function analyzeReachability(input) {
|
|
|
8089
8352
|
version: entry.version,
|
|
8090
8353
|
symbol,
|
|
8091
8354
|
tier: "reachable",
|
|
8092
|
-
evidence: `vulnerable symbol \`${identifier}\` is referenced in ${
|
|
8093
|
-
callPath:
|
|
8355
|
+
evidence: `vulnerable symbol \`${identifier}\` is referenced in ${sites.length} importing file${sites.length === 1 ? "" : "s"}`,
|
|
8356
|
+
callPath: sites.map(formatSitePath),
|
|
8357
|
+
sites,
|
|
8094
8358
|
graphConfidence: Math.min(baseConfidence, 0.75)
|
|
8095
8359
|
});
|
|
8096
8360
|
}
|
|
8097
8361
|
}
|
|
8098
8362
|
if (!anySymbolFound) {
|
|
8363
|
+
const { callPath, sites } = sitesFromImportFiles(evidence.importingFiles, 10);
|
|
8099
8364
|
findings.push({
|
|
8100
8365
|
advisoryId: entry.advisoryId,
|
|
8101
8366
|
ecosystem: entry.ecosystem,
|
|
@@ -8103,7 +8368,8 @@ async function analyzeReachability(input) {
|
|
|
8103
8368
|
version: entry.version,
|
|
8104
8369
|
tier: "not_reached",
|
|
8105
8370
|
evidence: `${entry.package} is imported, but none of its ${matchableSymbols.length} vulnerable symbol${matchableSymbols.length === 1 ? "" : "s"} is referenced in the ${filesToCheck.length} importing file${filesToCheck.length === 1 ? "" : "s"} checked`,
|
|
8106
|
-
callPath
|
|
8371
|
+
callPath,
|
|
8372
|
+
sites,
|
|
8107
8373
|
graphConfidence: Math.min(baseConfidence, 0.55)
|
|
8108
8374
|
});
|
|
8109
8375
|
}
|