@vibgrate/cli 2026.805.2 → 2026.806.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/DOCS.md +11 -5
- package/dist/{agent-PFYXJWWP.js → agent-DSC3EQLT.js} +11 -11
- package/dist/{agent-PFYXJWWP.js.map → agent-DSC3EQLT.js.map} +1 -1
- package/dist/{baseline-7C4F7PBS.js → baseline-KVCXVZFQ.js} +3 -3
- package/dist/{baseline-7C4F7PBS.js.map → baseline-KVCXVZFQ.js.map} +1 -1
- package/dist/{chunk-PPXAN2X5.js → chunk-455ZJQQ4.js} +5 -5
- package/dist/{chunk-PPXAN2X5.js.map → chunk-455ZJQQ4.js.map} +1 -1
- package/dist/{chunk-MDQO4ACI.js → chunk-6L6V77HW.js} +8 -8
- package/dist/{chunk-MDQO4ACI.js.map → chunk-6L6V77HW.js.map} +1 -1
- package/dist/{chunk-L5O6W5EB.js → chunk-6XKDAYYR.js} +4 -4
- package/dist/{chunk-L5O6W5EB.js.map → chunk-6XKDAYYR.js.map} +1 -1
- package/dist/{chunk-4IAKFZVG.js → chunk-7C5UKIXD.js} +4 -4
- package/dist/{chunk-4IAKFZVG.js.map → chunk-7C5UKIXD.js.map} +1 -1
- package/dist/{chunk-EEZ5HCL2.js → chunk-CBPDYYIH.js} +4 -4
- package/dist/{chunk-EEZ5HCL2.js.map → chunk-CBPDYYIH.js.map} +1 -1
- package/dist/{chunk-OAMAINC6.js → chunk-D2VEJHPC.js} +7 -7
- package/dist/{chunk-OAMAINC6.js.map → chunk-D2VEJHPC.js.map} +1 -1
- package/dist/{chunk-PZEJ4LHP.js → chunk-EW2ZMFUC.js} +4 -4
- package/dist/{chunk-PZEJ4LHP.js.map → chunk-EW2ZMFUC.js.map} +1 -1
- package/dist/{chunk-TFGUYBNC.js → chunk-HV4CKBXT.js} +3 -3
- package/dist/{chunk-TFGUYBNC.js.map → chunk-HV4CKBXT.js.map} +1 -1
- package/dist/{chunk-P64OTAUL.js → chunk-I2JNLAKW.js} +1295 -61
- package/dist/chunk-I2JNLAKW.js.map +1 -0
- package/dist/{chunk-ABJVJUKB.js → chunk-IQJUFRZZ.js} +35 -17
- package/dist/{chunk-ABJVJUKB.js.map → chunk-IQJUFRZZ.js.map} +1 -1
- package/dist/chunk-K6MLOGU4.js +6 -0
- package/dist/{chunk-54USY7IT.js.map → chunk-K6MLOGU4.js.map} +1 -1
- package/dist/{chunk-63QGVU4A.js → chunk-KAOSPAFK.js} +5 -5
- package/dist/{chunk-63QGVU4A.js.map → chunk-KAOSPAFK.js.map} +1 -1
- package/dist/{chunk-LEESW7CF.js → chunk-KYRH3567.js} +32 -12
- package/dist/chunk-KYRH3567.js.map +1 -0
- package/dist/{chunk-TPWMFEIA.js → chunk-QDKFGLI3.js} +6 -6
- package/dist/{chunk-TPWMFEIA.js.map → chunk-QDKFGLI3.js.map} +1 -1
- package/dist/{chunk-ZY6XAHLH.js → chunk-RL6MHAOK.js} +4 -4
- package/dist/{chunk-ZY6XAHLH.js.map → chunk-RL6MHAOK.js.map} +1 -1
- package/dist/{chunk-VETQRKXJ.js → chunk-SBVZGEOB.js} +3 -3
- package/dist/{chunk-VETQRKXJ.js.map → chunk-SBVZGEOB.js.map} +1 -1
- package/dist/{chunk-2U4SXS5U.js → chunk-SI4D7DYF.js} +13 -4
- package/dist/chunk-SI4D7DYF.js.map +1 -0
- package/dist/{chunk-TWSUMNKS.js → chunk-TOVVTZTM.js} +3 -3
- package/dist/{chunk-TWSUMNKS.js.map → chunk-TOVVTZTM.js.map} +1 -1
- package/dist/{chunk-3LDQD53S.js → chunk-VTJAPNJO.js} +4 -4
- package/dist/{chunk-3LDQD53S.js.map → chunk-VTJAPNJO.js.map} +1 -1
- package/dist/{chunk-ZXQP2GQE.js → chunk-ZMSTSEGR.js} +3 -3
- package/dist/{chunk-ZXQP2GQE.js.map → chunk-ZMSTSEGR.js.map} +1 -1
- package/dist/{chunk-TAV6XEFK.js → chunk-ZPPDKHGL.js} +65 -9
- package/dist/chunk-ZPPDKHGL.js.map +1 -0
- package/dist/cli.js +406 -244
- package/dist/cli.js.map +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/{ensure-map-7L3TPCGA.js → ensure-map-5E5TFPXJ.js} +12 -12
- package/dist/{ensure-map-7L3TPCGA.js.map → ensure-map-5E5TFPXJ.js.map} +1 -1
- package/dist/graph-backend-GQZXMNRI.js +13 -0
- package/dist/{graph-backend-5AMGXUDF.js.map → graph-backend-GQZXMNRI.js.map} +1 -1
- package/dist/index.d.ts +10 -3
- package/dist/index.js +11 -11
- package/dist/{interactive-5NXJTODL.js → interactive-7EZHEBHQ.js} +24 -22
- package/dist/interactive-7EZHEBHQ.js.map +1 -0
- package/dist/load-QBVKCWZT.js +9 -0
- package/dist/{load-B6KY2WPG.js.map → load-QBVKCWZT.js.map} +1 -1
- package/dist/{run-outcome-JO4IIEJJ.js → run-outcome-NQAU6DOA.js} +5 -5
- package/dist/{run-outcome-JO4IIEJJ.js.map → run-outcome-NQAU6DOA.js.map} +1 -1
- package/dist/runtime-session-ZPGU4PGW.js +20 -0
- package/dist/{runtime-session-LY3STY7C.js.map → runtime-session-ZPGU4PGW.js.map} +1 -1
- package/dist/session-QNSYTLLJ.js +15 -0
- package/dist/{session-KRLJTAK6.js.map → session-QNSYTLLJ.js.map} +1 -1
- package/dist/{stream-json-VP6TVWKF.js → stream-json-5WFD6HRO.js} +11 -11
- package/dist/{stream-json-VP6TVWKF.js.map → stream-json-5WFD6HRO.js.map} +1 -1
- package/dist/{vg-mcp-bridge-2CT67CXT.js → vg-mcp-bridge-VTGXA6CO.js} +8 -8
- package/dist/{vg-mcp-bridge-2CT67CXT.js.map → vg-mcp-bridge-VTGXA6CO.js.map} +1 -1
- package/dist/{vgd-BCBVZ2QA.js → vgd-54GEZWBI.js} +8 -8
- package/dist/vgd-54GEZWBI.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-2U4SXS5U.js.map +0 -1
- package/dist/chunk-54USY7IT.js +0 -6
- package/dist/chunk-LEESW7CF.js.map +0 -1
- package/dist/chunk-P64OTAUL.js.map +0 -1
- package/dist/chunk-TAV6XEFK.js.map +0 -1
- package/dist/graph-backend-5AMGXUDF.js +0 -13
- package/dist/interactive-5NXJTODL.js.map +0 -1
- package/dist/load-B6KY2WPG.js +0 -9
- package/dist/runtime-session-LY3STY7C.js +0 -20
- package/dist/session-KRLJTAK6.js +0 -15
- package/dist/vgd-BCBVZ2QA.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { loadAdvancedScanHook, baselineCommand } from './chunk-Y4JO6LYP.js';
|
|
3
|
-
import { fetchCatalog, resolveProviders } from './chunk-
|
|
4
|
-
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-
|
|
3
|
+
import { fetchCatalog, resolveProviders } from './chunk-IQJUFRZZ.js';
|
|
4
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-VTJAPNJO.js';
|
|
5
5
|
import './chunk-IS7VTH2Q.js';
|
|
6
|
-
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-
|
|
7
|
-
import {
|
|
6
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-6XKDAYYR.js';
|
|
7
|
+
import { runCodeSession } from './chunk-KAOSPAFK.js';
|
|
8
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-I2JNLAKW.js';
|
|
8
9
|
import './chunk-543E6WDJ.js';
|
|
10
|
+
import { summarizeDiffs, ScriptedProvider } from './chunk-SI4D7DYF.js';
|
|
9
11
|
import './chunk-7AVYKZEM.js';
|
|
10
12
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
11
|
-
import { runCodeSession } from './chunk-63QGVU4A.js';
|
|
12
|
-
import { summarizeDiffs, ScriptedProvider } from './chunk-2U4SXS5U.js';
|
|
13
13
|
import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
|
|
14
|
-
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-
|
|
15
|
-
export { runBuild } from './chunk-
|
|
14
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-D2VEJHPC.js';
|
|
15
|
+
export { runBuild } from './chunk-D2VEJHPC.js';
|
|
16
16
|
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
17
17
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
|
|
18
18
|
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
|
|
19
19
|
import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
20
20
|
import './chunk-IZDH67DX.js';
|
|
21
|
-
import './chunk-
|
|
21
|
+
import './chunk-HV4CKBXT.js';
|
|
22
22
|
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
|
|
23
23
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-JFE7XCAE.js';
|
|
24
24
|
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-3LOWJSAF.js';
|
|
25
25
|
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
26
|
-
import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-
|
|
27
|
-
import { refreshIfStale } from './chunk-
|
|
28
|
-
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-
|
|
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-
|
|
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-
|
|
26
|
+
import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-6L6V77HW.js';
|
|
27
|
+
import { refreshIfStale } from './chunk-455ZJQQ4.js';
|
|
28
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-7C5UKIXD.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-ZPPDKHGL.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-QDKFGLI3.js';
|
|
31
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-INIULQEP.js';
|
|
32
32
|
import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
|
|
33
33
|
import './chunk-VIWZ4QT7.js';
|
|
34
|
-
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-
|
|
34
|
+
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-CBPDYYIH.js';
|
|
35
35
|
import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
36
36
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
37
37
|
import './chunk-5I4VSBWQ.js';
|
|
@@ -39,21 +39,21 @@ import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-DT4KIV
|
|
|
39
39
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
40
40
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
|
|
41
41
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
42
|
-
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-
|
|
42
|
+
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-EW2ZMFUC.js';
|
|
43
43
|
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
|
|
44
44
|
import './chunk-RXP66R2E.js';
|
|
45
|
-
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-
|
|
46
|
-
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-
|
|
47
|
-
import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-
|
|
48
|
-
import { VERSION } from './chunk-
|
|
45
|
+
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-KYRH3567.js';
|
|
46
|
+
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-SBVZGEOB.js';
|
|
47
|
+
import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-ZMSTSEGR.js';
|
|
48
|
+
import { VERSION } from './chunk-K6MLOGU4.js';
|
|
49
49
|
import './chunk-BWPBB45M.js';
|
|
50
50
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
51
51
|
import './chunk-BPF3YX2U.js';
|
|
52
52
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
53
53
|
import * as fs11 from 'fs';
|
|
54
54
|
import fs11__default, { realpathSync } from 'fs';
|
|
55
|
-
import * as
|
|
56
|
-
import
|
|
55
|
+
import * as path41 from 'path';
|
|
56
|
+
import path41__default from 'path';
|
|
57
57
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
58
58
|
import { Command, CommanderError, Option } from 'commander';
|
|
59
59
|
import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
|
|
@@ -75,10 +75,10 @@ function registerStatus(program) {
|
|
|
75
75
|
applyGlobalOptions(cmd);
|
|
76
76
|
}
|
|
77
77
|
async function runStatus(global) {
|
|
78
|
-
const root2 =
|
|
78
|
+
const root2 = path41.resolve(global.cwd ?? ".");
|
|
79
79
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
80
80
|
const graph = loadGraph(root2, graphPath);
|
|
81
|
-
const hasCache = fs11.existsSync(
|
|
81
|
+
const hasCache = fs11.existsSync(path41.join(cacheDir(root2), "parse-cache.json"));
|
|
82
82
|
let stale = null;
|
|
83
83
|
let staleExact = false;
|
|
84
84
|
if (graph) {
|
|
@@ -98,8 +98,8 @@ async function runStatus(global) {
|
|
|
98
98
|
}
|
|
99
99
|
if (global.json) {
|
|
100
100
|
json({
|
|
101
|
-
root:
|
|
102
|
-
graphPath:
|
|
101
|
+
root: path41.relative(process.cwd(), root2) || ".",
|
|
102
|
+
graphPath: path41.relative(root2, graphPath),
|
|
103
103
|
built: graph !== null,
|
|
104
104
|
generatedAt: graph?.generatedAt ?? null,
|
|
105
105
|
counts: graph?.meta.counts ?? null,
|
|
@@ -114,11 +114,11 @@ async function runStatus(global) {
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
if (!graph) {
|
|
117
|
-
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(
|
|
117
|
+
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path41.relative(root2, graphPath))}`);
|
|
118
118
|
info(` run ${c.bold("vg")} to build one`);
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
-
info(`${c.cyan("vg")} \xB7 ${
|
|
121
|
+
info(`${c.cyan("vg")} \xB7 ${path41.relative(root2, graphPath)}`);
|
|
122
122
|
info(` generated ${graph.generatedAt}`);
|
|
123
123
|
info(
|
|
124
124
|
` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
|
|
@@ -135,7 +135,7 @@ async function runStatus(global) {
|
|
|
135
135
|
if (vibgrateDir(root2)) ;
|
|
136
136
|
}
|
|
137
137
|
function rootOf(global) {
|
|
138
|
-
return
|
|
138
|
+
return path41.resolve(global.cwd ?? ".");
|
|
139
139
|
}
|
|
140
140
|
function requireGraph(global) {
|
|
141
141
|
const root2 = rootOf(global);
|
|
@@ -179,7 +179,14 @@ function registerAsk(program) {
|
|
|
179
179
|
info(c.dim(" preparing semantic search (first use embeds the map; cached, resumable & offline after)\u2026"));
|
|
180
180
|
}
|
|
181
181
|
let reason;
|
|
182
|
-
|
|
182
|
+
let detail;
|
|
183
|
+
const embedder = await loadEmbedder({
|
|
184
|
+
local: global.local,
|
|
185
|
+
onUnavailable: (r, d) => {
|
|
186
|
+
reason = r;
|
|
187
|
+
detail = d;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
183
190
|
if (embedder) {
|
|
184
191
|
const bar = !global.json && firstRun ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
185
192
|
const vectors = await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
@@ -189,6 +196,7 @@ function registerAsk(program) {
|
|
|
189
196
|
} else {
|
|
190
197
|
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
191
198
|
note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
|
|
199
|
+
if (detail) note += ` (${detail})`;
|
|
192
200
|
}
|
|
193
201
|
} else {
|
|
194
202
|
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
@@ -237,11 +245,11 @@ function crashedMessage(signal) {
|
|
|
237
245
|
return `semantic search is disabled: its native backend (onnxruntime-node, via fastembed) crashed with ${signal} \u2014 using fast lexical search instead. This is almost always an install-script block: npm skips onnxruntime-node's postinstall under allow-scripts/ignore-scripts, so the platform binaries were never downloaded. Reinstall allowing them \u2014 npm install -g --allow-scripts=@vibgrate/cli,onnxruntime-node,msgpackr-extract @vibgrate/cli \u2014 or run with --local to stay lexical quietly.`;
|
|
238
246
|
}
|
|
239
247
|
function defaultCacheDir() {
|
|
240
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
241
|
-
return
|
|
248
|
+
const base = process.env.XDG_CACHE_HOME || path41.join(os.homedir(), ".cache");
|
|
249
|
+
return path41.join(base, "vibgrate", "models");
|
|
242
250
|
}
|
|
243
251
|
function verdictPath(dir) {
|
|
244
|
-
return
|
|
252
|
+
return path41.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
|
|
245
253
|
}
|
|
246
254
|
function readVerdict(dir) {
|
|
247
255
|
try {
|
|
@@ -260,14 +268,27 @@ function writeVerdict(dir, verdict) {
|
|
|
260
268
|
} catch {
|
|
261
269
|
}
|
|
262
270
|
}
|
|
271
|
+
function probeModuleUrl(from = import.meta.url) {
|
|
272
|
+
const dir = path41.dirname(fileURLToPath(from));
|
|
273
|
+
for (const name of ["embeddings.js", "index.js"]) {
|
|
274
|
+
const candidate = path41.join(dir, name);
|
|
275
|
+
if (fs11.existsSync(candidate)) return pathToFileURL(candidate).href;
|
|
276
|
+
}
|
|
277
|
+
return pathToFileURL(path41.join(dir, "index.js")).href;
|
|
278
|
+
}
|
|
263
279
|
function defaultRunProbe(timeoutMs) {
|
|
264
|
-
const moduleUrl =
|
|
280
|
+
const moduleUrl = probeModuleUrl();
|
|
265
281
|
const script = `
|
|
266
282
|
import(${JSON.stringify(moduleUrl)})
|
|
267
283
|
.then(async (m) => {
|
|
284
|
+
if (typeof m.loadEmbedder !== 'function') {
|
|
285
|
+
process.stdout.write('{"ok":false}');
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
268
288
|
const e = await m.loadEmbedder({ noDownload: true });
|
|
269
289
|
if (!e) { process.stdout.write('{"ok":false}'); return; }
|
|
270
290
|
await e.embedQuery('probe');
|
|
291
|
+
await e.embed(['probe document']);
|
|
271
292
|
process.stdout.write('{"ok":true}');
|
|
272
293
|
})
|
|
273
294
|
.catch(() => process.stdout.write('{"ok":false}'));
|
|
@@ -350,11 +371,12 @@ function registerEmbed(program) {
|
|
|
350
371
|
const bg = opts.bg === true;
|
|
351
372
|
const speak = !bg && !global.json;
|
|
352
373
|
if (global.local) {
|
|
353
|
-
if (
|
|
374
|
+
if (global.json) json({ embedded: 0, model: modelId, semantic: false, reason: "local" });
|
|
375
|
+
else if (speak) info(c.dim("vg embed \xB7 semantic is off (--local) \u2014 lexical search only"));
|
|
354
376
|
return;
|
|
355
377
|
}
|
|
356
378
|
if (countPending(graph, root2, modelId) === 0) {
|
|
357
|
-
if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId });
|
|
379
|
+
if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId, semantic: true });
|
|
358
380
|
else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
|
|
359
381
|
return;
|
|
360
382
|
}
|
|
@@ -365,6 +387,7 @@ function registerEmbed(program) {
|
|
|
365
387
|
return;
|
|
366
388
|
}
|
|
367
389
|
let reason;
|
|
390
|
+
let detail;
|
|
368
391
|
const embedder = await loadEmbedder({
|
|
369
392
|
local: global.local,
|
|
370
393
|
// Background warm-ups skip the download unless explicitly asked to fetch
|
|
@@ -372,17 +395,24 @@ function registerEmbed(program) {
|
|
|
372
395
|
// time `vg serve`/`vg ask` needs it).
|
|
373
396
|
noDownload: bg && opts.download !== true,
|
|
374
397
|
showDownloadProgress: !bg,
|
|
375
|
-
onUnavailable: (r) =>
|
|
398
|
+
onUnavailable: (r, d) => {
|
|
399
|
+
reason = r;
|
|
400
|
+
detail = d;
|
|
401
|
+
}
|
|
376
402
|
});
|
|
377
403
|
if (!embedder) {
|
|
378
|
-
if (
|
|
404
|
+
if (global.json) {
|
|
405
|
+
json({ embedded: 0, model: modelId, semantic: false, reason: reason ?? "init-failed", detail: detail ?? null });
|
|
406
|
+
} else if (reason) {
|
|
407
|
+
info(c.dim(`vg embed \xB7 ${unavailableMessage(reason)}${detail ? ` (${detail})` : ""}`));
|
|
408
|
+
}
|
|
379
409
|
return;
|
|
380
410
|
}
|
|
381
411
|
const pending = countPending(graph, root2, modelId);
|
|
382
412
|
const bar = speak ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
383
413
|
await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
384
414
|
bar?.done();
|
|
385
|
-
if (global.json) json({ embedded: pending, model: modelId });
|
|
415
|
+
if (global.json) json({ embedded: pending, model: modelId, semantic: true });
|
|
386
416
|
else if (speak) info(`${c.green("\u2714")} vg embed \xB7 semantic index ready (~${pending} node(s) \xB7 model ${modelId})`);
|
|
387
417
|
});
|
|
388
418
|
applyGlobalOptions(cmd);
|
|
@@ -989,7 +1019,7 @@ var PUBLISH_INTERVAL_MS = 2e3;
|
|
|
989
1019
|
var KEEPALIVE_MS = 1e4;
|
|
990
1020
|
var STALE_MS = 6e4;
|
|
991
1021
|
function liveStatsDir(root2) {
|
|
992
|
-
return
|
|
1022
|
+
return path41.join(cacheDir(root2), "serve-live");
|
|
993
1023
|
}
|
|
994
1024
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
995
1025
|
let entries;
|
|
@@ -1003,7 +1033,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
1003
1033
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1004
1034
|
let parsed;
|
|
1005
1035
|
try {
|
|
1006
|
-
parsed = JSON.parse(fs11.readFileSync(
|
|
1036
|
+
parsed = JSON.parse(fs11.readFileSync(path41.join(dir, name), "utf8"));
|
|
1007
1037
|
} catch {
|
|
1008
1038
|
continue;
|
|
1009
1039
|
}
|
|
@@ -1025,7 +1055,7 @@ var LiveStatsBus = class {
|
|
|
1025
1055
|
this.dir = dir;
|
|
1026
1056
|
this.stats = stats;
|
|
1027
1057
|
this.pid = pid;
|
|
1028
|
-
this.file =
|
|
1058
|
+
this.file = path41.join(dir, `serve-${this.pid}.json`);
|
|
1029
1059
|
}
|
|
1030
1060
|
dir;
|
|
1031
1061
|
stats;
|
|
@@ -1078,7 +1108,7 @@ var LiveStatsBus = class {
|
|
|
1078
1108
|
const out2 = [];
|
|
1079
1109
|
for (const name of entries.sort()) {
|
|
1080
1110
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1081
|
-
const file =
|
|
1111
|
+
const file = path41.join(this.dir, name);
|
|
1082
1112
|
let parsed;
|
|
1083
1113
|
try {
|
|
1084
1114
|
parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
@@ -1824,7 +1854,7 @@ function endOfLine(text, line) {
|
|
|
1824
1854
|
}
|
|
1825
1855
|
var CACHE_VERSION = "vg-lsp-scan-cache/2";
|
|
1826
1856
|
function cachePath(root2) {
|
|
1827
|
-
return
|
|
1857
|
+
return path41.join(cacheDir(root2), "lsp-scan.json");
|
|
1828
1858
|
}
|
|
1829
1859
|
function manifestHash(root2) {
|
|
1830
1860
|
const files = [];
|
|
@@ -1836,7 +1866,7 @@ function manifestHash(root2) {
|
|
|
1836
1866
|
return;
|
|
1837
1867
|
}
|
|
1838
1868
|
for (const entry of entries) {
|
|
1839
|
-
const abs =
|
|
1869
|
+
const abs = path41.join(dir, entry.name);
|
|
1840
1870
|
if (entry.isDirectory()) {
|
|
1841
1871
|
if (isSkippedDirName(entry.name)) continue;
|
|
1842
1872
|
walk2(abs);
|
|
@@ -1846,7 +1876,7 @@ function manifestHash(root2) {
|
|
|
1846
1876
|
const base = entry.name.toLowerCase();
|
|
1847
1877
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1848
1878
|
try {
|
|
1849
|
-
const rel =
|
|
1879
|
+
const rel = path41.relative(root2, abs).split(path41.sep).join("/");
|
|
1850
1880
|
files.push({ rel, hash: hashBytes(fs11.readFileSync(abs)) });
|
|
1851
1881
|
} catch {
|
|
1852
1882
|
}
|
|
@@ -1857,9 +1887,9 @@ function manifestHash(root2) {
|
|
|
1857
1887
|
return hashString(canonicalize(files));
|
|
1858
1888
|
}
|
|
1859
1889
|
function isDependencyFile(root2, filePath) {
|
|
1860
|
-
const rel =
|
|
1861
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
1862
|
-
const parts = rel.split(
|
|
1890
|
+
const rel = path41.relative(path41.resolve(root2), path41.resolve(filePath));
|
|
1891
|
+
if (rel === "" || rel.startsWith("..") || path41.isAbsolute(rel)) return false;
|
|
1892
|
+
const parts = rel.split(path41.sep);
|
|
1863
1893
|
if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
|
|
1864
1894
|
const base = parts[parts.length - 1].toLowerCase();
|
|
1865
1895
|
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
@@ -1890,7 +1920,7 @@ function writeScanCache(root2, key2, artifact) {
|
|
|
1890
1920
|
var MAX_ENTRIES = 1e3;
|
|
1891
1921
|
var KEEP_ENTRIES = 500;
|
|
1892
1922
|
function historyPath(root2) {
|
|
1893
|
-
return
|
|
1923
|
+
return path41.join(root2, ".vibgrate", "score-history.jsonl");
|
|
1894
1924
|
}
|
|
1895
1925
|
function parseLine(line) {
|
|
1896
1926
|
try {
|
|
@@ -1931,7 +1961,7 @@ function recordScore(root2, entry) {
|
|
|
1931
1961
|
}
|
|
1932
1962
|
}
|
|
1933
1963
|
const file = historyPath(root2);
|
|
1934
|
-
fs11.mkdirSync(
|
|
1964
|
+
fs11.mkdirSync(path41.dirname(file), { recursive: true });
|
|
1935
1965
|
ensureVibgrateGitignore(root2);
|
|
1936
1966
|
fs11.appendFileSync(file, `${JSON.stringify(entry)}
|
|
1937
1967
|
`);
|
|
@@ -1990,11 +2020,17 @@ async function runAsk(graph, params, ctx) {
|
|
|
1990
2020
|
const budgetMs = semanticBudgetMs();
|
|
1991
2021
|
log(`ask: trying the semantic path (budget ${Math.round(budgetMs / 1e3)}s)`);
|
|
1992
2022
|
let reason;
|
|
2023
|
+
let detail;
|
|
1993
2024
|
const started = Date.now();
|
|
1994
2025
|
try {
|
|
1995
2026
|
result = await withTimeout(
|
|
1996
2027
|
(async () => {
|
|
1997
|
-
const embedder = await loadEmbedder({
|
|
2028
|
+
const embedder = await loadEmbedder({
|
|
2029
|
+
onUnavailable: (r2, d) => {
|
|
2030
|
+
reason = r2;
|
|
2031
|
+
detail = d;
|
|
2032
|
+
}
|
|
2033
|
+
});
|
|
1998
2034
|
if (!embedder) return null;
|
|
1999
2035
|
log(`ask: embedder "${embedder.id}" loaded in ${Date.now() - started}ms; embedding nodes\u2026`);
|
|
2000
2036
|
const vectors = await getNodeEmbeddings(graph, embedder, ctx.root);
|
|
@@ -2008,7 +2044,9 @@ async function runAsk(graph, params, ctx) {
|
|
|
2008
2044
|
);
|
|
2009
2045
|
if (!result) {
|
|
2010
2046
|
note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
|
|
2011
|
-
log(
|
|
2047
|
+
log(
|
|
2048
|
+
`ask: semantic unavailable (${reason ?? "no backend"}) \u2014 falling back to lexical` + (detail ? ` \xB7 ${detail}` : "")
|
|
2049
|
+
);
|
|
2012
2050
|
}
|
|
2013
2051
|
} catch (err) {
|
|
2014
2052
|
mode = "lexical";
|
|
@@ -2902,7 +2940,7 @@ var VibgrateLanguageServer = class {
|
|
|
2902
2940
|
const ecosystem = osvEcosystem(proj.type);
|
|
2903
2941
|
if (!ecosystem) continue;
|
|
2904
2942
|
const relManifest = manifestRelativePath(proj);
|
|
2905
|
-
const absManifest =
|
|
2943
|
+
const absManifest = path41.resolve(this.opts.root, relManifest);
|
|
2906
2944
|
let text = null;
|
|
2907
2945
|
try {
|
|
2908
2946
|
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
@@ -3054,9 +3092,9 @@ function pruneArtifactProjects(a) {
|
|
|
3054
3092
|
return { ...a, projects, findings };
|
|
3055
3093
|
}
|
|
3056
3094
|
function projectByPath(a, projectPath) {
|
|
3057
|
-
const want =
|
|
3095
|
+
const want = path41.normalize(projectPath === "" ? "." : projectPath);
|
|
3058
3096
|
for (const proj of a.projects ?? []) {
|
|
3059
|
-
const got =
|
|
3097
|
+
const got = path41.normalize(proj.path === "" ? "." : proj.path);
|
|
3060
3098
|
if (got === want) return proj;
|
|
3061
3099
|
}
|
|
3062
3100
|
return void 0;
|
|
@@ -3093,12 +3131,12 @@ function buildProjectRefs(rootDir, projects) {
|
|
|
3093
3131
|
return refs.length > 0 ? refs : void 0;
|
|
3094
3132
|
}
|
|
3095
3133
|
function projectForFile(root2, a, filePath) {
|
|
3096
|
-
const dir =
|
|
3134
|
+
const dir = path41.dirname(path41.resolve(filePath));
|
|
3097
3135
|
let best;
|
|
3098
3136
|
let bestLen = -1;
|
|
3099
3137
|
for (const proj of a.projects ?? []) {
|
|
3100
|
-
const projDir =
|
|
3101
|
-
if ((dir === projDir || dir.startsWith(projDir +
|
|
3138
|
+
const projDir = path41.resolve(root2, proj.path);
|
|
3139
|
+
if ((dir === projDir || dir.startsWith(projDir + path41.sep)) && projDir.length > bestLen) {
|
|
3102
3140
|
best = proj;
|
|
3103
3141
|
bestLen = projDir.length;
|
|
3104
3142
|
}
|
|
@@ -3106,7 +3144,7 @@ function projectForFile(root2, a, filePath) {
|
|
|
3106
3144
|
return best;
|
|
3107
3145
|
}
|
|
3108
3146
|
function sameProject(location, projectPath) {
|
|
3109
|
-
return
|
|
3147
|
+
return path41.normalize(location) === path41.normalize(projectPath);
|
|
3110
3148
|
}
|
|
3111
3149
|
function hasReleaseDates(a) {
|
|
3112
3150
|
for (const proj of a.projects ?? []) {
|
|
@@ -3176,7 +3214,7 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3176
3214
|
const relManifest = manifestRelativePath(p);
|
|
3177
3215
|
if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
|
|
3178
3216
|
const ecosystem = osvEcosystem(p.type);
|
|
3179
|
-
const absManifest =
|
|
3217
|
+
const absManifest = path41.resolve(rootDir, relManifest);
|
|
3180
3218
|
let text = null;
|
|
3181
3219
|
try {
|
|
3182
3220
|
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
@@ -3244,34 +3282,34 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3244
3282
|
}
|
|
3245
3283
|
function manifestRelativePath(proj) {
|
|
3246
3284
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3247
|
-
const
|
|
3285
|
+
const join31 = (name) => base ? path41.join(base, name) : name;
|
|
3248
3286
|
switch (proj.type) {
|
|
3249
3287
|
case "node":
|
|
3250
3288
|
case "typescript":
|
|
3251
|
-
return
|
|
3289
|
+
return join31("package.json");
|
|
3252
3290
|
case "python":
|
|
3253
|
-
return
|
|
3291
|
+
return join31("pyproject.toml");
|
|
3254
3292
|
case "go":
|
|
3255
|
-
return
|
|
3293
|
+
return join31("go.mod");
|
|
3256
3294
|
case "rust":
|
|
3257
|
-
return
|
|
3295
|
+
return join31("Cargo.toml");
|
|
3258
3296
|
case "ruby":
|
|
3259
|
-
return
|
|
3297
|
+
return join31("Gemfile");
|
|
3260
3298
|
case "php":
|
|
3261
|
-
return
|
|
3299
|
+
return join31("composer.json");
|
|
3262
3300
|
case "java":
|
|
3263
3301
|
case "kotlin":
|
|
3264
3302
|
case "scala":
|
|
3265
3303
|
case "groovy":
|
|
3266
|
-
return
|
|
3304
|
+
return join31("pom.xml");
|
|
3267
3305
|
case "dotnet":
|
|
3268
|
-
return
|
|
3306
|
+
return join31(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
3269
3307
|
case "dart":
|
|
3270
|
-
return
|
|
3308
|
+
return join31("pubspec.yaml");
|
|
3271
3309
|
case "elixir":
|
|
3272
|
-
return
|
|
3310
|
+
return join31("mix.exs");
|
|
3273
3311
|
default:
|
|
3274
|
-
return
|
|
3312
|
+
return join31("package.json");
|
|
3275
3313
|
}
|
|
3276
3314
|
}
|
|
3277
3315
|
function lockfileRelativePath(rootDir, proj) {
|
|
@@ -3302,9 +3340,9 @@ function lockfileRelativePath(rootDir, proj) {
|
|
|
3302
3340
|
const dirsToTry = base ? [base, ""] : [""];
|
|
3303
3341
|
for (const dir of dirsToTry) {
|
|
3304
3342
|
for (const name of candidateNames) {
|
|
3305
|
-
const rel = dir ?
|
|
3343
|
+
const rel = dir ? path41.join(dir, name) : name;
|
|
3306
3344
|
try {
|
|
3307
|
-
if (fs11.existsSync(
|
|
3345
|
+
if (fs11.existsSync(path41.join(rootDir, rel))) return rel;
|
|
3308
3346
|
} catch {
|
|
3309
3347
|
}
|
|
3310
3348
|
}
|
|
@@ -3375,7 +3413,7 @@ function lookupImportFiles(map, pkg) {
|
|
|
3375
3413
|
}
|
|
3376
3414
|
function firstPackageMentionLine(root2, relFile, pkg) {
|
|
3377
3415
|
try {
|
|
3378
|
-
const abs =
|
|
3416
|
+
const abs = path41.resolve(root2, relFile);
|
|
3379
3417
|
const stat2 = fs11.statSync(abs);
|
|
3380
3418
|
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3381
3419
|
const text = fs11.readFileSync(abs, "utf8");
|
|
@@ -3579,8 +3617,8 @@ function hookCommand(vgBin) {
|
|
|
3579
3617
|
return `${vgBin} hook pre-tool-use`;
|
|
3580
3618
|
}
|
|
3581
3619
|
function installClaudeHooks(root2, vgBin = "vg") {
|
|
3582
|
-
const file =
|
|
3583
|
-
const rel =
|
|
3620
|
+
const file = path41.join(root2, ".claude", "settings.json");
|
|
3621
|
+
const rel = path41.join(".claude", "settings.json");
|
|
3584
3622
|
let settings = {};
|
|
3585
3623
|
if (fs11.existsSync(file)) {
|
|
3586
3624
|
try {
|
|
@@ -3621,8 +3659,8 @@ function installClaudeHooks(root2, vgBin = "vg") {
|
|
|
3621
3659
|
return { file: rel, status: "written" };
|
|
3622
3660
|
}
|
|
3623
3661
|
function uninstallClaudeHooks(root2) {
|
|
3624
|
-
const file =
|
|
3625
|
-
const rel =
|
|
3662
|
+
const file = path41.join(root2, ".claude", "settings.json");
|
|
3663
|
+
const rel = path41.join(".claude", "settings.json");
|
|
3626
3664
|
if (!fs11.existsSync(file)) return { file: rel, status: "unchanged" };
|
|
3627
3665
|
let settings;
|
|
3628
3666
|
try {
|
|
@@ -3648,7 +3686,7 @@ function uninstallClaudeHooks(root2) {
|
|
|
3648
3686
|
return { file: rel, status: "written" };
|
|
3649
3687
|
}
|
|
3650
3688
|
function writeSettings(file, settings) {
|
|
3651
|
-
fs11.mkdirSync(
|
|
3689
|
+
fs11.mkdirSync(path41.dirname(file), { recursive: true });
|
|
3652
3690
|
fs11.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
|
|
3653
3691
|
`);
|
|
3654
3692
|
}
|
|
@@ -3769,7 +3807,7 @@ function registryBase(opts) {
|
|
|
3769
3807
|
return (process.env.VIBGRATE_MODULE_REGISTRY || opts.registry || DEFAULT_REGISTRY).replace(/\/+$/, "");
|
|
3770
3808
|
}
|
|
3771
3809
|
function stateFile() {
|
|
3772
|
-
return
|
|
3810
|
+
return path41.join(path41.dirname(relevanceModuleDir()), "consent.json");
|
|
3773
3811
|
}
|
|
3774
3812
|
function readConsent() {
|
|
3775
3813
|
try {
|
|
@@ -3780,7 +3818,7 @@ function readConsent() {
|
|
|
3780
3818
|
}
|
|
3781
3819
|
function writeConsent(state) {
|
|
3782
3820
|
try {
|
|
3783
|
-
fs11.mkdirSync(
|
|
3821
|
+
fs11.mkdirSync(path41.dirname(stateFile()), { recursive: true });
|
|
3784
3822
|
fs11.writeFileSync(stateFile(), JSON.stringify(state));
|
|
3785
3823
|
} catch {
|
|
3786
3824
|
}
|
|
@@ -3791,8 +3829,8 @@ function kernelDisabled() {
|
|
|
3791
3829
|
}
|
|
3792
3830
|
function moduleInstalled() {
|
|
3793
3831
|
try {
|
|
3794
|
-
const meta = JSON.parse(fs11.readFileSync(
|
|
3795
|
-
if (fs11.existsSync(
|
|
3832
|
+
const meta = JSON.parse(fs11.readFileSync(path41.join(relevanceModuleDir(), ".module.json"), "utf8"));
|
|
3833
|
+
if (fs11.existsSync(path41.join(relevanceModuleDir(), "index.js"))) {
|
|
3796
3834
|
return { installed: true, version: meta.version };
|
|
3797
3835
|
}
|
|
3798
3836
|
} catch {
|
|
@@ -3841,7 +3879,7 @@ function untar(data) {
|
|
|
3841
3879
|
if (type !== "0" && type !== "\0") continue;
|
|
3842
3880
|
const name = pendingName ?? (prefix ? `${prefix}/${rawName}` : rawName);
|
|
3843
3881
|
pendingName = null;
|
|
3844
|
-
if (name.split("/").includes("..") ||
|
|
3882
|
+
if (name.split("/").includes("..") || path41.isAbsolute(name)) {
|
|
3845
3883
|
throw new Error(`unsafe path in tarball: ${name}`);
|
|
3846
3884
|
}
|
|
3847
3885
|
out2.push({ name, body: Buffer.from(body) });
|
|
@@ -3875,17 +3913,17 @@ async function installRelevanceModule(opts = {}) {
|
|
|
3875
3913
|
if (e.name.startsWith("package/dist/")) rel = e.name.slice("package/dist/".length);
|
|
3876
3914
|
else if (e.name === "package/LICENSE" || e.name === "package/README.md") rel = e.name.slice("package/".length);
|
|
3877
3915
|
if (!rel) continue;
|
|
3878
|
-
const target =
|
|
3879
|
-
if (!target.startsWith(dir +
|
|
3880
|
-
fs11.mkdirSync(
|
|
3916
|
+
const target = path41.join(dir, rel);
|
|
3917
|
+
if (!target.startsWith(dir + path41.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
|
|
3918
|
+
fs11.mkdirSync(path41.dirname(target), { recursive: true });
|
|
3881
3919
|
fs11.writeFileSync(target, e.body);
|
|
3882
3920
|
wrote += 1;
|
|
3883
3921
|
}
|
|
3884
|
-
if (!wrote || !fs11.existsSync(
|
|
3922
|
+
if (!wrote || !fs11.existsSync(path41.join(dir, "index.js"))) {
|
|
3885
3923
|
fs11.rmSync(dir, { recursive: true, force: true });
|
|
3886
3924
|
return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
|
|
3887
3925
|
}
|
|
3888
|
-
fs11.writeFileSync(
|
|
3926
|
+
fs11.writeFileSync(path41.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
|
|
3889
3927
|
resetRelevanceProviderCache();
|
|
3890
3928
|
return { status: "installed", version };
|
|
3891
3929
|
} catch (e) {
|
|
@@ -4044,7 +4082,7 @@ function registerShare(program) {
|
|
|
4044
4082
|
const cmd = program.command("share").description("make the map committable + auto-updating for your team (git)").option("--undo", "reverse what `vg share` installed").option("--reports", "also commit graph.html / GRAPH_REPORT.md (default: gitignored)").action(function(opts) {
|
|
4045
4083
|
const global = readGlobal(this);
|
|
4046
4084
|
const root2 = rootOf(global);
|
|
4047
|
-
const gitDir =
|
|
4085
|
+
const gitDir = path41.join(root2, ".git");
|
|
4048
4086
|
if (!fs11.existsSync(gitDir)) {
|
|
4049
4087
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
4050
4088
|
}
|
|
@@ -4066,15 +4104,15 @@ function registerShare(program) {
|
|
|
4066
4104
|
applyGlobalOptions(cmd);
|
|
4067
4105
|
}
|
|
4068
4106
|
function writeVibgrateGitignore(root2, reports) {
|
|
4069
|
-
const dir =
|
|
4107
|
+
const dir = path41.join(root2, ".vibgrate");
|
|
4070
4108
|
fs11.mkdirSync(dir, { recursive: true });
|
|
4071
4109
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
4072
4110
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
4073
|
-
fs11.writeFileSync(
|
|
4111
|
+
fs11.writeFileSync(path41.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
4074
4112
|
`);
|
|
4075
4113
|
}
|
|
4076
4114
|
function writeGitAttributes(root2) {
|
|
4077
|
-
const file =
|
|
4115
|
+
const file = path41.join(root2, ".gitattributes");
|
|
4078
4116
|
const line = ".vibgrate/graph.json merge=vg";
|
|
4079
4117
|
let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
|
|
4080
4118
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
@@ -4092,7 +4130,7 @@ function configureMergeDriver(root2) {
|
|
|
4092
4130
|
function installPreCommitHook(root2) {
|
|
4093
4131
|
const hooksDir = hookDir(root2);
|
|
4094
4132
|
fs11.mkdirSync(hooksDir, { recursive: true });
|
|
4095
|
-
const file =
|
|
4133
|
+
const file = path41.join(hooksDir, "pre-commit");
|
|
4096
4134
|
const block = [
|
|
4097
4135
|
HOOK_BEGIN,
|
|
4098
4136
|
"if command -v vg >/dev/null 2>&1; then",
|
|
@@ -4114,14 +4152,14 @@ ${content}`;
|
|
|
4114
4152
|
fs11.chmodSync(file, 493);
|
|
4115
4153
|
}
|
|
4116
4154
|
function undo(root2) {
|
|
4117
|
-
const hookFile =
|
|
4155
|
+
const hookFile = path41.join(hookDir(root2), "pre-commit");
|
|
4118
4156
|
if (fs11.existsSync(hookFile)) {
|
|
4119
4157
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
4120
4158
|
const next2 = fs11.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
4121
4159
|
if (next2.trim() === "#!/bin/sh") fs11.rmSync(hookFile);
|
|
4122
4160
|
else fs11.writeFileSync(hookFile, next2);
|
|
4123
4161
|
}
|
|
4124
|
-
const attr =
|
|
4162
|
+
const attr = path41.join(root2, ".gitattributes");
|
|
4125
4163
|
if (fs11.existsSync(attr)) {
|
|
4126
4164
|
const next2 = fs11.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
4127
4165
|
fs11.writeFileSync(attr, next2);
|
|
@@ -4134,10 +4172,10 @@ function undo(root2) {
|
|
|
4134
4172
|
function hookDir(root2) {
|
|
4135
4173
|
try {
|
|
4136
4174
|
const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
|
|
4137
|
-
if (configured) return
|
|
4175
|
+
if (configured) return path41.resolve(root2, configured);
|
|
4138
4176
|
} catch {
|
|
4139
4177
|
}
|
|
4140
|
-
return
|
|
4178
|
+
return path41.join(root2, ".git", "hooks");
|
|
4141
4179
|
}
|
|
4142
4180
|
function git(root2, args) {
|
|
4143
4181
|
return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
|
|
@@ -4151,7 +4189,7 @@ function registerWatch(program) {
|
|
|
4151
4189
|
const global = readGlobal(this);
|
|
4152
4190
|
const root2 = rootOf(global);
|
|
4153
4191
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
4154
|
-
const watchRoots = (paths.length ? paths : ["."]).map((p) =>
|
|
4192
|
+
const watchRoots = (paths.length ? paths : ["."]).map((p) => path41.resolve(root2, p));
|
|
4155
4193
|
for (const w of watchRoots) {
|
|
4156
4194
|
if (!fs11.existsSync(w)) {
|
|
4157
4195
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
@@ -4219,7 +4257,7 @@ function registerWatch(program) {
|
|
|
4219
4257
|
throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
|
|
4220
4258
|
}
|
|
4221
4259
|
}
|
|
4222
|
-
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) =>
|
|
4260
|
+
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path41.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
|
|
4223
4261
|
await new Promise((resolve21) => {
|
|
4224
4262
|
const stop = () => {
|
|
4225
4263
|
for (const w of watchers) w.close();
|
|
@@ -4552,7 +4590,7 @@ function normalizeStandards(raw) {
|
|
|
4552
4590
|
}
|
|
4553
4591
|
function loadStandards(root2) {
|
|
4554
4592
|
for (const rel of STANDARDS_FILES) {
|
|
4555
|
-
const p =
|
|
4593
|
+
const p = path41__default.join(root2, rel);
|
|
4556
4594
|
let text;
|
|
4557
4595
|
try {
|
|
4558
4596
|
text = fs11__default.readFileSync(p, "utf8");
|
|
@@ -5273,8 +5311,8 @@ async function runHostBench(options = {}) {
|
|
|
5273
5311
|
}
|
|
5274
5312
|
async function runArmSimulate(input) {
|
|
5275
5313
|
const { arm, lib, modelPath, turns, trie, env, live } = input;
|
|
5276
|
-
const
|
|
5277
|
-
const session = await acquireHostSession(lib,
|
|
5314
|
+
const path43 = `${modelPath}#${arm.id}`;
|
|
5315
|
+
const session = await acquireHostSession(lib, path43);
|
|
5278
5316
|
const system = "You are a coding agent with a Task Capsule.";
|
|
5279
5317
|
const capsule = "function readConfig(): Config { return load(); }";
|
|
5280
5318
|
let last = null;
|
|
@@ -6638,8 +6676,8 @@ function registerModels(program) {
|
|
|
6638
6676
|
}
|
|
6639
6677
|
});
|
|
6640
6678
|
if (opts.out) {
|
|
6641
|
-
const outPath =
|
|
6642
|
-
fs11.mkdirSync(
|
|
6679
|
+
const outPath = path41.resolve(opts.out);
|
|
6680
|
+
fs11.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
6643
6681
|
fs11.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
6644
6682
|
`);
|
|
6645
6683
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
@@ -6789,14 +6827,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
|
|
|
6789
6827
|
}
|
|
6790
6828
|
return exact[0];
|
|
6791
6829
|
}
|
|
6792
|
-
const base =
|
|
6830
|
+
const base = path41.basename(wantLc);
|
|
6793
6831
|
const soft = fleet.filter((m) => {
|
|
6794
6832
|
const n = m.name.toLowerCase();
|
|
6795
|
-
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) ||
|
|
6833
|
+
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path41.basename(n) === base;
|
|
6796
6834
|
});
|
|
6797
6835
|
if (soft.length === 1) return soft[0];
|
|
6798
6836
|
if (soft.length > 1) {
|
|
6799
|
-
const baseHits = soft.filter((m) =>
|
|
6837
|
+
const baseHits = soft.filter((m) => path41.basename(m.name).toLowerCase() === base);
|
|
6800
6838
|
const pool = baseHits.length ? baseHits : soft;
|
|
6801
6839
|
const order = ["ollama", "gguf", "lm-studio"];
|
|
6802
6840
|
for (const rt of order) {
|
|
@@ -6834,7 +6872,7 @@ function printBackends(backends) {
|
|
|
6834
6872
|
}
|
|
6835
6873
|
}
|
|
6836
6874
|
function codeConfigPath(root2) {
|
|
6837
|
-
return
|
|
6875
|
+
return path41.join(root2, ".vibgrate", "code.json");
|
|
6838
6876
|
}
|
|
6839
6877
|
function loadCodeConfig(root2) {
|
|
6840
6878
|
try {
|
|
@@ -6916,7 +6954,7 @@ function discoverMcpServers(root2, ownServers) {
|
|
|
6916
6954
|
const servers = {};
|
|
6917
6955
|
const sources = [];
|
|
6918
6956
|
for (const rel of MCP_CONFIG_FILES) {
|
|
6919
|
-
const found = readMcpServersFile(
|
|
6957
|
+
const found = readMcpServersFile(path41.join(root2, rel));
|
|
6920
6958
|
const names = Object.keys(found);
|
|
6921
6959
|
if (names.length) {
|
|
6922
6960
|
sources.push(rel);
|
|
@@ -6948,7 +6986,7 @@ function registerCode(program) {
|
|
|
6948
6986
|
try {
|
|
6949
6987
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6950
6988
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6951
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6989
|
+
const { loadGraph: loadGraph2 } = await import('./load-QBVKCWZT.js');
|
|
6952
6990
|
const state = readOrchestratorState2();
|
|
6953
6991
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6954
6992
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -7033,7 +7071,7 @@ function registerCode(program) {
|
|
|
7033
7071
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
7034
7072
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
7035
7073
|
}
|
|
7036
|
-
const { runInteractive } = await import('./interactive-
|
|
7074
|
+
const { runInteractive } = await import('./interactive-7EZHEBHQ.js');
|
|
7037
7075
|
await runInteractive(
|
|
7038
7076
|
rootOf(global),
|
|
7039
7077
|
global,
|
|
@@ -7063,7 +7101,7 @@ function registerCode(program) {
|
|
|
7063
7101
|
}
|
|
7064
7102
|
if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
7065
7103
|
{
|
|
7066
|
-
const { ensureCodeMap } = await import('./ensure-map-
|
|
7104
|
+
const { ensureCodeMap } = await import('./ensure-map-5E5TFPXJ.js');
|
|
7067
7105
|
const mapRoot = rootOf(global);
|
|
7068
7106
|
try {
|
|
7069
7107
|
await ensureCodeMap(mapRoot, global, {
|
|
@@ -7148,20 +7186,20 @@ function registerCode(program) {
|
|
|
7148
7186
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
7149
7187
|
};
|
|
7150
7188
|
try {
|
|
7151
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
7189
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-NQAU6DOA.js');
|
|
7152
7190
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
7153
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
7154
|
-
const { nodeCodeFs } = await import('./session-
|
|
7191
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-5WFD6HRO.js');
|
|
7192
|
+
const { nodeCodeFs } = await import('./session-QNSYTLLJ.js');
|
|
7155
7193
|
const readline6 = await import('readline');
|
|
7156
7194
|
const child = await import('child_process');
|
|
7157
7195
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
7158
7196
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7159
7197
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7160
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7161
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7198
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-ZPGU4PGW.js');
|
|
7199
|
+
const { resolveGraphBackend } = await import('./graph-backend-GQZXMNRI.js');
|
|
7162
7200
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7163
7201
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7164
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7202
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
|
|
7165
7203
|
const federation = loadOrDiscoverFederation(root2);
|
|
7166
7204
|
const modelProfile = mergeModelExecutionProfile(
|
|
7167
7205
|
resolveModelExecutionProfile({
|
|
@@ -7219,7 +7257,7 @@ ${res.stderr}` : ""),
|
|
|
7219
7257
|
exitCode: res.status ?? 1
|
|
7220
7258
|
};
|
|
7221
7259
|
};
|
|
7222
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7260
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-VTGXA6CO.js');
|
|
7223
7261
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7224
7262
|
getGraph: () => graph,
|
|
7225
7263
|
root: root2,
|
|
@@ -7240,10 +7278,10 @@ ${res.stderr}` : ""),
|
|
|
7240
7278
|
}
|
|
7241
7279
|
const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
|
|
7242
7280
|
const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
|
|
7243
|
-
const
|
|
7281
|
+
const os6 = await import('os');
|
|
7244
7282
|
const pathMod = await import('path');
|
|
7245
7283
|
const checkpointIndex = pathMod.join(
|
|
7246
|
-
fs11.mkdtempSync(pathMod.join(
|
|
7284
|
+
fs11.mkdtempSync(pathMod.join(os6.tmpdir(), "vg-code-cp-")),
|
|
7247
7285
|
"index"
|
|
7248
7286
|
);
|
|
7249
7287
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -7279,6 +7317,10 @@ ${res.stderr}` : ""),
|
|
|
7279
7317
|
providers: route.providers,
|
|
7280
7318
|
fsImpl: nodeCodeFs(root2),
|
|
7281
7319
|
run,
|
|
7320
|
+
// Live command-output events for the VG Code panel (async shell).
|
|
7321
|
+
// Sandboxed executionEnv still uses its own runner when set.
|
|
7322
|
+
streamShell: !executionEnv,
|
|
7323
|
+
allowSubagents: true,
|
|
7282
7324
|
executionEnv,
|
|
7283
7325
|
graphBackend,
|
|
7284
7326
|
modelProfile,
|
|
@@ -7309,8 +7351,8 @@ ${res.stderr}` : ""),
|
|
|
7309
7351
|
};
|
|
7310
7352
|
try {
|
|
7311
7353
|
if (opts.session) {
|
|
7312
|
-
const { runCodeStreamJsonSession } = await import('./stream-json-
|
|
7313
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
7354
|
+
const { runCodeStreamJsonSession } = await import('./stream-json-5WFD6HRO.js');
|
|
7355
|
+
const { runAgent: runAgent2 } = await import('./agent-DSC3EQLT.js');
|
|
7314
7356
|
const {
|
|
7315
7357
|
condenseSession,
|
|
7316
7358
|
loadLatestSession,
|
|
@@ -7478,8 +7520,8 @@ ${res.stderr}` : ""),
|
|
|
7478
7520
|
if (!autonomous && !tty) {
|
|
7479
7521
|
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).");
|
|
7480
7522
|
}
|
|
7481
|
-
const { agentTask } = await import('./interactive-
|
|
7482
|
-
const { nodeCodeFs } = await import('./session-
|
|
7523
|
+
const { agentTask } = await import('./interactive-7EZHEBHQ.js');
|
|
7524
|
+
const { nodeCodeFs } = await import('./session-QNSYTLLJ.js');
|
|
7483
7525
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
7484
7526
|
let priorSummary;
|
|
7485
7527
|
let priorInstruction;
|
|
@@ -7492,7 +7534,7 @@ ${res.stderr}` : ""),
|
|
|
7492
7534
|
}
|
|
7493
7535
|
}
|
|
7494
7536
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
7495
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7537
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-VTGXA6CO.js');
|
|
7496
7538
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7497
7539
|
getGraph: () => graph,
|
|
7498
7540
|
root: root2,
|
|
@@ -7516,11 +7558,11 @@ ${res.stderr}` : ""),
|
|
|
7516
7558
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
7517
7559
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7518
7560
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7519
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7520
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7561
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-ZPGU4PGW.js');
|
|
7562
|
+
const { resolveGraphBackend } = await import('./graph-backend-GQZXMNRI.js');
|
|
7521
7563
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7522
7564
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7523
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7565
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
|
|
7524
7566
|
const federation = loadFederation(root2);
|
|
7525
7567
|
const modelProfile = mergeModelExecutionProfile(
|
|
7526
7568
|
resolveModelExecutionProfile({
|
|
@@ -7827,7 +7869,7 @@ async function addCmd(root2, rest, opts, asJson) {
|
|
|
7827
7869
|
}
|
|
7828
7870
|
function readPackageVersion(root2) {
|
|
7829
7871
|
try {
|
|
7830
|
-
const pkg = JSON.parse(fs11__default.readFileSync(
|
|
7872
|
+
const pkg = JSON.parse(fs11__default.readFileSync(path41__default.join(root2, "package.json"), "utf8"));
|
|
7831
7873
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
7832
7874
|
} catch {
|
|
7833
7875
|
return void 0;
|
|
@@ -7850,8 +7892,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
|
|
|
7850
7892
|
if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
|
|
7851
7893
|
const version = (opts.version || readPackageVersion(root2) || "").trim();
|
|
7852
7894
|
if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
|
|
7853
|
-
const readme = readOptionalFile(opts.readme ?
|
|
7854
|
-
const dts = opts.dts ? readOptionalFile(
|
|
7895
|
+
const readme = readOptionalFile(opts.readme ? path41__default.resolve(opts.readme) : path41__default.join(root2, "README.md"));
|
|
7896
|
+
const dts = opts.dts ? readOptionalFile(path41__default.resolve(opts.dts)) : void 0;
|
|
7855
7897
|
if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
|
|
7856
7898
|
const result = await publishPrivateLibrary(
|
|
7857
7899
|
{ name, version, readme, dts, language: opts.language },
|
|
@@ -7983,7 +8025,7 @@ function registerExport(program) {
|
|
|
7983
8025
|
out(content.trimEnd());
|
|
7984
8026
|
return;
|
|
7985
8027
|
}
|
|
7986
|
-
fs11.mkdirSync(
|
|
8028
|
+
fs11.mkdirSync(path41.dirname(path41.resolve(file)), { recursive: true });
|
|
7987
8029
|
fs11.writeFileSync(file, content);
|
|
7988
8030
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
7989
8031
|
});
|
|
@@ -7994,43 +8036,43 @@ function detectFormat(file) {
|
|
|
7994
8036
|
if (lower.endsWith(".cdx.json")) return "cyclonedx";
|
|
7995
8037
|
if (lower.endsWith(".spdx.json")) return "spdx";
|
|
7996
8038
|
if (file === "-") return "json";
|
|
7997
|
-
return formatForExt(
|
|
8039
|
+
return formatForExt(path41.extname(file));
|
|
7998
8040
|
}
|
|
7999
8041
|
function registerBundle(program) {
|
|
8000
8042
|
const cmd = program.command("bundle").description("build an air-gapped bundle (grammars + graph + library catalog)").option("--offline", "offline bundle (default; present for clarity)").option("-o, --out <dir>", "output directory", "vg-bundle").action(function(opts) {
|
|
8001
8043
|
const global = readGlobal(this);
|
|
8002
8044
|
const root2 = rootOf(global);
|
|
8003
|
-
const outDir =
|
|
8045
|
+
const outDir = path41.resolve(root2, opts.out ?? "vg-bundle");
|
|
8004
8046
|
let grammarFiles;
|
|
8005
8047
|
try {
|
|
8006
8048
|
grammarFiles = resolvedGrammarFiles();
|
|
8007
8049
|
} catch {
|
|
8008
8050
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
8009
8051
|
}
|
|
8010
|
-
fs11.mkdirSync(
|
|
8052
|
+
fs11.mkdirSync(path41.join(outDir, "grammars"), { recursive: true });
|
|
8011
8053
|
let grammarCount = 0;
|
|
8012
8054
|
for (const { fileName, absPath } of grammarFiles) {
|
|
8013
|
-
fs11.copyFileSync(absPath,
|
|
8055
|
+
fs11.copyFileSync(absPath, path41.join(outDir, "grammars", fileName));
|
|
8014
8056
|
grammarCount++;
|
|
8015
8057
|
}
|
|
8016
8058
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
8017
8059
|
const graphSrc = resolveGraphPath(root2, global.graph);
|
|
8018
8060
|
if (fs11.existsSync(graphSrc)) {
|
|
8019
|
-
fs11.copyFileSync(graphSrc,
|
|
8061
|
+
fs11.copyFileSync(graphSrc, path41.join(outDir, "graph.json"));
|
|
8020
8062
|
included.push("graph.json");
|
|
8021
8063
|
} else {
|
|
8022
8064
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
8023
8065
|
if (graph) {
|
|
8024
|
-
fs11.writeFileSync(
|
|
8066
|
+
fs11.writeFileSync(path41.join(outDir, "graph.json"), serializeGraph(graph));
|
|
8025
8067
|
included.push("graph.json");
|
|
8026
8068
|
}
|
|
8027
8069
|
}
|
|
8028
8070
|
const cat = catalogPath(root2);
|
|
8029
8071
|
if (fs11.existsSync(cat)) {
|
|
8030
|
-
fs11.copyFileSync(cat,
|
|
8072
|
+
fs11.copyFileSync(cat, path41.join(outDir, "vibgrate.lib.json"));
|
|
8031
8073
|
included.push("vibgrate.lib.json");
|
|
8032
8074
|
if (fs11.existsSync(libDir(root2))) {
|
|
8033
|
-
fs11.cpSync(libDir(root2),
|
|
8075
|
+
fs11.cpSync(libDir(root2), path41.join(outDir, "lib"), { recursive: true });
|
|
8034
8076
|
included.push("lib/");
|
|
8035
8077
|
}
|
|
8036
8078
|
}
|
|
@@ -8042,15 +8084,15 @@ function registerBundle(program) {
|
|
|
8042
8084
|
included,
|
|
8043
8085
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
8044
8086
|
};
|
|
8045
|
-
fs11.writeFileSync(
|
|
8087
|
+
fs11.writeFileSync(path41.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
8046
8088
|
`);
|
|
8047
8089
|
if (global.json) {
|
|
8048
|
-
json({ out:
|
|
8090
|
+
json({ out: path41.relative(root2, outDir), ...manifest });
|
|
8049
8091
|
return;
|
|
8050
8092
|
}
|
|
8051
|
-
info(`${c.cyan("vg bundle")} \xB7 wrote ${
|
|
8093
|
+
info(`${c.cyan("vg bundle")} \xB7 wrote ${path41.relative(root2, outDir)}/`);
|
|
8052
8094
|
for (const i of included) info(` ${c.green("\u2714")} ${i}`);
|
|
8053
|
-
info(c.dim(` offline: vg build --grammars "${
|
|
8095
|
+
info(c.dim(` offline: vg build --grammars "${path41.relative(root2, outDir)}/grammars"`));
|
|
8054
8096
|
});
|
|
8055
8097
|
applyGlobalOptions(cmd);
|
|
8056
8098
|
}
|
|
@@ -8068,7 +8110,7 @@ async function runDoctor(global) {
|
|
|
8068
8110
|
const root2 = rootOf(global);
|
|
8069
8111
|
const local = global.local === true;
|
|
8070
8112
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
8071
|
-
const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(
|
|
8113
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path41.join(root2, f))) ?? null;
|
|
8072
8114
|
const graph = loadGraph(root2, graphPath);
|
|
8073
8115
|
let staleFiles = null;
|
|
8074
8116
|
if (graph) {
|
|
@@ -8094,13 +8136,13 @@ async function runDoctor(global) {
|
|
|
8094
8136
|
root: root2,
|
|
8095
8137
|
configFile,
|
|
8096
8138
|
map: {
|
|
8097
|
-
path:
|
|
8139
|
+
path: path41.relative(root2, graphPath),
|
|
8098
8140
|
built: graph !== null,
|
|
8099
8141
|
generatedAt: graph?.generatedAt ?? null,
|
|
8100
8142
|
staleFiles
|
|
8101
8143
|
},
|
|
8102
8144
|
libCatalog: {
|
|
8103
|
-
path:
|
|
8145
|
+
path: path41.relative(root2, catalogPath(root2)),
|
|
8104
8146
|
present: fs11.existsSync(catalogPath(root2)),
|
|
8105
8147
|
libraries: libCount
|
|
8106
8148
|
},
|
|
@@ -8158,7 +8200,7 @@ async function runDoctor(global) {
|
|
|
8158
8200
|
);
|
|
8159
8201
|
info(
|
|
8160
8202
|
` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
|
|
8161
|
-
` \xB7 last ${
|
|
8203
|
+
` \xB7 last ${path41.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
|
|
8162
8204
|
) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
|
|
8163
8205
|
);
|
|
8164
8206
|
if (li.dynamicOnToken || li.dynamicCustomSampler) {
|
|
@@ -8352,7 +8394,7 @@ function registerDaemon(program) {
|
|
|
8352
8394
|
const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
|
|
8353
8395
|
const global = readGlobal(this);
|
|
8354
8396
|
const socketPath = socketOf(this);
|
|
8355
|
-
const root2 =
|
|
8397
|
+
const root2 = path41.resolve(rootArg ?? rootOf(global));
|
|
8356
8398
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8357
8399
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8358
8400
|
}
|
|
@@ -8388,7 +8430,7 @@ function registerDaemon(program) {
|
|
|
8388
8430
|
const federation = cmd.command("federation").description("register a multi-root federation from .vibgrate/federation.json (or primary cwd)").argument("[root]", "primary repository root (default: cwd)").action(async function(rootArg) {
|
|
8389
8431
|
const global = readGlobal(this);
|
|
8390
8432
|
const socketPath = socketOf(this);
|
|
8391
|
-
const primary =
|
|
8433
|
+
const primary = path41.resolve(rootArg ?? rootOf(global));
|
|
8392
8434
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8393
8435
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8394
8436
|
}
|
|
@@ -8416,7 +8458,7 @@ function registerDaemon(program) {
|
|
|
8416
8458
|
const publish = cmd.command("publish").description("load the workspace code map into vgd ActiveGraph (from global/legacy store)").argument("[root]", "repository root (default: cwd)").option("--git-ref <ref>", "branch or SHA (default: detect HEAD)").action(async function(rootArg) {
|
|
8417
8459
|
const global = readGlobal(this);
|
|
8418
8460
|
const socketPath = socketOf(this);
|
|
8419
|
-
const root2 =
|
|
8461
|
+
const root2 = path41.resolve(rootArg ?? rootOf(global));
|
|
8420
8462
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8421
8463
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8422
8464
|
}
|
|
@@ -8430,7 +8472,7 @@ function registerDaemon(program) {
|
|
|
8430
8472
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
8431
8473
|
}
|
|
8432
8474
|
if (!loaded.ok) {
|
|
8433
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
8475
|
+
const { loadGraph: loadGraph2 } = await import('./load-QBVKCWZT.js');
|
|
8434
8476
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
8435
8477
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
8436
8478
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -8546,7 +8588,7 @@ function socketOf(cmd) {
|
|
|
8546
8588
|
let c2 = cmd;
|
|
8547
8589
|
while (c2) {
|
|
8548
8590
|
const opts = c2.opts();
|
|
8549
|
-
if (opts.socket) return
|
|
8591
|
+
if (opts.socket) return path41.resolve(opts.socket);
|
|
8550
8592
|
c2 = c2.parent;
|
|
8551
8593
|
}
|
|
8552
8594
|
return vgdSocketPath();
|
|
@@ -8823,11 +8865,11 @@ function registerLlmHost(program) {
|
|
|
8823
8865
|
applyGlobalOptions(cmd);
|
|
8824
8866
|
}
|
|
8825
8867
|
var initCommand = new Command("init").description("Initialize vibgrate in a project").argument("[path]", "Path to initialize", ".").option("--baseline", "Create initial baseline after init").option("--yes", "Skip confirmation prompts").action(async (targetPath, opts) => {
|
|
8826
|
-
const rootDir =
|
|
8827
|
-
const vibgrateDir2 =
|
|
8868
|
+
const rootDir = path41.resolve(targetPath);
|
|
8869
|
+
const vibgrateDir2 = path41.join(rootDir, ".vibgrate");
|
|
8828
8870
|
await ensureDir(vibgrateDir2);
|
|
8829
8871
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
|
|
8830
|
-
const configPath =
|
|
8872
|
+
const configPath = path41.join(rootDir, "vibgrate.config.ts");
|
|
8831
8873
|
if (await pathExists(configPath)) {
|
|
8832
8874
|
console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
|
|
8833
8875
|
} else {
|
|
@@ -8835,7 +8877,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
8835
8877
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
8836
8878
|
}
|
|
8837
8879
|
if (opts.baseline) {
|
|
8838
|
-
const { runBaseline } = await import('./baseline-
|
|
8880
|
+
const { runBaseline } = await import('./baseline-KVCXVZFQ.js');
|
|
8839
8881
|
await runBaseline(rootDir);
|
|
8840
8882
|
}
|
|
8841
8883
|
console.log("");
|
|
@@ -8938,7 +8980,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
8938
8980
|
};
|
|
8939
8981
|
}
|
|
8940
8982
|
async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
|
|
8941
|
-
const content = await readFile3(
|
|
8983
|
+
const content = await readFile3(path41.join(rootDir, relFile));
|
|
8942
8984
|
if (!content) return null;
|
|
8943
8985
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8944
8986
|
const re = new RegExp(`\\b${escaped}\\b`);
|
|
@@ -9174,7 +9216,7 @@ var AI_ASSISTANT_DETECTORS = [
|
|
|
9174
9216
|
async function detectAiAssistant(rootDir) {
|
|
9175
9217
|
for (const detector of AI_ASSISTANT_DETECTORS) {
|
|
9176
9218
|
for (const file of detector.files) {
|
|
9177
|
-
if (await pathExists$1(
|
|
9219
|
+
if (await pathExists$1(path41.join(rootDir, file))) {
|
|
9178
9220
|
return detector.name;
|
|
9179
9221
|
}
|
|
9180
9222
|
}
|
|
@@ -9368,7 +9410,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9368
9410
|
collectExcludes,
|
|
9369
9411
|
[]
|
|
9370
9412
|
).option("--concurrency <n>", "Max concurrent npm calls", "8").option("--push", "Auto-push results to Vibgrate API after scan").option("--dsn <dsn>", "DSN token for push (or use VIBGRATE_DSN env)").option("--region <region>", "Override data residency region for push (us, eu)").option("--strict", "Fail on push errors").option("--ui-purpose", "Enable optional UI purpose evidence extraction (slower)").option("--no-local-artifacts", "Do not write .vibgrate JSON artifacts to disk").option("--max-privacy", "Enable strongest privacy mode (minimal scanners, no local artifacts)").option("--offline", "Run without network calls; do not upload results").option("--full", "Comprehensive scan: turns on known-vulnerability detection (= --vulns) and, when a standards policy exists, a banned-dependency report \u2014 on top of drift scoring and the code map").option("--vulns", "Also scan installed dependencies for known vulnerabilities (OSV online, or advisories from --package-manifest when offline)").option("--package-manifest <file>", "Use local package-version manifest JSON/ZIP (for offline mode)").option("--project-scan-timeout <seconds>", "Per-project scan timeout in seconds (default: 180)").option("--drift-budget <score>", "Fail if DriftScore is above budget (0-100)").option("--drift-worsening <percent>", "Fail if drift worsens by more than % since baseline").option("--repository-name <name>", "Override the repository name recorded for this scan (defaults to the directory or package.json name)").option("--force", "Always create a fresh scan ingest, even if the repository is unchanged since the last scan (skips the unchanged/reuse optimization). Used by scheduled and dashboard-triggered scans.").option("--no-graph", "Skip building the local code map (the AI/docs index) that scan produces after scoring drift").option("--quiet", "Suppress promotional output (the free-plan tracking panel and the AI Context install prompt); scan results are unaffected").action(async (targetPath, opts) => {
|
|
9371
|
-
const rootDir =
|
|
9413
|
+
const rootDir = path41.resolve(targetPath);
|
|
9372
9414
|
if (!await pathExists$1(rootDir)) {
|
|
9373
9415
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
9374
9416
|
process.exit(1);
|
|
@@ -9376,7 +9418,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9376
9418
|
const hasDsn = !!resolveDsn(opts.dsn);
|
|
9377
9419
|
const willPush = !opts.offline && (opts.push || hasDsn);
|
|
9378
9420
|
const noLocalArtifacts = opts.localArtifacts === false;
|
|
9379
|
-
const isFirstRun = !await pathExists$1(
|
|
9421
|
+
const isFirstRun = !await pathExists$1(path41.join(rootDir, ".vibgrate", "scan_result.json"));
|
|
9380
9422
|
let pinnedRegion;
|
|
9381
9423
|
let planTier;
|
|
9382
9424
|
let upgradeUrl;
|
|
@@ -9655,11 +9697,11 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9655
9697
|
scanned++;
|
|
9656
9698
|
if (scanned > MAX_ENTRIES2) break;
|
|
9657
9699
|
if (e.isDirectory()) {
|
|
9658
|
-
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(
|
|
9700
|
+
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path41.join(dir, e.name), depth + 1);
|
|
9659
9701
|
continue;
|
|
9660
9702
|
}
|
|
9661
9703
|
if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
|
|
9662
|
-
const abs =
|
|
9704
|
+
const abs = path41.join(dir, e.name);
|
|
9663
9705
|
let mtimeMs;
|
|
9664
9706
|
try {
|
|
9665
9707
|
mtimeMs = fs11.statSync(abs).mtimeMs;
|
|
@@ -9668,7 +9710,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9668
9710
|
}
|
|
9669
9711
|
if (mtimeMs > newest) {
|
|
9670
9712
|
newest = mtimeMs;
|
|
9671
|
-
newestChanged =
|
|
9713
|
+
newestChanged = path41.relative(rootDir, abs) || e.name;
|
|
9672
9714
|
}
|
|
9673
9715
|
}
|
|
9674
9716
|
};
|
|
@@ -9808,13 +9850,13 @@ function analyzeTree(root2, packages) {
|
|
|
9808
9850
|
if (filesSeen >= MAX_FILES) return;
|
|
9809
9851
|
if (entry.isDirectory()) {
|
|
9810
9852
|
if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
9811
|
-
walk2(
|
|
9853
|
+
walk2(path41.join(dir, entry.name), depth + 1);
|
|
9812
9854
|
continue;
|
|
9813
9855
|
}
|
|
9814
|
-
const fileEco = EXT_ECOSYSTEM[
|
|
9856
|
+
const fileEco = EXT_ECOSYSTEM[path41.extname(entry.name)];
|
|
9815
9857
|
if (!fileEco || fileEco === "unknown") continue;
|
|
9816
9858
|
filesSeen++;
|
|
9817
|
-
const full =
|
|
9859
|
+
const full = path41.join(dir, entry.name);
|
|
9818
9860
|
let content;
|
|
9819
9861
|
try {
|
|
9820
9862
|
if (fs11.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
@@ -10129,7 +10171,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
10129
10171
|
}
|
|
10130
10172
|
const outcomes = effective.map((t) => {
|
|
10131
10173
|
const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
|
|
10132
|
-
return { t, res: run(c2,
|
|
10174
|
+
return { t, res: run(c2, path41.join(rootDir, t.dir)) };
|
|
10133
10175
|
});
|
|
10134
10176
|
const failures = outcomes.filter((o) => !o.res.ok);
|
|
10135
10177
|
if (failures.length === 0) {
|
|
@@ -10158,8 +10200,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
10158
10200
|
return results;
|
|
10159
10201
|
}
|
|
10160
10202
|
var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
|
|
10161
|
-
var CACHE_DIR =
|
|
10162
|
-
var CACHE_FILE =
|
|
10203
|
+
var CACHE_DIR = path41.join(os.homedir(), ".vibgrate");
|
|
10204
|
+
var CACHE_FILE = path41.join(CACHE_DIR, "update-check.json");
|
|
10163
10205
|
async function fetchLatestVersion() {
|
|
10164
10206
|
try {
|
|
10165
10207
|
const controller = new AbortController();
|
|
@@ -10191,6 +10233,52 @@ async function writeCache(data) {
|
|
|
10191
10233
|
} catch {
|
|
10192
10234
|
}
|
|
10193
10235
|
}
|
|
10236
|
+
var LOCK_ERROR_RE = /\b(EBUSY|EPERM|ETXTBSY|EACCES)\b|resource busy or locked|being used by another process|access is denied/i;
|
|
10237
|
+
function isFileLockError(output) {
|
|
10238
|
+
return LOCK_ERROR_RE.test(output);
|
|
10239
|
+
}
|
|
10240
|
+
function buildDeferredUpdateScript(opts) {
|
|
10241
|
+
const waitSeconds = opts.waitSeconds ?? 120;
|
|
10242
|
+
return [
|
|
10243
|
+
"@echo off",
|
|
10244
|
+
"setlocal",
|
|
10245
|
+
`set "VG_PID=${opts.pid}"`,
|
|
10246
|
+
`set "VG_LOG=${opts.logPath}"`,
|
|
10247
|
+
'echo Waiting for vg (pid %VG_PID%) to exit so its locked files can be replaced...> "%VG_LOG%"',
|
|
10248
|
+
`for /l %%i in (1,1,${waitSeconds}) do (`,
|
|
10249
|
+
' tasklist /FI "PID eq %VG_PID%" /NH 2>nul | find "%VG_PID%" >nul || goto :run',
|
|
10250
|
+
" ping -n 2 127.0.0.1 >nul",
|
|
10251
|
+
")",
|
|
10252
|
+
":run",
|
|
10253
|
+
`echo Running: ${opts.command}>> "%VG_LOG%"`,
|
|
10254
|
+
`call ${opts.command} >> "%VG_LOG%" 2>&1`,
|
|
10255
|
+
"if errorlevel 1 (",
|
|
10256
|
+
' echo.>> "%VG_LOG%"',
|
|
10257
|
+
' echo Update FAILED. See the npm output above.>> "%VG_LOG%"',
|
|
10258
|
+
") else (",
|
|
10259
|
+
' echo.>> "%VG_LOG%"',
|
|
10260
|
+
' echo Update complete.>> "%VG_LOG%"',
|
|
10261
|
+
")",
|
|
10262
|
+
""
|
|
10263
|
+
].join("\r\n");
|
|
10264
|
+
}
|
|
10265
|
+
function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
|
|
10266
|
+
const stamp = `${pid}-${process.hrtime.bigint().toString(36)}`;
|
|
10267
|
+
const scriptPath = path41.join(dir, `vg-update-${stamp}.cmd`);
|
|
10268
|
+
const logPath = path41.join(dir, `vg-update-${stamp}.log`);
|
|
10269
|
+
try {
|
|
10270
|
+
fs11.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
|
|
10271
|
+
const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
|
|
10272
|
+
detached: true,
|
|
10273
|
+
stdio: "ignore",
|
|
10274
|
+
windowsHide: true
|
|
10275
|
+
});
|
|
10276
|
+
child.unref();
|
|
10277
|
+
return { scriptPath, logPath };
|
|
10278
|
+
} catch {
|
|
10279
|
+
return null;
|
|
10280
|
+
}
|
|
10281
|
+
}
|
|
10194
10282
|
|
|
10195
10283
|
// src/reporting/commands/update.ts
|
|
10196
10284
|
var PACKAGE_NAME = "@vibgrate/cli";
|
|
@@ -10232,14 +10320,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
|
|
|
10232
10320
|
pm: "yarn",
|
|
10233
10321
|
root: () => {
|
|
10234
10322
|
const dir = tryRun("yarn global dir");
|
|
10235
|
-
return dir ?
|
|
10323
|
+
return dir ? path41.join(dir, "node_modules") : null;
|
|
10236
10324
|
}
|
|
10237
10325
|
},
|
|
10238
|
-
{ pm: "bun", root: () =>
|
|
10326
|
+
{ pm: "bun", root: () => path41.join(os.homedir(), ".bun", "install", "global", "node_modules") }
|
|
10239
10327
|
];
|
|
10240
10328
|
for (const probe of probes) {
|
|
10241
10329
|
const root2 = probe.root();
|
|
10242
|
-
if (root2 && await pathExists(
|
|
10330
|
+
if (root2 && await pathExists(path41.join(root2, pkg))) return probe.pm;
|
|
10243
10331
|
}
|
|
10244
10332
|
return null;
|
|
10245
10333
|
}
|
|
@@ -10258,15 +10346,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
|
|
|
10258
10346
|
}
|
|
10259
10347
|
}
|
|
10260
10348
|
async function detectPackageManager(cwd) {
|
|
10261
|
-
if (await pathExists(
|
|
10262
|
-
if (await pathExists(
|
|
10263
|
-
if (await pathExists(
|
|
10349
|
+
if (await pathExists(path41.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
10350
|
+
if (await pathExists(path41.join(cwd, "bun.lockb"))) return "bun";
|
|
10351
|
+
if (await pathExists(path41.join(cwd, "yarn.lock"))) return "yarn";
|
|
10264
10352
|
return "npm";
|
|
10265
10353
|
}
|
|
10266
10354
|
async function detectWorkspaceRoot(cwd) {
|
|
10267
|
-
if (await pathExists(
|
|
10355
|
+
if (await pathExists(path41.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
10268
10356
|
try {
|
|
10269
|
-
const pkgPath =
|
|
10357
|
+
const pkgPath = path41.join(cwd, "package.json");
|
|
10270
10358
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10271
10359
|
const pkg = JSON.parse(raw);
|
|
10272
10360
|
return pkg.workspaces != null;
|
|
@@ -10293,7 +10381,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
|
10293
10381
|
}
|
|
10294
10382
|
async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
10295
10383
|
try {
|
|
10296
|
-
const pkgPath =
|
|
10384
|
+
const pkgPath = path41.join(cwd, "package.json");
|
|
10297
10385
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10298
10386
|
const parsed = JSON.parse(raw);
|
|
10299
10387
|
if (parsed.devDependencies?.[pkg]) return "dev";
|
|
@@ -10303,16 +10391,84 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
|
10303
10391
|
return null;
|
|
10304
10392
|
}
|
|
10305
10393
|
async function confirmWorkspaceRoot(pm) {
|
|
10394
|
+
return confirm3(`Update the ${pm} workspace root with -w? [y/N]: `);
|
|
10395
|
+
}
|
|
10396
|
+
async function confirm3(question) {
|
|
10306
10397
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
|
|
10307
10398
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
10308
10399
|
return new Promise((resolve21) => {
|
|
10309
|
-
rl.question(chalk7.yellow(
|
|
10400
|
+
rl.question(chalk7.yellow(question), (ans) => {
|
|
10310
10401
|
rl.close();
|
|
10311
10402
|
const t = ans.trim().toLowerCase();
|
|
10312
10403
|
resolve21(t === "y" || t === "yes");
|
|
10313
10404
|
});
|
|
10314
10405
|
});
|
|
10315
10406
|
}
|
|
10407
|
+
var CAPTURED_OUTPUT_LIMIT = 64e3;
|
|
10408
|
+
async function runInstall(cmd, cwd) {
|
|
10409
|
+
const { spawn: spawn5 } = await import('child_process');
|
|
10410
|
+
return new Promise((resolve21) => {
|
|
10411
|
+
const child = spawn5(cmd, { cwd, shell: true, stdio: ["inherit", "pipe", "pipe"] });
|
|
10412
|
+
let output = "";
|
|
10413
|
+
const tee = (src, dest) => {
|
|
10414
|
+
if (!src) return;
|
|
10415
|
+
src.setEncoding("utf8");
|
|
10416
|
+
src.on("data", (chunk) => {
|
|
10417
|
+
dest.write(chunk);
|
|
10418
|
+
output += chunk;
|
|
10419
|
+
if (output.length > CAPTURED_OUTPUT_LIMIT) output = output.slice(-CAPTURED_OUTPUT_LIMIT);
|
|
10420
|
+
});
|
|
10421
|
+
};
|
|
10422
|
+
tee(child.stdout, process.stdout);
|
|
10423
|
+
tee(child.stderr, process.stderr);
|
|
10424
|
+
child.on("error", (err) => resolve21({ ok: false, output: `${output}
|
|
10425
|
+
${String(err)}` }));
|
|
10426
|
+
child.on("close", (code) => resolve21({ ok: code === 0, output }));
|
|
10427
|
+
});
|
|
10428
|
+
}
|
|
10429
|
+
async function releaseWindowsFileLocks(cwd, keepVersion) {
|
|
10430
|
+
reapAndReport(cwd, keepVersion);
|
|
10431
|
+
try {
|
|
10432
|
+
const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-54GEZWBI.js');
|
|
10433
|
+
const result = await stopVgd(vgdSocketPath2());
|
|
10434
|
+
if (result === "stopped") {
|
|
10435
|
+
console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
|
|
10436
|
+
} else if (result === "refused") {
|
|
10437
|
+
console.log(
|
|
10438
|
+
chalk7.dim(
|
|
10439
|
+
"A vgd embedded in another process (e.g. vg code) is running \u2014 close that session if the update reports a locked file."
|
|
10440
|
+
)
|
|
10441
|
+
);
|
|
10442
|
+
}
|
|
10443
|
+
} catch {
|
|
10444
|
+
}
|
|
10445
|
+
}
|
|
10446
|
+
async function offerDeferredWindowsUpdate(cmd, assumeYes) {
|
|
10447
|
+
console.error(
|
|
10448
|
+
chalk7.yellow("\nWindows could not replace a file that is still in use.") + chalk7.dim(
|
|
10449
|
+
"\nThis is the self-update case: vg loads native modules (.node), and Windows locks them\nfor as long as a process has them open \u2014 including this one. Re-running the same\ncommand by hand hits the identical lock."
|
|
10450
|
+
)
|
|
10451
|
+
);
|
|
10452
|
+
const proceed = assumeYes || await confirm3("Finish the update automatically after vg exits? [y/N]: ");
|
|
10453
|
+
if (!proceed) {
|
|
10454
|
+
console.error(
|
|
10455
|
+
chalk7.dim(
|
|
10456
|
+
"Skipped. To update manually, close every terminal and editor running vg (including\nMCP servers started by your AI client), then run:\n " + cmd
|
|
10457
|
+
)
|
|
10458
|
+
);
|
|
10459
|
+
return false;
|
|
10460
|
+
}
|
|
10461
|
+
const scheduled = scheduleDeferredUpdate(cmd);
|
|
10462
|
+
if (!scheduled) {
|
|
10463
|
+
console.error(chalk7.red(`Could not schedule the deferred update. Run manually once vg is closed: ${cmd}`));
|
|
10464
|
+
return false;
|
|
10465
|
+
}
|
|
10466
|
+
console.log(
|
|
10467
|
+
chalk7.green("\u2714") + " Update scheduled \u2014 it runs as soon as this process exits.\n" + chalk7.dim(` Transcript: ${scheduled.logPath}
|
|
10468
|
+
`) + chalk7.dim(' Check the new version with "vg --version" in a few seconds.')
|
|
10469
|
+
);
|
|
10470
|
+
return true;
|
|
10471
|
+
}
|
|
10316
10472
|
var updateCommand = new Command("update").description("Update vibgrate to the latest version").option("--check", "Only check for updates, do not install").option("--pm <manager>", "Package manager to use (npm, pnpm, yarn, bun)").option("--global", "Update global installation").option("-y, --yes", "Skip confirmation prompts (e.g. installing at a workspace root)").option("-w, --workspace-root", "Allow updating the pnpm workspace root (implies --yes for that prompt)").option("--no-reap", "Do not signal running vg serve processes on an older version to restart").action(
|
|
10317
10473
|
async (opts) => {
|
|
10318
10474
|
console.log(chalk7.dim(`Current version: ${VERSION}`));
|
|
@@ -10374,10 +10530,16 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10374
10530
|
cmd = getInstallCommand(pm, PACKAGE_NAME, latest, isDev, { workspaceRoot });
|
|
10375
10531
|
console.log(chalk7.dim(`Using ${pm}: ${cmd}`));
|
|
10376
10532
|
}
|
|
10377
|
-
|
|
10378
|
-
|
|
10533
|
+
if (process.platform === "win32" && isGlobal && opts.reap !== false) {
|
|
10534
|
+
await releaseWindowsFileLocks(cwd, latest);
|
|
10535
|
+
}
|
|
10536
|
+
const install = await runInstall(cmd, cwd);
|
|
10537
|
+
if (install.ok) {
|
|
10379
10538
|
console.log(chalk7.green("\u2714") + ` Updated to ${PACKAGE_NAME}@${latest}`);
|
|
10380
|
-
}
|
|
10539
|
+
} else if (process.platform === "win32" && isFileLockError(install.output)) {
|
|
10540
|
+
const scheduled = await offerDeferredWindowsUpdate(cmd, Boolean(opts.yes));
|
|
10541
|
+
process.exit(scheduled ? 0 : 1);
|
|
10542
|
+
} else {
|
|
10381
10543
|
console.error(chalk7.red(`Update failed. Run manually: ${cmd}`));
|
|
10382
10544
|
process.exit(1);
|
|
10383
10545
|
}
|
|
@@ -10392,7 +10554,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10392
10554
|
);
|
|
10393
10555
|
async function rewarmVgdAndReport(cwd) {
|
|
10394
10556
|
try {
|
|
10395
|
-
const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
10557
|
+
const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
|
|
10396
10558
|
if (!await vgdIsRunning2()) return;
|
|
10397
10559
|
const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
|
|
10398
10560
|
if (!loaded.ok || !("repositoryId" in loaded)) return;
|
|
@@ -10481,13 +10643,13 @@ function collectCandidates(artifact) {
|
|
|
10481
10643
|
return out2;
|
|
10482
10644
|
}
|
|
10483
10645
|
var defaultFixScanner = async (rootDir) => {
|
|
10484
|
-
const scratch =
|
|
10646
|
+
const scratch = path41.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
|
|
10485
10647
|
const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
|
|
10486
10648
|
const advanced = await loadAdvancedScanHook();
|
|
10487
10649
|
return runCoreScan(rootDir, scanOpts, advanced);
|
|
10488
10650
|
};
|
|
10489
10651
|
async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
|
|
10490
|
-
const artifactPath =
|
|
10652
|
+
const artifactPath = path41.isAbsolute(inFile) ? inFile : path41.join(rootDir, inFile);
|
|
10491
10653
|
if (await pathExists(artifactPath)) {
|
|
10492
10654
|
const staleness = scanStaleness(rootDir, artifactPath);
|
|
10493
10655
|
if (!staleness.stale) {
|
|
@@ -10514,7 +10676,7 @@ async function repositoryIdentity(rootDir, override) {
|
|
|
10514
10676
|
}
|
|
10515
10677
|
}
|
|
10516
10678
|
var fixCommand = new Command("fix").description("Get ranked, risk-tiered upgrade plans from the hosted planner and optionally apply them (prompts before changing files; --yes applies non-interactively, --dry-run previews, --no-apply only prints). Requires login/DSN.").argument("[path]", "Path to analyse", ".").option("--in <file>", "Scan artifact to read", ".vibgrate/scan_result.json").option("--format <format>", "Output format (text|json|md)", "text").option("--dsn <dsn>", 'DSN token (or use VIBGRATE_DSN env / "vg login")').option("--region <region>", "Override data residency region (us, eu)").option("--repository-name <name>", "Override the repository name recorded for this plan").option("--plan <tier>", "Apply a specific plan non-interactively (safe|balanced|aggressive)").option("--yes", "Apply the recommended plan without prompting").option("--dry-run", "Show what would change without applying").option("--no-apply", "Only print the plans; never modify the project").option("--fail-on-vulns <severity>", "Exit non-zero if the recommended plan leaves an advisory at/above this severity unresolved (low|moderate|high|critical)").action(async (targetPath, opts) => {
|
|
10517
|
-
const rootDir =
|
|
10679
|
+
const rootDir = path41.resolve(targetPath);
|
|
10518
10680
|
if (!await pathExists(rootDir)) {
|
|
10519
10681
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
10520
10682
|
process.exit(1);
|
|
@@ -10675,7 +10837,7 @@ function emit(report, format) {
|
|
|
10675
10837
|
}
|
|
10676
10838
|
}
|
|
10677
10839
|
function relProjectDir(rootDir, projectPath) {
|
|
10678
|
-
const rel =
|
|
10840
|
+
const rel = path41.isAbsolute(projectPath) ? path41.relative(rootDir, projectPath) : projectPath;
|
|
10679
10841
|
return rel === "" ? "." : rel;
|
|
10680
10842
|
}
|
|
10681
10843
|
async function buildTargetResolver(rootDir, artifact) {
|
|
@@ -11510,7 +11672,7 @@ function formatMarkdown(artifact) {
|
|
|
11510
11672
|
|
|
11511
11673
|
// src/reporting/commands/report.ts
|
|
11512
11674
|
var reportCommand = new Command("report").description("Generate a drift report from a scan artifact").option("--in <file>", "Input artifact file", ".vibgrate/scan_result.json").option("--format <format>", "Output format (md|text|json)", "text").action(async (opts) => {
|
|
11513
|
-
const artifactPath =
|
|
11675
|
+
const artifactPath = path41.resolve(opts.in);
|
|
11514
11676
|
if (!await pathExists(artifactPath)) {
|
|
11515
11677
|
console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
|
|
11516
11678
|
console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
|
|
@@ -11559,8 +11721,8 @@ function openUrl(url) {
|
|
|
11559
11721
|
// src/reporting/commands/login.ts
|
|
11560
11722
|
var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
11561
11723
|
function isInside(dir, file) {
|
|
11562
|
-
const rel =
|
|
11563
|
-
return !!rel && !rel.startsWith("..") && !
|
|
11724
|
+
const rel = path41.relative(dir, file);
|
|
11725
|
+
return !!rel && !rel.startsWith("..") && !path41.isAbsolute(rel);
|
|
11564
11726
|
}
|
|
11565
11727
|
var loginCommand = new Command("login").description("Authenticate the CLI with your Vibgrate workspace via the browser").option("--ingest <url>", "Ingest API URL (overrides --region)").option("--region <region>", `Data residency region (${availableRegionIds().join(", ")})`, "us").option("--no-browser", "Do not attempt to open a browser automatically").option(
|
|
11566
11728
|
"--local",
|
|
@@ -11815,7 +11977,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11815
11977
|
try {
|
|
11816
11978
|
const statements = [];
|
|
11817
11979
|
if (opts.from) {
|
|
11818
|
-
const fromPath =
|
|
11980
|
+
const fromPath = path41.resolve(opts.from);
|
|
11819
11981
|
if (!await pathExists(fromPath)) {
|
|
11820
11982
|
process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
|
|
11821
11983
|
`));
|
|
@@ -11833,9 +11995,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11833
11995
|
});
|
|
11834
11996
|
const json2 = JSON.stringify(doc, null, 2);
|
|
11835
11997
|
if (opts.out) {
|
|
11836
|
-
await writeTextFile(
|
|
11998
|
+
await writeTextFile(path41.resolve(opts.out), json2 + "\n");
|
|
11837
11999
|
process.stderr.write(
|
|
11838
|
-
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${
|
|
12000
|
+
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path41.resolve(opts.out)}
|
|
11839
12001
|
`
|
|
11840
12002
|
);
|
|
11841
12003
|
} else {
|
|
@@ -12018,7 +12180,7 @@ function formatDeltaText(base, current) {
|
|
|
12018
12180
|
return lines.join("\n");
|
|
12019
12181
|
}
|
|
12020
12182
|
async function readArtifactOrExit(filePath) {
|
|
12021
|
-
const absolutePath =
|
|
12183
|
+
const absolutePath = path41.resolve(filePath);
|
|
12022
12184
|
if (!await pathExists(absolutePath)) {
|
|
12023
12185
|
console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
|
|
12024
12186
|
process.exit(1);
|
|
@@ -12035,7 +12197,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
|
|
|
12035
12197
|
const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
|
|
12036
12198
|
const body = JSON.stringify(sbom, null, 2);
|
|
12037
12199
|
if (opts.out) {
|
|
12038
|
-
await writeTextFile(
|
|
12200
|
+
await writeTextFile(path41.resolve(opts.out), body);
|
|
12039
12201
|
console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
|
|
12040
12202
|
} else {
|
|
12041
12203
|
console.log(body);
|
|
@@ -12046,7 +12208,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
|
|
|
12046
12208
|
const current = await readArtifactOrExit(opts.to);
|
|
12047
12209
|
const report = formatDeltaText(base, current);
|
|
12048
12210
|
if (opts.out) {
|
|
12049
|
-
await writeTextFile(
|
|
12211
|
+
await writeTextFile(path41.resolve(opts.out), report);
|
|
12050
12212
|
console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
|
|
12051
12213
|
} else {
|
|
12052
12214
|
console.log(report);
|
|
@@ -12177,20 +12339,20 @@ function resolveRegime(id) {
|
|
|
12177
12339
|
return regime;
|
|
12178
12340
|
}
|
|
12179
12341
|
function evidenceDir(root2) {
|
|
12180
|
-
return
|
|
12342
|
+
return path41.join(root2, ".vibgrate", "evidence");
|
|
12181
12343
|
}
|
|
12182
12344
|
function orgPath(root2) {
|
|
12183
|
-
return
|
|
12345
|
+
return path41.join(evidenceDir(root2), "org.json");
|
|
12184
12346
|
}
|
|
12185
12347
|
function productsPath(root2) {
|
|
12186
|
-
return
|
|
12348
|
+
return path41.join(evidenceDir(root2), "products.json");
|
|
12187
12349
|
}
|
|
12188
12350
|
function releasesDir(root2) {
|
|
12189
|
-
return
|
|
12351
|
+
return path41.join(evidenceDir(root2), "releases");
|
|
12190
12352
|
}
|
|
12191
12353
|
function releasePath(root2, productId, version) {
|
|
12192
12354
|
const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12193
|
-
return
|
|
12355
|
+
return path41.join(releasesDir(root2), `${safe}.json`);
|
|
12194
12356
|
}
|
|
12195
12357
|
var DEFAULT_ORG = {
|
|
12196
12358
|
responsiblePersons: [],
|
|
@@ -12221,7 +12383,7 @@ async function freezeRelease(root2, release) {
|
|
|
12221
12383
|
const p = releasePath(root2, release.productId, release.version);
|
|
12222
12384
|
if (await pathExists(p)) {
|
|
12223
12385
|
throw new CliError(
|
|
12224
|
-
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${
|
|
12386
|
+
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path41.relative(root2, p)} only if it was frozen in error`,
|
|
12225
12387
|
ExitCode.USAGE_ERROR
|
|
12226
12388
|
);
|
|
12227
12389
|
}
|
|
@@ -12235,7 +12397,7 @@ async function loadReleases(root2, productId) {
|
|
|
12235
12397
|
const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
12236
12398
|
const releases = [];
|
|
12237
12399
|
for (const f of files) {
|
|
12238
|
-
const rel = await readJsonFile(
|
|
12400
|
+
const rel = await readJsonFile(path41.join(dir, f));
|
|
12239
12401
|
if (!productId || rel.productId === productId) releases.push(rel);
|
|
12240
12402
|
}
|
|
12241
12403
|
return releases;
|
|
@@ -12930,12 +13092,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
|
|
|
12930
13092
|
var DEFAULT_KEY = "attest-key.pem";
|
|
12931
13093
|
function resolveSigningKey(root2, explicit) {
|
|
12932
13094
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
12933
|
-
const keyPath = chosen ?
|
|
13095
|
+
const keyPath = chosen ? path41.resolve(chosen) : path41.join(root2, ".vibgrate", DEFAULT_KEY);
|
|
12934
13096
|
let minted = false;
|
|
12935
13097
|
if (!fs11.existsSync(keyPath)) {
|
|
12936
13098
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
12937
13099
|
const kp = generateKeypair();
|
|
12938
|
-
fs11.mkdirSync(
|
|
13100
|
+
fs11.mkdirSync(path41.dirname(keyPath), { recursive: true });
|
|
12939
13101
|
fs11.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
12940
13102
|
fs11.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
12941
13103
|
minted = true;
|
|
@@ -12953,16 +13115,16 @@ function resolveSigningKey(root2, explicit) {
|
|
|
12953
13115
|
}
|
|
12954
13116
|
function writeBundle(input) {
|
|
12955
13117
|
const dir = input.outDir;
|
|
12956
|
-
fs11.mkdirSync(
|
|
12957
|
-
const write = (rel, data) => fs11.writeFileSync(
|
|
13118
|
+
fs11.mkdirSync(path41.join(dir, "inputs", "releases"), { recursive: true });
|
|
13119
|
+
const write = (rel, data) => fs11.writeFileSync(path41.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
12958
13120
|
`);
|
|
12959
13121
|
write("result.json", input.result);
|
|
12960
|
-
write(
|
|
13122
|
+
write(path41.join("inputs", "advisory.json"), input.advisory);
|
|
12961
13123
|
for (const rel of input.releases) {
|
|
12962
13124
|
const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12963
|
-
write(
|
|
13125
|
+
write(path41.join("inputs", "releases", `${safe}.json`), rel);
|
|
12964
13126
|
}
|
|
12965
|
-
write(
|
|
13127
|
+
write(path41.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
|
|
12966
13128
|
write("provenance.json", {
|
|
12967
13129
|
method: "deterministic",
|
|
12968
13130
|
modelDrafted: [],
|
|
@@ -12978,13 +13140,13 @@ function writeBundle(input) {
|
|
|
12978
13140
|
disclaimer: input.regime.disclaimer
|
|
12979
13141
|
});
|
|
12980
13142
|
if (input.envelope) {
|
|
12981
|
-
fs11.writeFileSync(
|
|
13143
|
+
fs11.writeFileSync(path41.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
12982
13144
|
`);
|
|
12983
13145
|
}
|
|
12984
13146
|
if (input.timestampToken) {
|
|
12985
|
-
fs11.writeFileSync(
|
|
13147
|
+
fs11.writeFileSync(path41.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
12986
13148
|
}
|
|
12987
|
-
fs11.writeFileSync(
|
|
13149
|
+
fs11.writeFileSync(path41.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
12988
13150
|
return dir;
|
|
12989
13151
|
}
|
|
12990
13152
|
function verifyDoc(input) {
|
|
@@ -13045,13 +13207,13 @@ function undeterminedFields(result, regime) {
|
|
|
13045
13207
|
return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
|
|
13046
13208
|
}
|
|
13047
13209
|
async function recordDrill(root2, record) {
|
|
13048
|
-
const dir =
|
|
13049
|
-
const p =
|
|
13210
|
+
const dir = path41.join(evidenceDir(root2), "drills");
|
|
13211
|
+
const p = path41.join(dir, `${record.drillId}.json`);
|
|
13050
13212
|
await writeJsonFile(p, record);
|
|
13051
13213
|
return p;
|
|
13052
13214
|
}
|
|
13053
13215
|
async function hasRecentDrill(root2, asOf) {
|
|
13054
|
-
const dir =
|
|
13216
|
+
const dir = path41.join(evidenceDir(root2), "drills");
|
|
13055
13217
|
if (!await pathExists(dir)) return void 0;
|
|
13056
13218
|
const { readdir } = await import('fs/promises');
|
|
13057
13219
|
const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
|
|
@@ -13059,7 +13221,7 @@ async function hasRecentDrill(root2, asOf) {
|
|
|
13059
13221
|
if (files.length === 0) return void 0;
|
|
13060
13222
|
const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
|
|
13061
13223
|
for (const f of files) {
|
|
13062
|
-
const rec = await readJsonFile2(
|
|
13224
|
+
const rec = await readJsonFile2(path41.join(dir, f));
|
|
13063
13225
|
if (rec.ranAt >= cutoff) return true;
|
|
13064
13226
|
}
|
|
13065
13227
|
return false;
|
|
@@ -13139,7 +13301,7 @@ function formatRegimeList() {
|
|
|
13139
13301
|
|
|
13140
13302
|
// src/reporting/commands/evidence/index.ts
|
|
13141
13303
|
function root(opts) {
|
|
13142
|
-
return
|
|
13304
|
+
return path41.resolve(opts.cwd ?? process.cwd());
|
|
13143
13305
|
}
|
|
13144
13306
|
function slug(name) {
|
|
13145
13307
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
|
|
@@ -13227,7 +13389,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
13227
13389
|
const release = await buildRelease({
|
|
13228
13390
|
productId: product.id,
|
|
13229
13391
|
version,
|
|
13230
|
-
from:
|
|
13392
|
+
from: path41.resolve(rootDir, opts.from),
|
|
13231
13393
|
shipDate: opts.shipDate,
|
|
13232
13394
|
buildId: opts.buildId,
|
|
13233
13395
|
artefactDigest: opts.digest,
|
|
@@ -13235,7 +13397,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
13235
13397
|
frozenAt: nowIso()
|
|
13236
13398
|
});
|
|
13237
13399
|
const p = await freezeRelease(rootDir, release);
|
|
13238
|
-
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${
|
|
13400
|
+
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path41.relative(rootDir, p)}`);
|
|
13239
13401
|
});
|
|
13240
13402
|
async function runExposure(rootDir, vuln, opts) {
|
|
13241
13403
|
const org = await loadOrg(rootDir);
|
|
@@ -13287,7 +13449,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13287
13449
|
console.log("\n" + buildPack(result, regime, org, stage));
|
|
13288
13450
|
}
|
|
13289
13451
|
if (opts.bundle) {
|
|
13290
|
-
const dir =
|
|
13452
|
+
const dir = path41.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
|
|
13291
13453
|
let envelope;
|
|
13292
13454
|
if (opts.sign !== false) {
|
|
13293
13455
|
const { key: key2, minted } = resolveSigningKey(rootDir);
|
|
@@ -13295,7 +13457,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13295
13457
|
envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
|
|
13296
13458
|
}
|
|
13297
13459
|
writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
|
|
13298
|
-
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${
|
|
13460
|
+
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path41.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
|
|
13299
13461
|
}
|
|
13300
13462
|
process.exitCode = exposureExit(result.overallStatus);
|
|
13301
13463
|
});
|
|
@@ -13327,7 +13489,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
13327
13489
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
13328
13490
|
const md = buildPack(result, regime, org, stage);
|
|
13329
13491
|
if (opts.out) {
|
|
13330
|
-
fs11.writeFileSync(
|
|
13492
|
+
fs11.writeFileSync(path41.resolve(rootDir, opts.out), md);
|
|
13331
13493
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
13332
13494
|
} else {
|
|
13333
13495
|
console.log(md);
|
|
@@ -13369,18 +13531,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
13369
13531
|
}
|
|
13370
13532
|
});
|
|
13371
13533
|
var verifyCmd = new Command("verify").description("Verify an evidence bundle offline (no Vibgrate needed)").argument("<bundle>", "Path to an evidence bundle directory or evidence.intoto.jsonl").option("--pub <file>", "Public key PEM to pin the signer (establish trust)").action((bundlePath, opts) => {
|
|
13372
|
-
const abs =
|
|
13373
|
-
const envPath = fs11.statSync(abs).isDirectory() ?
|
|
13534
|
+
const abs = path41.resolve(bundlePath);
|
|
13535
|
+
const envPath = fs11.statSync(abs).isDirectory() ? path41.join(abs, "evidence.intoto.jsonl") : abs;
|
|
13374
13536
|
if (!fs11.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
13375
13537
|
const envelope = JSON.parse(fs11.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
13376
|
-
const resultPath =
|
|
13538
|
+
const resultPath = path41.join(path41.dirname(envPath), "result.json");
|
|
13377
13539
|
const result = fs11.existsSync(resultPath) ? JSON.parse(fs11.readFileSync(resultPath, "utf8")) : void 0;
|
|
13378
|
-
const publicKeyPem = opts.pub ? fs11.readFileSync(
|
|
13540
|
+
const publicKeyPem = opts.pub ? fs11.readFileSync(path41.resolve(opts.pub), "utf8") : void 0;
|
|
13379
13541
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
13380
13542
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
13381
13543
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
13382
13544
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
13383
|
-
const tsrPath =
|
|
13545
|
+
const tsrPath = path41.join(path41.dirname(envPath), "timestamp.tsr");
|
|
13384
13546
|
if (fs11.existsSync(tsrPath) && result) {
|
|
13385
13547
|
const t = verifyTimestamp(fs11.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
13386
13548
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
@@ -13449,12 +13611,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
|
|
|
13449
13611
|
const releases = [];
|
|
13450
13612
|
for (const list of releasesByProduct.values()) releases.push(...list);
|
|
13451
13613
|
const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
|
|
13452
|
-
const dir =
|
|
13453
|
-
await writeJsonFile(
|
|
13454
|
-
await writeJsonFile(
|
|
13455
|
-
for (const r of releases) await writeJsonFile(
|
|
13456
|
-
await writeJsonFile(
|
|
13457
|
-
console.error(chalk7.green("\u2714") + ` exported evidence state to ${
|
|
13614
|
+
const dir = path41.resolve(rootDir, opts.out);
|
|
13615
|
+
await writeJsonFile(path41.join(dir, "org.json"), org);
|
|
13616
|
+
await writeJsonFile(path41.join(dir, "products.json"), products);
|
|
13617
|
+
for (const r of releases) await writeJsonFile(path41.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
|
|
13618
|
+
await writeJsonFile(path41.join(dir, "readiness.json"), report);
|
|
13619
|
+
console.error(chalk7.green("\u2714") + ` exported evidence state to ${path41.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
|
|
13458
13620
|
});
|
|
13459
13621
|
var pushCmd = new Command("push").description("Push the product registry (and an optional exposure result) to Vibgrate Cloud").option(...cwdOption).option("--dsn <dsn>", "DSN token (or use VIBGRATE_DSN env / `vg login`)").option("--regime <id>", "Reporting regime").option("--result <file>", "An exposure result.json (or a bundle dir) to include").option("--signed", "Mark the included exposure result as signed").option("--strict", "Fail on push errors").action(async (opts) => {
|
|
13460
13622
|
const rootDir = root(opts);
|
|
@@ -13480,8 +13642,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
13480
13642
|
}));
|
|
13481
13643
|
let exposure;
|
|
13482
13644
|
if (opts.result) {
|
|
13483
|
-
const raw =
|
|
13484
|
-
const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ?
|
|
13645
|
+
const raw = path41.resolve(rootDir, opts.result);
|
|
13646
|
+
const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path41.join(raw, "result.json") : raw;
|
|
13485
13647
|
if (!fs11.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
13486
13648
|
exposure = JSON.parse(fs11.readFileSync(resultPath, "utf8"));
|
|
13487
13649
|
}
|
|
@@ -13677,7 +13839,7 @@ function dispatch(argv, cwd) {
|
|
|
13677
13839
|
}
|
|
13678
13840
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
13679
13841
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
13680
|
-
if (fs11.existsSync(
|
|
13842
|
+
if (fs11.existsSync(path41.resolve(cwd, first))) {
|
|
13681
13843
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
13682
13844
|
}
|
|
13683
13845
|
const moved = MOVED_COMMANDS[first];
|
|
@@ -13722,9 +13884,9 @@ async function main(argv = process.argv) {
|
|
|
13722
13884
|
}
|
|
13723
13885
|
function readCwd(raw) {
|
|
13724
13886
|
const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
|
|
13725
|
-
if (i >= 0 && raw[i + 1]) return
|
|
13887
|
+
if (i >= 0 && raw[i + 1]) return path41.resolve(raw[i + 1]);
|
|
13726
13888
|
const eq = raw.find((a) => a.startsWith("--cwd="));
|
|
13727
|
-
if (eq) return
|
|
13889
|
+
if (eq) return path41.resolve(eq.slice("--cwd=".length));
|
|
13728
13890
|
return process.cwd();
|
|
13729
13891
|
}
|
|
13730
13892
|
function handleError(err) {
|