@vibgrate/cli 2026.805.1 → 2026.806.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +8 -4
- package/README.md +1 -0
- package/dist/{agent-WH2VVIHM.js → agent-SBVWSP7G.js} +11 -11
- package/dist/{agent-WH2VVIHM.js.map → agent-SBVWSP7G.js.map} +1 -1
- package/dist/{baseline-LMGZURQF.js → baseline-NM53X2TB.js} +3 -3
- package/dist/{baseline-LMGZURQF.js.map → baseline-NM53X2TB.js.map} +1 -1
- package/dist/chunk-3Z6TDWNS.js +6 -0
- package/dist/{chunk-MEKXVHW7.js.map → chunk-3Z6TDWNS.js.map} +1 -1
- package/dist/{chunk-55Q56FD7.js → chunk-5AUCYYBG.js} +6 -6
- package/dist/{chunk-55Q56FD7.js.map → chunk-5AUCYYBG.js.map} +1 -1
- package/dist/{chunk-DG33XQX2.js → chunk-6XP2TQS5.js} +3 -3
- package/dist/{chunk-DG33XQX2.js.map → chunk-6XP2TQS5.js.map} +1 -1
- package/dist/{chunk-B6CWDTAG.js → chunk-A42UDYL2.js} +3 -3
- package/dist/{chunk-B6CWDTAG.js.map → chunk-A42UDYL2.js.map} +1 -1
- package/dist/{chunk-QTKGOXSE.js → chunk-AN7RCXE4.js} +3 -3
- package/dist/{chunk-QTKGOXSE.js.map → chunk-AN7RCXE4.js.map} +1 -1
- package/dist/{chunk-2U4SXS5U.js → chunk-BOAUTBTB.js} +4 -4
- package/dist/{chunk-2U4SXS5U.js.map → chunk-BOAUTBTB.js.map} +1 -1
- package/dist/{chunk-Q6OQPCYC.js → chunk-H4ZIJSHE.js} +7 -7
- package/dist/{chunk-Q6OQPCYC.js.map → chunk-H4ZIJSHE.js.map} +1 -1
- package/dist/{chunk-6LDYH3PR.js → chunk-ITGUM42X.js} +4 -4
- package/dist/{chunk-6LDYH3PR.js.map → chunk-ITGUM42X.js.map} +1 -1
- package/dist/{chunk-AQLP3V5Y.js → chunk-K3KEKY2L.js} +4 -4
- package/dist/{chunk-AQLP3V5Y.js.map → chunk-K3KEKY2L.js.map} +1 -1
- package/dist/{chunk-IA3WXZLB.js → chunk-KACPLPFT.js} +7 -7
- package/dist/{chunk-IA3WXZLB.js.map → chunk-KACPLPFT.js.map} +1 -1
- package/dist/{chunk-FTZGQPHB.js → chunk-LFHXJHOZ.js} +3 -3
- package/dist/{chunk-FTZGQPHB.js.map → chunk-LFHXJHOZ.js.map} +1 -1
- package/dist/{chunk-E72RZJPC.js → chunk-N6LGZBIC.js} +5 -5
- package/dist/{chunk-E72RZJPC.js.map → chunk-N6LGZBIC.js.map} +1 -1
- package/dist/{chunk-TSEE4YUQ.js → chunk-OGJ633I2.js} +5 -5
- package/dist/{chunk-TSEE4YUQ.js.map → chunk-OGJ633I2.js.map} +1 -1
- package/dist/{chunk-5HDCARJE.js → chunk-OKJTAHOL.js} +5 -5
- package/dist/{chunk-5HDCARJE.js.map → chunk-OKJTAHOL.js.map} +1 -1
- package/dist/{chunk-QCEGM4WC.js → chunk-SAHORNZX.js} +4 -4
- package/dist/{chunk-QCEGM4WC.js.map → chunk-SAHORNZX.js.map} +1 -1
- package/dist/{chunk-6IL3UJTE.js → chunk-SMDHK37H.js} +83 -4
- package/dist/chunk-SMDHK37H.js.map +1 -0
- package/dist/{chunk-LGYIYZVS.js → chunk-TWZLUOTR.js} +4 -4
- package/dist/{chunk-LGYIYZVS.js.map → chunk-TWZLUOTR.js.map} +1 -1
- package/dist/{chunk-IFCK26ZD.js → chunk-VJIRJLV2.js} +4 -4
- package/dist/{chunk-IFCK26ZD.js.map → chunk-VJIRJLV2.js.map} +1 -1
- package/dist/{chunk-3ZNFU2GI.js → chunk-VKVGREHC.js} +8 -8
- package/dist/{chunk-3ZNFU2GI.js.map → chunk-VKVGREHC.js.map} +1 -1
- package/dist/{chunk-YW45X2XK.js → chunk-VP5ECB7T.js} +119 -56
- package/dist/chunk-VP5ECB7T.js.map +1 -0
- package/dist/{chunk-4CM33QT2.js → chunk-Y6AMGI4L.js} +84 -6
- package/dist/chunk-Y6AMGI4L.js.map +1 -0
- package/dist/cli.js +386 -242
- package/dist/cli.js.map +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/{ensure-map-HWHMALI4.js → ensure-map-JICVC2ZJ.js} +12 -12
- package/dist/{ensure-map-HWHMALI4.js.map → ensure-map-JICVC2ZJ.js.map} +1 -1
- package/dist/graph-backend-TB35N5MC.js +13 -0
- package/dist/{graph-backend-H42SHYB5.js.map → graph-backend-TB35N5MC.js.map} +1 -1
- package/dist/index.d.ts +75 -9
- package/dist/index.js +11 -11
- package/dist/{interactive-AAKPP4BJ.js → interactive-IJS33F4K.js} +22 -22
- package/dist/{interactive-AAKPP4BJ.js.map → interactive-IJS33F4K.js.map} +1 -1
- package/dist/load-OMTSGVDX.js +9 -0
- package/dist/{load-BB52WJTD.js.map → load-OMTSGVDX.js.map} +1 -1
- package/dist/{run-outcome-TTLHJEDB.js → run-outcome-UENLWBWC.js} +5 -5
- package/dist/{run-outcome-TTLHJEDB.js.map → run-outcome-UENLWBWC.js.map} +1 -1
- package/dist/runtime-session-AFL7P4TQ.js +20 -0
- package/dist/{runtime-session-CKNRMKSK.js.map → runtime-session-AFL7P4TQ.js.map} +1 -1
- package/dist/session-HOS4454T.js +15 -0
- package/dist/{session-5TNNGP2K.js.map → session-HOS4454T.js.map} +1 -1
- package/dist/{stream-json-T6DS3GIO.js → stream-json-SVMGVBFB.js} +11 -11
- package/dist/{stream-json-T6DS3GIO.js.map → stream-json-SVMGVBFB.js.map} +1 -1
- package/dist/{vg-mcp-bridge-AP3B7BN6.js → vg-mcp-bridge-NYCAQEMU.js} +8 -8
- package/dist/{vg-mcp-bridge-AP3B7BN6.js.map → vg-mcp-bridge-NYCAQEMU.js.map} +1 -1
- package/dist/{vgd-FXIEZZT2.js → vgd-YFPJHQB5.js} +8 -8
- package/dist/vgd-YFPJHQB5.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-4CM33QT2.js.map +0 -1
- package/dist/chunk-6IL3UJTE.js.map +0 -1
- package/dist/chunk-MEKXVHW7.js +0 -6
- package/dist/chunk-YW45X2XK.js.map +0 -1
- package/dist/graph-backend-H42SHYB5.js +0 -13
- package/dist/load-BB52WJTD.js +0 -9
- package/dist/runtime-session-CKNRMKSK.js +0 -20
- package/dist/session-5TNNGP2K.js +0 -15
- package/dist/vgd-FXIEZZT2.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-OGJ633I2.js';
|
|
4
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-ITGUM42X.js';
|
|
5
5
|
import './chunk-IS7VTH2Q.js';
|
|
6
|
-
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-
|
|
7
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-
|
|
6
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-K3KEKY2L.js';
|
|
7
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-VKVGREHC.js';
|
|
8
8
|
import './chunk-543E6WDJ.js';
|
|
9
9
|
import './chunk-7AVYKZEM.js';
|
|
10
10
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
11
|
-
import { runCodeSession } from './chunk-
|
|
12
|
-
import { summarizeDiffs, ScriptedProvider } from './chunk-
|
|
11
|
+
import { runCodeSession } from './chunk-OKJTAHOL.js';
|
|
12
|
+
import { summarizeDiffs, ScriptedProvider } from './chunk-BOAUTBTB.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-KACPLPFT.js';
|
|
15
|
+
export { runBuild } from './chunk-KACPLPFT.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-LFHXJHOZ.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 } 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-VP5ECB7T.js';
|
|
27
|
+
import { refreshIfStale } from './chunk-N6LGZBIC.js';
|
|
28
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-TWZLUOTR.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-H4ZIJSHE.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-5AUCYYBG.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-VJIRJLV2.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-Y6AMGI4L.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-AN7RCXE4.js';
|
|
46
|
+
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-A42UDYL2.js';
|
|
47
|
+
import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-SMDHK37H.js';
|
|
48
|
+
import { VERSION } from './chunk-3Z6TDWNS.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);
|
|
@@ -237,11 +237,11 @@ function crashedMessage(signal) {
|
|
|
237
237
|
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
238
|
}
|
|
239
239
|
function defaultCacheDir() {
|
|
240
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
241
|
-
return
|
|
240
|
+
const base = process.env.XDG_CACHE_HOME || path41.join(os.homedir(), ".cache");
|
|
241
|
+
return path41.join(base, "vibgrate", "models");
|
|
242
242
|
}
|
|
243
243
|
function verdictPath(dir) {
|
|
244
|
-
return
|
|
244
|
+
return path41.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
|
|
245
245
|
}
|
|
246
246
|
function readVerdict(dir) {
|
|
247
247
|
try {
|
|
@@ -989,7 +989,7 @@ var PUBLISH_INTERVAL_MS = 2e3;
|
|
|
989
989
|
var KEEPALIVE_MS = 1e4;
|
|
990
990
|
var STALE_MS = 6e4;
|
|
991
991
|
function liveStatsDir(root2) {
|
|
992
|
-
return
|
|
992
|
+
return path41.join(cacheDir(root2), "serve-live");
|
|
993
993
|
}
|
|
994
994
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
995
995
|
let entries;
|
|
@@ -1003,7 +1003,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
1003
1003
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1004
1004
|
let parsed;
|
|
1005
1005
|
try {
|
|
1006
|
-
parsed = JSON.parse(fs11.readFileSync(
|
|
1006
|
+
parsed = JSON.parse(fs11.readFileSync(path41.join(dir, name), "utf8"));
|
|
1007
1007
|
} catch {
|
|
1008
1008
|
continue;
|
|
1009
1009
|
}
|
|
@@ -1025,7 +1025,7 @@ var LiveStatsBus = class {
|
|
|
1025
1025
|
this.dir = dir;
|
|
1026
1026
|
this.stats = stats;
|
|
1027
1027
|
this.pid = pid;
|
|
1028
|
-
this.file =
|
|
1028
|
+
this.file = path41.join(dir, `serve-${this.pid}.json`);
|
|
1029
1029
|
}
|
|
1030
1030
|
dir;
|
|
1031
1031
|
stats;
|
|
@@ -1078,7 +1078,7 @@ var LiveStatsBus = class {
|
|
|
1078
1078
|
const out2 = [];
|
|
1079
1079
|
for (const name of entries.sort()) {
|
|
1080
1080
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1081
|
-
const file =
|
|
1081
|
+
const file = path41.join(this.dir, name);
|
|
1082
1082
|
let parsed;
|
|
1083
1083
|
try {
|
|
1084
1084
|
parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
@@ -1824,7 +1824,7 @@ function endOfLine(text, line) {
|
|
|
1824
1824
|
}
|
|
1825
1825
|
var CACHE_VERSION = "vg-lsp-scan-cache/2";
|
|
1826
1826
|
function cachePath(root2) {
|
|
1827
|
-
return
|
|
1827
|
+
return path41.join(cacheDir(root2), "lsp-scan.json");
|
|
1828
1828
|
}
|
|
1829
1829
|
function manifestHash(root2) {
|
|
1830
1830
|
const files = [];
|
|
@@ -1836,7 +1836,7 @@ function manifestHash(root2) {
|
|
|
1836
1836
|
return;
|
|
1837
1837
|
}
|
|
1838
1838
|
for (const entry of entries) {
|
|
1839
|
-
const abs =
|
|
1839
|
+
const abs = path41.join(dir, entry.name);
|
|
1840
1840
|
if (entry.isDirectory()) {
|
|
1841
1841
|
if (isSkippedDirName(entry.name)) continue;
|
|
1842
1842
|
walk2(abs);
|
|
@@ -1846,7 +1846,7 @@ function manifestHash(root2) {
|
|
|
1846
1846
|
const base = entry.name.toLowerCase();
|
|
1847
1847
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1848
1848
|
try {
|
|
1849
|
-
const rel =
|
|
1849
|
+
const rel = path41.relative(root2, abs).split(path41.sep).join("/");
|
|
1850
1850
|
files.push({ rel, hash: hashBytes(fs11.readFileSync(abs)) });
|
|
1851
1851
|
} catch {
|
|
1852
1852
|
}
|
|
@@ -1857,9 +1857,9 @@ function manifestHash(root2) {
|
|
|
1857
1857
|
return hashString(canonicalize(files));
|
|
1858
1858
|
}
|
|
1859
1859
|
function isDependencyFile(root2, filePath) {
|
|
1860
|
-
const rel =
|
|
1861
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
1862
|
-
const parts = rel.split(
|
|
1860
|
+
const rel = path41.relative(path41.resolve(root2), path41.resolve(filePath));
|
|
1861
|
+
if (rel === "" || rel.startsWith("..") || path41.isAbsolute(rel)) return false;
|
|
1862
|
+
const parts = rel.split(path41.sep);
|
|
1863
1863
|
if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
|
|
1864
1864
|
const base = parts[parts.length - 1].toLowerCase();
|
|
1865
1865
|
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
@@ -1890,7 +1890,7 @@ function writeScanCache(root2, key2, artifact) {
|
|
|
1890
1890
|
var MAX_ENTRIES = 1e3;
|
|
1891
1891
|
var KEEP_ENTRIES = 500;
|
|
1892
1892
|
function historyPath(root2) {
|
|
1893
|
-
return
|
|
1893
|
+
return path41.join(root2, ".vibgrate", "score-history.jsonl");
|
|
1894
1894
|
}
|
|
1895
1895
|
function parseLine(line) {
|
|
1896
1896
|
try {
|
|
@@ -1931,7 +1931,7 @@ function recordScore(root2, entry) {
|
|
|
1931
1931
|
}
|
|
1932
1932
|
}
|
|
1933
1933
|
const file = historyPath(root2);
|
|
1934
|
-
fs11.mkdirSync(
|
|
1934
|
+
fs11.mkdirSync(path41.dirname(file), { recursive: true });
|
|
1935
1935
|
ensureVibgrateGitignore(root2);
|
|
1936
1936
|
fs11.appendFileSync(file, `${JSON.stringify(entry)}
|
|
1937
1937
|
`);
|
|
@@ -2458,6 +2458,11 @@ var VibgrateLanguageServer = class {
|
|
|
2458
2458
|
constructor(opts, output = process.stdout) {
|
|
2459
2459
|
this.opts = opts;
|
|
2460
2460
|
this.conn = new Connection(process.stdin, output);
|
|
2461
|
+
this.refresher = new RefreshScheduler({
|
|
2462
|
+
root: opts.root,
|
|
2463
|
+
graphPath: () => resolveGraphPath(opts.root),
|
|
2464
|
+
onSettled: (outcome) => this.onRefreshSettled(outcome)
|
|
2465
|
+
});
|
|
2461
2466
|
this.register();
|
|
2462
2467
|
}
|
|
2463
2468
|
opts;
|
|
@@ -2477,6 +2482,13 @@ var VibgrateLanguageServer = class {
|
|
|
2477
2482
|
shuttingDown = false;
|
|
2478
2483
|
graph = null;
|
|
2479
2484
|
graphBuilding = false;
|
|
2485
|
+
/**
|
|
2486
|
+
* Keeps the freshness probe / incremental rebuild OFF the query path. The
|
|
2487
|
+
* probe alone stat-walks the whole corpus synchronously (seconds on a 20k-file
|
|
2488
|
+
* workspace) and a real drift rebuilds the map; awaiting either inline made a
|
|
2489
|
+
* single Ask block for over a minute. See engine/refresh-scheduler.ts.
|
|
2490
|
+
*/
|
|
2491
|
+
refresher;
|
|
2480
2492
|
register() {
|
|
2481
2493
|
this.conn.onRequest("initialize", () => ({
|
|
2482
2494
|
capabilities: {
|
|
@@ -2799,18 +2811,30 @@ var VibgrateLanguageServer = class {
|
|
|
2799
2811
|
this.graphBuilding = false;
|
|
2800
2812
|
}
|
|
2801
2813
|
}
|
|
2802
|
-
/**
|
|
2814
|
+
/**
|
|
2815
|
+
* The graph for a query. The first call still builds the map (there is
|
|
2816
|
+
* nothing to answer from otherwise), but a *refresh* is only ever kicked off
|
|
2817
|
+
* here — never awaited to completion. The scheduler waits a micro-budget so a
|
|
2818
|
+
* warm probe can land, then we answer from the map we have; a rebuild that
|
|
2819
|
+
* outruns the budget is picked up by `onRefreshSettled` for the next query.
|
|
2820
|
+
*/
|
|
2803
2821
|
async graphForQuery() {
|
|
2804
2822
|
await this.ensureGraph();
|
|
2805
2823
|
if (!this.graph) return null;
|
|
2806
|
-
|
|
2807
|
-
const refreshed = await refreshIfStale(this.opts.root, { graphPath });
|
|
2808
|
-
if (refreshed.status === "refreshed" && refreshed.wrote) {
|
|
2809
|
-
const reloaded = loadGraph(this.opts.root);
|
|
2810
|
-
if (reloaded) this.graph = reloaded;
|
|
2811
|
-
}
|
|
2824
|
+
await this.refresher.maybeRefresh();
|
|
2812
2825
|
return this.graph;
|
|
2813
2826
|
}
|
|
2827
|
+
/**
|
|
2828
|
+
* A refresh finished. Reload only when it actually rewrote the map — and
|
|
2829
|
+
* prefer the SQLite index, because re-parsing a six-figure-node `graph.json`
|
|
2830
|
+
* is itself multi-second work we must not do more often than the map changes.
|
|
2831
|
+
*/
|
|
2832
|
+
onRefreshSettled(outcome) {
|
|
2833
|
+
if (outcome?.status !== "refreshed" || !outcome.wrote) return;
|
|
2834
|
+
const graphPath = resolveGraphPath(this.opts.root);
|
|
2835
|
+
const reloaded = loadGraphPreferIndex(this.opts.root, graphPath)?.graph ?? loadGraph(this.opts.root);
|
|
2836
|
+
if (reloaded) this.graph = reloaded;
|
|
2837
|
+
}
|
|
2814
2838
|
async onGraphQuery(params) {
|
|
2815
2839
|
const p = params;
|
|
2816
2840
|
const trace = (message) => this.conn.notify("window/logMessage", { type: 3, message: `Vibgrate graph: ${message}` });
|
|
@@ -2878,7 +2902,7 @@ var VibgrateLanguageServer = class {
|
|
|
2878
2902
|
const ecosystem = osvEcosystem(proj.type);
|
|
2879
2903
|
if (!ecosystem) continue;
|
|
2880
2904
|
const relManifest = manifestRelativePath(proj);
|
|
2881
|
-
const absManifest =
|
|
2905
|
+
const absManifest = path41.resolve(this.opts.root, relManifest);
|
|
2882
2906
|
let text = null;
|
|
2883
2907
|
try {
|
|
2884
2908
|
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
@@ -3030,9 +3054,9 @@ function pruneArtifactProjects(a) {
|
|
|
3030
3054
|
return { ...a, projects, findings };
|
|
3031
3055
|
}
|
|
3032
3056
|
function projectByPath(a, projectPath) {
|
|
3033
|
-
const want =
|
|
3057
|
+
const want = path41.normalize(projectPath === "" ? "." : projectPath);
|
|
3034
3058
|
for (const proj of a.projects ?? []) {
|
|
3035
|
-
const got =
|
|
3059
|
+
const got = path41.normalize(proj.path === "" ? "." : proj.path);
|
|
3036
3060
|
if (got === want) return proj;
|
|
3037
3061
|
}
|
|
3038
3062
|
return void 0;
|
|
@@ -3069,12 +3093,12 @@ function buildProjectRefs(rootDir, projects) {
|
|
|
3069
3093
|
return refs.length > 0 ? refs : void 0;
|
|
3070
3094
|
}
|
|
3071
3095
|
function projectForFile(root2, a, filePath) {
|
|
3072
|
-
const dir =
|
|
3096
|
+
const dir = path41.dirname(path41.resolve(filePath));
|
|
3073
3097
|
let best;
|
|
3074
3098
|
let bestLen = -1;
|
|
3075
3099
|
for (const proj of a.projects ?? []) {
|
|
3076
|
-
const projDir =
|
|
3077
|
-
if ((dir === projDir || dir.startsWith(projDir +
|
|
3100
|
+
const projDir = path41.resolve(root2, proj.path);
|
|
3101
|
+
if ((dir === projDir || dir.startsWith(projDir + path41.sep)) && projDir.length > bestLen) {
|
|
3078
3102
|
best = proj;
|
|
3079
3103
|
bestLen = projDir.length;
|
|
3080
3104
|
}
|
|
@@ -3082,7 +3106,7 @@ function projectForFile(root2, a, filePath) {
|
|
|
3082
3106
|
return best;
|
|
3083
3107
|
}
|
|
3084
3108
|
function sameProject(location, projectPath) {
|
|
3085
|
-
return
|
|
3109
|
+
return path41.normalize(location) === path41.normalize(projectPath);
|
|
3086
3110
|
}
|
|
3087
3111
|
function hasReleaseDates(a) {
|
|
3088
3112
|
for (const proj of a.projects ?? []) {
|
|
@@ -3152,7 +3176,7 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3152
3176
|
const relManifest = manifestRelativePath(p);
|
|
3153
3177
|
if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
|
|
3154
3178
|
const ecosystem = osvEcosystem(p.type);
|
|
3155
|
-
const absManifest =
|
|
3179
|
+
const absManifest = path41.resolve(rootDir, relManifest);
|
|
3156
3180
|
let text = null;
|
|
3157
3181
|
try {
|
|
3158
3182
|
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
@@ -3220,34 +3244,34 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3220
3244
|
}
|
|
3221
3245
|
function manifestRelativePath(proj) {
|
|
3222
3246
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3223
|
-
const
|
|
3247
|
+
const join31 = (name) => base ? path41.join(base, name) : name;
|
|
3224
3248
|
switch (proj.type) {
|
|
3225
3249
|
case "node":
|
|
3226
3250
|
case "typescript":
|
|
3227
|
-
return
|
|
3251
|
+
return join31("package.json");
|
|
3228
3252
|
case "python":
|
|
3229
|
-
return
|
|
3253
|
+
return join31("pyproject.toml");
|
|
3230
3254
|
case "go":
|
|
3231
|
-
return
|
|
3255
|
+
return join31("go.mod");
|
|
3232
3256
|
case "rust":
|
|
3233
|
-
return
|
|
3257
|
+
return join31("Cargo.toml");
|
|
3234
3258
|
case "ruby":
|
|
3235
|
-
return
|
|
3259
|
+
return join31("Gemfile");
|
|
3236
3260
|
case "php":
|
|
3237
|
-
return
|
|
3261
|
+
return join31("composer.json");
|
|
3238
3262
|
case "java":
|
|
3239
3263
|
case "kotlin":
|
|
3240
3264
|
case "scala":
|
|
3241
3265
|
case "groovy":
|
|
3242
|
-
return
|
|
3266
|
+
return join31("pom.xml");
|
|
3243
3267
|
case "dotnet":
|
|
3244
|
-
return
|
|
3268
|
+
return join31(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
3245
3269
|
case "dart":
|
|
3246
|
-
return
|
|
3270
|
+
return join31("pubspec.yaml");
|
|
3247
3271
|
case "elixir":
|
|
3248
|
-
return
|
|
3272
|
+
return join31("mix.exs");
|
|
3249
3273
|
default:
|
|
3250
|
-
return
|
|
3274
|
+
return join31("package.json");
|
|
3251
3275
|
}
|
|
3252
3276
|
}
|
|
3253
3277
|
function lockfileRelativePath(rootDir, proj) {
|
|
@@ -3278,9 +3302,9 @@ function lockfileRelativePath(rootDir, proj) {
|
|
|
3278
3302
|
const dirsToTry = base ? [base, ""] : [""];
|
|
3279
3303
|
for (const dir of dirsToTry) {
|
|
3280
3304
|
for (const name of candidateNames) {
|
|
3281
|
-
const rel = dir ?
|
|
3305
|
+
const rel = dir ? path41.join(dir, name) : name;
|
|
3282
3306
|
try {
|
|
3283
|
-
if (fs11.existsSync(
|
|
3307
|
+
if (fs11.existsSync(path41.join(rootDir, rel))) return rel;
|
|
3284
3308
|
} catch {
|
|
3285
3309
|
}
|
|
3286
3310
|
}
|
|
@@ -3351,7 +3375,7 @@ function lookupImportFiles(map, pkg) {
|
|
|
3351
3375
|
}
|
|
3352
3376
|
function firstPackageMentionLine(root2, relFile, pkg) {
|
|
3353
3377
|
try {
|
|
3354
|
-
const abs =
|
|
3378
|
+
const abs = path41.resolve(root2, relFile);
|
|
3355
3379
|
const stat2 = fs11.statSync(abs);
|
|
3356
3380
|
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3357
3381
|
const text = fs11.readFileSync(abs, "utf8");
|
|
@@ -3555,8 +3579,8 @@ function hookCommand(vgBin) {
|
|
|
3555
3579
|
return `${vgBin} hook pre-tool-use`;
|
|
3556
3580
|
}
|
|
3557
3581
|
function installClaudeHooks(root2, vgBin = "vg") {
|
|
3558
|
-
const file =
|
|
3559
|
-
const rel =
|
|
3582
|
+
const file = path41.join(root2, ".claude", "settings.json");
|
|
3583
|
+
const rel = path41.join(".claude", "settings.json");
|
|
3560
3584
|
let settings = {};
|
|
3561
3585
|
if (fs11.existsSync(file)) {
|
|
3562
3586
|
try {
|
|
@@ -3597,8 +3621,8 @@ function installClaudeHooks(root2, vgBin = "vg") {
|
|
|
3597
3621
|
return { file: rel, status: "written" };
|
|
3598
3622
|
}
|
|
3599
3623
|
function uninstallClaudeHooks(root2) {
|
|
3600
|
-
const file =
|
|
3601
|
-
const rel =
|
|
3624
|
+
const file = path41.join(root2, ".claude", "settings.json");
|
|
3625
|
+
const rel = path41.join(".claude", "settings.json");
|
|
3602
3626
|
if (!fs11.existsSync(file)) return { file: rel, status: "unchanged" };
|
|
3603
3627
|
let settings;
|
|
3604
3628
|
try {
|
|
@@ -3624,7 +3648,7 @@ function uninstallClaudeHooks(root2) {
|
|
|
3624
3648
|
return { file: rel, status: "written" };
|
|
3625
3649
|
}
|
|
3626
3650
|
function writeSettings(file, settings) {
|
|
3627
|
-
fs11.mkdirSync(
|
|
3651
|
+
fs11.mkdirSync(path41.dirname(file), { recursive: true });
|
|
3628
3652
|
fs11.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
|
|
3629
3653
|
`);
|
|
3630
3654
|
}
|
|
@@ -3745,7 +3769,7 @@ function registryBase(opts) {
|
|
|
3745
3769
|
return (process.env.VIBGRATE_MODULE_REGISTRY || opts.registry || DEFAULT_REGISTRY).replace(/\/+$/, "");
|
|
3746
3770
|
}
|
|
3747
3771
|
function stateFile() {
|
|
3748
|
-
return
|
|
3772
|
+
return path41.join(path41.dirname(relevanceModuleDir()), "consent.json");
|
|
3749
3773
|
}
|
|
3750
3774
|
function readConsent() {
|
|
3751
3775
|
try {
|
|
@@ -3756,7 +3780,7 @@ function readConsent() {
|
|
|
3756
3780
|
}
|
|
3757
3781
|
function writeConsent(state) {
|
|
3758
3782
|
try {
|
|
3759
|
-
fs11.mkdirSync(
|
|
3783
|
+
fs11.mkdirSync(path41.dirname(stateFile()), { recursive: true });
|
|
3760
3784
|
fs11.writeFileSync(stateFile(), JSON.stringify(state));
|
|
3761
3785
|
} catch {
|
|
3762
3786
|
}
|
|
@@ -3767,8 +3791,8 @@ function kernelDisabled() {
|
|
|
3767
3791
|
}
|
|
3768
3792
|
function moduleInstalled() {
|
|
3769
3793
|
try {
|
|
3770
|
-
const meta = JSON.parse(fs11.readFileSync(
|
|
3771
|
-
if (fs11.existsSync(
|
|
3794
|
+
const meta = JSON.parse(fs11.readFileSync(path41.join(relevanceModuleDir(), ".module.json"), "utf8"));
|
|
3795
|
+
if (fs11.existsSync(path41.join(relevanceModuleDir(), "index.js"))) {
|
|
3772
3796
|
return { installed: true, version: meta.version };
|
|
3773
3797
|
}
|
|
3774
3798
|
} catch {
|
|
@@ -3817,7 +3841,7 @@ function untar(data) {
|
|
|
3817
3841
|
if (type !== "0" && type !== "\0") continue;
|
|
3818
3842
|
const name = pendingName ?? (prefix ? `${prefix}/${rawName}` : rawName);
|
|
3819
3843
|
pendingName = null;
|
|
3820
|
-
if (name.split("/").includes("..") ||
|
|
3844
|
+
if (name.split("/").includes("..") || path41.isAbsolute(name)) {
|
|
3821
3845
|
throw new Error(`unsafe path in tarball: ${name}`);
|
|
3822
3846
|
}
|
|
3823
3847
|
out2.push({ name, body: Buffer.from(body) });
|
|
@@ -3851,17 +3875,17 @@ async function installRelevanceModule(opts = {}) {
|
|
|
3851
3875
|
if (e.name.startsWith("package/dist/")) rel = e.name.slice("package/dist/".length);
|
|
3852
3876
|
else if (e.name === "package/LICENSE" || e.name === "package/README.md") rel = e.name.slice("package/".length);
|
|
3853
3877
|
if (!rel) continue;
|
|
3854
|
-
const target =
|
|
3855
|
-
if (!target.startsWith(dir +
|
|
3856
|
-
fs11.mkdirSync(
|
|
3878
|
+
const target = path41.join(dir, rel);
|
|
3879
|
+
if (!target.startsWith(dir + path41.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
|
|
3880
|
+
fs11.mkdirSync(path41.dirname(target), { recursive: true });
|
|
3857
3881
|
fs11.writeFileSync(target, e.body);
|
|
3858
3882
|
wrote += 1;
|
|
3859
3883
|
}
|
|
3860
|
-
if (!wrote || !fs11.existsSync(
|
|
3884
|
+
if (!wrote || !fs11.existsSync(path41.join(dir, "index.js"))) {
|
|
3861
3885
|
fs11.rmSync(dir, { recursive: true, force: true });
|
|
3862
3886
|
return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
|
|
3863
3887
|
}
|
|
3864
|
-
fs11.writeFileSync(
|
|
3888
|
+
fs11.writeFileSync(path41.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
|
|
3865
3889
|
resetRelevanceProviderCache();
|
|
3866
3890
|
return { status: "installed", version };
|
|
3867
3891
|
} catch (e) {
|
|
@@ -4020,7 +4044,7 @@ function registerShare(program) {
|
|
|
4020
4044
|
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) {
|
|
4021
4045
|
const global = readGlobal(this);
|
|
4022
4046
|
const root2 = rootOf(global);
|
|
4023
|
-
const gitDir =
|
|
4047
|
+
const gitDir = path41.join(root2, ".git");
|
|
4024
4048
|
if (!fs11.existsSync(gitDir)) {
|
|
4025
4049
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
4026
4050
|
}
|
|
@@ -4042,15 +4066,15 @@ function registerShare(program) {
|
|
|
4042
4066
|
applyGlobalOptions(cmd);
|
|
4043
4067
|
}
|
|
4044
4068
|
function writeVibgrateGitignore(root2, reports) {
|
|
4045
|
-
const dir =
|
|
4069
|
+
const dir = path41.join(root2, ".vibgrate");
|
|
4046
4070
|
fs11.mkdirSync(dir, { recursive: true });
|
|
4047
4071
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
4048
4072
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
4049
|
-
fs11.writeFileSync(
|
|
4073
|
+
fs11.writeFileSync(path41.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
4050
4074
|
`);
|
|
4051
4075
|
}
|
|
4052
4076
|
function writeGitAttributes(root2) {
|
|
4053
|
-
const file =
|
|
4077
|
+
const file = path41.join(root2, ".gitattributes");
|
|
4054
4078
|
const line = ".vibgrate/graph.json merge=vg";
|
|
4055
4079
|
let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
|
|
4056
4080
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
@@ -4068,7 +4092,7 @@ function configureMergeDriver(root2) {
|
|
|
4068
4092
|
function installPreCommitHook(root2) {
|
|
4069
4093
|
const hooksDir = hookDir(root2);
|
|
4070
4094
|
fs11.mkdirSync(hooksDir, { recursive: true });
|
|
4071
|
-
const file =
|
|
4095
|
+
const file = path41.join(hooksDir, "pre-commit");
|
|
4072
4096
|
const block = [
|
|
4073
4097
|
HOOK_BEGIN,
|
|
4074
4098
|
"if command -v vg >/dev/null 2>&1; then",
|
|
@@ -4090,14 +4114,14 @@ ${content}`;
|
|
|
4090
4114
|
fs11.chmodSync(file, 493);
|
|
4091
4115
|
}
|
|
4092
4116
|
function undo(root2) {
|
|
4093
|
-
const hookFile =
|
|
4117
|
+
const hookFile = path41.join(hookDir(root2), "pre-commit");
|
|
4094
4118
|
if (fs11.existsSync(hookFile)) {
|
|
4095
4119
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
4096
4120
|
const next2 = fs11.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
4097
4121
|
if (next2.trim() === "#!/bin/sh") fs11.rmSync(hookFile);
|
|
4098
4122
|
else fs11.writeFileSync(hookFile, next2);
|
|
4099
4123
|
}
|
|
4100
|
-
const attr =
|
|
4124
|
+
const attr = path41.join(root2, ".gitattributes");
|
|
4101
4125
|
if (fs11.existsSync(attr)) {
|
|
4102
4126
|
const next2 = fs11.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
4103
4127
|
fs11.writeFileSync(attr, next2);
|
|
@@ -4110,10 +4134,10 @@ function undo(root2) {
|
|
|
4110
4134
|
function hookDir(root2) {
|
|
4111
4135
|
try {
|
|
4112
4136
|
const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
|
|
4113
|
-
if (configured) return
|
|
4137
|
+
if (configured) return path41.resolve(root2, configured);
|
|
4114
4138
|
} catch {
|
|
4115
4139
|
}
|
|
4116
|
-
return
|
|
4140
|
+
return path41.join(root2, ".git", "hooks");
|
|
4117
4141
|
}
|
|
4118
4142
|
function git(root2, args) {
|
|
4119
4143
|
return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
|
|
@@ -4127,7 +4151,7 @@ function registerWatch(program) {
|
|
|
4127
4151
|
const global = readGlobal(this);
|
|
4128
4152
|
const root2 = rootOf(global);
|
|
4129
4153
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
4130
|
-
const watchRoots = (paths.length ? paths : ["."]).map((p) =>
|
|
4154
|
+
const watchRoots = (paths.length ? paths : ["."]).map((p) => path41.resolve(root2, p));
|
|
4131
4155
|
for (const w of watchRoots) {
|
|
4132
4156
|
if (!fs11.existsSync(w)) {
|
|
4133
4157
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
@@ -4195,7 +4219,7 @@ function registerWatch(program) {
|
|
|
4195
4219
|
throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
|
|
4196
4220
|
}
|
|
4197
4221
|
}
|
|
4198
|
-
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) =>
|
|
4222
|
+
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path41.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
|
|
4199
4223
|
await new Promise((resolve21) => {
|
|
4200
4224
|
const stop = () => {
|
|
4201
4225
|
for (const w of watchers) w.close();
|
|
@@ -4528,7 +4552,7 @@ function normalizeStandards(raw) {
|
|
|
4528
4552
|
}
|
|
4529
4553
|
function loadStandards(root2) {
|
|
4530
4554
|
for (const rel of STANDARDS_FILES) {
|
|
4531
|
-
const p =
|
|
4555
|
+
const p = path41__default.join(root2, rel);
|
|
4532
4556
|
let text;
|
|
4533
4557
|
try {
|
|
4534
4558
|
text = fs11__default.readFileSync(p, "utf8");
|
|
@@ -5249,8 +5273,8 @@ async function runHostBench(options = {}) {
|
|
|
5249
5273
|
}
|
|
5250
5274
|
async function runArmSimulate(input) {
|
|
5251
5275
|
const { arm, lib, modelPath, turns, trie, env, live } = input;
|
|
5252
|
-
const
|
|
5253
|
-
const session = await acquireHostSession(lib,
|
|
5276
|
+
const path43 = `${modelPath}#${arm.id}`;
|
|
5277
|
+
const session = await acquireHostSession(lib, path43);
|
|
5254
5278
|
const system = "You are a coding agent with a Task Capsule.";
|
|
5255
5279
|
const capsule = "function readConfig(): Config { return load(); }";
|
|
5256
5280
|
let last = null;
|
|
@@ -6614,8 +6638,8 @@ function registerModels(program) {
|
|
|
6614
6638
|
}
|
|
6615
6639
|
});
|
|
6616
6640
|
if (opts.out) {
|
|
6617
|
-
const outPath =
|
|
6618
|
-
fs11.mkdirSync(
|
|
6641
|
+
const outPath = path41.resolve(opts.out);
|
|
6642
|
+
fs11.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
6619
6643
|
fs11.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
6620
6644
|
`);
|
|
6621
6645
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
@@ -6765,14 +6789,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
|
|
|
6765
6789
|
}
|
|
6766
6790
|
return exact[0];
|
|
6767
6791
|
}
|
|
6768
|
-
const base =
|
|
6792
|
+
const base = path41.basename(wantLc);
|
|
6769
6793
|
const soft = fleet.filter((m) => {
|
|
6770
6794
|
const n = m.name.toLowerCase();
|
|
6771
|
-
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) ||
|
|
6795
|
+
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path41.basename(n) === base;
|
|
6772
6796
|
});
|
|
6773
6797
|
if (soft.length === 1) return soft[0];
|
|
6774
6798
|
if (soft.length > 1) {
|
|
6775
|
-
const baseHits = soft.filter((m) =>
|
|
6799
|
+
const baseHits = soft.filter((m) => path41.basename(m.name).toLowerCase() === base);
|
|
6776
6800
|
const pool = baseHits.length ? baseHits : soft;
|
|
6777
6801
|
const order = ["ollama", "gguf", "lm-studio"];
|
|
6778
6802
|
for (const rt of order) {
|
|
@@ -6810,7 +6834,7 @@ function printBackends(backends) {
|
|
|
6810
6834
|
}
|
|
6811
6835
|
}
|
|
6812
6836
|
function codeConfigPath(root2) {
|
|
6813
|
-
return
|
|
6837
|
+
return path41.join(root2, ".vibgrate", "code.json");
|
|
6814
6838
|
}
|
|
6815
6839
|
function loadCodeConfig(root2) {
|
|
6816
6840
|
try {
|
|
@@ -6892,7 +6916,7 @@ function discoverMcpServers(root2, ownServers) {
|
|
|
6892
6916
|
const servers = {};
|
|
6893
6917
|
const sources = [];
|
|
6894
6918
|
for (const rel of MCP_CONFIG_FILES) {
|
|
6895
|
-
const found = readMcpServersFile(
|
|
6919
|
+
const found = readMcpServersFile(path41.join(root2, rel));
|
|
6896
6920
|
const names = Object.keys(found);
|
|
6897
6921
|
if (names.length) {
|
|
6898
6922
|
sources.push(rel);
|
|
@@ -6924,7 +6948,7 @@ function registerCode(program) {
|
|
|
6924
6948
|
try {
|
|
6925
6949
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6926
6950
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6927
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6951
|
+
const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
|
|
6928
6952
|
const state = readOrchestratorState2();
|
|
6929
6953
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6930
6954
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -7009,7 +7033,7 @@ function registerCode(program) {
|
|
|
7009
7033
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
7010
7034
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
7011
7035
|
}
|
|
7012
|
-
const { runInteractive } = await import('./interactive-
|
|
7036
|
+
const { runInteractive } = await import('./interactive-IJS33F4K.js');
|
|
7013
7037
|
await runInteractive(
|
|
7014
7038
|
rootOf(global),
|
|
7015
7039
|
global,
|
|
@@ -7039,7 +7063,7 @@ function registerCode(program) {
|
|
|
7039
7063
|
}
|
|
7040
7064
|
if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
7041
7065
|
{
|
|
7042
|
-
const { ensureCodeMap } = await import('./ensure-map-
|
|
7066
|
+
const { ensureCodeMap } = await import('./ensure-map-JICVC2ZJ.js');
|
|
7043
7067
|
const mapRoot = rootOf(global);
|
|
7044
7068
|
try {
|
|
7045
7069
|
await ensureCodeMap(mapRoot, global, {
|
|
@@ -7124,20 +7148,20 @@ function registerCode(program) {
|
|
|
7124
7148
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
7125
7149
|
};
|
|
7126
7150
|
try {
|
|
7127
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
7151
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-UENLWBWC.js');
|
|
7128
7152
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
7129
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
7130
|
-
const { nodeCodeFs } = await import('./session-
|
|
7153
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-SVMGVBFB.js');
|
|
7154
|
+
const { nodeCodeFs } = await import('./session-HOS4454T.js');
|
|
7131
7155
|
const readline6 = await import('readline');
|
|
7132
7156
|
const child = await import('child_process');
|
|
7133
7157
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
7134
7158
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7135
7159
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7136
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7137
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7160
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
|
|
7161
|
+
const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
|
|
7138
7162
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7139
7163
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7140
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7164
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
|
|
7141
7165
|
const federation = loadOrDiscoverFederation(root2);
|
|
7142
7166
|
const modelProfile = mergeModelExecutionProfile(
|
|
7143
7167
|
resolveModelExecutionProfile({
|
|
@@ -7195,7 +7219,7 @@ ${res.stderr}` : ""),
|
|
|
7195
7219
|
exitCode: res.status ?? 1
|
|
7196
7220
|
};
|
|
7197
7221
|
};
|
|
7198
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7222
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
|
|
7199
7223
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7200
7224
|
getGraph: () => graph,
|
|
7201
7225
|
root: root2,
|
|
@@ -7216,10 +7240,10 @@ ${res.stderr}` : ""),
|
|
|
7216
7240
|
}
|
|
7217
7241
|
const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
|
|
7218
7242
|
const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
|
|
7219
|
-
const
|
|
7243
|
+
const os6 = await import('os');
|
|
7220
7244
|
const pathMod = await import('path');
|
|
7221
7245
|
const checkpointIndex = pathMod.join(
|
|
7222
|
-
fs11.mkdtempSync(pathMod.join(
|
|
7246
|
+
fs11.mkdtempSync(pathMod.join(os6.tmpdir(), "vg-code-cp-")),
|
|
7223
7247
|
"index"
|
|
7224
7248
|
);
|
|
7225
7249
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -7285,8 +7309,8 @@ ${res.stderr}` : ""),
|
|
|
7285
7309
|
};
|
|
7286
7310
|
try {
|
|
7287
7311
|
if (opts.session) {
|
|
7288
|
-
const { runCodeStreamJsonSession } = await import('./stream-json-
|
|
7289
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
7312
|
+
const { runCodeStreamJsonSession } = await import('./stream-json-SVMGVBFB.js');
|
|
7313
|
+
const { runAgent: runAgent2 } = await import('./agent-SBVWSP7G.js');
|
|
7290
7314
|
const {
|
|
7291
7315
|
condenseSession,
|
|
7292
7316
|
loadLatestSession,
|
|
@@ -7454,8 +7478,8 @@ ${res.stderr}` : ""),
|
|
|
7454
7478
|
if (!autonomous && !tty) {
|
|
7455
7479
|
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).");
|
|
7456
7480
|
}
|
|
7457
|
-
const { agentTask } = await import('./interactive-
|
|
7458
|
-
const { nodeCodeFs } = await import('./session-
|
|
7481
|
+
const { agentTask } = await import('./interactive-IJS33F4K.js');
|
|
7482
|
+
const { nodeCodeFs } = await import('./session-HOS4454T.js');
|
|
7459
7483
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
7460
7484
|
let priorSummary;
|
|
7461
7485
|
let priorInstruction;
|
|
@@ -7468,7 +7492,7 @@ ${res.stderr}` : ""),
|
|
|
7468
7492
|
}
|
|
7469
7493
|
}
|
|
7470
7494
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
7471
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7495
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
|
|
7472
7496
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7473
7497
|
getGraph: () => graph,
|
|
7474
7498
|
root: root2,
|
|
@@ -7492,11 +7516,11 @@ ${res.stderr}` : ""),
|
|
|
7492
7516
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
7493
7517
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7494
7518
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7495
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7496
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7519
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
|
|
7520
|
+
const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
|
|
7497
7521
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7498
7522
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7499
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7523
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
|
|
7500
7524
|
const federation = loadFederation(root2);
|
|
7501
7525
|
const modelProfile = mergeModelExecutionProfile(
|
|
7502
7526
|
resolveModelExecutionProfile({
|
|
@@ -7803,7 +7827,7 @@ async function addCmd(root2, rest, opts, asJson) {
|
|
|
7803
7827
|
}
|
|
7804
7828
|
function readPackageVersion(root2) {
|
|
7805
7829
|
try {
|
|
7806
|
-
const pkg = JSON.parse(fs11__default.readFileSync(
|
|
7830
|
+
const pkg = JSON.parse(fs11__default.readFileSync(path41__default.join(root2, "package.json"), "utf8"));
|
|
7807
7831
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
7808
7832
|
} catch {
|
|
7809
7833
|
return void 0;
|
|
@@ -7826,8 +7850,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
|
|
|
7826
7850
|
if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
|
|
7827
7851
|
const version = (opts.version || readPackageVersion(root2) || "").trim();
|
|
7828
7852
|
if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
|
|
7829
|
-
const readme = readOptionalFile(opts.readme ?
|
|
7830
|
-
const dts = opts.dts ? readOptionalFile(
|
|
7853
|
+
const readme = readOptionalFile(opts.readme ? path41__default.resolve(opts.readme) : path41__default.join(root2, "README.md"));
|
|
7854
|
+
const dts = opts.dts ? readOptionalFile(path41__default.resolve(opts.dts)) : void 0;
|
|
7831
7855
|
if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
|
|
7832
7856
|
const result = await publishPrivateLibrary(
|
|
7833
7857
|
{ name, version, readme, dts, language: opts.language },
|
|
@@ -7959,7 +7983,7 @@ function registerExport(program) {
|
|
|
7959
7983
|
out(content.trimEnd());
|
|
7960
7984
|
return;
|
|
7961
7985
|
}
|
|
7962
|
-
fs11.mkdirSync(
|
|
7986
|
+
fs11.mkdirSync(path41.dirname(path41.resolve(file)), { recursive: true });
|
|
7963
7987
|
fs11.writeFileSync(file, content);
|
|
7964
7988
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
7965
7989
|
});
|
|
@@ -7970,43 +7994,43 @@ function detectFormat(file) {
|
|
|
7970
7994
|
if (lower.endsWith(".cdx.json")) return "cyclonedx";
|
|
7971
7995
|
if (lower.endsWith(".spdx.json")) return "spdx";
|
|
7972
7996
|
if (file === "-") return "json";
|
|
7973
|
-
return formatForExt(
|
|
7997
|
+
return formatForExt(path41.extname(file));
|
|
7974
7998
|
}
|
|
7975
7999
|
function registerBundle(program) {
|
|
7976
8000
|
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) {
|
|
7977
8001
|
const global = readGlobal(this);
|
|
7978
8002
|
const root2 = rootOf(global);
|
|
7979
|
-
const outDir =
|
|
8003
|
+
const outDir = path41.resolve(root2, opts.out ?? "vg-bundle");
|
|
7980
8004
|
let grammarFiles;
|
|
7981
8005
|
try {
|
|
7982
8006
|
grammarFiles = resolvedGrammarFiles();
|
|
7983
8007
|
} catch {
|
|
7984
8008
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
7985
8009
|
}
|
|
7986
|
-
fs11.mkdirSync(
|
|
8010
|
+
fs11.mkdirSync(path41.join(outDir, "grammars"), { recursive: true });
|
|
7987
8011
|
let grammarCount = 0;
|
|
7988
8012
|
for (const { fileName, absPath } of grammarFiles) {
|
|
7989
|
-
fs11.copyFileSync(absPath,
|
|
8013
|
+
fs11.copyFileSync(absPath, path41.join(outDir, "grammars", fileName));
|
|
7990
8014
|
grammarCount++;
|
|
7991
8015
|
}
|
|
7992
8016
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
7993
8017
|
const graphSrc = resolveGraphPath(root2, global.graph);
|
|
7994
8018
|
if (fs11.existsSync(graphSrc)) {
|
|
7995
|
-
fs11.copyFileSync(graphSrc,
|
|
8019
|
+
fs11.copyFileSync(graphSrc, path41.join(outDir, "graph.json"));
|
|
7996
8020
|
included.push("graph.json");
|
|
7997
8021
|
} else {
|
|
7998
8022
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
7999
8023
|
if (graph) {
|
|
8000
|
-
fs11.writeFileSync(
|
|
8024
|
+
fs11.writeFileSync(path41.join(outDir, "graph.json"), serializeGraph(graph));
|
|
8001
8025
|
included.push("graph.json");
|
|
8002
8026
|
}
|
|
8003
8027
|
}
|
|
8004
8028
|
const cat = catalogPath(root2);
|
|
8005
8029
|
if (fs11.existsSync(cat)) {
|
|
8006
|
-
fs11.copyFileSync(cat,
|
|
8030
|
+
fs11.copyFileSync(cat, path41.join(outDir, "vibgrate.lib.json"));
|
|
8007
8031
|
included.push("vibgrate.lib.json");
|
|
8008
8032
|
if (fs11.existsSync(libDir(root2))) {
|
|
8009
|
-
fs11.cpSync(libDir(root2),
|
|
8033
|
+
fs11.cpSync(libDir(root2), path41.join(outDir, "lib"), { recursive: true });
|
|
8010
8034
|
included.push("lib/");
|
|
8011
8035
|
}
|
|
8012
8036
|
}
|
|
@@ -8018,15 +8042,15 @@ function registerBundle(program) {
|
|
|
8018
8042
|
included,
|
|
8019
8043
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
8020
8044
|
};
|
|
8021
|
-
fs11.writeFileSync(
|
|
8045
|
+
fs11.writeFileSync(path41.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
8022
8046
|
`);
|
|
8023
8047
|
if (global.json) {
|
|
8024
|
-
json({ out:
|
|
8048
|
+
json({ out: path41.relative(root2, outDir), ...manifest });
|
|
8025
8049
|
return;
|
|
8026
8050
|
}
|
|
8027
|
-
info(`${c.cyan("vg bundle")} \xB7 wrote ${
|
|
8051
|
+
info(`${c.cyan("vg bundle")} \xB7 wrote ${path41.relative(root2, outDir)}/`);
|
|
8028
8052
|
for (const i of included) info(` ${c.green("\u2714")} ${i}`);
|
|
8029
|
-
info(c.dim(` offline: vg build --grammars "${
|
|
8053
|
+
info(c.dim(` offline: vg build --grammars "${path41.relative(root2, outDir)}/grammars"`));
|
|
8030
8054
|
});
|
|
8031
8055
|
applyGlobalOptions(cmd);
|
|
8032
8056
|
}
|
|
@@ -8044,7 +8068,7 @@ async function runDoctor(global) {
|
|
|
8044
8068
|
const root2 = rootOf(global);
|
|
8045
8069
|
const local = global.local === true;
|
|
8046
8070
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
8047
|
-
const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(
|
|
8071
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path41.join(root2, f))) ?? null;
|
|
8048
8072
|
const graph = loadGraph(root2, graphPath);
|
|
8049
8073
|
let staleFiles = null;
|
|
8050
8074
|
if (graph) {
|
|
@@ -8070,13 +8094,13 @@ async function runDoctor(global) {
|
|
|
8070
8094
|
root: root2,
|
|
8071
8095
|
configFile,
|
|
8072
8096
|
map: {
|
|
8073
|
-
path:
|
|
8097
|
+
path: path41.relative(root2, graphPath),
|
|
8074
8098
|
built: graph !== null,
|
|
8075
8099
|
generatedAt: graph?.generatedAt ?? null,
|
|
8076
8100
|
staleFiles
|
|
8077
8101
|
},
|
|
8078
8102
|
libCatalog: {
|
|
8079
|
-
path:
|
|
8103
|
+
path: path41.relative(root2, catalogPath(root2)),
|
|
8080
8104
|
present: fs11.existsSync(catalogPath(root2)),
|
|
8081
8105
|
libraries: libCount
|
|
8082
8106
|
},
|
|
@@ -8134,7 +8158,7 @@ async function runDoctor(global) {
|
|
|
8134
8158
|
);
|
|
8135
8159
|
info(
|
|
8136
8160
|
` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
|
|
8137
|
-
` \xB7 last ${
|
|
8161
|
+
` \xB7 last ${path41.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
|
|
8138
8162
|
) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
|
|
8139
8163
|
);
|
|
8140
8164
|
if (li.dynamicOnToken || li.dynamicCustomSampler) {
|
|
@@ -8328,7 +8352,7 @@ function registerDaemon(program) {
|
|
|
8328
8352
|
const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
|
|
8329
8353
|
const global = readGlobal(this);
|
|
8330
8354
|
const socketPath = socketOf(this);
|
|
8331
|
-
const root2 =
|
|
8355
|
+
const root2 = path41.resolve(rootArg ?? rootOf(global));
|
|
8332
8356
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8333
8357
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8334
8358
|
}
|
|
@@ -8364,7 +8388,7 @@ function registerDaemon(program) {
|
|
|
8364
8388
|
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) {
|
|
8365
8389
|
const global = readGlobal(this);
|
|
8366
8390
|
const socketPath = socketOf(this);
|
|
8367
|
-
const primary =
|
|
8391
|
+
const primary = path41.resolve(rootArg ?? rootOf(global));
|
|
8368
8392
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8369
8393
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8370
8394
|
}
|
|
@@ -8392,7 +8416,7 @@ function registerDaemon(program) {
|
|
|
8392
8416
|
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) {
|
|
8393
8417
|
const global = readGlobal(this);
|
|
8394
8418
|
const socketPath = socketOf(this);
|
|
8395
|
-
const root2 =
|
|
8419
|
+
const root2 = path41.resolve(rootArg ?? rootOf(global));
|
|
8396
8420
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8397
8421
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8398
8422
|
}
|
|
@@ -8406,7 +8430,7 @@ function registerDaemon(program) {
|
|
|
8406
8430
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
8407
8431
|
}
|
|
8408
8432
|
if (!loaded.ok) {
|
|
8409
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
8433
|
+
const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
|
|
8410
8434
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
8411
8435
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
8412
8436
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -8522,7 +8546,7 @@ function socketOf(cmd) {
|
|
|
8522
8546
|
let c2 = cmd;
|
|
8523
8547
|
while (c2) {
|
|
8524
8548
|
const opts = c2.opts();
|
|
8525
|
-
if (opts.socket) return
|
|
8549
|
+
if (opts.socket) return path41.resolve(opts.socket);
|
|
8526
8550
|
c2 = c2.parent;
|
|
8527
8551
|
}
|
|
8528
8552
|
return vgdSocketPath();
|
|
@@ -8799,11 +8823,11 @@ function registerLlmHost(program) {
|
|
|
8799
8823
|
applyGlobalOptions(cmd);
|
|
8800
8824
|
}
|
|
8801
8825
|
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) => {
|
|
8802
|
-
const rootDir =
|
|
8803
|
-
const vibgrateDir2 =
|
|
8826
|
+
const rootDir = path41.resolve(targetPath);
|
|
8827
|
+
const vibgrateDir2 = path41.join(rootDir, ".vibgrate");
|
|
8804
8828
|
await ensureDir(vibgrateDir2);
|
|
8805
8829
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
|
|
8806
|
-
const configPath =
|
|
8830
|
+
const configPath = path41.join(rootDir, "vibgrate.config.ts");
|
|
8807
8831
|
if (await pathExists(configPath)) {
|
|
8808
8832
|
console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
|
|
8809
8833
|
} else {
|
|
@@ -8811,7 +8835,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
8811
8835
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
8812
8836
|
}
|
|
8813
8837
|
if (opts.baseline) {
|
|
8814
|
-
const { runBaseline } = await import('./baseline-
|
|
8838
|
+
const { runBaseline } = await import('./baseline-NM53X2TB.js');
|
|
8815
8839
|
await runBaseline(rootDir);
|
|
8816
8840
|
}
|
|
8817
8841
|
console.log("");
|
|
@@ -8914,7 +8938,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
8914
8938
|
};
|
|
8915
8939
|
}
|
|
8916
8940
|
async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
|
|
8917
|
-
const content = await readFile3(
|
|
8941
|
+
const content = await readFile3(path41.join(rootDir, relFile));
|
|
8918
8942
|
if (!content) return null;
|
|
8919
8943
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8920
8944
|
const re = new RegExp(`\\b${escaped}\\b`);
|
|
@@ -9150,7 +9174,7 @@ var AI_ASSISTANT_DETECTORS = [
|
|
|
9150
9174
|
async function detectAiAssistant(rootDir) {
|
|
9151
9175
|
for (const detector of AI_ASSISTANT_DETECTORS) {
|
|
9152
9176
|
for (const file of detector.files) {
|
|
9153
|
-
if (await pathExists$1(
|
|
9177
|
+
if (await pathExists$1(path41.join(rootDir, file))) {
|
|
9154
9178
|
return detector.name;
|
|
9155
9179
|
}
|
|
9156
9180
|
}
|
|
@@ -9344,7 +9368,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9344
9368
|
collectExcludes,
|
|
9345
9369
|
[]
|
|
9346
9370
|
).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) => {
|
|
9347
|
-
const rootDir =
|
|
9371
|
+
const rootDir = path41.resolve(targetPath);
|
|
9348
9372
|
if (!await pathExists$1(rootDir)) {
|
|
9349
9373
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
9350
9374
|
process.exit(1);
|
|
@@ -9352,7 +9376,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9352
9376
|
const hasDsn = !!resolveDsn(opts.dsn);
|
|
9353
9377
|
const willPush = !opts.offline && (opts.push || hasDsn);
|
|
9354
9378
|
const noLocalArtifacts = opts.localArtifacts === false;
|
|
9355
|
-
const isFirstRun = !await pathExists$1(
|
|
9379
|
+
const isFirstRun = !await pathExists$1(path41.join(rootDir, ".vibgrate", "scan_result.json"));
|
|
9356
9380
|
let pinnedRegion;
|
|
9357
9381
|
let planTier;
|
|
9358
9382
|
let upgradeUrl;
|
|
@@ -9631,11 +9655,11 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9631
9655
|
scanned++;
|
|
9632
9656
|
if (scanned > MAX_ENTRIES2) break;
|
|
9633
9657
|
if (e.isDirectory()) {
|
|
9634
|
-
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(
|
|
9658
|
+
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path41.join(dir, e.name), depth + 1);
|
|
9635
9659
|
continue;
|
|
9636
9660
|
}
|
|
9637
9661
|
if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
|
|
9638
|
-
const abs =
|
|
9662
|
+
const abs = path41.join(dir, e.name);
|
|
9639
9663
|
let mtimeMs;
|
|
9640
9664
|
try {
|
|
9641
9665
|
mtimeMs = fs11.statSync(abs).mtimeMs;
|
|
@@ -9644,7 +9668,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9644
9668
|
}
|
|
9645
9669
|
if (mtimeMs > newest) {
|
|
9646
9670
|
newest = mtimeMs;
|
|
9647
|
-
newestChanged =
|
|
9671
|
+
newestChanged = path41.relative(rootDir, abs) || e.name;
|
|
9648
9672
|
}
|
|
9649
9673
|
}
|
|
9650
9674
|
};
|
|
@@ -9784,13 +9808,13 @@ function analyzeTree(root2, packages) {
|
|
|
9784
9808
|
if (filesSeen >= MAX_FILES) return;
|
|
9785
9809
|
if (entry.isDirectory()) {
|
|
9786
9810
|
if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
9787
|
-
walk2(
|
|
9811
|
+
walk2(path41.join(dir, entry.name), depth + 1);
|
|
9788
9812
|
continue;
|
|
9789
9813
|
}
|
|
9790
|
-
const fileEco = EXT_ECOSYSTEM[
|
|
9814
|
+
const fileEco = EXT_ECOSYSTEM[path41.extname(entry.name)];
|
|
9791
9815
|
if (!fileEco || fileEco === "unknown") continue;
|
|
9792
9816
|
filesSeen++;
|
|
9793
|
-
const full =
|
|
9817
|
+
const full = path41.join(dir, entry.name);
|
|
9794
9818
|
let content;
|
|
9795
9819
|
try {
|
|
9796
9820
|
if (fs11.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
@@ -10105,7 +10129,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
10105
10129
|
}
|
|
10106
10130
|
const outcomes = effective.map((t) => {
|
|
10107
10131
|
const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
|
|
10108
|
-
return { t, res: run(c2,
|
|
10132
|
+
return { t, res: run(c2, path41.join(rootDir, t.dir)) };
|
|
10109
10133
|
});
|
|
10110
10134
|
const failures = outcomes.filter((o) => !o.res.ok);
|
|
10111
10135
|
if (failures.length === 0) {
|
|
@@ -10134,8 +10158,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
10134
10158
|
return results;
|
|
10135
10159
|
}
|
|
10136
10160
|
var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
|
|
10137
|
-
var CACHE_DIR =
|
|
10138
|
-
var CACHE_FILE =
|
|
10161
|
+
var CACHE_DIR = path41.join(os.homedir(), ".vibgrate");
|
|
10162
|
+
var CACHE_FILE = path41.join(CACHE_DIR, "update-check.json");
|
|
10139
10163
|
async function fetchLatestVersion() {
|
|
10140
10164
|
try {
|
|
10141
10165
|
const controller = new AbortController();
|
|
@@ -10167,6 +10191,52 @@ async function writeCache(data) {
|
|
|
10167
10191
|
} catch {
|
|
10168
10192
|
}
|
|
10169
10193
|
}
|
|
10194
|
+
var LOCK_ERROR_RE = /\b(EBUSY|EPERM|ETXTBSY|EACCES)\b|resource busy or locked|being used by another process|access is denied/i;
|
|
10195
|
+
function isFileLockError(output) {
|
|
10196
|
+
return LOCK_ERROR_RE.test(output);
|
|
10197
|
+
}
|
|
10198
|
+
function buildDeferredUpdateScript(opts) {
|
|
10199
|
+
const waitSeconds = opts.waitSeconds ?? 120;
|
|
10200
|
+
return [
|
|
10201
|
+
"@echo off",
|
|
10202
|
+
"setlocal",
|
|
10203
|
+
`set "VG_PID=${opts.pid}"`,
|
|
10204
|
+
`set "VG_LOG=${opts.logPath}"`,
|
|
10205
|
+
'echo Waiting for vg (pid %VG_PID%) to exit so its locked files can be replaced...> "%VG_LOG%"',
|
|
10206
|
+
`for /l %%i in (1,1,${waitSeconds}) do (`,
|
|
10207
|
+
' tasklist /FI "PID eq %VG_PID%" /NH 2>nul | find "%VG_PID%" >nul || goto :run',
|
|
10208
|
+
" ping -n 2 127.0.0.1 >nul",
|
|
10209
|
+
")",
|
|
10210
|
+
":run",
|
|
10211
|
+
`echo Running: ${opts.command}>> "%VG_LOG%"`,
|
|
10212
|
+
`call ${opts.command} >> "%VG_LOG%" 2>&1`,
|
|
10213
|
+
"if errorlevel 1 (",
|
|
10214
|
+
' echo.>> "%VG_LOG%"',
|
|
10215
|
+
' echo Update FAILED. See the npm output above.>> "%VG_LOG%"',
|
|
10216
|
+
") else (",
|
|
10217
|
+
' echo.>> "%VG_LOG%"',
|
|
10218
|
+
' echo Update complete.>> "%VG_LOG%"',
|
|
10219
|
+
")",
|
|
10220
|
+
""
|
|
10221
|
+
].join("\r\n");
|
|
10222
|
+
}
|
|
10223
|
+
function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
|
|
10224
|
+
const stamp = `${pid}-${process.hrtime.bigint().toString(36)}`;
|
|
10225
|
+
const scriptPath = path41.join(dir, `vg-update-${stamp}.cmd`);
|
|
10226
|
+
const logPath = path41.join(dir, `vg-update-${stamp}.log`);
|
|
10227
|
+
try {
|
|
10228
|
+
fs11.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
|
|
10229
|
+
const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
|
|
10230
|
+
detached: true,
|
|
10231
|
+
stdio: "ignore",
|
|
10232
|
+
windowsHide: true
|
|
10233
|
+
});
|
|
10234
|
+
child.unref();
|
|
10235
|
+
return { scriptPath, logPath };
|
|
10236
|
+
} catch {
|
|
10237
|
+
return null;
|
|
10238
|
+
}
|
|
10239
|
+
}
|
|
10170
10240
|
|
|
10171
10241
|
// src/reporting/commands/update.ts
|
|
10172
10242
|
var PACKAGE_NAME = "@vibgrate/cli";
|
|
@@ -10208,14 +10278,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
|
|
|
10208
10278
|
pm: "yarn",
|
|
10209
10279
|
root: () => {
|
|
10210
10280
|
const dir = tryRun("yarn global dir");
|
|
10211
|
-
return dir ?
|
|
10281
|
+
return dir ? path41.join(dir, "node_modules") : null;
|
|
10212
10282
|
}
|
|
10213
10283
|
},
|
|
10214
|
-
{ pm: "bun", root: () =>
|
|
10284
|
+
{ pm: "bun", root: () => path41.join(os.homedir(), ".bun", "install", "global", "node_modules") }
|
|
10215
10285
|
];
|
|
10216
10286
|
for (const probe of probes) {
|
|
10217
10287
|
const root2 = probe.root();
|
|
10218
|
-
if (root2 && await pathExists(
|
|
10288
|
+
if (root2 && await pathExists(path41.join(root2, pkg))) return probe.pm;
|
|
10219
10289
|
}
|
|
10220
10290
|
return null;
|
|
10221
10291
|
}
|
|
@@ -10234,15 +10304,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
|
|
|
10234
10304
|
}
|
|
10235
10305
|
}
|
|
10236
10306
|
async function detectPackageManager(cwd) {
|
|
10237
|
-
if (await pathExists(
|
|
10238
|
-
if (await pathExists(
|
|
10239
|
-
if (await pathExists(
|
|
10307
|
+
if (await pathExists(path41.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
10308
|
+
if (await pathExists(path41.join(cwd, "bun.lockb"))) return "bun";
|
|
10309
|
+
if (await pathExists(path41.join(cwd, "yarn.lock"))) return "yarn";
|
|
10240
10310
|
return "npm";
|
|
10241
10311
|
}
|
|
10242
10312
|
async function detectWorkspaceRoot(cwd) {
|
|
10243
|
-
if (await pathExists(
|
|
10313
|
+
if (await pathExists(path41.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
10244
10314
|
try {
|
|
10245
|
-
const pkgPath =
|
|
10315
|
+
const pkgPath = path41.join(cwd, "package.json");
|
|
10246
10316
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10247
10317
|
const pkg = JSON.parse(raw);
|
|
10248
10318
|
return pkg.workspaces != null;
|
|
@@ -10269,7 +10339,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
|
10269
10339
|
}
|
|
10270
10340
|
async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
10271
10341
|
try {
|
|
10272
|
-
const pkgPath =
|
|
10342
|
+
const pkgPath = path41.join(cwd, "package.json");
|
|
10273
10343
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10274
10344
|
const parsed = JSON.parse(raw);
|
|
10275
10345
|
if (parsed.devDependencies?.[pkg]) return "dev";
|
|
@@ -10279,16 +10349,84 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
|
10279
10349
|
return null;
|
|
10280
10350
|
}
|
|
10281
10351
|
async function confirmWorkspaceRoot(pm) {
|
|
10352
|
+
return confirm3(`Update the ${pm} workspace root with -w? [y/N]: `);
|
|
10353
|
+
}
|
|
10354
|
+
async function confirm3(question) {
|
|
10282
10355
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
|
|
10283
10356
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
10284
10357
|
return new Promise((resolve21) => {
|
|
10285
|
-
rl.question(chalk7.yellow(
|
|
10358
|
+
rl.question(chalk7.yellow(question), (ans) => {
|
|
10286
10359
|
rl.close();
|
|
10287
10360
|
const t = ans.trim().toLowerCase();
|
|
10288
10361
|
resolve21(t === "y" || t === "yes");
|
|
10289
10362
|
});
|
|
10290
10363
|
});
|
|
10291
10364
|
}
|
|
10365
|
+
var CAPTURED_OUTPUT_LIMIT = 64e3;
|
|
10366
|
+
async function runInstall(cmd, cwd) {
|
|
10367
|
+
const { spawn: spawn5 } = await import('child_process');
|
|
10368
|
+
return new Promise((resolve21) => {
|
|
10369
|
+
const child = spawn5(cmd, { cwd, shell: true, stdio: ["inherit", "pipe", "pipe"] });
|
|
10370
|
+
let output = "";
|
|
10371
|
+
const tee = (src, dest) => {
|
|
10372
|
+
if (!src) return;
|
|
10373
|
+
src.setEncoding("utf8");
|
|
10374
|
+
src.on("data", (chunk) => {
|
|
10375
|
+
dest.write(chunk);
|
|
10376
|
+
output += chunk;
|
|
10377
|
+
if (output.length > CAPTURED_OUTPUT_LIMIT) output = output.slice(-CAPTURED_OUTPUT_LIMIT);
|
|
10378
|
+
});
|
|
10379
|
+
};
|
|
10380
|
+
tee(child.stdout, process.stdout);
|
|
10381
|
+
tee(child.stderr, process.stderr);
|
|
10382
|
+
child.on("error", (err) => resolve21({ ok: false, output: `${output}
|
|
10383
|
+
${String(err)}` }));
|
|
10384
|
+
child.on("close", (code) => resolve21({ ok: code === 0, output }));
|
|
10385
|
+
});
|
|
10386
|
+
}
|
|
10387
|
+
async function releaseWindowsFileLocks(cwd, keepVersion) {
|
|
10388
|
+
reapAndReport(cwd, keepVersion);
|
|
10389
|
+
try {
|
|
10390
|
+
const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-YFPJHQB5.js');
|
|
10391
|
+
const result = await stopVgd(vgdSocketPath2());
|
|
10392
|
+
if (result === "stopped") {
|
|
10393
|
+
console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
|
|
10394
|
+
} else if (result === "refused") {
|
|
10395
|
+
console.log(
|
|
10396
|
+
chalk7.dim(
|
|
10397
|
+
"A vgd embedded in another process (e.g. vg code) is running \u2014 close that session if the update reports a locked file."
|
|
10398
|
+
)
|
|
10399
|
+
);
|
|
10400
|
+
}
|
|
10401
|
+
} catch {
|
|
10402
|
+
}
|
|
10403
|
+
}
|
|
10404
|
+
async function offerDeferredWindowsUpdate(cmd, assumeYes) {
|
|
10405
|
+
console.error(
|
|
10406
|
+
chalk7.yellow("\nWindows could not replace a file that is still in use.") + chalk7.dim(
|
|
10407
|
+
"\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."
|
|
10408
|
+
)
|
|
10409
|
+
);
|
|
10410
|
+
const proceed = assumeYes || await confirm3("Finish the update automatically after vg exits? [y/N]: ");
|
|
10411
|
+
if (!proceed) {
|
|
10412
|
+
console.error(
|
|
10413
|
+
chalk7.dim(
|
|
10414
|
+
"Skipped. To update manually, close every terminal and editor running vg (including\nMCP servers started by your AI client), then run:\n " + cmd
|
|
10415
|
+
)
|
|
10416
|
+
);
|
|
10417
|
+
return false;
|
|
10418
|
+
}
|
|
10419
|
+
const scheduled = scheduleDeferredUpdate(cmd);
|
|
10420
|
+
if (!scheduled) {
|
|
10421
|
+
console.error(chalk7.red(`Could not schedule the deferred update. Run manually once vg is closed: ${cmd}`));
|
|
10422
|
+
return false;
|
|
10423
|
+
}
|
|
10424
|
+
console.log(
|
|
10425
|
+
chalk7.green("\u2714") + " Update scheduled \u2014 it runs as soon as this process exits.\n" + chalk7.dim(` Transcript: ${scheduled.logPath}
|
|
10426
|
+
`) + chalk7.dim(' Check the new version with "vg --version" in a few seconds.')
|
|
10427
|
+
);
|
|
10428
|
+
return true;
|
|
10429
|
+
}
|
|
10292
10430
|
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(
|
|
10293
10431
|
async (opts) => {
|
|
10294
10432
|
console.log(chalk7.dim(`Current version: ${VERSION}`));
|
|
@@ -10350,10 +10488,16 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10350
10488
|
cmd = getInstallCommand(pm, PACKAGE_NAME, latest, isDev, { workspaceRoot });
|
|
10351
10489
|
console.log(chalk7.dim(`Using ${pm}: ${cmd}`));
|
|
10352
10490
|
}
|
|
10353
|
-
|
|
10354
|
-
|
|
10491
|
+
if (process.platform === "win32" && isGlobal && opts.reap !== false) {
|
|
10492
|
+
await releaseWindowsFileLocks(cwd, latest);
|
|
10493
|
+
}
|
|
10494
|
+
const install = await runInstall(cmd, cwd);
|
|
10495
|
+
if (install.ok) {
|
|
10355
10496
|
console.log(chalk7.green("\u2714") + ` Updated to ${PACKAGE_NAME}@${latest}`);
|
|
10356
|
-
}
|
|
10497
|
+
} else if (process.platform === "win32" && isFileLockError(install.output)) {
|
|
10498
|
+
const scheduled = await offerDeferredWindowsUpdate(cmd, Boolean(opts.yes));
|
|
10499
|
+
process.exit(scheduled ? 0 : 1);
|
|
10500
|
+
} else {
|
|
10357
10501
|
console.error(chalk7.red(`Update failed. Run manually: ${cmd}`));
|
|
10358
10502
|
process.exit(1);
|
|
10359
10503
|
}
|
|
@@ -10368,7 +10512,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10368
10512
|
);
|
|
10369
10513
|
async function rewarmVgdAndReport(cwd) {
|
|
10370
10514
|
try {
|
|
10371
|
-
const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
10515
|
+
const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
|
|
10372
10516
|
if (!await vgdIsRunning2()) return;
|
|
10373
10517
|
const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
|
|
10374
10518
|
if (!loaded.ok || !("repositoryId" in loaded)) return;
|
|
@@ -10457,13 +10601,13 @@ function collectCandidates(artifact) {
|
|
|
10457
10601
|
return out2;
|
|
10458
10602
|
}
|
|
10459
10603
|
var defaultFixScanner = async (rootDir) => {
|
|
10460
|
-
const scratch =
|
|
10604
|
+
const scratch = path41.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
|
|
10461
10605
|
const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
|
|
10462
10606
|
const advanced = await loadAdvancedScanHook();
|
|
10463
10607
|
return runCoreScan(rootDir, scanOpts, advanced);
|
|
10464
10608
|
};
|
|
10465
10609
|
async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
|
|
10466
|
-
const artifactPath =
|
|
10610
|
+
const artifactPath = path41.isAbsolute(inFile) ? inFile : path41.join(rootDir, inFile);
|
|
10467
10611
|
if (await pathExists(artifactPath)) {
|
|
10468
10612
|
const staleness = scanStaleness(rootDir, artifactPath);
|
|
10469
10613
|
if (!staleness.stale) {
|
|
@@ -10490,7 +10634,7 @@ async function repositoryIdentity(rootDir, override) {
|
|
|
10490
10634
|
}
|
|
10491
10635
|
}
|
|
10492
10636
|
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) => {
|
|
10493
|
-
const rootDir =
|
|
10637
|
+
const rootDir = path41.resolve(targetPath);
|
|
10494
10638
|
if (!await pathExists(rootDir)) {
|
|
10495
10639
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
10496
10640
|
process.exit(1);
|
|
@@ -10651,7 +10795,7 @@ function emit(report, format) {
|
|
|
10651
10795
|
}
|
|
10652
10796
|
}
|
|
10653
10797
|
function relProjectDir(rootDir, projectPath) {
|
|
10654
|
-
const rel =
|
|
10798
|
+
const rel = path41.isAbsolute(projectPath) ? path41.relative(rootDir, projectPath) : projectPath;
|
|
10655
10799
|
return rel === "" ? "." : rel;
|
|
10656
10800
|
}
|
|
10657
10801
|
async function buildTargetResolver(rootDir, artifact) {
|
|
@@ -11486,7 +11630,7 @@ function formatMarkdown(artifact) {
|
|
|
11486
11630
|
|
|
11487
11631
|
// src/reporting/commands/report.ts
|
|
11488
11632
|
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) => {
|
|
11489
|
-
const artifactPath =
|
|
11633
|
+
const artifactPath = path41.resolve(opts.in);
|
|
11490
11634
|
if (!await pathExists(artifactPath)) {
|
|
11491
11635
|
console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
|
|
11492
11636
|
console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
|
|
@@ -11535,8 +11679,8 @@ function openUrl(url) {
|
|
|
11535
11679
|
// src/reporting/commands/login.ts
|
|
11536
11680
|
var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
11537
11681
|
function isInside(dir, file) {
|
|
11538
|
-
const rel =
|
|
11539
|
-
return !!rel && !rel.startsWith("..") && !
|
|
11682
|
+
const rel = path41.relative(dir, file);
|
|
11683
|
+
return !!rel && !rel.startsWith("..") && !path41.isAbsolute(rel);
|
|
11540
11684
|
}
|
|
11541
11685
|
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(
|
|
11542
11686
|
"--local",
|
|
@@ -11791,7 +11935,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11791
11935
|
try {
|
|
11792
11936
|
const statements = [];
|
|
11793
11937
|
if (opts.from) {
|
|
11794
|
-
const fromPath =
|
|
11938
|
+
const fromPath = path41.resolve(opts.from);
|
|
11795
11939
|
if (!await pathExists(fromPath)) {
|
|
11796
11940
|
process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
|
|
11797
11941
|
`));
|
|
@@ -11809,9 +11953,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11809
11953
|
});
|
|
11810
11954
|
const json2 = JSON.stringify(doc, null, 2);
|
|
11811
11955
|
if (opts.out) {
|
|
11812
|
-
await writeTextFile(
|
|
11956
|
+
await writeTextFile(path41.resolve(opts.out), json2 + "\n");
|
|
11813
11957
|
process.stderr.write(
|
|
11814
|
-
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${
|
|
11958
|
+
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path41.resolve(opts.out)}
|
|
11815
11959
|
`
|
|
11816
11960
|
);
|
|
11817
11961
|
} else {
|
|
@@ -11994,7 +12138,7 @@ function formatDeltaText(base, current) {
|
|
|
11994
12138
|
return lines.join("\n");
|
|
11995
12139
|
}
|
|
11996
12140
|
async function readArtifactOrExit(filePath) {
|
|
11997
|
-
const absolutePath =
|
|
12141
|
+
const absolutePath = path41.resolve(filePath);
|
|
11998
12142
|
if (!await pathExists(absolutePath)) {
|
|
11999
12143
|
console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
|
|
12000
12144
|
process.exit(1);
|
|
@@ -12011,7 +12155,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
|
|
|
12011
12155
|
const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
|
|
12012
12156
|
const body = JSON.stringify(sbom, null, 2);
|
|
12013
12157
|
if (opts.out) {
|
|
12014
|
-
await writeTextFile(
|
|
12158
|
+
await writeTextFile(path41.resolve(opts.out), body);
|
|
12015
12159
|
console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
|
|
12016
12160
|
} else {
|
|
12017
12161
|
console.log(body);
|
|
@@ -12022,7 +12166,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
|
|
|
12022
12166
|
const current = await readArtifactOrExit(opts.to);
|
|
12023
12167
|
const report = formatDeltaText(base, current);
|
|
12024
12168
|
if (opts.out) {
|
|
12025
|
-
await writeTextFile(
|
|
12169
|
+
await writeTextFile(path41.resolve(opts.out), report);
|
|
12026
12170
|
console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
|
|
12027
12171
|
} else {
|
|
12028
12172
|
console.log(report);
|
|
@@ -12153,20 +12297,20 @@ function resolveRegime(id) {
|
|
|
12153
12297
|
return regime;
|
|
12154
12298
|
}
|
|
12155
12299
|
function evidenceDir(root2) {
|
|
12156
|
-
return
|
|
12300
|
+
return path41.join(root2, ".vibgrate", "evidence");
|
|
12157
12301
|
}
|
|
12158
12302
|
function orgPath(root2) {
|
|
12159
|
-
return
|
|
12303
|
+
return path41.join(evidenceDir(root2), "org.json");
|
|
12160
12304
|
}
|
|
12161
12305
|
function productsPath(root2) {
|
|
12162
|
-
return
|
|
12306
|
+
return path41.join(evidenceDir(root2), "products.json");
|
|
12163
12307
|
}
|
|
12164
12308
|
function releasesDir(root2) {
|
|
12165
|
-
return
|
|
12309
|
+
return path41.join(evidenceDir(root2), "releases");
|
|
12166
12310
|
}
|
|
12167
12311
|
function releasePath(root2, productId, version) {
|
|
12168
12312
|
const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12169
|
-
return
|
|
12313
|
+
return path41.join(releasesDir(root2), `${safe}.json`);
|
|
12170
12314
|
}
|
|
12171
12315
|
var DEFAULT_ORG = {
|
|
12172
12316
|
responsiblePersons: [],
|
|
@@ -12197,7 +12341,7 @@ async function freezeRelease(root2, release) {
|
|
|
12197
12341
|
const p = releasePath(root2, release.productId, release.version);
|
|
12198
12342
|
if (await pathExists(p)) {
|
|
12199
12343
|
throw new CliError(
|
|
12200
|
-
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${
|
|
12344
|
+
`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`,
|
|
12201
12345
|
ExitCode.USAGE_ERROR
|
|
12202
12346
|
);
|
|
12203
12347
|
}
|
|
@@ -12211,7 +12355,7 @@ async function loadReleases(root2, productId) {
|
|
|
12211
12355
|
const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
12212
12356
|
const releases = [];
|
|
12213
12357
|
for (const f of files) {
|
|
12214
|
-
const rel = await readJsonFile(
|
|
12358
|
+
const rel = await readJsonFile(path41.join(dir, f));
|
|
12215
12359
|
if (!productId || rel.productId === productId) releases.push(rel);
|
|
12216
12360
|
}
|
|
12217
12361
|
return releases;
|
|
@@ -12906,12 +13050,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
|
|
|
12906
13050
|
var DEFAULT_KEY = "attest-key.pem";
|
|
12907
13051
|
function resolveSigningKey(root2, explicit) {
|
|
12908
13052
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
12909
|
-
const keyPath = chosen ?
|
|
13053
|
+
const keyPath = chosen ? path41.resolve(chosen) : path41.join(root2, ".vibgrate", DEFAULT_KEY);
|
|
12910
13054
|
let minted = false;
|
|
12911
13055
|
if (!fs11.existsSync(keyPath)) {
|
|
12912
13056
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
12913
13057
|
const kp = generateKeypair();
|
|
12914
|
-
fs11.mkdirSync(
|
|
13058
|
+
fs11.mkdirSync(path41.dirname(keyPath), { recursive: true });
|
|
12915
13059
|
fs11.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
12916
13060
|
fs11.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
12917
13061
|
minted = true;
|
|
@@ -12929,16 +13073,16 @@ function resolveSigningKey(root2, explicit) {
|
|
|
12929
13073
|
}
|
|
12930
13074
|
function writeBundle(input) {
|
|
12931
13075
|
const dir = input.outDir;
|
|
12932
|
-
fs11.mkdirSync(
|
|
12933
|
-
const write = (rel, data) => fs11.writeFileSync(
|
|
13076
|
+
fs11.mkdirSync(path41.join(dir, "inputs", "releases"), { recursive: true });
|
|
13077
|
+
const write = (rel, data) => fs11.writeFileSync(path41.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
12934
13078
|
`);
|
|
12935
13079
|
write("result.json", input.result);
|
|
12936
|
-
write(
|
|
13080
|
+
write(path41.join("inputs", "advisory.json"), input.advisory);
|
|
12937
13081
|
for (const rel of input.releases) {
|
|
12938
13082
|
const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12939
|
-
write(
|
|
13083
|
+
write(path41.join("inputs", "releases", `${safe}.json`), rel);
|
|
12940
13084
|
}
|
|
12941
|
-
write(
|
|
13085
|
+
write(path41.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
|
|
12942
13086
|
write("provenance.json", {
|
|
12943
13087
|
method: "deterministic",
|
|
12944
13088
|
modelDrafted: [],
|
|
@@ -12954,13 +13098,13 @@ function writeBundle(input) {
|
|
|
12954
13098
|
disclaimer: input.regime.disclaimer
|
|
12955
13099
|
});
|
|
12956
13100
|
if (input.envelope) {
|
|
12957
|
-
fs11.writeFileSync(
|
|
13101
|
+
fs11.writeFileSync(path41.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
12958
13102
|
`);
|
|
12959
13103
|
}
|
|
12960
13104
|
if (input.timestampToken) {
|
|
12961
|
-
fs11.writeFileSync(
|
|
13105
|
+
fs11.writeFileSync(path41.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
12962
13106
|
}
|
|
12963
|
-
fs11.writeFileSync(
|
|
13107
|
+
fs11.writeFileSync(path41.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
12964
13108
|
return dir;
|
|
12965
13109
|
}
|
|
12966
13110
|
function verifyDoc(input) {
|
|
@@ -13021,13 +13165,13 @@ function undeterminedFields(result, regime) {
|
|
|
13021
13165
|
return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
|
|
13022
13166
|
}
|
|
13023
13167
|
async function recordDrill(root2, record) {
|
|
13024
|
-
const dir =
|
|
13025
|
-
const p =
|
|
13168
|
+
const dir = path41.join(evidenceDir(root2), "drills");
|
|
13169
|
+
const p = path41.join(dir, `${record.drillId}.json`);
|
|
13026
13170
|
await writeJsonFile(p, record);
|
|
13027
13171
|
return p;
|
|
13028
13172
|
}
|
|
13029
13173
|
async function hasRecentDrill(root2, asOf) {
|
|
13030
|
-
const dir =
|
|
13174
|
+
const dir = path41.join(evidenceDir(root2), "drills");
|
|
13031
13175
|
if (!await pathExists(dir)) return void 0;
|
|
13032
13176
|
const { readdir } = await import('fs/promises');
|
|
13033
13177
|
const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
|
|
@@ -13035,7 +13179,7 @@ async function hasRecentDrill(root2, asOf) {
|
|
|
13035
13179
|
if (files.length === 0) return void 0;
|
|
13036
13180
|
const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
|
|
13037
13181
|
for (const f of files) {
|
|
13038
|
-
const rec = await readJsonFile2(
|
|
13182
|
+
const rec = await readJsonFile2(path41.join(dir, f));
|
|
13039
13183
|
if (rec.ranAt >= cutoff) return true;
|
|
13040
13184
|
}
|
|
13041
13185
|
return false;
|
|
@@ -13115,7 +13259,7 @@ function formatRegimeList() {
|
|
|
13115
13259
|
|
|
13116
13260
|
// src/reporting/commands/evidence/index.ts
|
|
13117
13261
|
function root(opts) {
|
|
13118
|
-
return
|
|
13262
|
+
return path41.resolve(opts.cwd ?? process.cwd());
|
|
13119
13263
|
}
|
|
13120
13264
|
function slug(name) {
|
|
13121
13265
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
|
|
@@ -13203,7 +13347,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
13203
13347
|
const release = await buildRelease({
|
|
13204
13348
|
productId: product.id,
|
|
13205
13349
|
version,
|
|
13206
|
-
from:
|
|
13350
|
+
from: path41.resolve(rootDir, opts.from),
|
|
13207
13351
|
shipDate: opts.shipDate,
|
|
13208
13352
|
buildId: opts.buildId,
|
|
13209
13353
|
artefactDigest: opts.digest,
|
|
@@ -13211,7 +13355,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
13211
13355
|
frozenAt: nowIso()
|
|
13212
13356
|
});
|
|
13213
13357
|
const p = await freezeRelease(rootDir, release);
|
|
13214
|
-
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${
|
|
13358
|
+
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path41.relative(rootDir, p)}`);
|
|
13215
13359
|
});
|
|
13216
13360
|
async function runExposure(rootDir, vuln, opts) {
|
|
13217
13361
|
const org = await loadOrg(rootDir);
|
|
@@ -13263,7 +13407,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13263
13407
|
console.log("\n" + buildPack(result, regime, org, stage));
|
|
13264
13408
|
}
|
|
13265
13409
|
if (opts.bundle) {
|
|
13266
|
-
const dir =
|
|
13410
|
+
const dir = path41.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
|
|
13267
13411
|
let envelope;
|
|
13268
13412
|
if (opts.sign !== false) {
|
|
13269
13413
|
const { key: key2, minted } = resolveSigningKey(rootDir);
|
|
@@ -13271,7 +13415,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13271
13415
|
envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
|
|
13272
13416
|
}
|
|
13273
13417
|
writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
|
|
13274
|
-
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${
|
|
13418
|
+
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path41.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
|
|
13275
13419
|
}
|
|
13276
13420
|
process.exitCode = exposureExit(result.overallStatus);
|
|
13277
13421
|
});
|
|
@@ -13303,7 +13447,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
13303
13447
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
13304
13448
|
const md = buildPack(result, regime, org, stage);
|
|
13305
13449
|
if (opts.out) {
|
|
13306
|
-
fs11.writeFileSync(
|
|
13450
|
+
fs11.writeFileSync(path41.resolve(rootDir, opts.out), md);
|
|
13307
13451
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
13308
13452
|
} else {
|
|
13309
13453
|
console.log(md);
|
|
@@ -13345,18 +13489,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
13345
13489
|
}
|
|
13346
13490
|
});
|
|
13347
13491
|
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) => {
|
|
13348
|
-
const abs =
|
|
13349
|
-
const envPath = fs11.statSync(abs).isDirectory() ?
|
|
13492
|
+
const abs = path41.resolve(bundlePath);
|
|
13493
|
+
const envPath = fs11.statSync(abs).isDirectory() ? path41.join(abs, "evidence.intoto.jsonl") : abs;
|
|
13350
13494
|
if (!fs11.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
13351
13495
|
const envelope = JSON.parse(fs11.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
13352
|
-
const resultPath =
|
|
13496
|
+
const resultPath = path41.join(path41.dirname(envPath), "result.json");
|
|
13353
13497
|
const result = fs11.existsSync(resultPath) ? JSON.parse(fs11.readFileSync(resultPath, "utf8")) : void 0;
|
|
13354
|
-
const publicKeyPem = opts.pub ? fs11.readFileSync(
|
|
13498
|
+
const publicKeyPem = opts.pub ? fs11.readFileSync(path41.resolve(opts.pub), "utf8") : void 0;
|
|
13355
13499
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
13356
13500
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
13357
13501
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
13358
13502
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
13359
|
-
const tsrPath =
|
|
13503
|
+
const tsrPath = path41.join(path41.dirname(envPath), "timestamp.tsr");
|
|
13360
13504
|
if (fs11.existsSync(tsrPath) && result) {
|
|
13361
13505
|
const t = verifyTimestamp(fs11.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
13362
13506
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
@@ -13425,12 +13569,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
|
|
|
13425
13569
|
const releases = [];
|
|
13426
13570
|
for (const list of releasesByProduct.values()) releases.push(...list);
|
|
13427
13571
|
const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
|
|
13428
|
-
const dir =
|
|
13429
|
-
await writeJsonFile(
|
|
13430
|
-
await writeJsonFile(
|
|
13431
|
-
for (const r of releases) await writeJsonFile(
|
|
13432
|
-
await writeJsonFile(
|
|
13433
|
-
console.error(chalk7.green("\u2714") + ` exported evidence state to ${
|
|
13572
|
+
const dir = path41.resolve(rootDir, opts.out);
|
|
13573
|
+
await writeJsonFile(path41.join(dir, "org.json"), org);
|
|
13574
|
+
await writeJsonFile(path41.join(dir, "products.json"), products);
|
|
13575
|
+
for (const r of releases) await writeJsonFile(path41.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
|
|
13576
|
+
await writeJsonFile(path41.join(dir, "readiness.json"), report);
|
|
13577
|
+
console.error(chalk7.green("\u2714") + ` exported evidence state to ${path41.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
|
|
13434
13578
|
});
|
|
13435
13579
|
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) => {
|
|
13436
13580
|
const rootDir = root(opts);
|
|
@@ -13456,8 +13600,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
13456
13600
|
}));
|
|
13457
13601
|
let exposure;
|
|
13458
13602
|
if (opts.result) {
|
|
13459
|
-
const raw =
|
|
13460
|
-
const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ?
|
|
13603
|
+
const raw = path41.resolve(rootDir, opts.result);
|
|
13604
|
+
const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path41.join(raw, "result.json") : raw;
|
|
13461
13605
|
if (!fs11.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
13462
13606
|
exposure = JSON.parse(fs11.readFileSync(resultPath, "utf8"));
|
|
13463
13607
|
}
|
|
@@ -13653,7 +13797,7 @@ function dispatch(argv, cwd) {
|
|
|
13653
13797
|
}
|
|
13654
13798
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
13655
13799
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
13656
|
-
if (fs11.existsSync(
|
|
13800
|
+
if (fs11.existsSync(path41.resolve(cwd, first))) {
|
|
13657
13801
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
13658
13802
|
}
|
|
13659
13803
|
const moved = MOVED_COMMANDS[first];
|
|
@@ -13698,9 +13842,9 @@ async function main(argv = process.argv) {
|
|
|
13698
13842
|
}
|
|
13699
13843
|
function readCwd(raw) {
|
|
13700
13844
|
const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
|
|
13701
|
-
if (i >= 0 && raw[i + 1]) return
|
|
13845
|
+
if (i >= 0 && raw[i + 1]) return path41.resolve(raw[i + 1]);
|
|
13702
13846
|
const eq = raw.find((a) => a.startsWith("--cwd="));
|
|
13703
|
-
if (eq) return
|
|
13847
|
+
if (eq) return path41.resolve(eq.slice("--cwd=".length));
|
|
13704
13848
|
return process.cwd();
|
|
13705
13849
|
}
|
|
13706
13850
|
function handleError(err) {
|