@vibgrate/cli 2026.803.3 → 2026.803.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-WYBWUBCC.js +26 -0
- package/dist/{agent-JTA4YWMQ.js.map → agent-WYBWUBCC.js.map} +1 -1
- package/dist/baseline-3HECX4Q6.js +9 -0
- package/dist/{baseline-2V7PKA7Q.js.map → baseline-3HECX4Q6.js.map} +1 -1
- package/dist/{chunk-TNADGCOX.js → chunk-23UPIFRU.js} +8 -8
- package/dist/{chunk-TNADGCOX.js.map → chunk-23UPIFRU.js.map} +1 -1
- package/dist/chunk-2A7XCANX.js +375 -0
- package/dist/chunk-2A7XCANX.js.map +1 -0
- package/dist/{chunk-QMME6TB4.js → chunk-4LGDQBYK.js} +3 -102
- package/dist/chunk-4LGDQBYK.js.map +1 -0
- package/dist/{chunk-L5PUNO3T.js → chunk-4ZMJKR74.js} +451 -22
- package/dist/chunk-4ZMJKR74.js.map +1 -0
- package/dist/{chunk-CPLG4GFB.js → chunk-537JBQVB.js} +4 -4
- package/dist/{chunk-CPLG4GFB.js.map → chunk-537JBQVB.js.map} +1 -1
- package/dist/{chunk-NUZM7UOR.js → chunk-5TS7N7J2.js} +59 -9
- package/dist/chunk-5TS7N7J2.js.map +1 -0
- package/dist/{chunk-XK5LKOBF.js → chunk-5WMFX7TY.js} +4 -4
- package/dist/{chunk-XK5LKOBF.js.map → chunk-5WMFX7TY.js.map} +1 -1
- package/dist/{chunk-M452MRWI.js → chunk-66B4ZQA3.js} +9 -8
- package/dist/chunk-66B4ZQA3.js.map +1 -0
- package/dist/{chunk-WGPS3NZQ.js → chunk-7BU7CWXC.js} +33 -11
- package/dist/chunk-7BU7CWXC.js.map +1 -0
- package/dist/{chunk-3Q3ZXJZP.js → chunk-7TOIESUT.js} +5 -4
- package/dist/chunk-7TOIESUT.js.map +1 -0
- package/dist/{chunk-4ACXDVON.js → chunk-BRUMBQV7.js} +4 -4
- package/dist/{chunk-4ACXDVON.js.map → chunk-BRUMBQV7.js.map} +1 -1
- package/dist/{chunk-M7773OUN.js → chunk-BUCNKYTW.js} +5 -5
- package/dist/{chunk-M7773OUN.js.map → chunk-BUCNKYTW.js.map} +1 -1
- package/dist/{chunk-NSWEJPLV.js → chunk-FAA7RBIG.js} +9 -9
- package/dist/{chunk-NSWEJPLV.js.map → chunk-FAA7RBIG.js.map} +1 -1
- package/dist/chunk-FZ5Y4KEI.js +6 -0
- package/dist/{chunk-7KNFG44U.js.map → chunk-FZ5Y4KEI.js.map} +1 -1
- package/dist/{chunk-UXR7FBE3.js → chunk-HBQC4XQJ.js} +6 -6
- package/dist/{chunk-UXR7FBE3.js.map → chunk-HBQC4XQJ.js.map} +1 -1
- package/dist/{chunk-KYX2YCXT.js → chunk-HVHCXM2E.js} +9 -9
- package/dist/{chunk-KYX2YCXT.js.map → chunk-HVHCXM2E.js.map} +1 -1
- package/dist/{chunk-NJFQCDGA.js → chunk-INIULQEP.js} +3 -3
- package/dist/{chunk-NJFQCDGA.js.map → chunk-INIULQEP.js.map} +1 -1
- package/dist/{chunk-K6Q6HTFD.js → chunk-JZGVUH57.js} +4 -4
- package/dist/{chunk-K6Q6HTFD.js.map → chunk-JZGVUH57.js.map} +1 -1
- package/dist/{chunk-TM5XQY3L.js → chunk-KFK7KCAH.js} +3 -3
- package/dist/{chunk-TM5XQY3L.js.map → chunk-KFK7KCAH.js.map} +1 -1
- package/dist/{chunk-6DFV4WCQ.js → chunk-OVDL76LB.js} +3 -3
- package/dist/{chunk-6DFV4WCQ.js.map → chunk-OVDL76LB.js.map} +1 -1
- package/dist/{chunk-SJFBXCII.js → chunk-QUI3E3TQ.js} +54 -9
- package/dist/chunk-QUI3E3TQ.js.map +1 -0
- package/dist/chunk-RBMKBYGV.js +102 -0
- package/dist/chunk-RBMKBYGV.js.map +1 -0
- package/dist/{chunk-HC44772H.js → chunk-TVRM57CE.js} +5 -373
- package/dist/chunk-TVRM57CE.js.map +1 -0
- package/dist/{chunk-PXM3VZYR.js → chunk-UWVFLVZX.js} +4 -4
- package/dist/{chunk-PXM3VZYR.js.map → chunk-UWVFLVZX.js.map} +1 -1
- package/dist/{chunk-6JP7HGIF.js → chunk-Y4JO6LYP.js} +3 -3
- package/dist/{chunk-6JP7HGIF.js.map → chunk-Y4JO6LYP.js.map} +1 -1
- package/dist/cli.js +489 -337
- package/dist/cli.js.map +1 -1
- package/dist/embed-worker-main.d.ts +2 -0
- package/dist/embed-worker-main.js +64 -0
- package/dist/embed-worker-main.js.map +1 -0
- package/dist/ensure-map-DZ53QXRT.js +31 -0
- package/dist/{ensure-map-TAVYMPEG.js.map → ensure-map-DZ53QXRT.js.map} +1 -1
- package/dist/graph-backend-3A2M22QN.js +13 -0
- package/dist/{graph-backend-WF4LGBGD.js.map → graph-backend-3A2M22QN.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/{interactive-6PN237LX.js → interactive-DB7IC3BL.js} +31 -29
- package/dist/interactive-DB7IC3BL.js.map +1 -0
- package/dist/load-6KVGUQMU.js +11 -0
- package/dist/{load-T2FOJUPI.js.map → load-6KVGUQMU.js.map} +1 -1
- package/dist/{run-outcome-AMIKAASL.js → run-outcome-YOYRC32U.js} +7 -6
- package/dist/run-outcome-YOYRC32U.js.map +1 -0
- package/dist/runtime-session-XEP7IPGP.js +22 -0
- package/dist/{runtime-session-QAVOPSSH.js.map → runtime-session-XEP7IPGP.js.map} +1 -1
- package/dist/session-5WKEACIF.js +17 -0
- package/dist/{session-SCHQQTHN.js.map → session-5WKEACIF.js.map} +1 -1
- package/dist/{stream-json-A6K2MONY.js → stream-json-3OJCPBWY.js} +13 -11
- package/dist/stream-json-3OJCPBWY.js.map +1 -0
- package/dist/{vg-mcp-bridge-3TSFOL4V.js → vg-mcp-bridge-PM3C4FQL.js} +12 -10
- package/dist/vg-mcp-bridge-PM3C4FQL.js.map +1 -0
- package/dist/{vgd-B67JCNJP.js → vgd-UTLMMPIZ.js} +12 -10
- package/dist/vgd-UTLMMPIZ.js.map +1 -0
- package/package.json +1 -1
- package/scripts/postinstall.mjs +22 -1
- package/dist/agent-JTA4YWMQ.js +0 -24
- package/dist/baseline-2V7PKA7Q.js +0 -9
- package/dist/chunk-3Q3ZXJZP.js.map +0 -1
- package/dist/chunk-7KNFG44U.js +0 -6
- package/dist/chunk-HC44772H.js.map +0 -1
- package/dist/chunk-L5PUNO3T.js.map +0 -1
- package/dist/chunk-M452MRWI.js.map +0 -1
- package/dist/chunk-NUZM7UOR.js.map +0 -1
- package/dist/chunk-QMME6TB4.js.map +0 -1
- package/dist/chunk-SJFBXCII.js.map +0 -1
- package/dist/chunk-WGPS3NZQ.js.map +0 -1
- package/dist/ensure-map-TAVYMPEG.js +0 -29
- package/dist/graph-backend-WF4LGBGD.js +0 -11
- package/dist/interactive-6PN237LX.js.map +0 -1
- package/dist/load-T2FOJUPI.js +0 -10
- package/dist/run-outcome-AMIKAASL.js.map +0 -1
- package/dist/runtime-session-QAVOPSSH.js +0 -20
- package/dist/session-SCHQQTHN.js +0 -15
- package/dist/stream-json-A6K2MONY.js.map +0 -1
- package/dist/vg-mcp-bridge-3TSFOL4V.js.map +0 -1
- package/dist/vgd-B67JCNJP.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,71 +1,73 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
3
|
-
import { fetchCatalog, resolveProviders } from './chunk-
|
|
4
|
-
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-
|
|
5
|
-
import
|
|
2
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-Y4JO6LYP.js';
|
|
3
|
+
import { fetchCatalog, resolveProviders } from './chunk-5TS7N7J2.js';
|
|
4
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-4ZMJKR74.js';
|
|
5
|
+
import './chunk-IS7VTH2Q.js';
|
|
6
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-UWVFLVZX.js';
|
|
7
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-7BU7CWXC.js';
|
|
8
|
+
import './chunk-543E6WDJ.js';
|
|
6
9
|
import './chunk-7AVYKZEM.js';
|
|
7
10
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
8
|
-
import { runCodeSession } from './chunk-
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
+
import { runCodeSession } from './chunk-BUCNKYTW.js';
|
|
12
|
+
import { summarizeDiffs, ScriptedProvider } from './chunk-QUI3E3TQ.js';
|
|
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-HVHCXM2E.js';
|
|
15
|
+
export { runBuild } from './chunk-HVHCXM2E.js';
|
|
11
16
|
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
12
|
-
import './chunk-IS7VTH2Q.js';
|
|
13
17
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
|
|
14
18
|
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
|
|
15
19
|
import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
16
20
|
import './chunk-IZDH67DX.js';
|
|
21
|
+
import './chunk-KFK7KCAH.js';
|
|
22
|
+
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
|
|
17
23
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-JFE7XCAE.js';
|
|
18
24
|
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-3LOWJSAF.js';
|
|
19
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-WGPS3NZQ.js';
|
|
20
|
-
import './chunk-543E6WDJ.js';
|
|
21
|
-
import { summarizeDiffs, ScriptedProvider } from './chunk-SJFBXCII.js';
|
|
22
|
-
import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
|
|
23
|
-
import './chunk-TM5XQY3L.js';
|
|
24
|
-
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.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 {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
26
|
+
import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt } from './chunk-FAA7RBIG.js';
|
|
27
|
+
import { refreshIfStale } from './chunk-HBQC4XQJ.js';
|
|
28
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-JZGVUH57.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-23UPIFRU.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-66B4ZQA3.js';
|
|
31
|
+
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift } from './chunk-INIULQEP.js';
|
|
31
32
|
import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
|
|
33
|
+
import './chunk-VIWZ4QT7.js';
|
|
34
|
+
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-5WMFX7TY.js';
|
|
32
35
|
import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
33
36
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
37
|
+
import './chunk-5I4VSBWQ.js';
|
|
34
38
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-DT4KIVRI.js';
|
|
35
39
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
36
|
-
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-K6Q6HTFD.js';
|
|
37
|
-
import './chunk-VIWZ4QT7.js';
|
|
38
|
-
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-XK5LKOBF.js';
|
|
39
40
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
|
|
40
41
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
41
|
-
import {
|
|
42
|
+
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-TVRM57CE.js';
|
|
42
43
|
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
|
|
43
44
|
import './chunk-RXP66R2E.js';
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import './chunk-
|
|
45
|
+
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, clearModelCache, withTimeout } from './chunk-2A7XCANX.js';
|
|
46
|
+
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-537JBQVB.js';
|
|
47
|
+
import { resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, ensureVibgrateGitignore } from './chunk-7TOIESUT.js';
|
|
48
|
+
import { VERSION } from './chunk-FZ5Y4KEI.js';
|
|
49
|
+
import './chunk-4LGDQBYK.js';
|
|
50
|
+
import { cacheDir, serializeGraph, stableStringify, parseGraph } from './chunk-RBMKBYGV.js';
|
|
49
51
|
import './chunk-BWPBB45M.js';
|
|
50
52
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
51
53
|
import './chunk-BPF3YX2U.js';
|
|
52
54
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
53
|
-
import * as
|
|
54
|
-
import
|
|
55
|
-
import * as
|
|
56
|
-
import
|
|
55
|
+
import * as fs11 from 'fs';
|
|
56
|
+
import fs11__default, { realpathSync } from 'fs';
|
|
57
|
+
import * as path40 from 'path';
|
|
58
|
+
import path40__default from 'path';
|
|
57
59
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
58
60
|
import { Command, CommanderError, Option } from 'commander';
|
|
61
|
+
import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
|
|
62
|
+
import * as os from 'os';
|
|
59
63
|
import * as semver3 from 'semver';
|
|
60
64
|
import semver3__default from 'semver';
|
|
61
65
|
import * as readline from 'readline';
|
|
62
66
|
import * as zlib from 'zlib';
|
|
63
67
|
import * as crypto3 from 'crypto';
|
|
64
68
|
import { randomUUID, createHash } from 'crypto';
|
|
65
|
-
import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
|
|
66
69
|
import chalk7 from 'chalk';
|
|
67
|
-
import * as
|
|
68
|
-
import * as os from 'os';
|
|
70
|
+
import * as fs25 from 'fs/promises';
|
|
69
71
|
|
|
70
72
|
init_cli_invocation();
|
|
71
73
|
function registerStatus(program) {
|
|
@@ -75,10 +77,10 @@ function registerStatus(program) {
|
|
|
75
77
|
applyGlobalOptions(cmd);
|
|
76
78
|
}
|
|
77
79
|
async function runStatus(global) {
|
|
78
|
-
const root2 =
|
|
80
|
+
const root2 = path40.resolve(global.cwd ?? ".");
|
|
79
81
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
80
82
|
const graph = loadGraph(root2, graphPath);
|
|
81
|
-
const hasCache =
|
|
83
|
+
const hasCache = fs11.existsSync(path40.join(cacheDir(root2), "parse-cache.json"));
|
|
82
84
|
let stale = null;
|
|
83
85
|
let staleExact = false;
|
|
84
86
|
if (graph) {
|
|
@@ -98,8 +100,8 @@ async function runStatus(global) {
|
|
|
98
100
|
}
|
|
99
101
|
if (global.json) {
|
|
100
102
|
json({
|
|
101
|
-
root:
|
|
102
|
-
graphPath:
|
|
103
|
+
root: path40.relative(process.cwd(), root2) || ".",
|
|
104
|
+
graphPath: path40.relative(root2, graphPath),
|
|
103
105
|
built: graph !== null,
|
|
104
106
|
generatedAt: graph?.generatedAt ?? null,
|
|
105
107
|
counts: graph?.meta.counts ?? null,
|
|
@@ -114,11 +116,11 @@ async function runStatus(global) {
|
|
|
114
116
|
return;
|
|
115
117
|
}
|
|
116
118
|
if (!graph) {
|
|
117
|
-
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(
|
|
119
|
+
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path40.relative(root2, graphPath))}`);
|
|
118
120
|
info(` run ${c.bold("vg")} to build one`);
|
|
119
121
|
return;
|
|
120
122
|
}
|
|
121
|
-
info(`${c.cyan("vg")} \xB7 ${
|
|
123
|
+
info(`${c.cyan("vg")} \xB7 ${path40.relative(root2, graphPath)}`);
|
|
122
124
|
info(` generated ${graph.generatedAt}`);
|
|
123
125
|
info(
|
|
124
126
|
` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
|
|
@@ -135,7 +137,7 @@ async function runStatus(global) {
|
|
|
135
137
|
if (vibgrateDir(root2)) ;
|
|
136
138
|
}
|
|
137
139
|
function rootOf(global) {
|
|
138
|
-
return
|
|
140
|
+
return path40.resolve(global.cwd ?? ".");
|
|
139
141
|
}
|
|
140
142
|
function requireGraph(global) {
|
|
141
143
|
const root2 = rootOf(global);
|
|
@@ -233,6 +235,107 @@ function registerAsk(program) {
|
|
|
233
235
|
});
|
|
234
236
|
applyGlobalOptions(cmd);
|
|
235
237
|
}
|
|
238
|
+
function crashedMessage(signal) {
|
|
239
|
+
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.`;
|
|
240
|
+
}
|
|
241
|
+
function defaultCacheDir() {
|
|
242
|
+
const base = process.env.XDG_CACHE_HOME || path40.join(os.homedir(), ".cache");
|
|
243
|
+
return path40.join(base, "vibgrate", "models");
|
|
244
|
+
}
|
|
245
|
+
function verdictPath(dir) {
|
|
246
|
+
return path40.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
|
|
247
|
+
}
|
|
248
|
+
function readVerdict(dir) {
|
|
249
|
+
try {
|
|
250
|
+
const raw = JSON.parse(fs11.readFileSync(verdictPath(dir), "utf8"));
|
|
251
|
+
if (raw?.status !== "ok" && raw?.status !== "crashed") return null;
|
|
252
|
+
if (raw.version !== VERSION) return null;
|
|
253
|
+
return raw;
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
function writeVerdict(dir, verdict) {
|
|
259
|
+
try {
|
|
260
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
261
|
+
fs11.writeFileSync(verdictPath(dir), JSON.stringify(verdict, null, 2) + "\n", "utf8");
|
|
262
|
+
} catch {
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function defaultRunProbe(timeoutMs) {
|
|
266
|
+
const moduleUrl = new URL("./embeddings.js", import.meta.url).href;
|
|
267
|
+
const script = `
|
|
268
|
+
import(${JSON.stringify(moduleUrl)})
|
|
269
|
+
.then(async (m) => {
|
|
270
|
+
const e = await m.loadEmbedder({ noDownload: true });
|
|
271
|
+
if (!e) { process.stdout.write('{"ok":false}'); return; }
|
|
272
|
+
await e.embedQuery('probe');
|
|
273
|
+
process.stdout.write('{"ok":true}');
|
|
274
|
+
})
|
|
275
|
+
.catch(() => process.stdout.write('{"ok":false}'));
|
|
276
|
+
`;
|
|
277
|
+
return new Promise((resolve21) => {
|
|
278
|
+
const child = spawn(process.execPath, ["--input-type=module", "-e", script], {
|
|
279
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
280
|
+
// The probe must never inherit a debugger port or loader flags that would
|
|
281
|
+
// change what it proves about the addon.
|
|
282
|
+
env: { ...process.env, NODE_OPTIONS: "" }
|
|
283
|
+
});
|
|
284
|
+
let stdout = "";
|
|
285
|
+
let settled = false;
|
|
286
|
+
const done = (signal, status) => {
|
|
287
|
+
if (settled) return;
|
|
288
|
+
settled = true;
|
|
289
|
+
clearTimeout(timer);
|
|
290
|
+
resolve21({ signal, status, stdout });
|
|
291
|
+
};
|
|
292
|
+
const timer = setTimeout(() => {
|
|
293
|
+
child.kill("SIGTERM");
|
|
294
|
+
done("SIGTERM", null);
|
|
295
|
+
}, timeoutMs);
|
|
296
|
+
child.stdout?.on("data", (d) => {
|
|
297
|
+
stdout += d.toString("utf8");
|
|
298
|
+
});
|
|
299
|
+
child.on("error", () => done(null, null));
|
|
300
|
+
child.on("close", (code, signal) => done(signal ?? null, code ?? null));
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
async function embedderHealth(options = {}) {
|
|
304
|
+
const dir = options.cacheDir ?? defaultCacheDir();
|
|
305
|
+
if (!options.force) {
|
|
306
|
+
const stored = readVerdict(dir);
|
|
307
|
+
if (stored?.status === "ok") return { status: "ok" };
|
|
308
|
+
if (stored?.status === "crashed") {
|
|
309
|
+
const signal = stored.signal ?? "a fatal signal";
|
|
310
|
+
return { status: "crashed", signal, message: crashedMessage(signal) };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const run = options.runProbe ?? defaultRunProbe;
|
|
314
|
+
let res;
|
|
315
|
+
try {
|
|
316
|
+
res = await run(options.timeoutMs ?? 3e4);
|
|
317
|
+
} catch {
|
|
318
|
+
return { status: "unknown" };
|
|
319
|
+
}
|
|
320
|
+
if (res.signal) {
|
|
321
|
+
if (res.signal === "SIGTERM") return { status: "unknown" };
|
|
322
|
+
writeVerdict(dir, { status: "crashed", signal: res.signal, at: (/* @__PURE__ */ new Date()).toISOString(), version: VERSION });
|
|
323
|
+
return { status: "crashed", signal: res.signal, message: crashedMessage(res.signal) };
|
|
324
|
+
}
|
|
325
|
+
if (res.stdout.includes('"ok":true')) {
|
|
326
|
+
writeVerdict(dir, { status: "ok", at: (/* @__PURE__ */ new Date()).toISOString(), version: VERSION });
|
|
327
|
+
return { status: "ok" };
|
|
328
|
+
}
|
|
329
|
+
return { status: "unknown" };
|
|
330
|
+
}
|
|
331
|
+
function clearEmbedderHealth(cacheDir2) {
|
|
332
|
+
try {
|
|
333
|
+
fs11.unlinkSync(verdictPath(cacheDir2 ?? defaultCacheDir()));
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/commands/embed.ts
|
|
236
339
|
function mb(bytes) {
|
|
237
340
|
if (bytes <= 0) return "0 MB";
|
|
238
341
|
if (bytes < 1024 * 1024) return `${Math.max(1, Math.round(bytes / 1024))} KB`;
|
|
@@ -257,6 +360,12 @@ function registerEmbed(program) {
|
|
|
257
360
|
else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
|
|
258
361
|
return;
|
|
259
362
|
}
|
|
363
|
+
const health = await embedderHealth();
|
|
364
|
+
if (health.status === "crashed") {
|
|
365
|
+
if (global.json) json({ embedded: 0, model: modelId, semantic: false, reason: "native-crash", signal: health.signal });
|
|
366
|
+
else if (speak) info(c.dim(`vg embed \xB7 ${health.message}`));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
260
369
|
let reason;
|
|
261
370
|
const embedder = await loadEmbedder({
|
|
262
371
|
local: global.local,
|
|
@@ -298,6 +407,7 @@ function showWhere(root2, modelId, asJson) {
|
|
|
298
407
|
function doClear(asJson) {
|
|
299
408
|
const before = modelCacheInfo();
|
|
300
409
|
const freed = clearModelCache();
|
|
410
|
+
clearEmbedderHealth();
|
|
301
411
|
if (asJson) {
|
|
302
412
|
json({ removed: before.present, bytesFreed: freed, dir: before.dir });
|
|
303
413
|
return;
|
|
@@ -871,12 +981,12 @@ var PUBLISH_INTERVAL_MS = 2e3;
|
|
|
871
981
|
var KEEPALIVE_MS = 1e4;
|
|
872
982
|
var STALE_MS = 6e4;
|
|
873
983
|
function liveStatsDir(root2) {
|
|
874
|
-
return
|
|
984
|
+
return path40.join(cacheDir(root2), "serve-live");
|
|
875
985
|
}
|
|
876
986
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
877
987
|
let entries;
|
|
878
988
|
try {
|
|
879
|
-
entries =
|
|
989
|
+
entries = fs11.readdirSync(dir);
|
|
880
990
|
} catch {
|
|
881
991
|
return [];
|
|
882
992
|
}
|
|
@@ -885,7 +995,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
885
995
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
886
996
|
let parsed;
|
|
887
997
|
try {
|
|
888
|
-
parsed = JSON.parse(
|
|
998
|
+
parsed = JSON.parse(fs11.readFileSync(path40.join(dir, name), "utf8"));
|
|
889
999
|
} catch {
|
|
890
1000
|
continue;
|
|
891
1001
|
}
|
|
@@ -907,7 +1017,7 @@ var LiveStatsBus = class {
|
|
|
907
1017
|
this.dir = dir;
|
|
908
1018
|
this.stats = stats;
|
|
909
1019
|
this.pid = pid;
|
|
910
|
-
this.file =
|
|
1020
|
+
this.file = path40.join(dir, `serve-${this.pid}.json`);
|
|
911
1021
|
}
|
|
912
1022
|
dir;
|
|
913
1023
|
stats;
|
|
@@ -939,10 +1049,10 @@ var LiveStatsBus = class {
|
|
|
939
1049
|
this.lastWriteAt = now;
|
|
940
1050
|
const body = { pid: this.pid, updatedAt: now, version: VERSION, snapshot: snap };
|
|
941
1051
|
try {
|
|
942
|
-
|
|
1052
|
+
fs11.mkdirSync(this.dir, { recursive: true });
|
|
943
1053
|
const tmp = `${this.file}.tmp`;
|
|
944
|
-
|
|
945
|
-
|
|
1054
|
+
fs11.writeFileSync(tmp, JSON.stringify(body));
|
|
1055
|
+
fs11.renameSync(tmp, this.file);
|
|
946
1056
|
} catch {
|
|
947
1057
|
}
|
|
948
1058
|
}
|
|
@@ -953,24 +1063,24 @@ var LiveStatsBus = class {
|
|
|
953
1063
|
siblings(now = Date.now()) {
|
|
954
1064
|
let entries;
|
|
955
1065
|
try {
|
|
956
|
-
entries =
|
|
1066
|
+
entries = fs11.readdirSync(this.dir);
|
|
957
1067
|
} catch {
|
|
958
1068
|
return [];
|
|
959
1069
|
}
|
|
960
1070
|
const out2 = [];
|
|
961
1071
|
for (const name of entries.sort()) {
|
|
962
1072
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
963
|
-
const file =
|
|
1073
|
+
const file = path40.join(this.dir, name);
|
|
964
1074
|
let parsed;
|
|
965
1075
|
try {
|
|
966
|
-
parsed = JSON.parse(
|
|
1076
|
+
parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
967
1077
|
} catch {
|
|
968
1078
|
continue;
|
|
969
1079
|
}
|
|
970
1080
|
if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
|
|
971
1081
|
if (now - parsed.updatedAt > STALE_MS) {
|
|
972
1082
|
try {
|
|
973
|
-
|
|
1083
|
+
fs11.unlinkSync(file);
|
|
974
1084
|
} catch {
|
|
975
1085
|
}
|
|
976
1086
|
continue;
|
|
@@ -982,7 +1092,7 @@ var LiveStatsBus = class {
|
|
|
982
1092
|
}
|
|
983
1093
|
unlinkOwn = () => {
|
|
984
1094
|
try {
|
|
985
|
-
|
|
1095
|
+
fs11.unlinkSync(this.file);
|
|
986
1096
|
} catch {
|
|
987
1097
|
}
|
|
988
1098
|
};
|
|
@@ -1295,12 +1405,12 @@ var LedgerTail = class {
|
|
|
1295
1405
|
if (size === this.offset) return;
|
|
1296
1406
|
let chunk;
|
|
1297
1407
|
try {
|
|
1298
|
-
const fd =
|
|
1408
|
+
const fd = fs11.openSync(this.file, "r");
|
|
1299
1409
|
try {
|
|
1300
1410
|
chunk = Buffer.alloc(size - this.offset);
|
|
1301
|
-
|
|
1411
|
+
fs11.readSync(fd, chunk, 0, chunk.length, this.offset);
|
|
1302
1412
|
} finally {
|
|
1303
|
-
|
|
1413
|
+
fs11.closeSync(fd);
|
|
1304
1414
|
}
|
|
1305
1415
|
} catch {
|
|
1306
1416
|
return;
|
|
@@ -1313,7 +1423,7 @@ var LedgerTail = class {
|
|
|
1313
1423
|
}
|
|
1314
1424
|
sizeOf() {
|
|
1315
1425
|
try {
|
|
1316
|
-
return
|
|
1426
|
+
return fs11.statSync(this.file).size;
|
|
1317
1427
|
} catch {
|
|
1318
1428
|
return 0;
|
|
1319
1429
|
}
|
|
@@ -1706,19 +1816,19 @@ function endOfLine(text, line) {
|
|
|
1706
1816
|
}
|
|
1707
1817
|
var CACHE_VERSION = "vg-lsp-scan-cache/2";
|
|
1708
1818
|
function cachePath(root2) {
|
|
1709
|
-
return
|
|
1819
|
+
return path40.join(cacheDir(root2), "lsp-scan.json");
|
|
1710
1820
|
}
|
|
1711
1821
|
function manifestHash(root2) {
|
|
1712
1822
|
const files = [];
|
|
1713
1823
|
const walk2 = (dir) => {
|
|
1714
1824
|
let entries;
|
|
1715
1825
|
try {
|
|
1716
|
-
entries =
|
|
1826
|
+
entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
1717
1827
|
} catch {
|
|
1718
1828
|
return;
|
|
1719
1829
|
}
|
|
1720
1830
|
for (const entry of entries) {
|
|
1721
|
-
const abs =
|
|
1831
|
+
const abs = path40.join(dir, entry.name);
|
|
1722
1832
|
if (entry.isDirectory()) {
|
|
1723
1833
|
if (isSkippedDirName(entry.name)) continue;
|
|
1724
1834
|
walk2(abs);
|
|
@@ -1728,8 +1838,8 @@ function manifestHash(root2) {
|
|
|
1728
1838
|
const base = entry.name.toLowerCase();
|
|
1729
1839
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1730
1840
|
try {
|
|
1731
|
-
const rel =
|
|
1732
|
-
files.push({ rel, hash: hashBytes(
|
|
1841
|
+
const rel = path40.relative(root2, abs).split(path40.sep).join("/");
|
|
1842
|
+
files.push({ rel, hash: hashBytes(fs11.readFileSync(abs)) });
|
|
1733
1843
|
} catch {
|
|
1734
1844
|
}
|
|
1735
1845
|
}
|
|
@@ -1739,16 +1849,16 @@ function manifestHash(root2) {
|
|
|
1739
1849
|
return hashString(canonicalize(files));
|
|
1740
1850
|
}
|
|
1741
1851
|
function isDependencyFile(root2, filePath) {
|
|
1742
|
-
const rel =
|
|
1743
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
1744
|
-
const parts = rel.split(
|
|
1852
|
+
const rel = path40.relative(path40.resolve(root2), path40.resolve(filePath));
|
|
1853
|
+
if (rel === "" || rel.startsWith("..") || path40.isAbsolute(rel)) return false;
|
|
1854
|
+
const parts = rel.split(path40.sep);
|
|
1745
1855
|
if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
|
|
1746
1856
|
const base = parts[parts.length - 1].toLowerCase();
|
|
1747
1857
|
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
1748
1858
|
}
|
|
1749
1859
|
function loadScanCache(root2, key2) {
|
|
1750
1860
|
try {
|
|
1751
|
-
const raw = JSON.parse(
|
|
1861
|
+
const raw = JSON.parse(fs11.readFileSync(cachePath(root2), "utf8"));
|
|
1752
1862
|
if (raw.version === CACHE_VERSION && raw.manifestHash === key2.manifestHash && raw.toolVersion === key2.toolVersion && raw.offline === key2.offline && raw.artifact) {
|
|
1753
1863
|
return { manifestHash: raw.manifestHash, artifact: raw.artifact };
|
|
1754
1864
|
}
|
|
@@ -1758,8 +1868,8 @@ function loadScanCache(root2, key2) {
|
|
|
1758
1868
|
}
|
|
1759
1869
|
function writeScanCache(root2, key2, artifact) {
|
|
1760
1870
|
try {
|
|
1761
|
-
|
|
1762
|
-
|
|
1871
|
+
fs11.mkdirSync(cacheDir(root2), { recursive: true });
|
|
1872
|
+
fs11.writeFileSync(
|
|
1763
1873
|
cachePath(root2),
|
|
1764
1874
|
stableStringify(
|
|
1765
1875
|
{ version: CACHE_VERSION, manifestHash: key2.manifestHash, toolVersion: key2.toolVersion, offline: key2.offline, artifact },
|
|
@@ -1772,7 +1882,7 @@ function writeScanCache(root2, key2, artifact) {
|
|
|
1772
1882
|
var MAX_ENTRIES = 1e3;
|
|
1773
1883
|
var KEEP_ENTRIES = 500;
|
|
1774
1884
|
function historyPath(root2) {
|
|
1775
|
-
return
|
|
1885
|
+
return path40.join(root2, ".vibgrate", "score-history.jsonl");
|
|
1776
1886
|
}
|
|
1777
1887
|
function parseLine(line) {
|
|
1778
1888
|
try {
|
|
@@ -1786,7 +1896,7 @@ function parseLine(line) {
|
|
|
1786
1896
|
}
|
|
1787
1897
|
function readHistory(root2) {
|
|
1788
1898
|
try {
|
|
1789
|
-
return
|
|
1899
|
+
return fs11.readFileSync(historyPath(root2), "utf8").split("\n").filter((l) => l.trim()).map(parseLine).filter((e) => e !== null);
|
|
1790
1900
|
} catch {
|
|
1791
1901
|
return [];
|
|
1792
1902
|
}
|
|
@@ -1813,14 +1923,14 @@ function recordScore(root2, entry) {
|
|
|
1813
1923
|
}
|
|
1814
1924
|
}
|
|
1815
1925
|
const file = historyPath(root2);
|
|
1816
|
-
|
|
1926
|
+
fs11.mkdirSync(path40.dirname(file), { recursive: true });
|
|
1817
1927
|
ensureVibgrateGitignore(root2);
|
|
1818
|
-
|
|
1928
|
+
fs11.appendFileSync(file, `${JSON.stringify(entry)}
|
|
1819
1929
|
`);
|
|
1820
1930
|
const all = readHistory(root2);
|
|
1821
1931
|
if (all.length > MAX_ENTRIES) {
|
|
1822
1932
|
const kept = all.slice(-KEEP_ENTRIES);
|
|
1823
|
-
|
|
1933
|
+
fs11.writeFileSync(file, kept.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
1824
1934
|
}
|
|
1825
1935
|
} catch {
|
|
1826
1936
|
}
|
|
@@ -1860,7 +1970,9 @@ async function runAsk(graph, params, ctx) {
|
|
|
1860
1970
|
const question = (params.question ?? "").trim();
|
|
1861
1971
|
if (!question) return { ok: false, mode: "ask", error: "bad-request", message: "question is required" };
|
|
1862
1972
|
const budget = params.budget ?? 2e3;
|
|
1863
|
-
const
|
|
1973
|
+
const semanticRequested = !!params.semantic && !ctx.offline && ctx.semantic !== false;
|
|
1974
|
+
const health = semanticRequested ? await embedderHealth() : { status: "unknown" };
|
|
1975
|
+
const wantSemantic = semanticRequested && health.status !== "crashed";
|
|
1864
1976
|
const log = ctx.log ?? (() => {
|
|
1865
1977
|
});
|
|
1866
1978
|
let result = null;
|
|
@@ -1898,6 +2010,9 @@ async function runAsk(graph, params, ctx) {
|
|
|
1898
2010
|
`ask: semantic path abandoned after ${Date.now() - started}ms (${err instanceof Error ? err.message : String(err)}) \u2014 falling back to lexical`
|
|
1899
2011
|
);
|
|
1900
2012
|
}
|
|
2013
|
+
} else if (health.status === "crashed") {
|
|
2014
|
+
note = health.message;
|
|
2015
|
+
log(`ask: semantic disabled \u2014 native backend crashed with ${health.signal}; answering lexically`);
|
|
1901
2016
|
} else if (params.semantic && ctx.semantic === false) {
|
|
1902
2017
|
note = "semantic search is turned off \u2014 used lexical";
|
|
1903
2018
|
} else if (params.semantic && ctx.offline) {
|
|
@@ -2736,10 +2851,10 @@ var VibgrateLanguageServer = class {
|
|
|
2736
2851
|
const ecosystem = osvEcosystem(proj.type);
|
|
2737
2852
|
if (!ecosystem) continue;
|
|
2738
2853
|
const relManifest = manifestRelativePath(proj);
|
|
2739
|
-
const absManifest =
|
|
2854
|
+
const absManifest = path40.resolve(this.opts.root, relManifest);
|
|
2740
2855
|
let text = null;
|
|
2741
2856
|
try {
|
|
2742
|
-
if (
|
|
2857
|
+
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
2743
2858
|
} catch {
|
|
2744
2859
|
text = null;
|
|
2745
2860
|
}
|
|
@@ -2869,9 +2984,9 @@ function pruneArtifactProjects(a) {
|
|
|
2869
2984
|
return { ...a, projects, findings };
|
|
2870
2985
|
}
|
|
2871
2986
|
function projectByPath(a, projectPath) {
|
|
2872
|
-
const want =
|
|
2987
|
+
const want = path40.normalize(projectPath === "" ? "." : projectPath);
|
|
2873
2988
|
for (const proj of a.projects ?? []) {
|
|
2874
|
-
const got =
|
|
2989
|
+
const got = path40.normalize(proj.path === "" ? "." : proj.path);
|
|
2875
2990
|
if (got === want) return proj;
|
|
2876
2991
|
}
|
|
2877
2992
|
return void 0;
|
|
@@ -2908,12 +3023,12 @@ function buildProjectRefs(rootDir, projects) {
|
|
|
2908
3023
|
return refs.length > 0 ? refs : void 0;
|
|
2909
3024
|
}
|
|
2910
3025
|
function projectForFile(root2, a, filePath) {
|
|
2911
|
-
const dir =
|
|
3026
|
+
const dir = path40.dirname(path40.resolve(filePath));
|
|
2912
3027
|
let best;
|
|
2913
3028
|
let bestLen = -1;
|
|
2914
3029
|
for (const proj of a.projects ?? []) {
|
|
2915
|
-
const projDir =
|
|
2916
|
-
if ((dir === projDir || dir.startsWith(projDir +
|
|
3030
|
+
const projDir = path40.resolve(root2, proj.path);
|
|
3031
|
+
if ((dir === projDir || dir.startsWith(projDir + path40.sep)) && projDir.length > bestLen) {
|
|
2917
3032
|
best = proj;
|
|
2918
3033
|
bestLen = projDir.length;
|
|
2919
3034
|
}
|
|
@@ -2921,7 +3036,7 @@ function projectForFile(root2, a, filePath) {
|
|
|
2921
3036
|
return best;
|
|
2922
3037
|
}
|
|
2923
3038
|
function sameProject(location, projectPath) {
|
|
2924
|
-
return
|
|
3039
|
+
return path40.normalize(location) === path40.normalize(projectPath);
|
|
2925
3040
|
}
|
|
2926
3041
|
function hasReleaseDates(a) {
|
|
2927
3042
|
for (const proj of a.projects ?? []) {
|
|
@@ -2991,10 +3106,10 @@ function buildBreakdown(rootDir, projects) {
|
|
|
2991
3106
|
const relManifest = manifestRelativePath(p);
|
|
2992
3107
|
if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
|
|
2993
3108
|
const ecosystem = osvEcosystem(p.type);
|
|
2994
|
-
const absManifest =
|
|
3109
|
+
const absManifest = path40.resolve(rootDir, relManifest);
|
|
2995
3110
|
let text = null;
|
|
2996
3111
|
try {
|
|
2997
|
-
if (
|
|
3112
|
+
if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
|
|
2998
3113
|
} catch {
|
|
2999
3114
|
text = null;
|
|
3000
3115
|
}
|
|
@@ -3059,34 +3174,34 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3059
3174
|
}
|
|
3060
3175
|
function manifestRelativePath(proj) {
|
|
3061
3176
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3062
|
-
const
|
|
3177
|
+
const join30 = (name) => base ? path40.join(base, name) : name;
|
|
3063
3178
|
switch (proj.type) {
|
|
3064
3179
|
case "node":
|
|
3065
3180
|
case "typescript":
|
|
3066
|
-
return
|
|
3181
|
+
return join30("package.json");
|
|
3067
3182
|
case "python":
|
|
3068
|
-
return
|
|
3183
|
+
return join30("pyproject.toml");
|
|
3069
3184
|
case "go":
|
|
3070
|
-
return
|
|
3185
|
+
return join30("go.mod");
|
|
3071
3186
|
case "rust":
|
|
3072
|
-
return
|
|
3187
|
+
return join30("Cargo.toml");
|
|
3073
3188
|
case "ruby":
|
|
3074
|
-
return
|
|
3189
|
+
return join30("Gemfile");
|
|
3075
3190
|
case "php":
|
|
3076
|
-
return
|
|
3191
|
+
return join30("composer.json");
|
|
3077
3192
|
case "java":
|
|
3078
3193
|
case "kotlin":
|
|
3079
3194
|
case "scala":
|
|
3080
3195
|
case "groovy":
|
|
3081
|
-
return
|
|
3196
|
+
return join30("pom.xml");
|
|
3082
3197
|
case "dotnet":
|
|
3083
|
-
return
|
|
3198
|
+
return join30(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
3084
3199
|
case "dart":
|
|
3085
|
-
return
|
|
3200
|
+
return join30("pubspec.yaml");
|
|
3086
3201
|
case "elixir":
|
|
3087
|
-
return
|
|
3202
|
+
return join30("mix.exs");
|
|
3088
3203
|
default:
|
|
3089
|
-
return
|
|
3204
|
+
return join30("package.json");
|
|
3090
3205
|
}
|
|
3091
3206
|
}
|
|
3092
3207
|
function lockfileRelativePath(rootDir, proj) {
|
|
@@ -3117,9 +3232,9 @@ function lockfileRelativePath(rootDir, proj) {
|
|
|
3117
3232
|
const dirsToTry = base ? [base, ""] : [""];
|
|
3118
3233
|
for (const dir of dirsToTry) {
|
|
3119
3234
|
for (const name of candidateNames) {
|
|
3120
|
-
const rel = dir ?
|
|
3235
|
+
const rel = dir ? path40.join(dir, name) : name;
|
|
3121
3236
|
try {
|
|
3122
|
-
if (
|
|
3237
|
+
if (fs11.existsSync(path40.join(rootDir, rel))) return rel;
|
|
3123
3238
|
} catch {
|
|
3124
3239
|
}
|
|
3125
3240
|
}
|
|
@@ -3190,10 +3305,10 @@ function lookupImportFiles(map, pkg) {
|
|
|
3190
3305
|
}
|
|
3191
3306
|
function firstPackageMentionLine(root2, relFile, pkg) {
|
|
3192
3307
|
try {
|
|
3193
|
-
const abs =
|
|
3194
|
-
const stat2 =
|
|
3308
|
+
const abs = path40.resolve(root2, relFile);
|
|
3309
|
+
const stat2 = fs11.statSync(abs);
|
|
3195
3310
|
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3196
|
-
const text =
|
|
3311
|
+
const text = fs11.readFileSync(abs, "utf8");
|
|
3197
3312
|
const tokens = [pkg];
|
|
3198
3313
|
if (pkg.startsWith("@")) {
|
|
3199
3314
|
const parts = pkg.split("/");
|
|
@@ -3345,7 +3460,7 @@ function hoverMarkdown(dep, contribution) {
|
|
|
3345
3460
|
return lines.join("\n");
|
|
3346
3461
|
}
|
|
3347
3462
|
function startLanguageServer(opts) {
|
|
3348
|
-
if (!
|
|
3463
|
+
if (!fs11.existsSync(opts.root)) {
|
|
3349
3464
|
process.stderr.write(`vg lsp: root does not exist: ${opts.root}
|
|
3350
3465
|
`);
|
|
3351
3466
|
process.exit(1);
|
|
@@ -3394,12 +3509,12 @@ function hookCommand(vgBin) {
|
|
|
3394
3509
|
return `${vgBin} hook pre-tool-use`;
|
|
3395
3510
|
}
|
|
3396
3511
|
function installClaudeHooks(root2, vgBin = "vg") {
|
|
3397
|
-
const file =
|
|
3398
|
-
const rel =
|
|
3512
|
+
const file = path40.join(root2, ".claude", "settings.json");
|
|
3513
|
+
const rel = path40.join(".claude", "settings.json");
|
|
3399
3514
|
let settings = {};
|
|
3400
|
-
if (
|
|
3515
|
+
if (fs11.existsSync(file)) {
|
|
3401
3516
|
try {
|
|
3402
|
-
const parsed = JSON.parse(
|
|
3517
|
+
const parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
3403
3518
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3404
3519
|
return { file: rel, status: "skipped", note: "settings.json is not a JSON object \u2014 left untouched" };
|
|
3405
3520
|
}
|
|
@@ -3436,12 +3551,12 @@ function installClaudeHooks(root2, vgBin = "vg") {
|
|
|
3436
3551
|
return { file: rel, status: "written" };
|
|
3437
3552
|
}
|
|
3438
3553
|
function uninstallClaudeHooks(root2) {
|
|
3439
|
-
const file =
|
|
3440
|
-
const rel =
|
|
3441
|
-
if (!
|
|
3554
|
+
const file = path40.join(root2, ".claude", "settings.json");
|
|
3555
|
+
const rel = path40.join(".claude", "settings.json");
|
|
3556
|
+
if (!fs11.existsSync(file)) return { file: rel, status: "unchanged" };
|
|
3442
3557
|
let settings;
|
|
3443
3558
|
try {
|
|
3444
|
-
settings = JSON.parse(
|
|
3559
|
+
settings = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
3445
3560
|
} catch {
|
|
3446
3561
|
return { file: rel, status: "skipped", note: "settings.json is not parseable JSON \u2014 left untouched" };
|
|
3447
3562
|
}
|
|
@@ -3463,8 +3578,8 @@ function uninstallClaudeHooks(root2) {
|
|
|
3463
3578
|
return { file: rel, status: "written" };
|
|
3464
3579
|
}
|
|
3465
3580
|
function writeSettings(file, settings) {
|
|
3466
|
-
|
|
3467
|
-
|
|
3581
|
+
fs11.mkdirSync(path40.dirname(file), { recursive: true });
|
|
3582
|
+
fs11.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
|
|
3468
3583
|
`);
|
|
3469
3584
|
}
|
|
3470
3585
|
|
|
@@ -3584,19 +3699,19 @@ function registryBase(opts) {
|
|
|
3584
3699
|
return (process.env.VIBGRATE_MODULE_REGISTRY || opts.registry || DEFAULT_REGISTRY).replace(/\/+$/, "");
|
|
3585
3700
|
}
|
|
3586
3701
|
function stateFile() {
|
|
3587
|
-
return
|
|
3702
|
+
return path40.join(path40.dirname(relevanceModuleDir()), "consent.json");
|
|
3588
3703
|
}
|
|
3589
3704
|
function readConsent() {
|
|
3590
3705
|
try {
|
|
3591
|
-
return JSON.parse(
|
|
3706
|
+
return JSON.parse(fs11.readFileSync(stateFile(), "utf8"));
|
|
3592
3707
|
} catch {
|
|
3593
3708
|
return {};
|
|
3594
3709
|
}
|
|
3595
3710
|
}
|
|
3596
3711
|
function writeConsent(state) {
|
|
3597
3712
|
try {
|
|
3598
|
-
|
|
3599
|
-
|
|
3713
|
+
fs11.mkdirSync(path40.dirname(stateFile()), { recursive: true });
|
|
3714
|
+
fs11.writeFileSync(stateFile(), JSON.stringify(state));
|
|
3600
3715
|
} catch {
|
|
3601
3716
|
}
|
|
3602
3717
|
}
|
|
@@ -3606,8 +3721,8 @@ function kernelDisabled() {
|
|
|
3606
3721
|
}
|
|
3607
3722
|
function moduleInstalled() {
|
|
3608
3723
|
try {
|
|
3609
|
-
const meta = JSON.parse(
|
|
3610
|
-
if (
|
|
3724
|
+
const meta = JSON.parse(fs11.readFileSync(path40.join(relevanceModuleDir(), ".module.json"), "utf8"));
|
|
3725
|
+
if (fs11.existsSync(path40.join(relevanceModuleDir(), "index.js"))) {
|
|
3611
3726
|
return { installed: true, version: meta.version };
|
|
3612
3727
|
}
|
|
3613
3728
|
} catch {
|
|
@@ -3656,7 +3771,7 @@ function untar(data) {
|
|
|
3656
3771
|
if (type !== "0" && type !== "\0") continue;
|
|
3657
3772
|
const name = pendingName ?? (prefix ? `${prefix}/${rawName}` : rawName);
|
|
3658
3773
|
pendingName = null;
|
|
3659
|
-
if (name.split("/").includes("..") ||
|
|
3774
|
+
if (name.split("/").includes("..") || path40.isAbsolute(name)) {
|
|
3660
3775
|
throw new Error(`unsafe path in tarball: ${name}`);
|
|
3661
3776
|
}
|
|
3662
3777
|
out2.push({ name, body: Buffer.from(body) });
|
|
@@ -3682,25 +3797,25 @@ async function installRelevanceModule(opts = {}) {
|
|
|
3682
3797
|
verifyIntegrity(gz, dist.integrity, dist.shasum);
|
|
3683
3798
|
const entries = untar(zlib.gunzipSync(gz));
|
|
3684
3799
|
const dir = relevanceModuleDir();
|
|
3685
|
-
|
|
3686
|
-
|
|
3800
|
+
fs11.rmSync(dir, { recursive: true, force: true });
|
|
3801
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
3687
3802
|
let wrote = 0;
|
|
3688
3803
|
for (const e of entries) {
|
|
3689
3804
|
let rel = null;
|
|
3690
3805
|
if (e.name.startsWith("package/dist/")) rel = e.name.slice("package/dist/".length);
|
|
3691
3806
|
else if (e.name === "package/LICENSE" || e.name === "package/README.md") rel = e.name.slice("package/".length);
|
|
3692
3807
|
if (!rel) continue;
|
|
3693
|
-
const target =
|
|
3694
|
-
if (!target.startsWith(dir +
|
|
3695
|
-
|
|
3696
|
-
|
|
3808
|
+
const target = path40.join(dir, rel);
|
|
3809
|
+
if (!target.startsWith(dir + path40.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
|
|
3810
|
+
fs11.mkdirSync(path40.dirname(target), { recursive: true });
|
|
3811
|
+
fs11.writeFileSync(target, e.body);
|
|
3697
3812
|
wrote += 1;
|
|
3698
3813
|
}
|
|
3699
|
-
if (!wrote || !
|
|
3700
|
-
|
|
3814
|
+
if (!wrote || !fs11.existsSync(path40.join(dir, "index.js"))) {
|
|
3815
|
+
fs11.rmSync(dir, { recursive: true, force: true });
|
|
3701
3816
|
return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
|
|
3702
3817
|
}
|
|
3703
|
-
|
|
3818
|
+
fs11.writeFileSync(path40.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
|
|
3704
3819
|
resetRelevanceProviderCache();
|
|
3705
3820
|
return { status: "installed", version };
|
|
3706
3821
|
} catch (e) {
|
|
@@ -3708,7 +3823,7 @@ async function installRelevanceModule(opts = {}) {
|
|
|
3708
3823
|
}
|
|
3709
3824
|
}
|
|
3710
3825
|
function removeRelevanceModule() {
|
|
3711
|
-
|
|
3826
|
+
fs11.rmSync(relevanceModuleDir(), { recursive: true, force: true });
|
|
3712
3827
|
resetRelevanceProviderCache();
|
|
3713
3828
|
}
|
|
3714
3829
|
async function ensureRelevanceModule(io = {}) {
|
|
@@ -3817,7 +3932,7 @@ function hookContext(payloadText, root2, graphOverride) {
|
|
|
3817
3932
|
let graph;
|
|
3818
3933
|
try {
|
|
3819
3934
|
const preferred = loadGraphPreferIndex(root2, graphPath);
|
|
3820
|
-
graph = preferred ? preferred.graph : parseGraph(
|
|
3935
|
+
graph = preferred ? preferred.graph : parseGraph(fs11.readFileSync(graphPath, "utf8"));
|
|
3821
3936
|
} catch {
|
|
3822
3937
|
return null;
|
|
3823
3938
|
}
|
|
@@ -3839,7 +3954,7 @@ function registerHook(program) {
|
|
|
3839
3954
|
const global = readGlobal(this);
|
|
3840
3955
|
const root2 = rootOf(global);
|
|
3841
3956
|
try {
|
|
3842
|
-
const stdin =
|
|
3957
|
+
const stdin = fs11.readFileSync(0, "utf8");
|
|
3843
3958
|
const context = hookContext(stdin, root2, global.graph);
|
|
3844
3959
|
if (context) {
|
|
3845
3960
|
process.stdout.write(
|
|
@@ -3859,8 +3974,8 @@ function registerShare(program) {
|
|
|
3859
3974
|
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) {
|
|
3860
3975
|
const global = readGlobal(this);
|
|
3861
3976
|
const root2 = rootOf(global);
|
|
3862
|
-
const gitDir =
|
|
3863
|
-
if (!
|
|
3977
|
+
const gitDir = path40.join(root2, ".git");
|
|
3978
|
+
if (!fs11.existsSync(gitDir)) {
|
|
3864
3979
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
3865
3980
|
}
|
|
3866
3981
|
if (opts.undo) {
|
|
@@ -3881,23 +3996,23 @@ function registerShare(program) {
|
|
|
3881
3996
|
applyGlobalOptions(cmd);
|
|
3882
3997
|
}
|
|
3883
3998
|
function writeVibgrateGitignore(root2, reports) {
|
|
3884
|
-
const dir =
|
|
3885
|
-
|
|
3999
|
+
const dir = path40.join(root2, ".vibgrate");
|
|
4000
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
3886
4001
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
3887
4002
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
3888
|
-
|
|
4003
|
+
fs11.writeFileSync(path40.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
3889
4004
|
`);
|
|
3890
4005
|
}
|
|
3891
4006
|
function writeGitAttributes(root2) {
|
|
3892
|
-
const file =
|
|
4007
|
+
const file = path40.join(root2, ".gitattributes");
|
|
3893
4008
|
const line = ".vibgrate/graph.json merge=vg";
|
|
3894
|
-
let content =
|
|
4009
|
+
let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
|
|
3895
4010
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
3896
4011
|
content = content.length ? `${content.replace(/\s*$/, "")}
|
|
3897
4012
|
${line}
|
|
3898
4013
|
` : `${line}
|
|
3899
4014
|
`;
|
|
3900
|
-
|
|
4015
|
+
fs11.writeFileSync(file, content);
|
|
3901
4016
|
}
|
|
3902
4017
|
}
|
|
3903
4018
|
function configureMergeDriver(root2) {
|
|
@@ -3906,8 +4021,8 @@ function configureMergeDriver(root2) {
|
|
|
3906
4021
|
}
|
|
3907
4022
|
function installPreCommitHook(root2) {
|
|
3908
4023
|
const hooksDir = hookDir(root2);
|
|
3909
|
-
|
|
3910
|
-
const file =
|
|
4024
|
+
fs11.mkdirSync(hooksDir, { recursive: true });
|
|
4025
|
+
const file = path40.join(hooksDir, "pre-commit");
|
|
3911
4026
|
const block = [
|
|
3912
4027
|
HOOK_BEGIN,
|
|
3913
4028
|
"if command -v vg >/dev/null 2>&1; then",
|
|
@@ -3916,7 +4031,7 @@ function installPreCommitHook(root2) {
|
|
|
3916
4031
|
"fi",
|
|
3917
4032
|
HOOK_END
|
|
3918
4033
|
].join("\n");
|
|
3919
|
-
let content =
|
|
4034
|
+
let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "#!/bin/sh\n";
|
|
3920
4035
|
const re = new RegExp(`${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}`);
|
|
3921
4036
|
if (re.test(content)) content = content.replace(re, block);
|
|
3922
4037
|
else content = `${content.replace(/\s*$/, "")}
|
|
@@ -3925,21 +4040,21 @@ ${block}
|
|
|
3925
4040
|
`;
|
|
3926
4041
|
if (!content.startsWith("#!")) content = `#!/bin/sh
|
|
3927
4042
|
${content}`;
|
|
3928
|
-
|
|
3929
|
-
|
|
4043
|
+
fs11.writeFileSync(file, content);
|
|
4044
|
+
fs11.chmodSync(file, 493);
|
|
3930
4045
|
}
|
|
3931
4046
|
function undo(root2) {
|
|
3932
|
-
const hookFile =
|
|
3933
|
-
if (
|
|
4047
|
+
const hookFile = path40.join(hookDir(root2), "pre-commit");
|
|
4048
|
+
if (fs11.existsSync(hookFile)) {
|
|
3934
4049
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
3935
|
-
const next2 =
|
|
3936
|
-
if (next2.trim() === "#!/bin/sh")
|
|
3937
|
-
else
|
|
4050
|
+
const next2 = fs11.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
4051
|
+
if (next2.trim() === "#!/bin/sh") fs11.rmSync(hookFile);
|
|
4052
|
+
else fs11.writeFileSync(hookFile, next2);
|
|
3938
4053
|
}
|
|
3939
|
-
const attr =
|
|
3940
|
-
if (
|
|
3941
|
-
const next2 =
|
|
3942
|
-
|
|
4054
|
+
const attr = path40.join(root2, ".gitattributes");
|
|
4055
|
+
if (fs11.existsSync(attr)) {
|
|
4056
|
+
const next2 = fs11.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
4057
|
+
fs11.writeFileSync(attr, next2);
|
|
3943
4058
|
}
|
|
3944
4059
|
try {
|
|
3945
4060
|
git(root2, ["config", "--remove-section", "merge.vg"]);
|
|
@@ -3949,10 +4064,10 @@ function undo(root2) {
|
|
|
3949
4064
|
function hookDir(root2) {
|
|
3950
4065
|
try {
|
|
3951
4066
|
const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
|
|
3952
|
-
if (configured) return
|
|
4067
|
+
if (configured) return path40.resolve(root2, configured);
|
|
3953
4068
|
} catch {
|
|
3954
4069
|
}
|
|
3955
|
-
return
|
|
4070
|
+
return path40.join(root2, ".git", "hooks");
|
|
3956
4071
|
}
|
|
3957
4072
|
function git(root2, args) {
|
|
3958
4073
|
return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
|
|
@@ -3966,9 +4081,9 @@ function registerWatch(program) {
|
|
|
3966
4081
|
const global = readGlobal(this);
|
|
3967
4082
|
const root2 = rootOf(global);
|
|
3968
4083
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
3969
|
-
const watchRoots = (paths.length ? paths : ["."]).map((p) =>
|
|
4084
|
+
const watchRoots = (paths.length ? paths : ["."]).map((p) => path40.resolve(root2, p));
|
|
3970
4085
|
for (const w of watchRoots) {
|
|
3971
|
-
if (!
|
|
4086
|
+
if (!fs11.existsSync(w)) {
|
|
3972
4087
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
3973
4088
|
}
|
|
3974
4089
|
}
|
|
@@ -4021,7 +4136,7 @@ function registerWatch(program) {
|
|
|
4021
4136
|
const watchers = [];
|
|
4022
4137
|
for (const w of watchRoots) {
|
|
4023
4138
|
try {
|
|
4024
|
-
const watcher =
|
|
4139
|
+
const watcher = fs11.watch(w, { recursive: true }, (_event, filename) => {
|
|
4025
4140
|
if (!filename) {
|
|
4026
4141
|
schedule("change");
|
|
4027
4142
|
return;
|
|
@@ -4034,7 +4149,7 @@ function registerWatch(program) {
|
|
|
4034
4149
|
throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
|
|
4035
4150
|
}
|
|
4036
4151
|
}
|
|
4037
|
-
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) =>
|
|
4152
|
+
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path40.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
|
|
4038
4153
|
await new Promise((resolve21) => {
|
|
4039
4154
|
const stop = () => {
|
|
4040
4155
|
for (const w of watchers) w.close();
|
|
@@ -4367,10 +4482,10 @@ function normalizeStandards(raw) {
|
|
|
4367
4482
|
}
|
|
4368
4483
|
function loadStandards(root2) {
|
|
4369
4484
|
for (const rel of STANDARDS_FILES) {
|
|
4370
|
-
const p =
|
|
4485
|
+
const p = path40__default.join(root2, rel);
|
|
4371
4486
|
let text;
|
|
4372
4487
|
try {
|
|
4373
|
-
text =
|
|
4488
|
+
text = fs11__default.readFileSync(p, "utf8");
|
|
4374
4489
|
} catch {
|
|
4375
4490
|
continue;
|
|
4376
4491
|
}
|
|
@@ -5088,8 +5203,8 @@ async function runHostBench(options = {}) {
|
|
|
5088
5203
|
}
|
|
5089
5204
|
async function runArmSimulate(input) {
|
|
5090
5205
|
const { arm, lib, modelPath, turns, trie, env, live } = input;
|
|
5091
|
-
const
|
|
5092
|
-
const session = await acquireHostSession(lib,
|
|
5206
|
+
const path42 = `${modelPath}#${arm.id}`;
|
|
5207
|
+
const session = await acquireHostSession(lib, path42);
|
|
5093
5208
|
const system = "You are a coding agent with a Task Capsule.";
|
|
5094
5209
|
const capsule = "function readConfig(): Config { return load(); }";
|
|
5095
5210
|
let last = null;
|
|
@@ -6301,7 +6416,7 @@ function registerModels(program) {
|
|
|
6301
6416
|
);
|
|
6302
6417
|
}
|
|
6303
6418
|
} else {
|
|
6304
|
-
if (!target.path || !
|
|
6419
|
+
if (!target.path || !fs11.existsSync(target.path)) {
|
|
6305
6420
|
throw new CliError(
|
|
6306
6421
|
`model file not found at ${target.path || "(unknown path)"} \u2014 it may already be removed.`,
|
|
6307
6422
|
ExitCode.NOT_FOUND
|
|
@@ -6315,7 +6430,7 @@ function registerModels(program) {
|
|
|
6315
6430
|
}
|
|
6316
6431
|
if (!global.json) info(c.dim(` $ rm ${target.path}`));
|
|
6317
6432
|
try {
|
|
6318
|
-
|
|
6433
|
+
fs11.unlinkSync(target.path);
|
|
6319
6434
|
} catch (e) {
|
|
6320
6435
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6321
6436
|
throw new CliError(`could not delete ${target.path}: ${msg}`, ExitCode.ERROR);
|
|
@@ -6453,9 +6568,9 @@ function registerModels(program) {
|
|
|
6453
6568
|
}
|
|
6454
6569
|
});
|
|
6455
6570
|
if (opts.out) {
|
|
6456
|
-
const outPath =
|
|
6457
|
-
|
|
6458
|
-
|
|
6571
|
+
const outPath = path40.resolve(opts.out);
|
|
6572
|
+
fs11.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
6573
|
+
fs11.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
6459
6574
|
`);
|
|
6460
6575
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
6461
6576
|
}
|
|
@@ -6604,14 +6719,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
|
|
|
6604
6719
|
}
|
|
6605
6720
|
return exact[0];
|
|
6606
6721
|
}
|
|
6607
|
-
const base =
|
|
6722
|
+
const base = path40.basename(wantLc);
|
|
6608
6723
|
const soft = fleet.filter((m) => {
|
|
6609
6724
|
const n = m.name.toLowerCase();
|
|
6610
|
-
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) ||
|
|
6725
|
+
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path40.basename(n) === base;
|
|
6611
6726
|
});
|
|
6612
6727
|
if (soft.length === 1) return soft[0];
|
|
6613
6728
|
if (soft.length > 1) {
|
|
6614
|
-
const baseHits = soft.filter((m) =>
|
|
6729
|
+
const baseHits = soft.filter((m) => path40.basename(m.name).toLowerCase() === base);
|
|
6615
6730
|
const pool = baseHits.length ? baseHits : soft;
|
|
6616
6731
|
const order = ["ollama", "gguf", "lm-studio"];
|
|
6617
6732
|
for (const rt of order) {
|
|
@@ -6649,11 +6764,11 @@ function printBackends(backends) {
|
|
|
6649
6764
|
}
|
|
6650
6765
|
}
|
|
6651
6766
|
function codeConfigPath(root2) {
|
|
6652
|
-
return
|
|
6767
|
+
return path40.join(root2, ".vibgrate", "code.json");
|
|
6653
6768
|
}
|
|
6654
6769
|
function loadCodeConfig(root2) {
|
|
6655
6770
|
try {
|
|
6656
|
-
const raw = JSON.parse(
|
|
6771
|
+
const raw = JSON.parse(fs11.readFileSync(codeConfigPath(root2), "utf8"));
|
|
6657
6772
|
return sanitize(raw);
|
|
6658
6773
|
} catch {
|
|
6659
6774
|
return {};
|
|
@@ -6720,7 +6835,7 @@ function contextBudgetFor(config, modelContextWindow) {
|
|
|
6720
6835
|
var MCP_CONFIG_FILES = [".cursor/mcp.json", ".vscode/mcp.json", ".mcp.json"];
|
|
6721
6836
|
function readMcpServersFile(file) {
|
|
6722
6837
|
try {
|
|
6723
|
-
const raw = JSON.parse(
|
|
6838
|
+
const raw = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
6724
6839
|
const map = raw.mcpServers ?? raw.servers;
|
|
6725
6840
|
return map && typeof map === "object" ? parseMcpServers(map) : {};
|
|
6726
6841
|
} catch {
|
|
@@ -6731,7 +6846,7 @@ function discoverMcpServers(root2, ownServers) {
|
|
|
6731
6846
|
const servers = {};
|
|
6732
6847
|
const sources = [];
|
|
6733
6848
|
for (const rel of MCP_CONFIG_FILES) {
|
|
6734
|
-
const found = readMcpServersFile(
|
|
6849
|
+
const found = readMcpServersFile(path40.join(root2, rel));
|
|
6735
6850
|
const names = Object.keys(found);
|
|
6736
6851
|
if (names.length) {
|
|
6737
6852
|
sources.push(rel);
|
|
@@ -6763,7 +6878,7 @@ function registerCode(program) {
|
|
|
6763
6878
|
try {
|
|
6764
6879
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6765
6880
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6766
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6881
|
+
const { loadGraph: loadGraph2 } = await import('./load-6KVGUQMU.js');
|
|
6767
6882
|
const state = readOrchestratorState2();
|
|
6768
6883
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6769
6884
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -6848,7 +6963,7 @@ function registerCode(program) {
|
|
|
6848
6963
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
6849
6964
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
6850
6965
|
}
|
|
6851
|
-
const { runInteractive } = await import('./interactive-
|
|
6966
|
+
const { runInteractive } = await import('./interactive-DB7IC3BL.js');
|
|
6852
6967
|
await runInteractive(
|
|
6853
6968
|
rootOf(global),
|
|
6854
6969
|
global,
|
|
@@ -6878,7 +6993,7 @@ function registerCode(program) {
|
|
|
6878
6993
|
}
|
|
6879
6994
|
if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
6880
6995
|
{
|
|
6881
|
-
const { ensureCodeMap } = await import('./ensure-map-
|
|
6996
|
+
const { ensureCodeMap } = await import('./ensure-map-DZ53QXRT.js');
|
|
6882
6997
|
const mapRoot = rootOf(global);
|
|
6883
6998
|
try {
|
|
6884
6999
|
await ensureCodeMap(mapRoot, global, {
|
|
@@ -6915,7 +7030,7 @@ function registerCode(program) {
|
|
|
6915
7030
|
let mockReply;
|
|
6916
7031
|
if (opts.mock) {
|
|
6917
7032
|
try {
|
|
6918
|
-
mockReply =
|
|
7033
|
+
mockReply = fs11.readFileSync(opts.mock, "utf8");
|
|
6919
7034
|
} catch {
|
|
6920
7035
|
throw new CliError(`couldn't read the --mock file: ${opts.mock}`, ExitCode.USAGE_ERROR);
|
|
6921
7036
|
}
|
|
@@ -6963,20 +7078,20 @@ function registerCode(program) {
|
|
|
6963
7078
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
6964
7079
|
};
|
|
6965
7080
|
try {
|
|
6966
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
7081
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-YOYRC32U.js');
|
|
6967
7082
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
6968
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
6969
|
-
const { nodeCodeFs } = await import('./session-
|
|
7083
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-3OJCPBWY.js');
|
|
7084
|
+
const { nodeCodeFs } = await import('./session-5WKEACIF.js');
|
|
6970
7085
|
const readline6 = await import('readline');
|
|
6971
7086
|
const child = await import('child_process');
|
|
6972
7087
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
6973
7088
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6974
7089
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6975
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6976
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7090
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-XEP7IPGP.js');
|
|
7091
|
+
const { resolveGraphBackend } = await import('./graph-backend-3A2M22QN.js');
|
|
6977
7092
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6978
7093
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6979
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7094
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-UTLMMPIZ.js');
|
|
6980
7095
|
const federation = loadOrDiscoverFederation(root2);
|
|
6981
7096
|
const modelProfile = mergeModelExecutionProfile(
|
|
6982
7097
|
resolveModelExecutionProfile({
|
|
@@ -7034,7 +7149,7 @@ ${res.stderr}` : ""),
|
|
|
7034
7149
|
exitCode: res.status ?? 1
|
|
7035
7150
|
};
|
|
7036
7151
|
};
|
|
7037
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7152
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PM3C4FQL.js');
|
|
7038
7153
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7039
7154
|
getGraph: () => graph,
|
|
7040
7155
|
root: root2,
|
|
@@ -7055,10 +7170,10 @@ ${res.stderr}` : ""),
|
|
|
7055
7170
|
}
|
|
7056
7171
|
const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
|
|
7057
7172
|
const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
|
|
7058
|
-
const
|
|
7173
|
+
const os5 = await import('os');
|
|
7059
7174
|
const pathMod = await import('path');
|
|
7060
7175
|
const checkpointIndex = pathMod.join(
|
|
7061
|
-
|
|
7176
|
+
fs11.mkdtempSync(pathMod.join(os5.tmpdir(), "vg-code-cp-")),
|
|
7062
7177
|
"index"
|
|
7063
7178
|
);
|
|
7064
7179
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -7124,8 +7239,8 @@ ${res.stderr}` : ""),
|
|
|
7124
7239
|
};
|
|
7125
7240
|
try {
|
|
7126
7241
|
if (opts.session) {
|
|
7127
|
-
const { runCodeStreamJsonSession } = await import('./stream-json-
|
|
7128
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
7242
|
+
const { runCodeStreamJsonSession } = await import('./stream-json-3OJCPBWY.js');
|
|
7243
|
+
const { runAgent: runAgent2 } = await import('./agent-WYBWUBCC.js');
|
|
7129
7244
|
const {
|
|
7130
7245
|
condenseSession,
|
|
7131
7246
|
loadLatestSession,
|
|
@@ -7293,8 +7408,8 @@ ${res.stderr}` : ""),
|
|
|
7293
7408
|
if (!autonomous && !tty) {
|
|
7294
7409
|
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).");
|
|
7295
7410
|
}
|
|
7296
|
-
const { agentTask } = await import('./interactive-
|
|
7297
|
-
const { nodeCodeFs } = await import('./session-
|
|
7411
|
+
const { agentTask } = await import('./interactive-DB7IC3BL.js');
|
|
7412
|
+
const { nodeCodeFs } = await import('./session-5WKEACIF.js');
|
|
7298
7413
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
7299
7414
|
let priorSummary;
|
|
7300
7415
|
let priorInstruction;
|
|
@@ -7307,7 +7422,7 @@ ${res.stderr}` : ""),
|
|
|
7307
7422
|
}
|
|
7308
7423
|
}
|
|
7309
7424
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
7310
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7425
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PM3C4FQL.js');
|
|
7311
7426
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7312
7427
|
getGraph: () => graph,
|
|
7313
7428
|
root: root2,
|
|
@@ -7331,11 +7446,11 @@ ${res.stderr}` : ""),
|
|
|
7331
7446
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
7332
7447
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7333
7448
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7334
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7335
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7449
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-XEP7IPGP.js');
|
|
7450
|
+
const { resolveGraphBackend } = await import('./graph-backend-3A2M22QN.js');
|
|
7336
7451
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7337
7452
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7338
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
7453
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-UTLMMPIZ.js');
|
|
7339
7454
|
const federation = loadFederation(root2);
|
|
7340
7455
|
const modelProfile = mergeModelExecutionProfile(
|
|
7341
7456
|
resolveModelExecutionProfile({
|
|
@@ -7429,7 +7544,7 @@ ${res.stderr}` : ""),
|
|
|
7429
7544
|
attribution: { client: "vg-code", provider: providerSlug, model: primary?.model }
|
|
7430
7545
|
});
|
|
7431
7546
|
if (opts.out) {
|
|
7432
|
-
|
|
7547
|
+
fs11.writeFileSync(opts.out, JSON.stringify(result, null, 2) + "\n");
|
|
7433
7548
|
}
|
|
7434
7549
|
if (global.json) {
|
|
7435
7550
|
json(result);
|
|
@@ -7642,7 +7757,7 @@ async function addCmd(root2, rest, opts, asJson) {
|
|
|
7642
7757
|
}
|
|
7643
7758
|
function readPackageVersion(root2) {
|
|
7644
7759
|
try {
|
|
7645
|
-
const pkg = JSON.parse(
|
|
7760
|
+
const pkg = JSON.parse(fs11__default.readFileSync(path40__default.join(root2, "package.json"), "utf8"));
|
|
7646
7761
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
7647
7762
|
} catch {
|
|
7648
7763
|
return void 0;
|
|
@@ -7650,7 +7765,7 @@ function readPackageVersion(root2) {
|
|
|
7650
7765
|
}
|
|
7651
7766
|
function readOptionalFile(p) {
|
|
7652
7767
|
try {
|
|
7653
|
-
const t =
|
|
7768
|
+
const t = fs11__default.readFileSync(p, "utf8");
|
|
7654
7769
|
return t.trim() ? t : void 0;
|
|
7655
7770
|
} catch {
|
|
7656
7771
|
return void 0;
|
|
@@ -7665,8 +7780,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
|
|
|
7665
7780
|
if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
|
|
7666
7781
|
const version = (opts.version || readPackageVersion(root2) || "").trim();
|
|
7667
7782
|
if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
|
|
7668
|
-
const readme = readOptionalFile(opts.readme ?
|
|
7669
|
-
const dts = opts.dts ? readOptionalFile(
|
|
7783
|
+
const readme = readOptionalFile(opts.readme ? path40__default.resolve(opts.readme) : path40__default.join(root2, "README.md"));
|
|
7784
|
+
const dts = opts.dts ? readOptionalFile(path40__default.resolve(opts.dts)) : void 0;
|
|
7670
7785
|
if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
|
|
7671
7786
|
const result = await publishPrivateLibrary(
|
|
7672
7787
|
{ name, version, readme, dts, language: opts.language },
|
|
@@ -7798,8 +7913,8 @@ function registerExport(program) {
|
|
|
7798
7913
|
out(content.trimEnd());
|
|
7799
7914
|
return;
|
|
7800
7915
|
}
|
|
7801
|
-
|
|
7802
|
-
|
|
7916
|
+
fs11.mkdirSync(path40.dirname(path40.resolve(file)), { recursive: true });
|
|
7917
|
+
fs11.writeFileSync(file, content);
|
|
7803
7918
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
7804
7919
|
});
|
|
7805
7920
|
applyGlobalOptions(cmd);
|
|
@@ -7809,43 +7924,43 @@ function detectFormat(file) {
|
|
|
7809
7924
|
if (lower.endsWith(".cdx.json")) return "cyclonedx";
|
|
7810
7925
|
if (lower.endsWith(".spdx.json")) return "spdx";
|
|
7811
7926
|
if (file === "-") return "json";
|
|
7812
|
-
return formatForExt(
|
|
7927
|
+
return formatForExt(path40.extname(file));
|
|
7813
7928
|
}
|
|
7814
7929
|
function registerBundle(program) {
|
|
7815
7930
|
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) {
|
|
7816
7931
|
const global = readGlobal(this);
|
|
7817
7932
|
const root2 = rootOf(global);
|
|
7818
|
-
const outDir =
|
|
7933
|
+
const outDir = path40.resolve(root2, opts.out ?? "vg-bundle");
|
|
7819
7934
|
let grammarFiles;
|
|
7820
7935
|
try {
|
|
7821
7936
|
grammarFiles = resolvedGrammarFiles();
|
|
7822
7937
|
} catch {
|
|
7823
7938
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
7824
7939
|
}
|
|
7825
|
-
|
|
7940
|
+
fs11.mkdirSync(path40.join(outDir, "grammars"), { recursive: true });
|
|
7826
7941
|
let grammarCount = 0;
|
|
7827
7942
|
for (const { fileName, absPath } of grammarFiles) {
|
|
7828
|
-
|
|
7943
|
+
fs11.copyFileSync(absPath, path40.join(outDir, "grammars", fileName));
|
|
7829
7944
|
grammarCount++;
|
|
7830
7945
|
}
|
|
7831
7946
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
7832
7947
|
const graphSrc = resolveGraphPath(root2, global.graph);
|
|
7833
|
-
if (
|
|
7834
|
-
|
|
7948
|
+
if (fs11.existsSync(graphSrc)) {
|
|
7949
|
+
fs11.copyFileSync(graphSrc, path40.join(outDir, "graph.json"));
|
|
7835
7950
|
included.push("graph.json");
|
|
7836
7951
|
} else {
|
|
7837
7952
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
7838
7953
|
if (graph) {
|
|
7839
|
-
|
|
7954
|
+
fs11.writeFileSync(path40.join(outDir, "graph.json"), serializeGraph(graph));
|
|
7840
7955
|
included.push("graph.json");
|
|
7841
7956
|
}
|
|
7842
7957
|
}
|
|
7843
7958
|
const cat = catalogPath(root2);
|
|
7844
|
-
if (
|
|
7845
|
-
|
|
7959
|
+
if (fs11.existsSync(cat)) {
|
|
7960
|
+
fs11.copyFileSync(cat, path40.join(outDir, "vibgrate.lib.json"));
|
|
7846
7961
|
included.push("vibgrate.lib.json");
|
|
7847
|
-
if (
|
|
7848
|
-
|
|
7962
|
+
if (fs11.existsSync(libDir(root2))) {
|
|
7963
|
+
fs11.cpSync(libDir(root2), path40.join(outDir, "lib"), { recursive: true });
|
|
7849
7964
|
included.push("lib/");
|
|
7850
7965
|
}
|
|
7851
7966
|
}
|
|
@@ -7857,15 +7972,15 @@ function registerBundle(program) {
|
|
|
7857
7972
|
included,
|
|
7858
7973
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
7859
7974
|
};
|
|
7860
|
-
|
|
7975
|
+
fs11.writeFileSync(path40.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
7861
7976
|
`);
|
|
7862
7977
|
if (global.json) {
|
|
7863
|
-
json({ out:
|
|
7978
|
+
json({ out: path40.relative(root2, outDir), ...manifest });
|
|
7864
7979
|
return;
|
|
7865
7980
|
}
|
|
7866
|
-
info(`${c.cyan("vg bundle")} \xB7 wrote ${
|
|
7981
|
+
info(`${c.cyan("vg bundle")} \xB7 wrote ${path40.relative(root2, outDir)}/`);
|
|
7867
7982
|
for (const i of included) info(` ${c.green("\u2714")} ${i}`);
|
|
7868
|
-
info(c.dim(` offline: vg build --grammars "${
|
|
7983
|
+
info(c.dim(` offline: vg build --grammars "${path40.relative(root2, outDir)}/grammars"`));
|
|
7869
7984
|
});
|
|
7870
7985
|
applyGlobalOptions(cmd);
|
|
7871
7986
|
}
|
|
@@ -7883,7 +7998,7 @@ async function runDoctor(global) {
|
|
|
7883
7998
|
const root2 = rootOf(global);
|
|
7884
7999
|
const local = global.local === true;
|
|
7885
8000
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
7886
|
-
const configFile = CONFIG_BASENAMES.find((f) =>
|
|
8001
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path40.join(root2, f))) ?? null;
|
|
7887
8002
|
const graph = loadGraph(root2, graphPath);
|
|
7888
8003
|
let staleFiles = null;
|
|
7889
8004
|
if (graph) {
|
|
@@ -7909,14 +8024,14 @@ async function runDoctor(global) {
|
|
|
7909
8024
|
root: root2,
|
|
7910
8025
|
configFile,
|
|
7911
8026
|
map: {
|
|
7912
|
-
path:
|
|
8027
|
+
path: path40.relative(root2, graphPath),
|
|
7913
8028
|
built: graph !== null,
|
|
7914
8029
|
generatedAt: graph?.generatedAt ?? null,
|
|
7915
8030
|
staleFiles
|
|
7916
8031
|
},
|
|
7917
8032
|
libCatalog: {
|
|
7918
|
-
path:
|
|
7919
|
-
present:
|
|
8033
|
+
path: path40.relative(root2, catalogPath(root2)),
|
|
8034
|
+
present: fs11.existsSync(catalogPath(root2)),
|
|
7920
8035
|
libraries: libCount
|
|
7921
8036
|
},
|
|
7922
8037
|
credentials: creds,
|
|
@@ -7973,7 +8088,7 @@ async function runDoctor(global) {
|
|
|
7973
8088
|
);
|
|
7974
8089
|
info(
|
|
7975
8090
|
` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
|
|
7976
|
-
` \xB7 last ${
|
|
8091
|
+
` \xB7 last ${path40.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
|
|
7977
8092
|
) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
|
|
7978
8093
|
);
|
|
7979
8094
|
if (li.dynamicOnToken || li.dynamicCustomSampler) {
|
|
@@ -8038,12 +8153,24 @@ function registerDaemon(program) {
|
|
|
8038
8153
|
}
|
|
8039
8154
|
const res = await vgdRequest({ op: "status" }, { socketPath });
|
|
8040
8155
|
if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
|
|
8041
|
-
|
|
8156
|
+
const semantic = await vgdRequest({ op: "embed-status" }, { socketPath }).catch(() => null);
|
|
8157
|
+
const semanticPayload = semantic && semantic.ok && "semantic" in semantic ? semantic.semantic : void 0;
|
|
8158
|
+
if (global.json) json({ running: true, ...res, semantic: semanticPayload });
|
|
8042
8159
|
else if ("pid" in res) {
|
|
8043
8160
|
const slots = typeof res.graphSlots === "number" ? ` \xB7 ${res.graphSlots} graph slot(s)` : "";
|
|
8044
8161
|
info(
|
|
8045
8162
|
`vgd \xB7 running pid ${res.pid} \xB7 ${res.workspaces} workspace(s)${slots} \xB7 ${res.uptimeMs}ms up \xB7 ${c.dim(res.socketPath)}`
|
|
8046
8163
|
);
|
|
8164
|
+
if (semanticPayload) {
|
|
8165
|
+
const ready = semanticPayload.slots.filter((sl) => sl.state === "ready");
|
|
8166
|
+
const vectors = ready.reduce((n, sl) => n + sl.vectors, 0);
|
|
8167
|
+
const detail = semanticPayload.worker === "unavailable" ? c.dim(semanticPayload.reason ?? "semantic off \u2014 lexical only") : `${ready.length}/${semanticPayload.slots.length} index(es) ready \xB7 ${vectors} vector(s)` + (semanticPayload.model ? ` \xB7 ${semanticPayload.model}` : "");
|
|
8168
|
+
info(` semantic \xB7 worker ${semanticPayload.worker} \xB7 ${detail}`);
|
|
8169
|
+
for (const sl of semanticPayload.slots) {
|
|
8170
|
+
if (sl.state === "ready") continue;
|
|
8171
|
+
info(c.dim(` ${sl.repositoryId}@${sl.gitRef} \xB7 ${sl.state}${sl.error ? ` \u2014 ${sl.error}` : ""}`));
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8047
8174
|
}
|
|
8048
8175
|
});
|
|
8049
8176
|
applyGlobalOptions(status);
|
|
@@ -8055,7 +8182,13 @@ function registerDaemon(program) {
|
|
|
8055
8182
|
}
|
|
8056
8183
|
let requestShutdown = () => {
|
|
8057
8184
|
};
|
|
8058
|
-
const server = await startVgdServer({
|
|
8185
|
+
const server = await startVgdServer({
|
|
8186
|
+
socketPath,
|
|
8187
|
+
onShutdownRequest: () => requestShutdown(),
|
|
8188
|
+
// Show the daemon working: graph publishes, branch switches, new repos,
|
|
8189
|
+
// and every semantic index build. Silent under --quiet/--json.
|
|
8190
|
+
log: global.quiet || global.json ? void 0 : (message) => info(c.dim(`vgd \xB7 ${message}`))
|
|
8191
|
+
});
|
|
8059
8192
|
if (!global.quiet) {
|
|
8060
8193
|
info(`vgd \xB7 listening on ${c.dim(server.socketPath)} (${VGD_PROTOCOL_VERSION})`);
|
|
8061
8194
|
info(c.dim(" register a workspace: vg daemon register"));
|
|
@@ -8149,7 +8282,7 @@ function registerDaemon(program) {
|
|
|
8149
8282
|
const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
|
|
8150
8283
|
const global = readGlobal(this);
|
|
8151
8284
|
const socketPath = socketOf(this);
|
|
8152
|
-
const root2 =
|
|
8285
|
+
const root2 = path40.resolve(rootArg ?? rootOf(global));
|
|
8153
8286
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8154
8287
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8155
8288
|
}
|
|
@@ -8185,7 +8318,7 @@ function registerDaemon(program) {
|
|
|
8185
8318
|
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) {
|
|
8186
8319
|
const global = readGlobal(this);
|
|
8187
8320
|
const socketPath = socketOf(this);
|
|
8188
|
-
const primary =
|
|
8321
|
+
const primary = path40.resolve(rootArg ?? rootOf(global));
|
|
8189
8322
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8190
8323
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8191
8324
|
}
|
|
@@ -8213,7 +8346,7 @@ function registerDaemon(program) {
|
|
|
8213
8346
|
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) {
|
|
8214
8347
|
const global = readGlobal(this);
|
|
8215
8348
|
const socketPath = socketOf(this);
|
|
8216
|
-
const root2 =
|
|
8349
|
+
const root2 = path40.resolve(rootArg ?? rootOf(global));
|
|
8217
8350
|
if (!await vgdIsRunning({ socketPath })) {
|
|
8218
8351
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
8219
8352
|
}
|
|
@@ -8227,7 +8360,7 @@ function registerDaemon(program) {
|
|
|
8227
8360
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
8228
8361
|
}
|
|
8229
8362
|
if (!loaded.ok) {
|
|
8230
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
8363
|
+
const { loadGraph: loadGraph2 } = await import('./load-6KVGUQMU.js');
|
|
8231
8364
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
8232
8365
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
8233
8366
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -8343,7 +8476,7 @@ function socketOf(cmd) {
|
|
|
8343
8476
|
let c2 = cmd;
|
|
8344
8477
|
while (c2) {
|
|
8345
8478
|
const opts = c2.opts();
|
|
8346
|
-
if (opts.socket) return
|
|
8479
|
+
if (opts.socket) return path40.resolve(opts.socket);
|
|
8347
8480
|
c2 = c2.parent;
|
|
8348
8481
|
}
|
|
8349
8482
|
return vgdSocketPath();
|
|
@@ -8415,7 +8548,7 @@ async function restartVgdIfRunning(socketPath = vgdSocketPath()) {
|
|
|
8415
8548
|
}
|
|
8416
8549
|
function readVgdPid() {
|
|
8417
8550
|
try {
|
|
8418
|
-
const raw =
|
|
8551
|
+
const raw = fs11.readFileSync(vgdPidPath(), "utf8").trim();
|
|
8419
8552
|
const pid = Number.parseInt(raw, 10);
|
|
8420
8553
|
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
8421
8554
|
} catch {
|
|
@@ -8500,7 +8633,7 @@ function registerPolicy(program) {
|
|
|
8500
8633
|
const global = readGlobal(this);
|
|
8501
8634
|
let raw;
|
|
8502
8635
|
try {
|
|
8503
|
-
raw =
|
|
8636
|
+
raw = fs11.readFileSync(file, "utf8");
|
|
8504
8637
|
} catch {
|
|
8505
8638
|
throw new CliError(`cannot read ${file}`, ExitCode.NOT_FOUND);
|
|
8506
8639
|
}
|
|
@@ -8620,11 +8753,11 @@ function registerLlmHost(program) {
|
|
|
8620
8753
|
applyGlobalOptions(cmd);
|
|
8621
8754
|
}
|
|
8622
8755
|
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) => {
|
|
8623
|
-
const rootDir =
|
|
8624
|
-
const vibgrateDir2 =
|
|
8756
|
+
const rootDir = path40.resolve(targetPath);
|
|
8757
|
+
const vibgrateDir2 = path40.join(rootDir, ".vibgrate");
|
|
8625
8758
|
await ensureDir(vibgrateDir2);
|
|
8626
8759
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
|
|
8627
|
-
const configPath =
|
|
8760
|
+
const configPath = path40.join(rootDir, "vibgrate.config.ts");
|
|
8628
8761
|
if (await pathExists(configPath)) {
|
|
8629
8762
|
console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
|
|
8630
8763
|
} else {
|
|
@@ -8632,7 +8765,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
8632
8765
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
8633
8766
|
}
|
|
8634
8767
|
if (opts.baseline) {
|
|
8635
|
-
const { runBaseline } = await import('./baseline-
|
|
8768
|
+
const { runBaseline } = await import('./baseline-3HECX4Q6.js');
|
|
8636
8769
|
await runBaseline(rootDir);
|
|
8637
8770
|
}
|
|
8638
8771
|
console.log("");
|
|
@@ -8735,7 +8868,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
8735
8868
|
};
|
|
8736
8869
|
}
|
|
8737
8870
|
async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
|
|
8738
|
-
const content = await readFile3(
|
|
8871
|
+
const content = await readFile3(path40.join(rootDir, relFile));
|
|
8739
8872
|
if (!content) return null;
|
|
8740
8873
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8741
8874
|
const re = new RegExp(`\\b${escaped}\\b`);
|
|
@@ -8773,9 +8906,9 @@ function sitesFromImportFiles(files, limit = 10) {
|
|
|
8773
8906
|
}
|
|
8774
8907
|
async function defaultReadFile(absPath) {
|
|
8775
8908
|
try {
|
|
8776
|
-
const stat2 = await
|
|
8909
|
+
const stat2 = await fs25.stat(absPath);
|
|
8777
8910
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
8778
|
-
return await
|
|
8911
|
+
return await fs25.readFile(absPath, "utf8");
|
|
8779
8912
|
} catch {
|
|
8780
8913
|
return null;
|
|
8781
8914
|
}
|
|
@@ -8971,7 +9104,7 @@ var AI_ASSISTANT_DETECTORS = [
|
|
|
8971
9104
|
async function detectAiAssistant(rootDir) {
|
|
8972
9105
|
for (const detector of AI_ASSISTANT_DETECTORS) {
|
|
8973
9106
|
for (const file of detector.files) {
|
|
8974
|
-
if (await pathExists$1(
|
|
9107
|
+
if (await pathExists$1(path40.join(rootDir, file))) {
|
|
8975
9108
|
return detector.name;
|
|
8976
9109
|
}
|
|
8977
9110
|
}
|
|
@@ -9165,7 +9298,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9165
9298
|
collectExcludes,
|
|
9166
9299
|
[]
|
|
9167
9300
|
).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) => {
|
|
9168
|
-
const rootDir =
|
|
9301
|
+
const rootDir = path40.resolve(targetPath);
|
|
9169
9302
|
if (!await pathExists$1(rootDir)) {
|
|
9170
9303
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
9171
9304
|
process.exit(1);
|
|
@@ -9173,7 +9306,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9173
9306
|
const hasDsn = !!resolveDsn(opts.dsn);
|
|
9174
9307
|
const willPush = !opts.offline && (opts.push || hasDsn);
|
|
9175
9308
|
const noLocalArtifacts = opts.localArtifacts === false;
|
|
9176
|
-
const isFirstRun = !await pathExists$1(
|
|
9309
|
+
const isFirstRun = !await pathExists$1(path40.join(rootDir, ".vibgrate", "scan_result.json"));
|
|
9177
9310
|
let pinnedRegion;
|
|
9178
9311
|
let planTier;
|
|
9179
9312
|
let upgradeUrl;
|
|
@@ -9432,7 +9565,7 @@ var SKIP_DIRS2 = /* @__PURE__ */ new Set([
|
|
|
9432
9565
|
function scanStaleness(rootDir, artifactPath) {
|
|
9433
9566
|
let ref;
|
|
9434
9567
|
try {
|
|
9435
|
-
ref =
|
|
9568
|
+
ref = fs11.statSync(artifactPath).mtimeMs;
|
|
9436
9569
|
} catch {
|
|
9437
9570
|
return { stale: false };
|
|
9438
9571
|
}
|
|
@@ -9444,7 +9577,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9444
9577
|
if (depth > 8 || scanned > MAX_ENTRIES2) return;
|
|
9445
9578
|
let entries;
|
|
9446
9579
|
try {
|
|
9447
|
-
entries =
|
|
9580
|
+
entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
9448
9581
|
} catch {
|
|
9449
9582
|
return;
|
|
9450
9583
|
}
|
|
@@ -9452,20 +9585,20 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
9452
9585
|
scanned++;
|
|
9453
9586
|
if (scanned > MAX_ENTRIES2) break;
|
|
9454
9587
|
if (e.isDirectory()) {
|
|
9455
|
-
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(
|
|
9588
|
+
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path40.join(dir, e.name), depth + 1);
|
|
9456
9589
|
continue;
|
|
9457
9590
|
}
|
|
9458
9591
|
if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
|
|
9459
|
-
const abs =
|
|
9592
|
+
const abs = path40.join(dir, e.name);
|
|
9460
9593
|
let mtimeMs;
|
|
9461
9594
|
try {
|
|
9462
|
-
mtimeMs =
|
|
9595
|
+
mtimeMs = fs11.statSync(abs).mtimeMs;
|
|
9463
9596
|
} catch {
|
|
9464
9597
|
continue;
|
|
9465
9598
|
}
|
|
9466
9599
|
if (mtimeMs > newest) {
|
|
9467
9600
|
newest = mtimeMs;
|
|
9468
|
-
newestChanged =
|
|
9601
|
+
newestChanged = path40.relative(rootDir, abs) || e.name;
|
|
9469
9602
|
}
|
|
9470
9603
|
}
|
|
9471
9604
|
};
|
|
@@ -9596,7 +9729,7 @@ function analyzeTree(root2, packages) {
|
|
|
9596
9729
|
if (depth > MAX_DEPTH || filesSeen >= MAX_FILES) return;
|
|
9597
9730
|
let entries;
|
|
9598
9731
|
try {
|
|
9599
|
-
entries =
|
|
9732
|
+
entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
9600
9733
|
} catch {
|
|
9601
9734
|
return;
|
|
9602
9735
|
}
|
|
@@ -9605,17 +9738,17 @@ function analyzeTree(root2, packages) {
|
|
|
9605
9738
|
if (filesSeen >= MAX_FILES) return;
|
|
9606
9739
|
if (entry.isDirectory()) {
|
|
9607
9740
|
if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
9608
|
-
walk2(
|
|
9741
|
+
walk2(path40.join(dir, entry.name), depth + 1);
|
|
9609
9742
|
continue;
|
|
9610
9743
|
}
|
|
9611
|
-
const fileEco = EXT_ECOSYSTEM[
|
|
9744
|
+
const fileEco = EXT_ECOSYSTEM[path40.extname(entry.name)];
|
|
9612
9745
|
if (!fileEco || fileEco === "unknown") continue;
|
|
9613
9746
|
filesSeen++;
|
|
9614
|
-
const full =
|
|
9747
|
+
const full = path40.join(dir, entry.name);
|
|
9615
9748
|
let content;
|
|
9616
9749
|
try {
|
|
9617
|
-
if (
|
|
9618
|
-
content =
|
|
9750
|
+
if (fs11.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
9751
|
+
content = fs11.readFileSync(full, "utf8");
|
|
9619
9752
|
} catch {
|
|
9620
9753
|
continue;
|
|
9621
9754
|
}
|
|
@@ -9926,7 +10059,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
9926
10059
|
}
|
|
9927
10060
|
const outcomes = effective.map((t) => {
|
|
9928
10061
|
const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
|
|
9929
|
-
return { t, res: run(c2,
|
|
10062
|
+
return { t, res: run(c2, path40.join(rootDir, t.dir)) };
|
|
9930
10063
|
});
|
|
9931
10064
|
const failures = outcomes.filter((o) => !o.res.ok);
|
|
9932
10065
|
if (failures.length === 0) {
|
|
@@ -9955,8 +10088,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
9955
10088
|
return results;
|
|
9956
10089
|
}
|
|
9957
10090
|
var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
|
|
9958
|
-
var CACHE_DIR =
|
|
9959
|
-
var CACHE_FILE =
|
|
10091
|
+
var CACHE_DIR = path40.join(os.homedir(), ".vibgrate");
|
|
10092
|
+
var CACHE_FILE = path40.join(CACHE_DIR, "update-check.json");
|
|
9960
10093
|
async function fetchLatestVersion() {
|
|
9961
10094
|
try {
|
|
9962
10095
|
const controller = new AbortController();
|
|
@@ -9983,8 +10116,8 @@ async function fetchLatestVersion() {
|
|
|
9983
10116
|
}
|
|
9984
10117
|
async function writeCache(data) {
|
|
9985
10118
|
try {
|
|
9986
|
-
await
|
|
9987
|
-
await
|
|
10119
|
+
await fs25.mkdir(CACHE_DIR, { recursive: true });
|
|
10120
|
+
await fs25.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
9988
10121
|
} catch {
|
|
9989
10122
|
}
|
|
9990
10123
|
}
|
|
@@ -9995,7 +10128,7 @@ function detectGlobalInstall(execPath = process.argv[1] || "", cwd = process.cwd
|
|
|
9995
10128
|
if (!execPath) return null;
|
|
9996
10129
|
let resolved = execPath;
|
|
9997
10130
|
try {
|
|
9998
|
-
resolved =
|
|
10131
|
+
resolved = fs11.realpathSync(execPath);
|
|
9999
10132
|
} catch {
|
|
10000
10133
|
}
|
|
10001
10134
|
const p = resolved.replace(/\\/g, "/");
|
|
@@ -10025,14 +10158,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
|
|
|
10025
10158
|
pm: "yarn",
|
|
10026
10159
|
root: () => {
|
|
10027
10160
|
const dir = tryRun("yarn global dir");
|
|
10028
|
-
return dir ?
|
|
10161
|
+
return dir ? path40.join(dir, "node_modules") : null;
|
|
10029
10162
|
}
|
|
10030
10163
|
},
|
|
10031
|
-
{ pm: "bun", root: () =>
|
|
10164
|
+
{ pm: "bun", root: () => path40.join(os.homedir(), ".bun", "install", "global", "node_modules") }
|
|
10032
10165
|
];
|
|
10033
10166
|
for (const probe of probes) {
|
|
10034
10167
|
const root2 = probe.root();
|
|
10035
|
-
if (root2 && await pathExists(
|
|
10168
|
+
if (root2 && await pathExists(path40.join(root2, pkg))) return probe.pm;
|
|
10036
10169
|
}
|
|
10037
10170
|
return null;
|
|
10038
10171
|
}
|
|
@@ -10051,15 +10184,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
|
|
|
10051
10184
|
}
|
|
10052
10185
|
}
|
|
10053
10186
|
async function detectPackageManager(cwd) {
|
|
10054
|
-
if (await pathExists(
|
|
10055
|
-
if (await pathExists(
|
|
10056
|
-
if (await pathExists(
|
|
10187
|
+
if (await pathExists(path40.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
10188
|
+
if (await pathExists(path40.join(cwd, "bun.lockb"))) return "bun";
|
|
10189
|
+
if (await pathExists(path40.join(cwd, "yarn.lock"))) return "yarn";
|
|
10057
10190
|
return "npm";
|
|
10058
10191
|
}
|
|
10059
10192
|
async function detectWorkspaceRoot(cwd) {
|
|
10060
|
-
if (await pathExists(
|
|
10193
|
+
if (await pathExists(path40.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
10061
10194
|
try {
|
|
10062
|
-
const pkgPath =
|
|
10195
|
+
const pkgPath = path40.join(cwd, "package.json");
|
|
10063
10196
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10064
10197
|
const pkg = JSON.parse(raw);
|
|
10065
10198
|
return pkg.workspaces != null;
|
|
@@ -10084,7 +10217,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
|
10084
10217
|
}
|
|
10085
10218
|
async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
10086
10219
|
try {
|
|
10087
|
-
const pkgPath =
|
|
10220
|
+
const pkgPath = path40.join(cwd, "package.json");
|
|
10088
10221
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
10089
10222
|
const parsed = JSON.parse(raw);
|
|
10090
10223
|
if (parsed.devDependencies?.[pkg]) return "dev";
|
|
@@ -10174,8 +10307,27 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10174
10307
|
}
|
|
10175
10308
|
if (opts.reap !== false) reapAndReport(cwd, latest);
|
|
10176
10309
|
if (opts.reap !== false) await restartVgdAndReport();
|
|
10310
|
+
try {
|
|
10311
|
+
clearEmbedderHealth();
|
|
10312
|
+
} catch {
|
|
10313
|
+
}
|
|
10314
|
+
if (opts.reap !== false) await rewarmVgdAndReport(cwd);
|
|
10177
10315
|
}
|
|
10178
10316
|
);
|
|
10317
|
+
async function rewarmVgdAndReport(cwd) {
|
|
10318
|
+
try {
|
|
10319
|
+
const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-UTLMMPIZ.js');
|
|
10320
|
+
if (!await vgdIsRunning2()) return;
|
|
10321
|
+
const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
|
|
10322
|
+
if (!loaded.ok || !("repositoryId" in loaded)) return;
|
|
10323
|
+
console.log(chalk7.dim("Re-published the code map into the restarted daemon."));
|
|
10324
|
+
const indexed = await vgdRequest2({ op: "embed-index", repositoryId: loaded.repositoryId });
|
|
10325
|
+
if (indexed.ok && "vectors" in indexed && indexed.state === "ready") {
|
|
10326
|
+
console.log(chalk7.dim(`Semantic index warm again (${indexed.vectors} vectors).`));
|
|
10327
|
+
}
|
|
10328
|
+
} catch {
|
|
10329
|
+
}
|
|
10330
|
+
}
|
|
10179
10331
|
async function restartVgdAndReport() {
|
|
10180
10332
|
let result;
|
|
10181
10333
|
try {
|
|
@@ -10253,13 +10405,13 @@ function collectCandidates(artifact) {
|
|
|
10253
10405
|
return out2;
|
|
10254
10406
|
}
|
|
10255
10407
|
var defaultFixScanner = async (rootDir) => {
|
|
10256
|
-
const scratch =
|
|
10408
|
+
const scratch = path40.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
|
|
10257
10409
|
const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
|
|
10258
10410
|
const advanced = await loadAdvancedScanHook();
|
|
10259
10411
|
return runCoreScan(rootDir, scanOpts, advanced);
|
|
10260
10412
|
};
|
|
10261
10413
|
async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
|
|
10262
|
-
const artifactPath =
|
|
10414
|
+
const artifactPath = path40.isAbsolute(inFile) ? inFile : path40.join(rootDir, inFile);
|
|
10263
10415
|
if (await pathExists(artifactPath)) {
|
|
10264
10416
|
const staleness = scanStaleness(rootDir, artifactPath);
|
|
10265
10417
|
if (!staleness.stale) {
|
|
@@ -10286,7 +10438,7 @@ async function repositoryIdentity(rootDir, override) {
|
|
|
10286
10438
|
}
|
|
10287
10439
|
}
|
|
10288
10440
|
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) => {
|
|
10289
|
-
const rootDir =
|
|
10441
|
+
const rootDir = path40.resolve(targetPath);
|
|
10290
10442
|
if (!await pathExists(rootDir)) {
|
|
10291
10443
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
10292
10444
|
process.exit(1);
|
|
@@ -10447,7 +10599,7 @@ function emit(report, format) {
|
|
|
10447
10599
|
}
|
|
10448
10600
|
}
|
|
10449
10601
|
function relProjectDir(rootDir, projectPath) {
|
|
10450
|
-
const rel =
|
|
10602
|
+
const rel = path40.isAbsolute(projectPath) ? path40.relative(rootDir, projectPath) : projectPath;
|
|
10451
10603
|
return rel === "" ? "." : rel;
|
|
10452
10604
|
}
|
|
10453
10605
|
async function buildTargetResolver(rootDir, artifact) {
|
|
@@ -11282,7 +11434,7 @@ function formatMarkdown(artifact) {
|
|
|
11282
11434
|
|
|
11283
11435
|
// src/reporting/commands/report.ts
|
|
11284
11436
|
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) => {
|
|
11285
|
-
const artifactPath =
|
|
11437
|
+
const artifactPath = path40.resolve(opts.in);
|
|
11286
11438
|
if (!await pathExists(artifactPath)) {
|
|
11287
11439
|
console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
|
|
11288
11440
|
console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
|
|
@@ -11331,8 +11483,8 @@ function openUrl(url) {
|
|
|
11331
11483
|
// src/reporting/commands/login.ts
|
|
11332
11484
|
var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
11333
11485
|
function isInside(dir, file) {
|
|
11334
|
-
const rel =
|
|
11335
|
-
return !!rel && !rel.startsWith("..") && !
|
|
11486
|
+
const rel = path40.relative(dir, file);
|
|
11487
|
+
return !!rel && !rel.startsWith("..") && !path40.isAbsolute(rel);
|
|
11336
11488
|
}
|
|
11337
11489
|
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(
|
|
11338
11490
|
"--local",
|
|
@@ -11587,7 +11739,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11587
11739
|
try {
|
|
11588
11740
|
const statements = [];
|
|
11589
11741
|
if (opts.from) {
|
|
11590
|
-
const fromPath =
|
|
11742
|
+
const fromPath = path40.resolve(opts.from);
|
|
11591
11743
|
if (!await pathExists(fromPath)) {
|
|
11592
11744
|
process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
|
|
11593
11745
|
`));
|
|
@@ -11605,9 +11757,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
11605
11757
|
});
|
|
11606
11758
|
const json2 = JSON.stringify(doc, null, 2);
|
|
11607
11759
|
if (opts.out) {
|
|
11608
|
-
await writeTextFile(
|
|
11760
|
+
await writeTextFile(path40.resolve(opts.out), json2 + "\n");
|
|
11609
11761
|
process.stderr.write(
|
|
11610
|
-
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${
|
|
11762
|
+
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path40.resolve(opts.out)}
|
|
11611
11763
|
`
|
|
11612
11764
|
);
|
|
11613
11765
|
} else {
|
|
@@ -11790,7 +11942,7 @@ function formatDeltaText(base, current) {
|
|
|
11790
11942
|
return lines.join("\n");
|
|
11791
11943
|
}
|
|
11792
11944
|
async function readArtifactOrExit(filePath) {
|
|
11793
|
-
const absolutePath =
|
|
11945
|
+
const absolutePath = path40.resolve(filePath);
|
|
11794
11946
|
if (!await pathExists(absolutePath)) {
|
|
11795
11947
|
console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
|
|
11796
11948
|
process.exit(1);
|
|
@@ -11807,7 +11959,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
|
|
|
11807
11959
|
const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
|
|
11808
11960
|
const body = JSON.stringify(sbom, null, 2);
|
|
11809
11961
|
if (opts.out) {
|
|
11810
|
-
await writeTextFile(
|
|
11962
|
+
await writeTextFile(path40.resolve(opts.out), body);
|
|
11811
11963
|
console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
|
|
11812
11964
|
} else {
|
|
11813
11965
|
console.log(body);
|
|
@@ -11818,7 +11970,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
|
|
|
11818
11970
|
const current = await readArtifactOrExit(opts.to);
|
|
11819
11971
|
const report = formatDeltaText(base, current);
|
|
11820
11972
|
if (opts.out) {
|
|
11821
|
-
await writeTextFile(
|
|
11973
|
+
await writeTextFile(path40.resolve(opts.out), report);
|
|
11822
11974
|
console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
|
|
11823
11975
|
} else {
|
|
11824
11976
|
console.log(report);
|
|
@@ -11949,20 +12101,20 @@ function resolveRegime(id) {
|
|
|
11949
12101
|
return regime;
|
|
11950
12102
|
}
|
|
11951
12103
|
function evidenceDir(root2) {
|
|
11952
|
-
return
|
|
12104
|
+
return path40.join(root2, ".vibgrate", "evidence");
|
|
11953
12105
|
}
|
|
11954
12106
|
function orgPath(root2) {
|
|
11955
|
-
return
|
|
12107
|
+
return path40.join(evidenceDir(root2), "org.json");
|
|
11956
12108
|
}
|
|
11957
12109
|
function productsPath(root2) {
|
|
11958
|
-
return
|
|
12110
|
+
return path40.join(evidenceDir(root2), "products.json");
|
|
11959
12111
|
}
|
|
11960
12112
|
function releasesDir(root2) {
|
|
11961
|
-
return
|
|
12113
|
+
return path40.join(evidenceDir(root2), "releases");
|
|
11962
12114
|
}
|
|
11963
12115
|
function releasePath(root2, productId, version) {
|
|
11964
12116
|
const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
11965
|
-
return
|
|
12117
|
+
return path40.join(releasesDir(root2), `${safe}.json`);
|
|
11966
12118
|
}
|
|
11967
12119
|
var DEFAULT_ORG = {
|
|
11968
12120
|
responsiblePersons: [],
|
|
@@ -11993,7 +12145,7 @@ async function freezeRelease(root2, release) {
|
|
|
11993
12145
|
const p = releasePath(root2, release.productId, release.version);
|
|
11994
12146
|
if (await pathExists(p)) {
|
|
11995
12147
|
throw new CliError(
|
|
11996
|
-
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${
|
|
12148
|
+
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path40.relative(root2, p)} only if it was frozen in error`,
|
|
11997
12149
|
ExitCode.USAGE_ERROR
|
|
11998
12150
|
);
|
|
11999
12151
|
}
|
|
@@ -12007,7 +12159,7 @@ async function loadReleases(root2, productId) {
|
|
|
12007
12159
|
const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
12008
12160
|
const releases = [];
|
|
12009
12161
|
for (const f of files) {
|
|
12010
|
-
const rel = await readJsonFile(
|
|
12162
|
+
const rel = await readJsonFile(path40.join(dir, f));
|
|
12011
12163
|
if (!productId || rel.productId === productId) releases.push(rel);
|
|
12012
12164
|
}
|
|
12013
12165
|
return releases;
|
|
@@ -12702,19 +12854,19 @@ function verifyEvidenceEnvelope(env, opts = {}) {
|
|
|
12702
12854
|
var DEFAULT_KEY = "attest-key.pem";
|
|
12703
12855
|
function resolveSigningKey(root2, explicit) {
|
|
12704
12856
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
12705
|
-
const keyPath = chosen ?
|
|
12857
|
+
const keyPath = chosen ? path40.resolve(chosen) : path40.join(root2, ".vibgrate", DEFAULT_KEY);
|
|
12706
12858
|
let minted = false;
|
|
12707
|
-
if (!
|
|
12859
|
+
if (!fs11.existsSync(keyPath)) {
|
|
12708
12860
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
12709
12861
|
const kp = generateKeypair();
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12862
|
+
fs11.mkdirSync(path40.dirname(keyPath), { recursive: true });
|
|
12863
|
+
fs11.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
12864
|
+
fs11.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
12713
12865
|
minted = true;
|
|
12714
12866
|
}
|
|
12715
12867
|
let key2;
|
|
12716
12868
|
try {
|
|
12717
|
-
key2 = crypto3.createPrivateKey(
|
|
12869
|
+
key2 = crypto3.createPrivateKey(fs11.readFileSync(keyPath, "utf8"));
|
|
12718
12870
|
} catch {
|
|
12719
12871
|
throw new CliError(`could not read an Ed25519 private key from ${keyPath}`, ExitCode.USAGE_ERROR);
|
|
12720
12872
|
}
|
|
@@ -12725,16 +12877,16 @@ function resolveSigningKey(root2, explicit) {
|
|
|
12725
12877
|
}
|
|
12726
12878
|
function writeBundle(input) {
|
|
12727
12879
|
const dir = input.outDir;
|
|
12728
|
-
|
|
12729
|
-
const write = (rel, data) =>
|
|
12880
|
+
fs11.mkdirSync(path40.join(dir, "inputs", "releases"), { recursive: true });
|
|
12881
|
+
const write = (rel, data) => fs11.writeFileSync(path40.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
12730
12882
|
`);
|
|
12731
12883
|
write("result.json", input.result);
|
|
12732
|
-
write(
|
|
12884
|
+
write(path40.join("inputs", "advisory.json"), input.advisory);
|
|
12733
12885
|
for (const rel of input.releases) {
|
|
12734
12886
|
const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12735
|
-
write(
|
|
12887
|
+
write(path40.join("inputs", "releases", `${safe}.json`), rel);
|
|
12736
12888
|
}
|
|
12737
|
-
write(
|
|
12889
|
+
write(path40.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
|
|
12738
12890
|
write("provenance.json", {
|
|
12739
12891
|
method: "deterministic",
|
|
12740
12892
|
modelDrafted: [],
|
|
@@ -12750,13 +12902,13 @@ function writeBundle(input) {
|
|
|
12750
12902
|
disclaimer: input.regime.disclaimer
|
|
12751
12903
|
});
|
|
12752
12904
|
if (input.envelope) {
|
|
12753
|
-
|
|
12905
|
+
fs11.writeFileSync(path40.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
12754
12906
|
`);
|
|
12755
12907
|
}
|
|
12756
12908
|
if (input.timestampToken) {
|
|
12757
|
-
|
|
12909
|
+
fs11.writeFileSync(path40.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
12758
12910
|
}
|
|
12759
|
-
|
|
12911
|
+
fs11.writeFileSync(path40.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
12760
12912
|
return dir;
|
|
12761
12913
|
}
|
|
12762
12914
|
function verifyDoc(input) {
|
|
@@ -12817,13 +12969,13 @@ function undeterminedFields(result, regime) {
|
|
|
12817
12969
|
return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
|
|
12818
12970
|
}
|
|
12819
12971
|
async function recordDrill(root2, record) {
|
|
12820
|
-
const dir =
|
|
12821
|
-
const p =
|
|
12972
|
+
const dir = path40.join(evidenceDir(root2), "drills");
|
|
12973
|
+
const p = path40.join(dir, `${record.drillId}.json`);
|
|
12822
12974
|
await writeJsonFile(p, record);
|
|
12823
12975
|
return p;
|
|
12824
12976
|
}
|
|
12825
12977
|
async function hasRecentDrill(root2, asOf) {
|
|
12826
|
-
const dir =
|
|
12978
|
+
const dir = path40.join(evidenceDir(root2), "drills");
|
|
12827
12979
|
if (!await pathExists(dir)) return void 0;
|
|
12828
12980
|
const { readdir } = await import('fs/promises');
|
|
12829
12981
|
const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
|
|
@@ -12831,7 +12983,7 @@ async function hasRecentDrill(root2, asOf) {
|
|
|
12831
12983
|
if (files.length === 0) return void 0;
|
|
12832
12984
|
const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
|
|
12833
12985
|
for (const f of files) {
|
|
12834
|
-
const rec = await readJsonFile2(
|
|
12986
|
+
const rec = await readJsonFile2(path40.join(dir, f));
|
|
12835
12987
|
if (rec.ranAt >= cutoff) return true;
|
|
12836
12988
|
}
|
|
12837
12989
|
return false;
|
|
@@ -12911,7 +13063,7 @@ function formatRegimeList() {
|
|
|
12911
13063
|
|
|
12912
13064
|
// src/reporting/commands/evidence/index.ts
|
|
12913
13065
|
function root(opts) {
|
|
12914
|
-
return
|
|
13066
|
+
return path40.resolve(opts.cwd ?? process.cwd());
|
|
12915
13067
|
}
|
|
12916
13068
|
function slug(name) {
|
|
12917
13069
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
|
|
@@ -12999,7 +13151,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
12999
13151
|
const release = await buildRelease({
|
|
13000
13152
|
productId: product.id,
|
|
13001
13153
|
version,
|
|
13002
|
-
from:
|
|
13154
|
+
from: path40.resolve(rootDir, opts.from),
|
|
13003
13155
|
shipDate: opts.shipDate,
|
|
13004
13156
|
buildId: opts.buildId,
|
|
13005
13157
|
artefactDigest: opts.digest,
|
|
@@ -13007,7 +13159,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
13007
13159
|
frozenAt: nowIso()
|
|
13008
13160
|
});
|
|
13009
13161
|
const p = await freezeRelease(rootDir, release);
|
|
13010
|
-
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${
|
|
13162
|
+
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path40.relative(rootDir, p)}`);
|
|
13011
13163
|
});
|
|
13012
13164
|
async function runExposure(rootDir, vuln, opts) {
|
|
13013
13165
|
const org = await loadOrg(rootDir);
|
|
@@ -13059,7 +13211,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13059
13211
|
console.log("\n" + buildPack(result, regime, org, stage));
|
|
13060
13212
|
}
|
|
13061
13213
|
if (opts.bundle) {
|
|
13062
|
-
const dir =
|
|
13214
|
+
const dir = path40.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
|
|
13063
13215
|
let envelope;
|
|
13064
13216
|
if (opts.sign !== false) {
|
|
13065
13217
|
const { key: key2, minted } = resolveSigningKey(rootDir);
|
|
@@ -13067,7 +13219,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
13067
13219
|
envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
|
|
13068
13220
|
}
|
|
13069
13221
|
writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
|
|
13070
|
-
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${
|
|
13222
|
+
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path40.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
|
|
13071
13223
|
}
|
|
13072
13224
|
process.exitCode = exposureExit(result.overallStatus);
|
|
13073
13225
|
});
|
|
@@ -13099,7 +13251,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
13099
13251
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
13100
13252
|
const md = buildPack(result, regime, org, stage);
|
|
13101
13253
|
if (opts.out) {
|
|
13102
|
-
|
|
13254
|
+
fs11.writeFileSync(path40.resolve(rootDir, opts.out), md);
|
|
13103
13255
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
13104
13256
|
} else {
|
|
13105
13257
|
console.log(md);
|
|
@@ -13141,20 +13293,20 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
13141
13293
|
}
|
|
13142
13294
|
});
|
|
13143
13295
|
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) => {
|
|
13144
|
-
const abs =
|
|
13145
|
-
const envPath =
|
|
13146
|
-
if (!
|
|
13147
|
-
const envelope = JSON.parse(
|
|
13148
|
-
const resultPath =
|
|
13149
|
-
const result =
|
|
13150
|
-
const publicKeyPem = opts.pub ?
|
|
13296
|
+
const abs = path40.resolve(bundlePath);
|
|
13297
|
+
const envPath = fs11.statSync(abs).isDirectory() ? path40.join(abs, "evidence.intoto.jsonl") : abs;
|
|
13298
|
+
if (!fs11.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
13299
|
+
const envelope = JSON.parse(fs11.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
13300
|
+
const resultPath = path40.join(path40.dirname(envPath), "result.json");
|
|
13301
|
+
const result = fs11.existsSync(resultPath) ? JSON.parse(fs11.readFileSync(resultPath, "utf8")) : void 0;
|
|
13302
|
+
const publicKeyPem = opts.pub ? fs11.readFileSync(path40.resolve(opts.pub), "utf8") : void 0;
|
|
13151
13303
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
13152
13304
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
13153
13305
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
13154
13306
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
13155
|
-
const tsrPath =
|
|
13156
|
-
if (
|
|
13157
|
-
const t = verifyTimestamp(
|
|
13307
|
+
const tsrPath = path40.join(path40.dirname(envPath), "timestamp.tsr");
|
|
13308
|
+
if (fs11.existsSync(tsrPath) && result) {
|
|
13309
|
+
const t = verifyTimestamp(fs11.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
13158
13310
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
13159
13311
|
console.log(" " + tcolor("TIMESTAMP") + ` ${t.reason}`);
|
|
13160
13312
|
}
|
|
@@ -13221,12 +13373,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
|
|
|
13221
13373
|
const releases = [];
|
|
13222
13374
|
for (const list of releasesByProduct.values()) releases.push(...list);
|
|
13223
13375
|
const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
|
|
13224
|
-
const dir =
|
|
13225
|
-
await writeJsonFile(
|
|
13226
|
-
await writeJsonFile(
|
|
13227
|
-
for (const r of releases) await writeJsonFile(
|
|
13228
|
-
await writeJsonFile(
|
|
13229
|
-
console.error(chalk7.green("\u2714") + ` exported evidence state to ${
|
|
13376
|
+
const dir = path40.resolve(rootDir, opts.out);
|
|
13377
|
+
await writeJsonFile(path40.join(dir, "org.json"), org);
|
|
13378
|
+
await writeJsonFile(path40.join(dir, "products.json"), products);
|
|
13379
|
+
for (const r of releases) await writeJsonFile(path40.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
|
|
13380
|
+
await writeJsonFile(path40.join(dir, "readiness.json"), report);
|
|
13381
|
+
console.error(chalk7.green("\u2714") + ` exported evidence state to ${path40.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
|
|
13230
13382
|
});
|
|
13231
13383
|
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) => {
|
|
13232
13384
|
const rootDir = root(opts);
|
|
@@ -13252,10 +13404,10 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
13252
13404
|
}));
|
|
13253
13405
|
let exposure;
|
|
13254
13406
|
if (opts.result) {
|
|
13255
|
-
const raw =
|
|
13256
|
-
const resultPath =
|
|
13257
|
-
if (!
|
|
13258
|
-
exposure = JSON.parse(
|
|
13407
|
+
const raw = path40.resolve(rootDir, opts.result);
|
|
13408
|
+
const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path40.join(raw, "result.json") : raw;
|
|
13409
|
+
if (!fs11.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
13410
|
+
exposure = JSON.parse(fs11.readFileSync(resultPath, "utf8"));
|
|
13259
13411
|
}
|
|
13260
13412
|
const payload = { schemaVersion: "evidence-push-1", regime: regime.id, generatedAt: nowIso(), signed: Boolean(opts.signed), products: productPayload, exposure };
|
|
13261
13413
|
const body = JSON.stringify(payload);
|
|
@@ -13449,7 +13601,7 @@ function dispatch(argv, cwd) {
|
|
|
13449
13601
|
}
|
|
13450
13602
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
13451
13603
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
13452
|
-
if (
|
|
13604
|
+
if (fs11.existsSync(path40.resolve(cwd, first))) {
|
|
13453
13605
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
13454
13606
|
}
|
|
13455
13607
|
const moved = MOVED_COMMANDS[first];
|
|
@@ -13494,9 +13646,9 @@ async function main(argv = process.argv) {
|
|
|
13494
13646
|
}
|
|
13495
13647
|
function readCwd(raw) {
|
|
13496
13648
|
const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
|
|
13497
|
-
if (i >= 0 && raw[i + 1]) return
|
|
13649
|
+
if (i >= 0 && raw[i + 1]) return path40.resolve(raw[i + 1]);
|
|
13498
13650
|
const eq = raw.find((a) => a.startsWith("--cwd="));
|
|
13499
|
-
if (eq) return
|
|
13651
|
+
if (eq) return path40.resolve(eq.slice("--cwd=".length));
|
|
13500
13652
|
return process.cwd();
|
|
13501
13653
|
}
|
|
13502
13654
|
function handleError(err) {
|