@vibgrate/cli 2026.730.2 → 2026.731.2
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/{agent-33BMKWJC.js → agent-6PPW5GIV.js} +4 -4
- package/dist/{agent-33BMKWJC.js.map → agent-6PPW5GIV.js.map} +1 -1
- package/dist/baseline-ZMHL6DXF.js +9 -0
- package/dist/{baseline-536TQZIB.js.map → baseline-ZMHL6DXF.js.map} +1 -1
- package/dist/{chunk-EGCB5K3P.js → chunk-4CGLQXSI.js} +3 -3
- package/dist/{chunk-EGCB5K3P.js.map → chunk-4CGLQXSI.js.map} +1 -1
- package/dist/chunk-4DZC3ADC.js +42 -0
- package/dist/chunk-4DZC3ADC.js.map +1 -0
- package/dist/chunk-4TC6RJ7U.js +326 -0
- package/dist/chunk-4TC6RJ7U.js.map +1 -0
- package/dist/{chunk-ZW5W627G.js → chunk-5J45MN3K.js} +13 -328
- package/dist/chunk-5J45MN3K.js.map +1 -0
- package/dist/{chunk-IDAQV3NQ.js → chunk-DT4KIVRI.js} +57 -17
- package/dist/chunk-DT4KIVRI.js.map +1 -0
- package/dist/{chunk-NSK25UT2.js → chunk-EX2SH5CT.js} +3 -3
- package/dist/{chunk-NSK25UT2.js.map → chunk-EX2SH5CT.js.map} +1 -1
- package/dist/{chunk-UPH2RJ7L.js → chunk-FF5ZQ6KI.js} +23 -6
- package/dist/chunk-FF5ZQ6KI.js.map +1 -0
- package/dist/{chunk-HWN4P64B.js → chunk-IZNOMGR6.js} +3 -3
- package/dist/{chunk-HWN4P64B.js.map → chunk-IZNOMGR6.js.map} +1 -1
- package/dist/chunk-L6BRBFBP.js +65 -0
- package/dist/chunk-L6BRBFBP.js.map +1 -0
- package/dist/{chunk-WHXVU23K.js → chunk-LZX5NH4V.js} +7 -7
- package/dist/{chunk-WHXVU23K.js.map → chunk-LZX5NH4V.js.map} +1 -1
- package/dist/chunk-NNB2H4BA.js +6 -0
- package/dist/{chunk-BZPZ3OM6.js.map → chunk-NNB2H4BA.js.map} +1 -1
- package/dist/{chunk-KGWEBM2J.js → chunk-Q7HUXIUF.js} +3 -3
- package/dist/{chunk-KGWEBM2J.js.map → chunk-Q7HUXIUF.js.map} +1 -1
- package/dist/{chunk-PHVVVOW7.js → chunk-QWOJO32H.js} +3 -3
- package/dist/{chunk-PHVVVOW7.js.map → chunk-QWOJO32H.js.map} +1 -1
- package/dist/{chunk-RV5DTGYT.js → chunk-RIWLXMMT.js} +3 -3
- package/dist/{chunk-RV5DTGYT.js.map → chunk-RIWLXMMT.js.map} +1 -1
- package/dist/{chunk-LCQILWQL.js → chunk-TNCD5VFX.js} +3 -3
- package/dist/{chunk-LCQILWQL.js.map → chunk-TNCD5VFX.js.map} +1 -1
- package/dist/{chunk-CPX7XP3O.js → chunk-XRN7DQGR.js} +11 -11
- package/dist/{chunk-CPX7XP3O.js.map → chunk-XRN7DQGR.js.map} +1 -1
- package/dist/{chunk-A5LF4VS4.js → chunk-Y44GPOBL.js} +41 -65
- package/dist/chunk-Y44GPOBL.js.map +1 -0
- package/dist/cli.d.ts +5 -1
- package/dist/cli.js +467 -86
- package/dist/cli.js.map +1 -1
- package/dist/ensure-map-C3NEC2GI.js +28 -0
- package/dist/ensure-map-C3NEC2GI.js.map +1 -0
- package/dist/fs-NTQUFCXV.js +4 -0
- package/dist/fs-NTQUFCXV.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/{interactive-MR7DTVYS.js → interactive-2TAYVEHE.js} +19 -16
- package/dist/interactive-2TAYVEHE.js.map +1 -0
- package/dist/load-A5BGEQWP.js +10 -0
- package/dist/{load-RFQFTTIT.js.map → load-A5BGEQWP.js.map} +1 -1
- package/dist/{run-outcome-EKB6YQIK.js → run-outcome-OSIVMVT7.js} +5 -5
- package/dist/{run-outcome-EKB6YQIK.js.map → run-outcome-OSIVMVT7.js.map} +1 -1
- package/dist/{runtime-session-23RZLEA4.js → runtime-session-UPTC3E6N.js} +7 -7
- package/dist/{runtime-session-23RZLEA4.js.map → runtime-session-UPTC3E6N.js.map} +1 -1
- package/dist/{stream-json-3YOPU3LF.js → stream-json-CFKBL3MR.js} +4 -4
- package/dist/{stream-json-3YOPU3LF.js.map → stream-json-CFKBL3MR.js.map} +1 -1
- package/dist/{vg-mcp-bridge-UZFHPP2Q.js → vg-mcp-bridge-JHRKJBVT.js} +6 -6
- package/dist/{vg-mcp-bridge-UZFHPP2Q.js.map → vg-mcp-bridge-JHRKJBVT.js.map} +1 -1
- package/dist/{vgd-VIPBL7W4.js → vgd-HNPOSXKZ.js} +6 -6
- package/dist/vgd-HNPOSXKZ.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-536TQZIB.js +0 -9
- package/dist/chunk-A5LF4VS4.js.map +0 -1
- package/dist/chunk-BZPZ3OM6.js +0 -6
- package/dist/chunk-IDAQV3NQ.js.map +0 -1
- package/dist/chunk-UPH2RJ7L.js.map +0 -1
- package/dist/chunk-ZW5W627G.js.map +0 -1
- package/dist/fs-HNR6LAI7.js +0 -4
- package/dist/fs-HNR6LAI7.js.map +0 -1
- package/dist/interactive-MR7DTVYS.js.map +0 -1
- package/dist/load-RFQFTTIT.js +0 -10
- package/dist/vgd-VIPBL7W4.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-FF5ZQ6KI.js';
|
|
3
|
+
import { fetchCatalog, resolveProviders } from './chunk-4TC6RJ7U.js';
|
|
4
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-EX2SH5CT.js';
|
|
5
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-TNCD5VFX.js';
|
|
6
6
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
7
7
|
import { runCodeSession } from './chunk-WBMMRERH.js';
|
|
8
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-5J45MN3K.js';
|
|
9
|
+
export { runBuild } from './chunk-5J45MN3K.js';
|
|
8
10
|
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
9
|
-
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-NSK25UT2.js';
|
|
10
11
|
import './chunk-5I4VSBWQ.js';
|
|
11
12
|
import './chunk-IS7VTH2Q.js';
|
|
12
13
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
|
|
@@ -15,7 +16,7 @@ import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
|
15
16
|
import './chunk-IZDH67DX.js';
|
|
16
17
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-EVLS2M5G.js';
|
|
17
18
|
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-X634FZVG.js';
|
|
18
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-
|
|
19
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-Q7HUXIUF.js';
|
|
19
20
|
import './chunk-543E6WDJ.js';
|
|
20
21
|
import { summarizeDiffs, ScriptedProvider } from './chunk-MYM5VIJ4.js';
|
|
21
22
|
import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
|
|
@@ -23,15 +24,16 @@ import './chunk-RGEVBSLK.js';
|
|
|
23
24
|
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
|
|
24
25
|
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
25
26
|
import './chunk-7AVYKZEM.js';
|
|
26
|
-
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
27
|
+
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-LZX5NH4V.js';
|
|
28
|
+
import { refreshIfStale } from './chunk-L6BRBFBP.js';
|
|
29
|
+
import { CliError, ExitCode, driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, isSkippedDirName, SKIP_FILES, SKIP_DIRS } from './chunk-Y44GPOBL.js';
|
|
30
|
+
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-RIWLXMMT.js';
|
|
31
|
+
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-XRN7DQGR.js';
|
|
29
32
|
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, perDependencyDrift } from './chunk-CPX7XP3O.js';
|
|
31
33
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
34
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-US2DAKCM.js';
|
|
32
35
|
import './chunk-IPICO2RV.js';
|
|
33
36
|
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-FHJBGPJZ.js';
|
|
34
|
-
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-US2DAKCM.js';
|
|
35
37
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
|
|
36
38
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
37
39
|
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-EETK7S43.js';
|
|
@@ -39,14 +41,14 @@ import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
|
39
41
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
40
42
|
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
|
|
41
43
|
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-
|
|
44
|
+
import { loadGraph, SCHEMA_VERSION } from './chunk-IZNOMGR6.js';
|
|
45
|
+
import { resolveGraphPath, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-QWOJO32H.js';
|
|
46
|
+
import { VERSION } from './chunk-NNB2H4BA.js';
|
|
45
47
|
import { cacheDir, serializeGraph, stableStringify } from './chunk-ZKNB4YH4.js';
|
|
46
48
|
import './chunk-BWPBB45M.js';
|
|
47
49
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
48
50
|
import './chunk-BPF3YX2U.js';
|
|
49
|
-
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-
|
|
51
|
+
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-DT4KIVRI.js';
|
|
50
52
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
51
53
|
import * as fs7 from 'fs';
|
|
52
54
|
import fs7__default, { realpathSync } from 'fs';
|
|
@@ -1707,7 +1709,7 @@ function manifestHash(root2) {
|
|
|
1707
1709
|
for (const entry of entries) {
|
|
1708
1710
|
const abs = path37.join(dir, entry.name);
|
|
1709
1711
|
if (entry.isDirectory()) {
|
|
1710
|
-
if (
|
|
1712
|
+
if (isSkippedDirName(entry.name)) continue;
|
|
1711
1713
|
walk2(abs);
|
|
1712
1714
|
continue;
|
|
1713
1715
|
}
|
|
@@ -1729,7 +1731,7 @@ function isDependencyFile(root2, filePath) {
|
|
|
1729
1731
|
const rel = path37.relative(path37.resolve(root2), path37.resolve(filePath));
|
|
1730
1732
|
if (rel === "" || rel.startsWith("..") || path37.isAbsolute(rel)) return false;
|
|
1731
1733
|
const parts = rel.split(path37.sep);
|
|
1732
|
-
if (parts.slice(0, -1).some((dir) =>
|
|
1734
|
+
if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
|
|
1733
1735
|
const base = parts[parts.length - 1].toLowerCase();
|
|
1734
1736
|
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
1735
1737
|
}
|
|
@@ -2009,6 +2011,30 @@ function runTree(graph, params) {
|
|
|
2009
2011
|
}
|
|
2010
2012
|
|
|
2011
2013
|
// src/lsp/enrich.ts
|
|
2014
|
+
var REACH_RANK = {
|
|
2015
|
+
reached: 3,
|
|
2016
|
+
potentially_reachable: 2,
|
|
2017
|
+
unknown: 1,
|
|
2018
|
+
"not-observed": 0
|
|
2019
|
+
};
|
|
2020
|
+
function mergeReachability(a, b) {
|
|
2021
|
+
const left = a ?? "unknown";
|
|
2022
|
+
const right = b ?? "unknown";
|
|
2023
|
+
return REACH_RANK[right] > REACH_RANK[left] ? right : left;
|
|
2024
|
+
}
|
|
2025
|
+
function mergeReachSites(a, b) {
|
|
2026
|
+
const out2 = [];
|
|
2027
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2028
|
+
for (const site of [...a ?? [], ...b ?? []]) {
|
|
2029
|
+
if (!site?.file) continue;
|
|
2030
|
+
const k = `${site.file}::${site.line ?? ""}::${site.symbol ?? ""}`;
|
|
2031
|
+
if (seen.has(k)) continue;
|
|
2032
|
+
seen.add(k);
|
|
2033
|
+
out2.push(site);
|
|
2034
|
+
if (out2.length >= 10) break;
|
|
2035
|
+
}
|
|
2036
|
+
return out2;
|
|
2037
|
+
}
|
|
2012
2038
|
var OSV_QUERY_URL = "https://api.osv.dev/v1/query";
|
|
2013
2039
|
var KEV_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json";
|
|
2014
2040
|
var cache = /* @__PURE__ */ new Map();
|
|
@@ -2171,10 +2197,11 @@ async function scanWorkspaceVulns(targets, opts = { offline: false }) {
|
|
|
2171
2197
|
existing.locations.push(loc);
|
|
2172
2198
|
}
|
|
2173
2199
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
existing.
|
|
2200
|
+
existing.reachability = mergeReachability(existing.reachability, t.reachability);
|
|
2201
|
+
if (t.reachSites?.length) {
|
|
2202
|
+
existing.reachSites = mergeReachSites(existing.reachSites, t.reachSites);
|
|
2177
2203
|
}
|
|
2204
|
+
if (!existing.reachEvidence && t.reachEvidence) existing.reachEvidence = t.reachEvidence;
|
|
2178
2205
|
if (!existing.latestStable && t.latestStable) existing.latestStable = t.latestStable;
|
|
2179
2206
|
if (!existing.section && t.section) existing.section = t.section;
|
|
2180
2207
|
}
|
|
@@ -2195,10 +2222,14 @@ async function scanWorkspaceVulns(targets, opts = { offline: false }) {
|
|
|
2195
2222
|
else if (r.source === "error") anyError = true;
|
|
2196
2223
|
const locations = t.locations.length ? t.locations : t.file ? [{ file: t.file, line: t.line ?? null }] : [];
|
|
2197
2224
|
const seenIds = /* @__PURE__ */ new Set();
|
|
2225
|
+
const seenCves = /* @__PURE__ */ new Set();
|
|
2198
2226
|
for (const v of r.vulns) {
|
|
2199
2227
|
if (seenIds.has(v.id)) continue;
|
|
2228
|
+
const cveKeys = (v.cves ?? []).map((c2) => c2.toUpperCase()).filter(Boolean);
|
|
2229
|
+
if (cveKeys.length && cveKeys.every((c2) => seenCves.has(c2))) continue;
|
|
2200
2230
|
seenIds.add(v.id);
|
|
2201
|
-
const
|
|
2231
|
+
for (const c2 of cveKeys) seenCves.add(c2);
|
|
2232
|
+
const kevHit = cveKeys.some((c2) => kev.cves.has(c2));
|
|
2202
2233
|
findings.push({
|
|
2203
2234
|
package: t.package,
|
|
2204
2235
|
version: t.version,
|
|
@@ -2211,6 +2242,8 @@ async function scanWorkspaceVulns(targets, opts = { offline: false }) {
|
|
|
2211
2242
|
published: v.published,
|
|
2212
2243
|
kev: kevHit,
|
|
2213
2244
|
reachability: t.reachability ?? "unknown",
|
|
2245
|
+
reachSites: t.reachSites ?? [],
|
|
2246
|
+
reachEvidence: t.reachEvidence ?? null,
|
|
2214
2247
|
file: locations[0]?.file ?? t.file ?? null,
|
|
2215
2248
|
line: locations[0]?.line ?? t.line ?? null,
|
|
2216
2249
|
locations,
|
|
@@ -2335,6 +2368,7 @@ var VibgrateLanguageServer = class {
|
|
|
2335
2368
|
this.conn.onRequest("vibgrate/graph/query", (_m, params) => this.onGraphQuery(params));
|
|
2336
2369
|
this.conn.onRequest("vibgrate/score/forFile", (_m, params) => this.onScoreForFile(params));
|
|
2337
2370
|
this.conn.onRequest("vibgrate/score/forProject", (_m, params) => this.onScoreForProject(params));
|
|
2371
|
+
this.conn.onRequest("vibgrate/architecture", (_m, params) => this.onArchitecture(params));
|
|
2338
2372
|
this.conn.onRequest("vibgrate/score/history", (_m, params) => {
|
|
2339
2373
|
const p = params;
|
|
2340
2374
|
const days = typeof p?.days === "number" && p.days > 0 && p.days <= 365 ? p.days : 90;
|
|
@@ -2454,9 +2488,9 @@ var VibgrateLanguageServer = class {
|
|
|
2454
2488
|
rootPath: a.rootPath,
|
|
2455
2489
|
scannedAt: a.timestamp,
|
|
2456
2490
|
...delta !== void 0 ? { delta } : {},
|
|
2457
|
-
...buildBreakdown(
|
|
2491
|
+
...buildBreakdown(this.opts.root, a.projects ?? []) ? { breakdown: buildBreakdown(this.opts.root, a.projects ?? []) } : {},
|
|
2458
2492
|
...buildEolHorizon(a.projects ?? []) ? { eolHorizon: buildEolHorizon(a.projects ?? []) } : {},
|
|
2459
|
-
...buildProjectRefs(a.projects ?? []) ? { projects: buildProjectRefs(a.projects ?? []) } : {}
|
|
2493
|
+
...buildProjectRefs(this.opts.root, a.projects ?? []) ? { projects: buildProjectRefs(this.opts.root, a.projects ?? []) } : {}
|
|
2460
2494
|
};
|
|
2461
2495
|
this.conn.notify("vibgrate/score", payload);
|
|
2462
2496
|
}
|
|
@@ -2639,7 +2673,7 @@ var VibgrateLanguageServer = class {
|
|
|
2639
2673
|
kevSource: "skipped"
|
|
2640
2674
|
};
|
|
2641
2675
|
}
|
|
2642
|
-
const
|
|
2676
|
+
const importMap = packageImportMap(this.graph);
|
|
2643
2677
|
const targets = [];
|
|
2644
2678
|
for (const proj of a.projects ?? []) {
|
|
2645
2679
|
if (isPrunedWorkspacePath(proj.path) || isPrunedWorkspacePath(manifestRelativePath(proj))) {
|
|
@@ -2664,8 +2698,22 @@ var VibgrateLanguageServer = class {
|
|
|
2664
2698
|
if (l >= 0) line = l + 1;
|
|
2665
2699
|
}
|
|
2666
2700
|
let reachability = "unknown";
|
|
2667
|
-
|
|
2668
|
-
|
|
2701
|
+
let reachSites = [];
|
|
2702
|
+
let reachEvidence = null;
|
|
2703
|
+
if (importMap) {
|
|
2704
|
+
const files = lookupImportFiles(importMap, dep.package);
|
|
2705
|
+
if (files.length > 0) {
|
|
2706
|
+
reachability = "reached";
|
|
2707
|
+
reachSites = files.slice(0, 10).map((file) => ({
|
|
2708
|
+
file,
|
|
2709
|
+
// Best-effort first line that mentions the package name (import site).
|
|
2710
|
+
line: firstPackageMentionLine(this.opts.root, file, dep.package)
|
|
2711
|
+
}));
|
|
2712
|
+
reachEvidence = `${dep.package} is imported by ${files.length} file${files.length === 1 ? "" : "s"} in the code map`;
|
|
2713
|
+
} else {
|
|
2714
|
+
reachability = "not-observed";
|
|
2715
|
+
reachEvidence = `no import of ${dep.package} was found in the code map`;
|
|
2716
|
+
}
|
|
2669
2717
|
}
|
|
2670
2718
|
targets.push({
|
|
2671
2719
|
ecosystem,
|
|
@@ -2675,7 +2723,9 @@ var VibgrateLanguageServer = class {
|
|
|
2675
2723
|
line,
|
|
2676
2724
|
section: dep.section ?? null,
|
|
2677
2725
|
latestStable: dep.latestStable ?? null,
|
|
2678
|
-
reachability
|
|
2726
|
+
reachability,
|
|
2727
|
+
reachSites,
|
|
2728
|
+
reachEvidence
|
|
2679
2729
|
});
|
|
2680
2730
|
}
|
|
2681
2731
|
}
|
|
@@ -2686,7 +2736,7 @@ var VibgrateLanguageServer = class {
|
|
|
2686
2736
|
const a = this.artifact;
|
|
2687
2737
|
if (!a || !p.uri) return null;
|
|
2688
2738
|
const project = projectForFile(this.opts.root, a, uriToPath(p.uri));
|
|
2689
|
-
return project ? scoreForProject(a, project) : null;
|
|
2739
|
+
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
2690
2740
|
}
|
|
2691
2741
|
/**
|
|
2692
2742
|
* `vibgrate/score/forProject` — monorepo scope picker. Returns the same
|
|
@@ -2697,7 +2747,42 @@ var VibgrateLanguageServer = class {
|
|
|
2697
2747
|
const a = this.artifact;
|
|
2698
2748
|
if (!a || typeof p.path !== "string") return null;
|
|
2699
2749
|
const project = projectByPath(a, p.path);
|
|
2700
|
-
return project ? scoreForProject(a, project) : null;
|
|
2750
|
+
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
2751
|
+
}
|
|
2752
|
+
/**
|
|
2753
|
+
* `vibgrate/architecture` — the Architecture panel. `path` absent or
|
|
2754
|
+
* `'__repo__'` returns the whole-workspace aggregate (`extended.architecture`);
|
|
2755
|
+
* a project path returns that project's own detection (`ProjectScan.architecture`).
|
|
2756
|
+
* Returns `null` when the scanner hasn't produced architecture data yet (still
|
|
2757
|
+
* scanning, or the archetype/layer scanner is disabled) rather than an empty
|
|
2758
|
+
* shape a client might mistake for "no layers detected".
|
|
2759
|
+
*/
|
|
2760
|
+
onArchitecture(params) {
|
|
2761
|
+
const p = params;
|
|
2762
|
+
const a = this.artifact;
|
|
2763
|
+
if (!a) return null;
|
|
2764
|
+
if (!p?.path || p.path === "__repo__") {
|
|
2765
|
+
const arch = a.extended?.architecture;
|
|
2766
|
+
if (!arch) return null;
|
|
2767
|
+
return {
|
|
2768
|
+
archetype: arch.archetype,
|
|
2769
|
+
archetypeConfidence: arch.archetypeConfidence,
|
|
2770
|
+
layers: arch.layers,
|
|
2771
|
+
totalClassified: arch.totalClassified,
|
|
2772
|
+
unclassified: arch.unclassified
|
|
2773
|
+
};
|
|
2774
|
+
}
|
|
2775
|
+
const project = projectByPath(a, p.path);
|
|
2776
|
+
if (!project?.architecture) return null;
|
|
2777
|
+
return {
|
|
2778
|
+
archetype: project.architecture.archetype,
|
|
2779
|
+
archetypeConfidence: project.architecture.archetypeConfidence,
|
|
2780
|
+
layers: project.architecture.layers,
|
|
2781
|
+
totalClassified: project.architecture.totalClassified,
|
|
2782
|
+
unclassified: project.architecture.unclassified,
|
|
2783
|
+
manifestPath: manifestRelativePath(project),
|
|
2784
|
+
lockfilePath: lockfileRelativePath(this.opts.root, project)
|
|
2785
|
+
};
|
|
2701
2786
|
}
|
|
2702
2787
|
};
|
|
2703
2788
|
function uriToPath(uri) {
|
|
@@ -2711,7 +2796,11 @@ function isPrunedWorkspacePath(relPath) {
|
|
|
2711
2796
|
if (!relPath || relPath === "." || relPath === "") return false;
|
|
2712
2797
|
const parts = relPath.split(/[/\\]/).filter(Boolean);
|
|
2713
2798
|
if (parts.includes(".claude")) return true;
|
|
2714
|
-
return parts.some((p) =>
|
|
2799
|
+
return parts.some((p) => {
|
|
2800
|
+
if (SKIP_DIRS.has(p)) return true;
|
|
2801
|
+
if (p.startsWith(".venv") || p.startsWith("venv-") || p === "site-packages") return true;
|
|
2802
|
+
return false;
|
|
2803
|
+
});
|
|
2715
2804
|
}
|
|
2716
2805
|
function pruneArtifactProjects(a) {
|
|
2717
2806
|
const projects = (a.projects ?? []).filter(
|
|
@@ -2733,14 +2822,83 @@ function projectByPath(a, projectPath) {
|
|
|
2733
2822
|
}
|
|
2734
2823
|
return void 0;
|
|
2735
2824
|
}
|
|
2736
|
-
function
|
|
2825
|
+
function projectHasLocalLockOrCsproj(rootDir, proj) {
|
|
2826
|
+
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
2827
|
+
const dirAbs = base ? path37.join(rootDir, base) : rootDir;
|
|
2828
|
+
const lockNames = (() => {
|
|
2829
|
+
switch (proj.type) {
|
|
2830
|
+
case "node":
|
|
2831
|
+
case "typescript":
|
|
2832
|
+
return ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "bun.lockb", "bun.lock"];
|
|
2833
|
+
case "python":
|
|
2834
|
+
return ["poetry.lock", "uv.lock", "Pipfile.lock"];
|
|
2835
|
+
case "go":
|
|
2836
|
+
return ["go.sum"];
|
|
2837
|
+
case "rust":
|
|
2838
|
+
return ["Cargo.lock"];
|
|
2839
|
+
case "ruby":
|
|
2840
|
+
return ["Gemfile.lock"];
|
|
2841
|
+
case "php":
|
|
2842
|
+
return ["composer.lock"];
|
|
2843
|
+
case "dotnet":
|
|
2844
|
+
return ["packages.lock.json"];
|
|
2845
|
+
case "dart":
|
|
2846
|
+
return ["pubspec.lock"];
|
|
2847
|
+
case "java":
|
|
2848
|
+
case "kotlin":
|
|
2849
|
+
case "scala":
|
|
2850
|
+
case "groovy":
|
|
2851
|
+
return ["gradle.lockfile"];
|
|
2852
|
+
default:
|
|
2853
|
+
return [
|
|
2854
|
+
"pnpm-lock.yaml",
|
|
2855
|
+
"yarn.lock",
|
|
2856
|
+
"package-lock.json",
|
|
2857
|
+
"bun.lockb",
|
|
2858
|
+
"poetry.lock",
|
|
2859
|
+
"uv.lock",
|
|
2860
|
+
"Cargo.lock",
|
|
2861
|
+
"go.sum",
|
|
2862
|
+
"Gemfile.lock",
|
|
2863
|
+
"composer.lock",
|
|
2864
|
+
"packages.lock.json",
|
|
2865
|
+
"pubspec.lock"
|
|
2866
|
+
];
|
|
2867
|
+
}
|
|
2868
|
+
})();
|
|
2869
|
+
for (const name of lockNames) {
|
|
2870
|
+
try {
|
|
2871
|
+
if (fs7.existsSync(path37.join(dirAbs, name))) return true;
|
|
2872
|
+
} catch {
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
try {
|
|
2876
|
+
if (fs7.existsSync(dirAbs)) {
|
|
2877
|
+
const entries = fs7.readdirSync(dirAbs);
|
|
2878
|
+
if (entries.some((e) => /\.(csproj|fsproj|vbproj)$/i.test(e))) return true;
|
|
2879
|
+
}
|
|
2880
|
+
} catch {
|
|
2881
|
+
}
|
|
2882
|
+
const manifest = manifestRelativePath(proj);
|
|
2883
|
+
if (/\.(csproj|fsproj|vbproj)$/i.test(manifest)) {
|
|
2884
|
+
try {
|
|
2885
|
+
if (fs7.existsSync(path37.join(rootDir, manifest))) return true;
|
|
2886
|
+
} catch {
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
return false;
|
|
2890
|
+
}
|
|
2891
|
+
function buildProjectRefs(rootDir, projects) {
|
|
2737
2892
|
if (projects.length === 0) return void 0;
|
|
2738
|
-
|
|
2893
|
+
const refs = projects.filter((p) => projectHasLocalLockOrCsproj(rootDir, p)).map((p) => {
|
|
2739
2894
|
const rel = p.path === "" ? "." : p.path;
|
|
2740
|
-
const base = rel === "." ? "
|
|
2895
|
+
const base = rel === "." || rel === "" ? "root" : path37.basename(rel);
|
|
2896
|
+
const lockfilePath = lockfileRelativePath(rootDir, p);
|
|
2741
2897
|
return {
|
|
2742
2898
|
path: rel,
|
|
2743
|
-
name:
|
|
2899
|
+
name: base,
|
|
2900
|
+
manifestPath: manifestRelativePath(p),
|
|
2901
|
+
...lockfilePath ? { lockfilePath } : {},
|
|
2744
2902
|
...p.drift ? {
|
|
2745
2903
|
score: p.drift.score,
|
|
2746
2904
|
band: p.drift.riskLevel ?? "low",
|
|
@@ -2748,6 +2906,7 @@ function buildProjectRefs(projects) {
|
|
|
2748
2906
|
} : {}
|
|
2749
2907
|
};
|
|
2750
2908
|
}).sort((a, b) => a.path.localeCompare(b.path));
|
|
2909
|
+
return refs.length > 0 ? refs : void 0;
|
|
2751
2910
|
}
|
|
2752
2911
|
function projectForFile(root2, a, filePath) {
|
|
2753
2912
|
const dir = path37.dirname(path37.resolve(filePath));
|
|
@@ -2773,7 +2932,7 @@ function hasReleaseDates(a) {
|
|
|
2773
2932
|
}
|
|
2774
2933
|
return false;
|
|
2775
2934
|
}
|
|
2776
|
-
function scoreForProject(a, proj) {
|
|
2935
|
+
function scoreForProject(rootDir, a, proj) {
|
|
2777
2936
|
if (!proj.drift) return null;
|
|
2778
2937
|
let behind = 0;
|
|
2779
2938
|
let total = 0;
|
|
@@ -2796,9 +2955,9 @@ function scoreForProject(a, proj) {
|
|
|
2796
2955
|
counts: { behind, eol, unmaintained, total },
|
|
2797
2956
|
rootPath: proj.path === "" ? "." : proj.path,
|
|
2798
2957
|
scannedAt: a.timestamp,
|
|
2799
|
-
...buildBreakdown(
|
|
2958
|
+
...buildBreakdown(rootDir, [proj]) ? { breakdown: buildBreakdown(rootDir, [proj]) } : {},
|
|
2800
2959
|
...buildEolHorizon([proj]) ? { eolHorizon: buildEolHorizon([proj]) } : {},
|
|
2801
|
-
...buildProjectRefs(a.projects ?? []) ? { projects: buildProjectRefs(a.projects ?? []) } : {}
|
|
2960
|
+
...buildProjectRefs(rootDir, a.projects ?? []) ? { projects: buildProjectRefs(rootDir, a.projects ?? []) } : {}
|
|
2802
2961
|
};
|
|
2803
2962
|
}
|
|
2804
2963
|
function runtimeHorizonLabel(project) {
|
|
@@ -2827,17 +2986,52 @@ function bandForScore(n) {
|
|
|
2827
2986
|
if (n <= 60) return "moderate";
|
|
2828
2987
|
return "high";
|
|
2829
2988
|
}
|
|
2830
|
-
function buildBreakdown(
|
|
2989
|
+
function buildBreakdown(rootDir, projects) {
|
|
2831
2990
|
const byPkg = /* @__PURE__ */ new Map();
|
|
2832
2991
|
for (const p of projects) {
|
|
2992
|
+
const relManifest = manifestRelativePath(p);
|
|
2993
|
+
if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
|
|
2833
2994
|
const ecosystem = osvEcosystem(p.type);
|
|
2995
|
+
const absManifest = path37.resolve(rootDir, relManifest);
|
|
2996
|
+
let text = null;
|
|
2997
|
+
try {
|
|
2998
|
+
if (fs7.existsSync(absManifest)) text = fs7.readFileSync(absManifest, "utf8");
|
|
2999
|
+
} catch {
|
|
3000
|
+
text = null;
|
|
3001
|
+
}
|
|
3002
|
+
const kind = manifestKind(absManifest);
|
|
2834
3003
|
for (const d of p.dependencies ?? []) {
|
|
2835
|
-
|
|
3004
|
+
let line = null;
|
|
3005
|
+
if (text && kind !== "unknown") {
|
|
3006
|
+
const l = findPackageLine(text, d.package, kind);
|
|
3007
|
+
if (l >= 0) line = l + 1;
|
|
3008
|
+
}
|
|
3009
|
+
const loc = { file: relManifest, line };
|
|
3010
|
+
const existing = byPkg.get(d.package);
|
|
3011
|
+
if (!existing) {
|
|
3012
|
+
byPkg.set(d.package, { row: d, ecosystem, locations: [loc] });
|
|
3013
|
+
continue;
|
|
3014
|
+
}
|
|
3015
|
+
if (!existing.locations.some((x) => x.file === loc.file && x.line === loc.line)) {
|
|
3016
|
+
existing.locations.push(loc);
|
|
3017
|
+
}
|
|
3018
|
+
const prev = perDependencyDrift(existing.row, {
|
|
3019
|
+
unsupported: existing.row.unsupported === true,
|
|
3020
|
+
abandoned: existing.row.abandoned === true
|
|
3021
|
+
});
|
|
3022
|
+
const next2 = perDependencyDrift(d, {
|
|
3023
|
+
unsupported: d.unsupported === true,
|
|
3024
|
+
abandoned: d.abandoned === true
|
|
3025
|
+
});
|
|
3026
|
+
if (!next2.excluded && (prev.excluded || next2.drift > prev.drift)) {
|
|
3027
|
+
existing.row = d;
|
|
3028
|
+
if (ecosystem) existing.ecosystem = ecosystem;
|
|
3029
|
+
}
|
|
2836
3030
|
}
|
|
2837
3031
|
}
|
|
2838
3032
|
if (byPkg.size === 0) return void 0;
|
|
2839
3033
|
const items = [];
|
|
2840
|
-
for (const [, { row, ecosystem }] of byPkg) {
|
|
3034
|
+
for (const [, { row, ecosystem, locations }] of byPkg) {
|
|
2841
3035
|
const scored = perDependencyDrift(row, {
|
|
2842
3036
|
unsupported: row.unsupported === true,
|
|
2843
3037
|
abandoned: row.abandoned === true
|
|
@@ -2857,7 +3051,8 @@ function buildBreakdown(_drift, projects) {
|
|
|
2857
3051
|
mode: scored.mode,
|
|
2858
3052
|
unsupported: scored.unsupported || row.unsupported === true,
|
|
2859
3053
|
abandoned: scored.flags.includes("abandoned-floor") || row.abandoned === true,
|
|
2860
|
-
flags: scored.flags
|
|
3054
|
+
flags: scored.flags,
|
|
3055
|
+
locations
|
|
2861
3056
|
});
|
|
2862
3057
|
}
|
|
2863
3058
|
items.sort((a, b) => b.drift - a.drift || a.package.localeCompare(b.package));
|
|
@@ -2895,30 +3090,129 @@ function manifestRelativePath(proj) {
|
|
|
2895
3090
|
return join27("package.json");
|
|
2896
3091
|
}
|
|
2897
3092
|
}
|
|
2898
|
-
function
|
|
3093
|
+
function lockfileRelativePath(rootDir, proj) {
|
|
3094
|
+
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3095
|
+
const candidateNames = (() => {
|
|
3096
|
+
switch (proj.type) {
|
|
3097
|
+
case "node":
|
|
3098
|
+
case "typescript":
|
|
3099
|
+
return ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "bun.lockb"];
|
|
3100
|
+
case "python":
|
|
3101
|
+
return ["poetry.lock", "uv.lock", "Pipfile.lock"];
|
|
3102
|
+
case "go":
|
|
3103
|
+
return ["go.sum"];
|
|
3104
|
+
case "rust":
|
|
3105
|
+
return ["Cargo.lock"];
|
|
3106
|
+
case "ruby":
|
|
3107
|
+
return ["Gemfile.lock"];
|
|
3108
|
+
case "php":
|
|
3109
|
+
return ["composer.lock"];
|
|
3110
|
+
case "dotnet":
|
|
3111
|
+
return ["packages.lock.json"];
|
|
3112
|
+
case "dart":
|
|
3113
|
+
return ["pubspec.lock"];
|
|
3114
|
+
default:
|
|
3115
|
+
return [];
|
|
3116
|
+
}
|
|
3117
|
+
})();
|
|
3118
|
+
const dirsToTry = base ? [base, ""] : [""];
|
|
3119
|
+
for (const dir of dirsToTry) {
|
|
3120
|
+
for (const name of candidateNames) {
|
|
3121
|
+
const rel = dir ? path37.join(dir, name) : name;
|
|
3122
|
+
try {
|
|
3123
|
+
if (fs7.existsSync(path37.join(rootDir, rel))) return rel;
|
|
3124
|
+
} catch {
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
return void 0;
|
|
3129
|
+
}
|
|
3130
|
+
function packageImportMap(graph) {
|
|
2899
3131
|
if (!graph?.nodes?.length) return null;
|
|
2900
|
-
const
|
|
3132
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
3133
|
+
const map = /* @__PURE__ */ new Map();
|
|
3134
|
+
const addPkg = (raw, file) => {
|
|
3135
|
+
if (!file) return;
|
|
3136
|
+
const cleaned = raw.replace(/^node_modules\//, "").replace(/\\/g, "/");
|
|
3137
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3138
|
+
keys.add(cleaned.toLowerCase());
|
|
3139
|
+
if (cleaned.startsWith("@")) {
|
|
3140
|
+
const parts = cleaned.split("/");
|
|
3141
|
+
if (parts.length >= 2) keys.add(`${parts[0]}/${parts[1]}`.toLowerCase());
|
|
3142
|
+
} else {
|
|
3143
|
+
keys.add(cleaned.split("/")[0].toLowerCase());
|
|
3144
|
+
}
|
|
3145
|
+
for (const k of keys) {
|
|
3146
|
+
let set = map.get(k);
|
|
3147
|
+
if (!set) {
|
|
3148
|
+
set = /* @__PURE__ */ new Set();
|
|
3149
|
+
map.set(k, set);
|
|
3150
|
+
}
|
|
3151
|
+
set.add(file);
|
|
3152
|
+
}
|
|
3153
|
+
};
|
|
3154
|
+
for (const e of graph.edges ?? []) {
|
|
3155
|
+
if (e.kind !== "import") continue;
|
|
3156
|
+
const src = byId.get(e.src);
|
|
3157
|
+
const dst = byId.get(e.dst);
|
|
3158
|
+
if (!src?.file || !dst) continue;
|
|
3159
|
+
if (dst.kind !== "external" && dst.kind !== "package" && dst.kind !== "module") continue;
|
|
3160
|
+
for (const raw of [dst.name, dst.qualifiedName].filter(Boolean)) {
|
|
3161
|
+
addPkg(raw, src.file);
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
2901
3164
|
for (const n of graph.nodes) {
|
|
2902
3165
|
if (n.kind !== "external" && n.kind !== "package" && n.kind !== "module") continue;
|
|
2903
|
-
const
|
|
2904
|
-
|
|
2905
|
-
|
|
3166
|
+
for (const raw of [n.name, n.qualifiedName].filter(Boolean)) {
|
|
3167
|
+
const cleaned = raw.replace(/^node_modules\//, "").replace(/\\/g, "/").toLowerCase();
|
|
3168
|
+
if (!map.has(cleaned)) map.set(cleaned, /* @__PURE__ */ new Set());
|
|
2906
3169
|
if (cleaned.startsWith("@")) {
|
|
2907
3170
|
const parts = cleaned.split("/");
|
|
2908
|
-
if (parts.length >= 2
|
|
2909
|
-
|
|
2910
|
-
|
|
3171
|
+
if (parts.length >= 2 && !map.has(`${parts[0]}/${parts[1]}`)) {
|
|
3172
|
+
map.set(`${parts[0]}/${parts[1]}`, /* @__PURE__ */ new Set());
|
|
3173
|
+
}
|
|
2911
3174
|
}
|
|
2912
|
-
set.add(cleaned.toLowerCase());
|
|
2913
3175
|
}
|
|
2914
3176
|
}
|
|
2915
|
-
|
|
3177
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
3178
|
+
for (const [k, files] of map) {
|
|
3179
|
+
out2.set(k, [...files].sort());
|
|
3180
|
+
}
|
|
3181
|
+
return out2;
|
|
2916
3182
|
}
|
|
2917
|
-
function
|
|
3183
|
+
function lookupImportFiles(map, pkg) {
|
|
2918
3184
|
const p = pkg.toLowerCase();
|
|
2919
|
-
if (
|
|
2920
|
-
if (!p.startsWith("@")
|
|
2921
|
-
|
|
3185
|
+
if (map.has(p)) return map.get(p);
|
|
3186
|
+
if (!p.startsWith("@")) {
|
|
3187
|
+
const root2 = p.split("/")[0];
|
|
3188
|
+
if (map.has(root2)) return map.get(root2);
|
|
3189
|
+
}
|
|
3190
|
+
return [];
|
|
3191
|
+
}
|
|
3192
|
+
function firstPackageMentionLine(root2, relFile, pkg) {
|
|
3193
|
+
try {
|
|
3194
|
+
const abs = path37.resolve(root2, relFile);
|
|
3195
|
+
const stat2 = fs7.statSync(abs);
|
|
3196
|
+
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3197
|
+
const text = fs7.readFileSync(abs, "utf8");
|
|
3198
|
+
const tokens = [pkg];
|
|
3199
|
+
if (pkg.startsWith("@")) {
|
|
3200
|
+
const parts = pkg.split("/");
|
|
3201
|
+
if (parts[1]) tokens.push(parts[1]);
|
|
3202
|
+
} else if (pkg.includes("/")) {
|
|
3203
|
+
tokens.push(pkg.split("/")[0]);
|
|
3204
|
+
}
|
|
3205
|
+
const lines = text.split(/\r?\n/);
|
|
3206
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3207
|
+
const line = lines[i];
|
|
3208
|
+
if (!/import|require|from|use |include/.test(line) && !line.includes(pkg)) continue;
|
|
3209
|
+
for (const t of tokens) {
|
|
3210
|
+
if (t && line.includes(t)) return i + 1;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
} catch {
|
|
3214
|
+
}
|
|
3215
|
+
return null;
|
|
2922
3216
|
}
|
|
2923
3217
|
function osvEcosystem(type) {
|
|
2924
3218
|
switch (type) {
|
|
@@ -3044,7 +3338,7 @@ function hoverMarkdown(dep, contribution) {
|
|
|
3044
3338
|
majorsBehind: dep.majorsBehind ?? 0
|
|
3045
3339
|
});
|
|
3046
3340
|
const explainUri = commandUri("vibgrate.explain", { package: dep.package });
|
|
3047
|
-
lines.push(`[
|
|
3341
|
+
lines.push(`[Fix \u2192](${routeFixUri}) \xB7 [Explain this drift](${explainUri})`);
|
|
3048
3342
|
}
|
|
3049
3343
|
lines.push("");
|
|
3050
3344
|
lines.push("---");
|
|
@@ -3117,12 +3411,24 @@ function registerInstall(program) {
|
|
|
3117
3411
|
return;
|
|
3118
3412
|
}
|
|
3119
3413
|
if (global.json) {
|
|
3120
|
-
json(
|
|
3414
|
+
json(
|
|
3415
|
+
ASSISTANTS.map((a) => ({
|
|
3416
|
+
id: a.id,
|
|
3417
|
+
label: a.label,
|
|
3418
|
+
mcp: !!a.mcp,
|
|
3419
|
+
skill: !!a.skill,
|
|
3420
|
+
nudge: !!a.nudge,
|
|
3421
|
+
installed: isAssistantInstalled(a, root2)
|
|
3422
|
+
}))
|
|
3423
|
+
);
|
|
3121
3424
|
} else {
|
|
3122
3425
|
info(`${c.cyan("vg install")} \xB7 supported assistants`);
|
|
3123
3426
|
const pad4 = Math.max(...ASSISTANTS.map((a) => a.id.length)) + 2;
|
|
3124
3427
|
for (const a of ASSISTANTS) {
|
|
3125
|
-
|
|
3428
|
+
const on = isAssistantInstalled(a, root2) ? c.green("on") : c.dim("off");
|
|
3429
|
+
info(
|
|
3430
|
+
` ${c.bold(a.id.padEnd(pad4))} ${a.label} ${on} ${c.dim(`mcp:${a.mcp ? "\u2713" : "\u2014"} skill:${a.skill ? "\u2713" : "\u2014"} nudge:${a.nudge ? "\u2713" : "\u2014"}`)}`
|
|
3431
|
+
);
|
|
3126
3432
|
}
|
|
3127
3433
|
}
|
|
3128
3434
|
return;
|
|
@@ -6108,7 +6414,7 @@ function registerCode(program) {
|
|
|
6108
6414
|
try {
|
|
6109
6415
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6110
6416
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6111
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6417
|
+
const { loadGraph: loadGraph2 } = await import('./load-A5BGEQWP.js');
|
|
6112
6418
|
const state = readOrchestratorState2();
|
|
6113
6419
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6114
6420
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -6192,7 +6498,7 @@ function registerCode(program) {
|
|
|
6192
6498
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
6193
6499
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
6194
6500
|
}
|
|
6195
|
-
const { runInteractive } = await import('./interactive-
|
|
6501
|
+
const { runInteractive } = await import('./interactive-2TAYVEHE.js');
|
|
6196
6502
|
await runInteractive(
|
|
6197
6503
|
rootOf(global),
|
|
6198
6504
|
global,
|
|
@@ -6221,6 +6527,40 @@ function registerCode(program) {
|
|
|
6221
6527
|
return;
|
|
6222
6528
|
}
|
|
6223
6529
|
if (!instruction) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
6530
|
+
{
|
|
6531
|
+
const { ensureCodeMap } = await import('./ensure-map-C3NEC2GI.js');
|
|
6532
|
+
const mapRoot = rootOf(global);
|
|
6533
|
+
try {
|
|
6534
|
+
await ensureCodeMap(mapRoot, global, {
|
|
6535
|
+
onProgress: (p) => {
|
|
6536
|
+
if (opts.streamJson) {
|
|
6537
|
+
process.stdout.write(
|
|
6538
|
+
JSON.stringify({
|
|
6539
|
+
event: "event",
|
|
6540
|
+
type: "map_build",
|
|
6541
|
+
phase: p.phase,
|
|
6542
|
+
message: p.message,
|
|
6543
|
+
...p.pct != null ? { pct: p.pct } : {}
|
|
6544
|
+
}) + "\n"
|
|
6545
|
+
);
|
|
6546
|
+
return;
|
|
6547
|
+
}
|
|
6548
|
+
if (!global.json && !global.quiet && (p.phase === "start" || p.phase === "done")) {
|
|
6549
|
+
info(c.dim(`vg code \xB7 ${p.message}`));
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
});
|
|
6553
|
+
} catch (e) {
|
|
6554
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
6555
|
+
if (opts.streamJson) {
|
|
6556
|
+
process.stdout.write(
|
|
6557
|
+
JSON.stringify({ event: "error", message: `Could not build the code map: ${msg}` }) + "\n"
|
|
6558
|
+
);
|
|
6559
|
+
return;
|
|
6560
|
+
}
|
|
6561
|
+
throw e;
|
|
6562
|
+
}
|
|
6563
|
+
}
|
|
6224
6564
|
const { root: root2, graph } = requireGraph(global);
|
|
6225
6565
|
let mockReply;
|
|
6226
6566
|
if (opts.mock) {
|
|
@@ -6273,20 +6613,20 @@ function registerCode(program) {
|
|
|
6273
6613
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
6274
6614
|
};
|
|
6275
6615
|
try {
|
|
6276
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
6616
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-OSIVMVT7.js');
|
|
6277
6617
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
6278
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
6618
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-CFKBL3MR.js');
|
|
6279
6619
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
6280
6620
|
const readline5 = await import('readline');
|
|
6281
6621
|
const child = await import('child_process');
|
|
6282
6622
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
6283
6623
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6284
6624
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6285
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6625
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-UPTC3E6N.js');
|
|
6286
6626
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6287
6627
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6288
6628
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6289
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6629
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-HNPOSXKZ.js');
|
|
6290
6630
|
const federation = loadOrDiscoverFederation(root2);
|
|
6291
6631
|
const modelProfile = mergeModelExecutionProfile(
|
|
6292
6632
|
resolveModelExecutionProfile({
|
|
@@ -6344,7 +6684,7 @@ ${res.stderr}` : ""),
|
|
|
6344
6684
|
exitCode: res.status ?? 1
|
|
6345
6685
|
};
|
|
6346
6686
|
};
|
|
6347
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6687
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-JHRKJBVT.js');
|
|
6348
6688
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6349
6689
|
getGraph: () => graph,
|
|
6350
6690
|
root: root2,
|
|
@@ -6431,8 +6771,8 @@ ${res.stderr}` : ""),
|
|
|
6431
6771
|
};
|
|
6432
6772
|
try {
|
|
6433
6773
|
if (opts.session) {
|
|
6434
|
-
const { runCodeStreamJsonSession } = await import('./stream-json-
|
|
6435
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
6774
|
+
const { runCodeStreamJsonSession } = await import('./stream-json-CFKBL3MR.js');
|
|
6775
|
+
const { runAgent: runAgent2 } = await import('./agent-6PPW5GIV.js');
|
|
6436
6776
|
const {
|
|
6437
6777
|
loadLatestSession,
|
|
6438
6778
|
newSession,
|
|
@@ -6580,7 +6920,7 @@ ${res.stderr}` : ""),
|
|
|
6580
6920
|
if (!autonomous && !tty) {
|
|
6581
6921
|
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).");
|
|
6582
6922
|
}
|
|
6583
|
-
const { agentTask } = await import('./interactive-
|
|
6923
|
+
const { agentTask } = await import('./interactive-2TAYVEHE.js');
|
|
6584
6924
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
6585
6925
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
6586
6926
|
let priorSummary;
|
|
@@ -6590,7 +6930,7 @@ ${res.stderr}` : ""),
|
|
|
6590
6930
|
if (prev) priorSummary = summarizeSession(prev);
|
|
6591
6931
|
}
|
|
6592
6932
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
6593
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6933
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-JHRKJBVT.js');
|
|
6594
6934
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6595
6935
|
getGraph: () => graph,
|
|
6596
6936
|
root: root2,
|
|
@@ -6614,11 +6954,11 @@ ${res.stderr}` : ""),
|
|
|
6614
6954
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
6615
6955
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6616
6956
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6617
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6957
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-UPTC3E6N.js');
|
|
6618
6958
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6619
6959
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6620
6960
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6621
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6961
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-HNPOSXKZ.js');
|
|
6622
6962
|
const federation = loadFederation(root2);
|
|
6623
6963
|
const modelProfile = mergeModelExecutionProfile(
|
|
6624
6964
|
resolveModelExecutionProfile({
|
|
@@ -7508,7 +7848,7 @@ function registerDaemon(program) {
|
|
|
7508
7848
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
7509
7849
|
}
|
|
7510
7850
|
if (!loaded.ok) {
|
|
7511
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
7851
|
+
const { loadGraph: loadGraph2 } = await import('./load-A5BGEQWP.js');
|
|
7512
7852
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7513
7853
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7514
7854
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -7913,7 +8253,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
7913
8253
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
7914
8254
|
}
|
|
7915
8255
|
if (opts.baseline) {
|
|
7916
|
-
const { runBaseline } = await import('./baseline-
|
|
8256
|
+
const { runBaseline } = await import('./baseline-ZMHL6DXF.js');
|
|
7917
8257
|
await runBaseline(rootDir);
|
|
7918
8258
|
}
|
|
7919
8259
|
console.log("");
|
|
@@ -8015,11 +8355,42 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
8015
8355
|
importingFiles: [...files].sort()
|
|
8016
8356
|
};
|
|
8017
8357
|
}
|
|
8018
|
-
async function
|
|
8358
|
+
async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
|
|
8019
8359
|
const content = await readFile3(path37.join(rootDir, relFile));
|
|
8020
|
-
if (!content) return
|
|
8360
|
+
if (!content) return null;
|
|
8021
8361
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8022
|
-
|
|
8362
|
+
const re = new RegExp(`\\b${escaped}\\b`);
|
|
8363
|
+
const lines = content.split(/\r?\n/);
|
|
8364
|
+
for (let i = 0; i < lines.length; i++) {
|
|
8365
|
+
if (re.test(lines[i])) return i + 1;
|
|
8366
|
+
}
|
|
8367
|
+
return null;
|
|
8368
|
+
}
|
|
8369
|
+
function formatSitePath(site) {
|
|
8370
|
+
return site.line != null && site.line > 0 ? `${site.file}:${site.line}` : site.file;
|
|
8371
|
+
}
|
|
8372
|
+
function enclosingFunctionName(graph, relFile, line) {
|
|
8373
|
+
if (line == null || line < 1) return null;
|
|
8374
|
+
let best = null;
|
|
8375
|
+
let bestSpan = Number.POSITIVE_INFINITY;
|
|
8376
|
+
for (const node2 of graph.nodes) {
|
|
8377
|
+
if (node2.file !== relFile) continue;
|
|
8378
|
+
if (node2.kind !== "function" && node2.kind !== "method") continue;
|
|
8379
|
+
const start = node2.span?.start;
|
|
8380
|
+
const end = node2.span?.end;
|
|
8381
|
+
if (start == null || end == null) continue;
|
|
8382
|
+
if (line < start || line > end) continue;
|
|
8383
|
+
const span = end - start;
|
|
8384
|
+
if (span < bestSpan) {
|
|
8385
|
+
bestSpan = span;
|
|
8386
|
+
best = node2;
|
|
8387
|
+
}
|
|
8388
|
+
}
|
|
8389
|
+
return best?.name ?? null;
|
|
8390
|
+
}
|
|
8391
|
+
function sitesFromImportFiles(files, limit = 10) {
|
|
8392
|
+
const sites = files.slice(0, limit).map((file) => ({ file }));
|
|
8393
|
+
return { callPath: sites.map(formatSitePath), sites };
|
|
8023
8394
|
}
|
|
8024
8395
|
async function defaultReadFile(absPath) {
|
|
8025
8396
|
try {
|
|
@@ -8102,6 +8473,7 @@ async function analyzeReachability(input) {
|
|
|
8102
8473
|
}
|
|
8103
8474
|
const matchableSymbols = entry.symbols.map((s) => ({ symbol: s.symbol, identifier: symbolIdentifier(s.symbol) })).filter((s) => isMatchableIdentifier(s.identifier));
|
|
8104
8475
|
if (entry.symbolCoverage !== "function" || matchableSymbols.length === 0) {
|
|
8476
|
+
const { callPath, sites } = sitesFromImportFiles(evidence.importingFiles, 10);
|
|
8105
8477
|
findings.push({
|
|
8106
8478
|
advisoryId: entry.advisoryId,
|
|
8107
8479
|
ecosystem: entry.ecosystem,
|
|
@@ -8109,7 +8481,8 @@ async function analyzeReachability(input) {
|
|
|
8109
8481
|
version: entry.version,
|
|
8110
8482
|
tier: "potentially_reachable",
|
|
8111
8483
|
evidence: `${entry.package} is imported by ${evidence.importingFiles.length} file${evidence.importingFiles.length === 1 ? "" : "s"}; vulnerable symbols unresolved (coverage: ${entry.symbolCoverage})`,
|
|
8112
|
-
callPath
|
|
8484
|
+
callPath,
|
|
8485
|
+
sites,
|
|
8113
8486
|
graphConfidence: Math.min(baseConfidence, 0.6)
|
|
8114
8487
|
});
|
|
8115
8488
|
continue;
|
|
@@ -8117,14 +8490,19 @@ async function analyzeReachability(input) {
|
|
|
8117
8490
|
const filesToCheck = evidence.importingFiles.slice(0, MAX_FILES_PER_PACKAGE);
|
|
8118
8491
|
let anySymbolFound = false;
|
|
8119
8492
|
for (const { symbol, identifier } of matchableSymbols) {
|
|
8120
|
-
const
|
|
8493
|
+
const sites = [];
|
|
8121
8494
|
for (const relFile of filesToCheck) {
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8495
|
+
const line = await firstReferenceLine(input.rootDir, relFile, identifier, readFile3);
|
|
8496
|
+
if (line == null) continue;
|
|
8497
|
+
sites.push({
|
|
8498
|
+
file: relFile,
|
|
8499
|
+
line,
|
|
8500
|
+
symbol,
|
|
8501
|
+
function: enclosingFunctionName(input.graph, relFile, line)
|
|
8502
|
+
});
|
|
8503
|
+
if (sites.length >= 5) break;
|
|
8126
8504
|
}
|
|
8127
|
-
if (
|
|
8505
|
+
if (sites.length > 0) {
|
|
8128
8506
|
anySymbolFound = true;
|
|
8129
8507
|
findings.push({
|
|
8130
8508
|
advisoryId: entry.advisoryId,
|
|
@@ -8133,13 +8511,15 @@ async function analyzeReachability(input) {
|
|
|
8133
8511
|
version: entry.version,
|
|
8134
8512
|
symbol,
|
|
8135
8513
|
tier: "reachable",
|
|
8136
|
-
evidence: `vulnerable symbol \`${identifier}\` is referenced in ${
|
|
8137
|
-
callPath:
|
|
8514
|
+
evidence: `vulnerable symbol \`${identifier}\` is referenced in ${sites.length} importing file${sites.length === 1 ? "" : "s"}`,
|
|
8515
|
+
callPath: sites.map(formatSitePath),
|
|
8516
|
+
sites,
|
|
8138
8517
|
graphConfidence: Math.min(baseConfidence, 0.75)
|
|
8139
8518
|
});
|
|
8140
8519
|
}
|
|
8141
8520
|
}
|
|
8142
8521
|
if (!anySymbolFound) {
|
|
8522
|
+
const { callPath, sites } = sitesFromImportFiles(evidence.importingFiles, 10);
|
|
8143
8523
|
findings.push({
|
|
8144
8524
|
advisoryId: entry.advisoryId,
|
|
8145
8525
|
ecosystem: entry.ecosystem,
|
|
@@ -8147,7 +8527,8 @@ async function analyzeReachability(input) {
|
|
|
8147
8527
|
version: entry.version,
|
|
8148
8528
|
tier: "not_reached",
|
|
8149
8529
|
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`,
|
|
8150
|
-
callPath
|
|
8530
|
+
callPath,
|
|
8531
|
+
sites,
|
|
8151
8532
|
graphConfidence: Math.min(baseConfidence, 0.55)
|
|
8152
8533
|
});
|
|
8153
8534
|
}
|