@vibgrate/cli 2026.729.3 → 2026.730.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-Z4Z66IGM.js → agent-33BMKWJC.js} +4 -4
- package/dist/{agent-Z4Z66IGM.js.map → agent-33BMKWJC.js.map} +1 -1
- package/dist/baseline-V6MYDEMS.js +9 -0
- package/dist/{baseline-Q3QQF5QF.js.map → baseline-V6MYDEMS.js.map} +1 -1
- package/dist/{chunk-JXMZCTVZ.js → chunk-5G7C6H2G.js} +14 -204
- package/dist/chunk-5G7C6H2G.js.map +1 -0
- package/dist/{chunk-RIEUPFXO.js → chunk-6D4BCGRQ.js} +6 -62
- package/dist/chunk-6D4BCGRQ.js.map +1 -0
- package/dist/{chunk-YMSXP6AO.js → chunk-6WNJJXFY.js} +4 -4
- package/dist/{chunk-YMSXP6AO.js.map → chunk-6WNJJXFY.js.map} +1 -1
- package/dist/{chunk-HWFVBYX4.js → chunk-CFL3QQQZ.js} +7 -6
- package/dist/chunk-CFL3QQQZ.js.map +1 -0
- package/dist/{chunk-EQ3IOFIG.js → chunk-CQDCZQFV.js} +3 -3
- package/dist/{chunk-EQ3IOFIG.js.map → chunk-CQDCZQFV.js.map} +1 -1
- package/dist/{chunk-KBPNH67Q.js → chunk-DBMYWNLC.js} +3 -3
- package/dist/{chunk-KBPNH67Q.js.map → chunk-DBMYWNLC.js.map} +1 -1
- package/dist/{chunk-5MNX3OLS.js → chunk-EKCNSRNJ.js} +7 -6
- package/dist/chunk-EKCNSRNJ.js.map +1 -0
- package/dist/{chunk-G4HTI4ZM.js → chunk-FHJBGPJZ.js} +3 -2
- package/dist/chunk-FHJBGPJZ.js.map +1 -0
- package/dist/{chunk-3FQSBVQD.js → chunk-GLT3N7T2.js} +8 -5
- package/dist/chunk-GLT3N7T2.js.map +1 -0
- package/dist/chunk-HTLDXEHW.js +60 -0
- package/dist/chunk-HTLDXEHW.js.map +1 -0
- package/dist/{chunk-GI6W53LM.js → chunk-IDAQV3NQ.js} +4 -2
- package/dist/chunk-IDAQV3NQ.js.map +1 -0
- package/dist/{chunk-42RDYQFF.js → chunk-KGWEBM2J.js} +3 -3
- package/dist/{chunk-42RDYQFF.js.map → chunk-KGWEBM2J.js.map} +1 -1
- package/dist/{chunk-4BOWWYSE.js → chunk-ON7PZNYV.js} +12 -11
- package/dist/chunk-ON7PZNYV.js.map +1 -0
- package/dist/chunk-Q4UQ73NA.js +6 -0
- package/dist/{chunk-N3HCPBFY.js.map → chunk-Q4UQ73NA.js.map} +1 -1
- package/dist/chunk-TJ3WIJ7H.js +216 -0
- package/dist/chunk-TJ3WIJ7H.js.map +1 -0
- package/dist/chunk-VOEYUAER.js +203 -0
- package/dist/chunk-VOEYUAER.js.map +1 -0
- package/dist/cli.js +390 -507
- package/dist/cli.js.map +1 -1
- package/dist/{fs-6JKZNQ3U.js → fs-HNR6LAI7.js} +3 -3
- package/dist/fs-HNR6LAI7.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/{interactive-MJVMY5JP.js → interactive-NJG6467J.js} +16 -14
- package/dist/interactive-NJG6467J.js.map +1 -0
- package/dist/load-YPSEDYIW.js +10 -0
- package/dist/{load-4PARCNMD.js.map → load-YPSEDYIW.js.map} +1 -1
- package/dist/run-outcome-5FQWHWYK.js +253 -0
- package/dist/run-outcome-5FQWHWYK.js.map +1 -0
- package/dist/{runtime-session-AILFASQV.js → runtime-session-Y4ZD3QDO.js} +7 -6
- package/dist/{runtime-session-AILFASQV.js.map → runtime-session-Y4ZD3QDO.js.map} +1 -1
- package/dist/{stream-json-MTPWWVRR.js → stream-json-3YOPU3LF.js} +4 -4
- package/dist/{stream-json-MTPWWVRR.js.map → stream-json-3YOPU3LF.js.map} +1 -1
- package/dist/{vg-mcp-bridge-BLHEIWMT.js → vg-mcp-bridge-PZFGTZSA.js} +8 -7
- package/dist/vg-mcp-bridge-PZFGTZSA.js.map +1 -0
- package/dist/{vgd-S7D2SITC.js → vgd-DH7AHQ23.js} +6 -5
- package/dist/vgd-DH7AHQ23.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-Q3QQF5QF.js +0 -9
- package/dist/chunk-3FQSBVQD.js.map +0 -1
- package/dist/chunk-4BOWWYSE.js.map +0 -1
- package/dist/chunk-5MNX3OLS.js.map +0 -1
- package/dist/chunk-G4HTI4ZM.js.map +0 -1
- package/dist/chunk-GI6W53LM.js.map +0 -1
- package/dist/chunk-HWFVBYX4.js.map +0 -1
- package/dist/chunk-JXMZCTVZ.js.map +0 -1
- package/dist/chunk-N3HCPBFY.js +0 -6
- package/dist/chunk-RIEUPFXO.js.map +0 -1
- package/dist/fs-6JKZNQ3U.js.map +0 -1
- package/dist/interactive-MJVMY5JP.js.map +0 -1
- package/dist/load-4PARCNMD.js +0 -9
- package/dist/vg-mcp-bridge-BLHEIWMT.js.map +0 -1
- package/dist/vgd-S7D2SITC.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-
|
|
3
|
-
export { runBuild } from './chunk-
|
|
4
|
-
import {
|
|
2
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-EKCNSRNJ.js';
|
|
3
|
+
export { runBuild } from './chunk-EKCNSRNJ.js';
|
|
4
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-TJ3WIJ7H.js';
|
|
5
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-6WNJJXFY.js';
|
|
5
6
|
import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
|
|
6
7
|
import { runCodeSession } from './chunk-WBMMRERH.js';
|
|
7
8
|
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
8
|
-
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-
|
|
9
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-CQDCZQFV.js';
|
|
9
10
|
import './chunk-5I4VSBWQ.js';
|
|
10
11
|
import './chunk-IS7VTH2Q.js';
|
|
11
12
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
|
|
@@ -14,7 +15,7 @@ import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
|
14
15
|
import './chunk-IZDH67DX.js';
|
|
15
16
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-EVLS2M5G.js';
|
|
16
17
|
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-X634FZVG.js';
|
|
17
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-
|
|
18
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-KGWEBM2J.js';
|
|
18
19
|
import './chunk-543E6WDJ.js';
|
|
19
20
|
import { summarizeDiffs, ScriptedProvider } from './chunk-MYM5VIJ4.js';
|
|
20
21
|
import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
|
|
@@ -22,13 +23,14 @@ import './chunk-RGEVBSLK.js';
|
|
|
22
23
|
import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
|
|
23
24
|
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
24
25
|
import './chunk-7AVYKZEM.js';
|
|
25
|
-
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-
|
|
26
|
-
import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-
|
|
27
|
-
import { resolveDsn,
|
|
28
|
-
import {
|
|
26
|
+
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-CFL3QQQZ.js';
|
|
27
|
+
import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-GLT3N7T2.js';
|
|
28
|
+
import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-6D4BCGRQ.js';
|
|
29
|
+
import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
|
|
30
|
+
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-ON7PZNYV.js';
|
|
29
31
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
30
32
|
import './chunk-IPICO2RV.js';
|
|
31
|
-
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-
|
|
33
|
+
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-FHJBGPJZ.js';
|
|
32
34
|
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-US2DAKCM.js';
|
|
33
35
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
|
|
34
36
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
@@ -37,29 +39,30 @@ import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
|
37
39
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
38
40
|
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
|
|
39
41
|
import './chunk-RXP66R2E.js';
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
+
import { loadGraph, SCHEMA_VERSION } from './chunk-VOEYUAER.js';
|
|
43
|
+
import { resolveGraphPath, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-5G7C6H2G.js';
|
|
44
|
+
import { VERSION } from './chunk-Q4UQ73NA.js';
|
|
42
45
|
import { cacheDir, serializeGraph, stableStringify } from './chunk-ZKNB4YH4.js';
|
|
43
46
|
import './chunk-BWPBB45M.js';
|
|
44
47
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
45
48
|
import './chunk-BPF3YX2U.js';
|
|
46
|
-
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-
|
|
49
|
+
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-IDAQV3NQ.js';
|
|
47
50
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
48
|
-
import * as
|
|
49
|
-
import
|
|
50
|
-
import * as
|
|
51
|
-
import
|
|
51
|
+
import * as fs7 from 'fs';
|
|
52
|
+
import fs7__default, { realpathSync } from 'fs';
|
|
53
|
+
import * as path37 from 'path';
|
|
54
|
+
import path37__default from 'path';
|
|
52
55
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
53
56
|
import { Command, CommanderError, Option } from 'commander';
|
|
54
|
-
import * as os from 'os';
|
|
55
|
-
import * as crypto3 from 'crypto';
|
|
56
|
-
import { randomUUID } from 'crypto';
|
|
57
57
|
import * as semver3 from 'semver';
|
|
58
58
|
import semver3__default from 'semver';
|
|
59
59
|
import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
|
|
60
60
|
import * as readline from 'readline';
|
|
61
|
+
import * as crypto3 from 'crypto';
|
|
62
|
+
import { randomUUID } from 'crypto';
|
|
61
63
|
import chalk7 from 'chalk';
|
|
62
|
-
import * as
|
|
64
|
+
import * as fs21 from 'fs/promises';
|
|
65
|
+
import * as os from 'os';
|
|
63
66
|
|
|
64
67
|
init_cli_invocation();
|
|
65
68
|
function registerStatus(program) {
|
|
@@ -69,10 +72,10 @@ function registerStatus(program) {
|
|
|
69
72
|
applyGlobalOptions(cmd);
|
|
70
73
|
}
|
|
71
74
|
async function runStatus(global) {
|
|
72
|
-
const root2 =
|
|
75
|
+
const root2 = path37.resolve(global.cwd ?? ".");
|
|
73
76
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
74
77
|
const graph = loadGraph(root2, graphPath);
|
|
75
|
-
const hasCache =
|
|
78
|
+
const hasCache = fs7.existsSync(path37.join(cacheDir(root2), "parse-cache.json"));
|
|
76
79
|
let stale = null;
|
|
77
80
|
let staleExact = false;
|
|
78
81
|
if (graph) {
|
|
@@ -92,8 +95,8 @@ async function runStatus(global) {
|
|
|
92
95
|
}
|
|
93
96
|
if (global.json) {
|
|
94
97
|
json({
|
|
95
|
-
root:
|
|
96
|
-
graphPath:
|
|
98
|
+
root: path37.relative(process.cwd(), root2) || ".",
|
|
99
|
+
graphPath: path37.relative(root2, graphPath),
|
|
97
100
|
built: graph !== null,
|
|
98
101
|
generatedAt: graph?.generatedAt ?? null,
|
|
99
102
|
counts: graph?.meta.counts ?? null,
|
|
@@ -108,11 +111,11 @@ async function runStatus(global) {
|
|
|
108
111
|
return;
|
|
109
112
|
}
|
|
110
113
|
if (!graph) {
|
|
111
|
-
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(
|
|
114
|
+
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path37.relative(root2, graphPath))}`);
|
|
112
115
|
info(` run ${c.bold("vg")} to build one`);
|
|
113
116
|
return;
|
|
114
117
|
}
|
|
115
|
-
info(`${c.cyan("vg")} \xB7 ${
|
|
118
|
+
info(`${c.cyan("vg")} \xB7 ${path37.relative(root2, graphPath)}`);
|
|
116
119
|
info(` generated ${graph.generatedAt}`);
|
|
117
120
|
info(
|
|
118
121
|
` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
|
|
@@ -129,7 +132,7 @@ async function runStatus(global) {
|
|
|
129
132
|
if (vibgrateDir(root2)) ;
|
|
130
133
|
}
|
|
131
134
|
function rootOf(global) {
|
|
132
|
-
return
|
|
135
|
+
return path37.resolve(global.cwd ?? ".");
|
|
133
136
|
}
|
|
134
137
|
function requireGraph(global) {
|
|
135
138
|
const root2 = rootOf(global);
|
|
@@ -838,210 +841,6 @@ function fmtRef(r) {
|
|
|
838
841
|
function pad2(s, n) {
|
|
839
842
|
return s.padStart(n, " ");
|
|
840
843
|
}
|
|
841
|
-
var SCHEMA_VERSION2 = "1";
|
|
842
|
-
var OFFSET_FILE = "stats-share.json";
|
|
843
|
-
var INSTALL_ID_DIR = path38.join(os.homedir(), ".vibgrate");
|
|
844
|
-
var INSTALL_ID_FILE = path38.join(INSTALL_ID_DIR, "install-id");
|
|
845
|
-
var SEND_TIMEOUT_MS = 4e3;
|
|
846
|
-
function telemetryOptOut(env = process.env) {
|
|
847
|
-
const dnt = (env.DO_NOT_TRACK ?? "").trim().toLowerCase();
|
|
848
|
-
if (dnt !== "" && dnt !== "0" && dnt !== "false") return "DO_NOT_TRACK";
|
|
849
|
-
const vt = (env.VIBGRATE_TELEMETRY ?? "").trim().toLowerCase();
|
|
850
|
-
if (vt === "0" || vt === "false" || vt === "off") return "VIBGRATE_TELEMETRY";
|
|
851
|
-
return null;
|
|
852
|
-
}
|
|
853
|
-
var CI_ENV_VARS = [
|
|
854
|
-
"CI",
|
|
855
|
-
"GITHUB_ACTIONS",
|
|
856
|
-
"GITLAB_CI",
|
|
857
|
-
"CIRCLECI",
|
|
858
|
-
"TRAVIS",
|
|
859
|
-
"BUILDKITE",
|
|
860
|
-
"JENKINS_URL",
|
|
861
|
-
"TF_BUILD"
|
|
862
|
-
];
|
|
863
|
-
function isCI(env = process.env) {
|
|
864
|
-
return CI_ENV_VARS.some((v) => {
|
|
865
|
-
const val = (env[v] ?? "").trim().toLowerCase();
|
|
866
|
-
return val !== "" && val !== "0" && val !== "false";
|
|
867
|
-
});
|
|
868
|
-
}
|
|
869
|
-
function installId(env = process.env) {
|
|
870
|
-
if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();
|
|
871
|
-
try {
|
|
872
|
-
const existing = fs8.readFileSync(INSTALL_ID_FILE, "utf8").trim();
|
|
873
|
-
if (isUuid(existing)) return existing;
|
|
874
|
-
} catch {
|
|
875
|
-
}
|
|
876
|
-
const id = randomUuid();
|
|
877
|
-
try {
|
|
878
|
-
fs8.mkdirSync(INSTALL_ID_DIR, { recursive: true });
|
|
879
|
-
fs8.writeFileSync(INSTALL_ID_FILE, id + "\n", { mode: 384 });
|
|
880
|
-
} catch {
|
|
881
|
-
}
|
|
882
|
-
return id;
|
|
883
|
-
}
|
|
884
|
-
function isUuid(s) {
|
|
885
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
|
|
886
|
-
}
|
|
887
|
-
function randomUuid() {
|
|
888
|
-
return randomUUID();
|
|
889
|
-
}
|
|
890
|
-
function statsEndpoint() {
|
|
891
|
-
const override = process.env.VIBGRATE_STATS_ENDPOINT;
|
|
892
|
-
if (override && /^https?:\/\//.test(override)) return override;
|
|
893
|
-
return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;
|
|
894
|
-
}
|
|
895
|
-
function offsetPath(root2) {
|
|
896
|
-
return path38.join(cacheDir(root2), OFFSET_FILE);
|
|
897
|
-
}
|
|
898
|
-
function ledgerFilePath(root2) {
|
|
899
|
-
return path38.join(cacheDir(root2), "savings.jsonl");
|
|
900
|
-
}
|
|
901
|
-
function readOffset(root2) {
|
|
902
|
-
try {
|
|
903
|
-
const raw = JSON.parse(fs8.readFileSync(offsetPath(root2), "utf8"));
|
|
904
|
-
return typeof raw.offset === "number" && raw.offset >= 0 ? raw.offset : 0;
|
|
905
|
-
} catch {
|
|
906
|
-
return 0;
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
function writeOffset(root2, offset) {
|
|
910
|
-
try {
|
|
911
|
-
fs8.mkdirSync(cacheDir(root2), { recursive: true });
|
|
912
|
-
fs8.writeFileSync(offsetPath(root2), JSON.stringify({ offset }) + "\n");
|
|
913
|
-
} catch {
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
function buildBatch(root2, fromOffset, id = installId()) {
|
|
917
|
-
const file = ledgerFilePath(root2);
|
|
918
|
-
let size = 0;
|
|
919
|
-
try {
|
|
920
|
-
size = fs8.statSync(file).size;
|
|
921
|
-
} catch {
|
|
922
|
-
return { batch: null, newOffset: 0 };
|
|
923
|
-
}
|
|
924
|
-
const start = fromOffset > size ? 0 : fromOffset;
|
|
925
|
-
if (start >= size) return { batch: null, newOffset: size };
|
|
926
|
-
let text = "";
|
|
927
|
-
try {
|
|
928
|
-
const fd = fs8.openSync(file, "r");
|
|
929
|
-
try {
|
|
930
|
-
const buf = Buffer.alloc(size - start);
|
|
931
|
-
fs8.readSync(fd, buf, 0, buf.length, start);
|
|
932
|
-
text = buf.toString("utf8");
|
|
933
|
-
} finally {
|
|
934
|
-
fs8.closeSync(fd);
|
|
935
|
-
}
|
|
936
|
-
} catch {
|
|
937
|
-
return { batch: null, newOffset: fromOffset };
|
|
938
|
-
}
|
|
939
|
-
const lastNl = text.lastIndexOf("\n");
|
|
940
|
-
if (lastNl < 0) return { batch: null, newOffset: start };
|
|
941
|
-
const consumed = start + lastNl + 1;
|
|
942
|
-
const rows = /* @__PURE__ */ new Map();
|
|
943
|
-
let total = 0;
|
|
944
|
-
let minTs = Infinity;
|
|
945
|
-
let maxTs = -Infinity;
|
|
946
|
-
for (const line of text.slice(0, lastNl).split("\n")) {
|
|
947
|
-
if (!line.trim()) continue;
|
|
948
|
-
let e;
|
|
949
|
-
try {
|
|
950
|
-
e = JSON.parse(line);
|
|
951
|
-
} catch {
|
|
952
|
-
continue;
|
|
953
|
-
}
|
|
954
|
-
const source = e.source ?? "mcp";
|
|
955
|
-
const client = e.client ?? "unknown";
|
|
956
|
-
const outcome = e.outcome ?? "complete";
|
|
957
|
-
const key2 = `${source}|${client}|${e.tool}|${outcome}`;
|
|
958
|
-
const row = rows.get(key2) ?? {
|
|
959
|
-
source,
|
|
960
|
-
client,
|
|
961
|
-
tool: e.tool,
|
|
962
|
-
outcome,
|
|
963
|
-
calls: 0,
|
|
964
|
-
vgTokens: 0,
|
|
965
|
-
baselineTokens: 0
|
|
966
|
-
};
|
|
967
|
-
row.calls++;
|
|
968
|
-
row.vgTokens += e.vgTokens ?? 0;
|
|
969
|
-
row.baselineTokens += e.baselineTokens ?? 0;
|
|
970
|
-
rows.set(key2, row);
|
|
971
|
-
total++;
|
|
972
|
-
if (typeof e.ts === "number") {
|
|
973
|
-
if (e.ts < minTs) minTs = e.ts;
|
|
974
|
-
if (e.ts > maxTs) maxTs = e.ts;
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };
|
|
978
|
-
const batch = {
|
|
979
|
-
schemaVersion: SCHEMA_VERSION2,
|
|
980
|
-
installId: id,
|
|
981
|
-
vgVersion: VERSION,
|
|
982
|
-
os: process.platform,
|
|
983
|
-
arch: process.arch,
|
|
984
|
-
windowStart: new Date(minTs).toISOString(),
|
|
985
|
-
windowEnd: new Date(maxTs).toISOString(),
|
|
986
|
-
totalCalls: total,
|
|
987
|
-
rows: [...rows.values()]
|
|
988
|
-
};
|
|
989
|
-
return { batch, newOffset: consumed };
|
|
990
|
-
}
|
|
991
|
-
async function postBatch(batch) {
|
|
992
|
-
const controller = new AbortController();
|
|
993
|
-
const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);
|
|
994
|
-
timer.unref?.();
|
|
995
|
-
try {
|
|
996
|
-
const res = await fetch(statsEndpoint(), {
|
|
997
|
-
method: "POST",
|
|
998
|
-
headers: { "Content-Type": "application/json", Connection: "close" },
|
|
999
|
-
body: JSON.stringify(batch),
|
|
1000
|
-
signal: controller.signal
|
|
1001
|
-
});
|
|
1002
|
-
return res.ok;
|
|
1003
|
-
} catch {
|
|
1004
|
-
return false;
|
|
1005
|
-
} finally {
|
|
1006
|
-
clearTimeout(timer);
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
var StatsSharer = class {
|
|
1010
|
-
constructor(root2) {
|
|
1011
|
-
this.root = root2;
|
|
1012
|
-
this.offset = readOffset(root2);
|
|
1013
|
-
}
|
|
1014
|
-
root;
|
|
1015
|
-
id = installId();
|
|
1016
|
-
offset;
|
|
1017
|
-
flushing = false;
|
|
1018
|
-
/**
|
|
1019
|
-
* Flush any new ledger entries. Single-flight (a slow POST won't overlap the
|
|
1020
|
-
* next tick). Best-effort: any failure is swallowed and retried next time.
|
|
1021
|
-
*/
|
|
1022
|
-
async flush() {
|
|
1023
|
-
if (this.flushing) return;
|
|
1024
|
-
this.flushing = true;
|
|
1025
|
-
try {
|
|
1026
|
-
const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);
|
|
1027
|
-
if (!batch) {
|
|
1028
|
-
if (newOffset > this.offset) {
|
|
1029
|
-
this.offset = newOffset;
|
|
1030
|
-
writeOffset(this.root, newOffset);
|
|
1031
|
-
}
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
const ok = await postBatch(batch);
|
|
1035
|
-
if (ok) {
|
|
1036
|
-
this.offset = newOffset;
|
|
1037
|
-
writeOffset(this.root, newOffset);
|
|
1038
|
-
}
|
|
1039
|
-
} catch {
|
|
1040
|
-
} finally {
|
|
1041
|
-
this.flushing = false;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
};
|
|
1045
844
|
|
|
1046
845
|
// src/util/origin.ts
|
|
1047
846
|
function originAllowed(origin, allowlist) {
|
|
@@ -1067,12 +866,12 @@ var PUBLISH_INTERVAL_MS = 2e3;
|
|
|
1067
866
|
var KEEPALIVE_MS = 1e4;
|
|
1068
867
|
var STALE_MS = 6e4;
|
|
1069
868
|
function liveStatsDir(root2) {
|
|
1070
|
-
return
|
|
869
|
+
return path37.join(cacheDir(root2), "serve-live");
|
|
1071
870
|
}
|
|
1072
871
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
1073
872
|
let entries;
|
|
1074
873
|
try {
|
|
1075
|
-
entries =
|
|
874
|
+
entries = fs7.readdirSync(dir);
|
|
1076
875
|
} catch {
|
|
1077
876
|
return [];
|
|
1078
877
|
}
|
|
@@ -1081,7 +880,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
1081
880
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1082
881
|
let parsed;
|
|
1083
882
|
try {
|
|
1084
|
-
parsed = JSON.parse(
|
|
883
|
+
parsed = JSON.parse(fs7.readFileSync(path37.join(dir, name), "utf8"));
|
|
1085
884
|
} catch {
|
|
1086
885
|
continue;
|
|
1087
886
|
}
|
|
@@ -1103,7 +902,7 @@ var LiveStatsBus = class {
|
|
|
1103
902
|
this.dir = dir;
|
|
1104
903
|
this.stats = stats;
|
|
1105
904
|
this.pid = pid;
|
|
1106
|
-
this.file =
|
|
905
|
+
this.file = path37.join(dir, `serve-${this.pid}.json`);
|
|
1107
906
|
}
|
|
1108
907
|
dir;
|
|
1109
908
|
stats;
|
|
@@ -1135,10 +934,10 @@ var LiveStatsBus = class {
|
|
|
1135
934
|
this.lastWriteAt = now;
|
|
1136
935
|
const body = { pid: this.pid, updatedAt: now, version: VERSION, snapshot: snap };
|
|
1137
936
|
try {
|
|
1138
|
-
|
|
937
|
+
fs7.mkdirSync(this.dir, { recursive: true });
|
|
1139
938
|
const tmp = `${this.file}.tmp`;
|
|
1140
|
-
|
|
1141
|
-
|
|
939
|
+
fs7.writeFileSync(tmp, JSON.stringify(body));
|
|
940
|
+
fs7.renameSync(tmp, this.file);
|
|
1142
941
|
} catch {
|
|
1143
942
|
}
|
|
1144
943
|
}
|
|
@@ -1149,24 +948,24 @@ var LiveStatsBus = class {
|
|
|
1149
948
|
siblings(now = Date.now()) {
|
|
1150
949
|
let entries;
|
|
1151
950
|
try {
|
|
1152
|
-
entries =
|
|
951
|
+
entries = fs7.readdirSync(this.dir);
|
|
1153
952
|
} catch {
|
|
1154
953
|
return [];
|
|
1155
954
|
}
|
|
1156
955
|
const out2 = [];
|
|
1157
956
|
for (const name of entries.sort()) {
|
|
1158
957
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1159
|
-
const file =
|
|
958
|
+
const file = path37.join(this.dir, name);
|
|
1160
959
|
let parsed;
|
|
1161
960
|
try {
|
|
1162
|
-
parsed = JSON.parse(
|
|
961
|
+
parsed = JSON.parse(fs7.readFileSync(file, "utf8"));
|
|
1163
962
|
} catch {
|
|
1164
963
|
continue;
|
|
1165
964
|
}
|
|
1166
965
|
if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
|
|
1167
966
|
if (now - parsed.updatedAt > STALE_MS) {
|
|
1168
967
|
try {
|
|
1169
|
-
|
|
968
|
+
fs7.unlinkSync(file);
|
|
1170
969
|
} catch {
|
|
1171
970
|
}
|
|
1172
971
|
continue;
|
|
@@ -1178,7 +977,7 @@ var LiveStatsBus = class {
|
|
|
1178
977
|
}
|
|
1179
978
|
unlinkOwn = () => {
|
|
1180
979
|
try {
|
|
1181
|
-
|
|
980
|
+
fs7.unlinkSync(this.file);
|
|
1182
981
|
} catch {
|
|
1183
982
|
}
|
|
1184
983
|
};
|
|
@@ -1491,12 +1290,12 @@ var LedgerTail = class {
|
|
|
1491
1290
|
if (size === this.offset) return;
|
|
1492
1291
|
let chunk;
|
|
1493
1292
|
try {
|
|
1494
|
-
const fd =
|
|
1293
|
+
const fd = fs7.openSync(this.file, "r");
|
|
1495
1294
|
try {
|
|
1496
1295
|
chunk = Buffer.alloc(size - this.offset);
|
|
1497
|
-
|
|
1296
|
+
fs7.readSync(fd, chunk, 0, chunk.length, this.offset);
|
|
1498
1297
|
} finally {
|
|
1499
|
-
|
|
1298
|
+
fs7.closeSync(fd);
|
|
1500
1299
|
}
|
|
1501
1300
|
} catch {
|
|
1502
1301
|
return;
|
|
@@ -1509,7 +1308,7 @@ var LedgerTail = class {
|
|
|
1509
1308
|
}
|
|
1510
1309
|
sizeOf() {
|
|
1511
1310
|
try {
|
|
1512
|
-
return
|
|
1311
|
+
return fs7.statSync(this.file).size;
|
|
1513
1312
|
} catch {
|
|
1514
1313
|
return 0;
|
|
1515
1314
|
}
|
|
@@ -1894,19 +1693,19 @@ function endOfLine(text, line) {
|
|
|
1894
1693
|
}
|
|
1895
1694
|
var CACHE_VERSION = "vg-lsp-scan-cache/2";
|
|
1896
1695
|
function cachePath(root2) {
|
|
1897
|
-
return
|
|
1696
|
+
return path37.join(cacheDir(root2), "lsp-scan.json");
|
|
1898
1697
|
}
|
|
1899
1698
|
function manifestHash(root2) {
|
|
1900
1699
|
const files = [];
|
|
1901
1700
|
const walk2 = (dir) => {
|
|
1902
1701
|
let entries;
|
|
1903
1702
|
try {
|
|
1904
|
-
entries =
|
|
1703
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
1905
1704
|
} catch {
|
|
1906
1705
|
return;
|
|
1907
1706
|
}
|
|
1908
1707
|
for (const entry of entries) {
|
|
1909
|
-
const abs =
|
|
1708
|
+
const abs = path37.join(dir, entry.name);
|
|
1910
1709
|
if (entry.isDirectory()) {
|
|
1911
1710
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
1912
1711
|
walk2(abs);
|
|
@@ -1916,8 +1715,8 @@ function manifestHash(root2) {
|
|
|
1916
1715
|
const base = entry.name.toLowerCase();
|
|
1917
1716
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1918
1717
|
try {
|
|
1919
|
-
const rel =
|
|
1920
|
-
files.push({ rel, hash: hashBytes(
|
|
1718
|
+
const rel = path37.relative(root2, abs).split(path37.sep).join("/");
|
|
1719
|
+
files.push({ rel, hash: hashBytes(fs7.readFileSync(abs)) });
|
|
1921
1720
|
} catch {
|
|
1922
1721
|
}
|
|
1923
1722
|
}
|
|
@@ -1927,16 +1726,16 @@ function manifestHash(root2) {
|
|
|
1927
1726
|
return hashString(canonicalize(files));
|
|
1928
1727
|
}
|
|
1929
1728
|
function isDependencyFile(root2, filePath) {
|
|
1930
|
-
const rel =
|
|
1931
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
1932
|
-
const parts = rel.split(
|
|
1729
|
+
const rel = path37.relative(path37.resolve(root2), path37.resolve(filePath));
|
|
1730
|
+
if (rel === "" || rel.startsWith("..") || path37.isAbsolute(rel)) return false;
|
|
1731
|
+
const parts = rel.split(path37.sep);
|
|
1933
1732
|
if (parts.slice(0, -1).some((dir) => SKIP_DIRS.has(dir))) return false;
|
|
1934
1733
|
const base = parts[parts.length - 1].toLowerCase();
|
|
1935
1734
|
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
1936
1735
|
}
|
|
1937
1736
|
function loadScanCache(root2, key2) {
|
|
1938
1737
|
try {
|
|
1939
|
-
const raw = JSON.parse(
|
|
1738
|
+
const raw = JSON.parse(fs7.readFileSync(cachePath(root2), "utf8"));
|
|
1940
1739
|
if (raw.version === CACHE_VERSION && raw.manifestHash === key2.manifestHash && raw.toolVersion === key2.toolVersion && raw.offline === key2.offline && raw.artifact) {
|
|
1941
1740
|
return { manifestHash: raw.manifestHash, artifact: raw.artifact };
|
|
1942
1741
|
}
|
|
@@ -1946,8 +1745,8 @@ function loadScanCache(root2, key2) {
|
|
|
1946
1745
|
}
|
|
1947
1746
|
function writeScanCache(root2, key2, artifact) {
|
|
1948
1747
|
try {
|
|
1949
|
-
|
|
1950
|
-
|
|
1748
|
+
fs7.mkdirSync(cacheDir(root2), { recursive: true });
|
|
1749
|
+
fs7.writeFileSync(
|
|
1951
1750
|
cachePath(root2),
|
|
1952
1751
|
stableStringify(
|
|
1953
1752
|
{ version: CACHE_VERSION, manifestHash: key2.manifestHash, toolVersion: key2.toolVersion, offline: key2.offline, artifact },
|
|
@@ -1960,7 +1759,7 @@ function writeScanCache(root2, key2, artifact) {
|
|
|
1960
1759
|
var MAX_ENTRIES = 1e3;
|
|
1961
1760
|
var KEEP_ENTRIES = 500;
|
|
1962
1761
|
function historyPath(root2) {
|
|
1963
|
-
return
|
|
1762
|
+
return path37.join(root2, ".vibgrate", "score-history.jsonl");
|
|
1964
1763
|
}
|
|
1965
1764
|
function parseLine(line) {
|
|
1966
1765
|
try {
|
|
@@ -1974,7 +1773,7 @@ function parseLine(line) {
|
|
|
1974
1773
|
}
|
|
1975
1774
|
function readHistory(root2) {
|
|
1976
1775
|
try {
|
|
1977
|
-
return
|
|
1776
|
+
return fs7.readFileSync(historyPath(root2), "utf8").split("\n").filter((l) => l.trim()).map(parseLine).filter((e) => e !== null);
|
|
1978
1777
|
} catch {
|
|
1979
1778
|
return [];
|
|
1980
1779
|
}
|
|
@@ -2001,13 +1800,14 @@ function recordScore(root2, entry) {
|
|
|
2001
1800
|
}
|
|
2002
1801
|
}
|
|
2003
1802
|
const file = historyPath(root2);
|
|
2004
|
-
|
|
2005
|
-
|
|
1803
|
+
fs7.mkdirSync(path37.dirname(file), { recursive: true });
|
|
1804
|
+
ensureVibgrateGitignore(root2);
|
|
1805
|
+
fs7.appendFileSync(file, `${JSON.stringify(entry)}
|
|
2006
1806
|
`);
|
|
2007
1807
|
const all = readHistory(root2);
|
|
2008
1808
|
if (all.length > MAX_ENTRIES) {
|
|
2009
1809
|
const kept = all.slice(-KEEP_ENTRIES);
|
|
2010
|
-
|
|
1810
|
+
fs7.writeFileSync(file, kept.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
2011
1811
|
}
|
|
2012
1812
|
} catch {
|
|
2013
1813
|
}
|
|
@@ -2469,6 +2269,12 @@ var VibgrateLanguageServer = class {
|
|
|
2469
2269
|
artifact = null;
|
|
2470
2270
|
scanning = false;
|
|
2471
2271
|
queued = false;
|
|
2272
|
+
/**
|
|
2273
|
+
* Sticky until the next `scan()` runs: set by explicit "Rescan Workspace"
|
|
2274
|
+
* (and preserved if a non-force schedule races the debounce). Bypasses the
|
|
2275
|
+
* LSP scan cache so config/SKIP_DIRS changes actually re-score.
|
|
2276
|
+
*/
|
|
2277
|
+
forceNextScan = false;
|
|
2472
2278
|
debounce = null;
|
|
2473
2279
|
shuttingDown = false;
|
|
2474
2280
|
graph = null;
|
|
@@ -2538,7 +2344,7 @@ var VibgrateLanguageServer = class {
|
|
|
2538
2344
|
this.conn.onRequest("workspace/executeCommand", (_m, params) => {
|
|
2539
2345
|
const p = params;
|
|
2540
2346
|
if (p.command === "vibgrate.rescan") {
|
|
2541
|
-
this.scheduleScan(0);
|
|
2347
|
+
this.scheduleScan(0, { force: true });
|
|
2542
2348
|
return { ok: true };
|
|
2543
2349
|
}
|
|
2544
2350
|
return null;
|
|
@@ -2553,7 +2359,8 @@ var VibgrateLanguageServer = class {
|
|
|
2553
2359
|
});
|
|
2554
2360
|
}
|
|
2555
2361
|
// ── Scanning ─────────────────────────────────────────────────────────────
|
|
2556
|
-
scheduleScan(delayMs) {
|
|
2362
|
+
scheduleScan(delayMs, opts) {
|
|
2363
|
+
if (opts?.force) this.forceNextScan = true;
|
|
2557
2364
|
if (this.debounce) clearTimeout(this.debounce);
|
|
2558
2365
|
this.debounce = setTimeout(() => void this.scan(), delayMs);
|
|
2559
2366
|
}
|
|
@@ -2563,11 +2370,13 @@ var VibgrateLanguageServer = class {
|
|
|
2563
2370
|
return;
|
|
2564
2371
|
}
|
|
2565
2372
|
this.scanning = true;
|
|
2373
|
+
const force = this.forceNextScan;
|
|
2374
|
+
this.forceNextScan = false;
|
|
2566
2375
|
try {
|
|
2567
2376
|
const cacheKey = { manifestHash: manifestHash(this.opts.root), toolVersion: VERSION, offline: this.opts.offline };
|
|
2568
|
-
const cached = loadScanCache(this.opts.root, cacheKey);
|
|
2377
|
+
const cached = force ? null : loadScanCache(this.opts.root, cacheKey);
|
|
2569
2378
|
if (cached) {
|
|
2570
|
-
this.artifact = cached.artifact;
|
|
2379
|
+
this.artifact = pruneArtifactProjects(cached.artifact);
|
|
2571
2380
|
} else {
|
|
2572
2381
|
const scanOpts = {
|
|
2573
2382
|
format: "json",
|
|
@@ -2582,7 +2391,7 @@ var VibgrateLanguageServer = class {
|
|
|
2582
2391
|
vibgrateVersion: VERSION
|
|
2583
2392
|
};
|
|
2584
2393
|
const advanced = await loadAdvancedScanHook();
|
|
2585
|
-
this.artifact = await runCoreScan(this.opts.root, scanOpts, advanced);
|
|
2394
|
+
this.artifact = pruneArtifactProjects(await runCoreScan(this.opts.root, scanOpts, advanced));
|
|
2586
2395
|
writeScanCache(this.opts.root, cacheKey, this.artifact);
|
|
2587
2396
|
}
|
|
2588
2397
|
this.publishScore();
|
|
@@ -2644,7 +2453,8 @@ var VibgrateLanguageServer = class {
|
|
|
2644
2453
|
rootPath: a.rootPath,
|
|
2645
2454
|
scannedAt: a.timestamp,
|
|
2646
2455
|
...delta !== void 0 ? { delta } : {},
|
|
2647
|
-
...buildBreakdown(a.drift, a.projects ?? []) ? { breakdown: buildBreakdown(a.drift, a.projects ?? []) } : {}
|
|
2456
|
+
...buildBreakdown(a.drift, a.projects ?? []) ? { breakdown: buildBreakdown(a.drift, a.projects ?? []) } : {},
|
|
2457
|
+
...buildEolHorizon(a.projects ?? []) ? { eolHorizon: buildEolHorizon(a.projects ?? []) } : {}
|
|
2648
2458
|
};
|
|
2649
2459
|
this.conn.notify("vibgrate/score", payload);
|
|
2650
2460
|
}
|
|
@@ -2830,13 +2640,16 @@ var VibgrateLanguageServer = class {
|
|
|
2830
2640
|
const reachedPkgs = packageReachSet(this.graph);
|
|
2831
2641
|
const targets = [];
|
|
2832
2642
|
for (const proj of a.projects ?? []) {
|
|
2643
|
+
if (isPrunedWorkspacePath(proj.path) || isPrunedWorkspacePath(manifestRelativePath(proj))) {
|
|
2644
|
+
continue;
|
|
2645
|
+
}
|
|
2833
2646
|
const ecosystem = osvEcosystem(proj.type);
|
|
2834
2647
|
if (!ecosystem) continue;
|
|
2835
2648
|
const relManifest = manifestRelativePath(proj);
|
|
2836
|
-
const absManifest =
|
|
2649
|
+
const absManifest = path37.resolve(this.opts.root, relManifest);
|
|
2837
2650
|
let text = null;
|
|
2838
2651
|
try {
|
|
2839
|
-
if (
|
|
2652
|
+
if (fs7.existsSync(absManifest)) text = fs7.readFileSync(absManifest, "utf8");
|
|
2840
2653
|
} catch {
|
|
2841
2654
|
text = null;
|
|
2842
2655
|
}
|
|
@@ -2881,13 +2694,31 @@ function uriToPath(uri) {
|
|
|
2881
2694
|
return uri;
|
|
2882
2695
|
}
|
|
2883
2696
|
}
|
|
2697
|
+
function isPrunedWorkspacePath(relPath) {
|
|
2698
|
+
if (!relPath || relPath === "." || relPath === "") return false;
|
|
2699
|
+
const parts = relPath.split(/[/\\]/).filter(Boolean);
|
|
2700
|
+
if (parts.includes(".claude")) return true;
|
|
2701
|
+
return parts.some((p) => SKIP_DIRS.has(p));
|
|
2702
|
+
}
|
|
2703
|
+
function pruneArtifactProjects(a) {
|
|
2704
|
+
const projects = (a.projects ?? []).filter(
|
|
2705
|
+
(p) => !isPrunedWorkspacePath(p.path) && !isPrunedWorkspacePath(manifestRelativePath(p))
|
|
2706
|
+
);
|
|
2707
|
+
if (projects.length === (a.projects ?? []).length) {
|
|
2708
|
+
const findings2 = (a.findings ?? []).filter((f) => !isPrunedWorkspacePath(f.location));
|
|
2709
|
+
if (findings2.length === (a.findings ?? []).length) return a;
|
|
2710
|
+
return { ...a, findings: findings2 };
|
|
2711
|
+
}
|
|
2712
|
+
const findings = (a.findings ?? []).filter((f) => !isPrunedWorkspacePath(f.location));
|
|
2713
|
+
return { ...a, projects, findings };
|
|
2714
|
+
}
|
|
2884
2715
|
function projectForFile(root2, a, filePath) {
|
|
2885
|
-
const dir =
|
|
2716
|
+
const dir = path37.dirname(path37.resolve(filePath));
|
|
2886
2717
|
let best;
|
|
2887
2718
|
let bestLen = -1;
|
|
2888
2719
|
for (const proj of a.projects ?? []) {
|
|
2889
|
-
const projDir =
|
|
2890
|
-
if ((dir === projDir || dir.startsWith(projDir +
|
|
2720
|
+
const projDir = path37.resolve(root2, proj.path);
|
|
2721
|
+
if ((dir === projDir || dir.startsWith(projDir + path37.sep)) && projDir.length > bestLen) {
|
|
2891
2722
|
best = proj;
|
|
2892
2723
|
bestLen = projDir.length;
|
|
2893
2724
|
}
|
|
@@ -2895,7 +2726,7 @@ function projectForFile(root2, a, filePath) {
|
|
|
2895
2726
|
return best;
|
|
2896
2727
|
}
|
|
2897
2728
|
function sameProject(location, projectPath) {
|
|
2898
|
-
return
|
|
2729
|
+
return path37.normalize(location) === path37.normalize(projectPath);
|
|
2899
2730
|
}
|
|
2900
2731
|
function hasReleaseDates(a) {
|
|
2901
2732
|
for (const proj of a.projects ?? []) {
|
|
@@ -2928,9 +2759,31 @@ function scoreForProject(a, proj) {
|
|
|
2928
2759
|
counts: { behind, eol, unmaintained, total },
|
|
2929
2760
|
rootPath: proj.path,
|
|
2930
2761
|
scannedAt: a.timestamp,
|
|
2931
|
-
...buildBreakdown(proj.drift, [proj]) ? { breakdown: buildBreakdown(proj.drift, [proj]) } : {}
|
|
2762
|
+
...buildBreakdown(proj.drift, [proj]) ? { breakdown: buildBreakdown(proj.drift, [proj]) } : {},
|
|
2763
|
+
...buildEolHorizon([proj]) ? { eolHorizon: buildEolHorizon([proj]) } : {}
|
|
2932
2764
|
};
|
|
2933
2765
|
}
|
|
2766
|
+
function runtimeHorizonLabel(project) {
|
|
2767
|
+
const kind = project.type === "node" ? "Node.js" : project.type === "dotnet" ? ".NET" : project.type === "python" ? "Python" : project.type === "java" ? "Java" : project.type;
|
|
2768
|
+
return project.runtime ? `${kind} ${project.runtime}` : kind;
|
|
2769
|
+
}
|
|
2770
|
+
function buildEolHorizon(projects, now = Date.now()) {
|
|
2771
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
2772
|
+
for (const p of projects) {
|
|
2773
|
+
if (!p.runtimeEolDate) continue;
|
|
2774
|
+
const t = Date.parse(p.runtimeEolDate);
|
|
2775
|
+
if (!Number.isFinite(t)) continue;
|
|
2776
|
+
const label = runtimeHorizonLabel(p);
|
|
2777
|
+
if (byLabel.has(label)) continue;
|
|
2778
|
+
byLabel.set(label, {
|
|
2779
|
+
runtime: label,
|
|
2780
|
+
eolDate: p.runtimeEolDate,
|
|
2781
|
+
daysUntil: Math.round((t - now) / (24 * 60 * 60 * 1e3))
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
if (byLabel.size === 0) return void 0;
|
|
2785
|
+
return [...byLabel.values()].sort((a, b) => a.daysUntil - b.daysUntil).slice(0, 5);
|
|
2786
|
+
}
|
|
2934
2787
|
function bandForScore(n) {
|
|
2935
2788
|
if (n <= 30) return "low";
|
|
2936
2789
|
if (n <= 60) return "moderate";
|
|
@@ -2968,34 +2821,34 @@ function buildBreakdown(drift, projects) {
|
|
|
2968
2821
|
}
|
|
2969
2822
|
function manifestRelativePath(proj) {
|
|
2970
2823
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
2971
|
-
const
|
|
2824
|
+
const join27 = (name) => base ? path37.join(base, name) : name;
|
|
2972
2825
|
switch (proj.type) {
|
|
2973
2826
|
case "node":
|
|
2974
2827
|
case "typescript":
|
|
2975
|
-
return
|
|
2828
|
+
return join27("package.json");
|
|
2976
2829
|
case "python":
|
|
2977
|
-
return
|
|
2830
|
+
return join27("pyproject.toml");
|
|
2978
2831
|
case "go":
|
|
2979
|
-
return
|
|
2832
|
+
return join27("go.mod");
|
|
2980
2833
|
case "rust":
|
|
2981
|
-
return
|
|
2834
|
+
return join27("Cargo.toml");
|
|
2982
2835
|
case "ruby":
|
|
2983
|
-
return
|
|
2836
|
+
return join27("Gemfile");
|
|
2984
2837
|
case "php":
|
|
2985
|
-
return
|
|
2838
|
+
return join27("composer.json");
|
|
2986
2839
|
case "java":
|
|
2987
2840
|
case "kotlin":
|
|
2988
2841
|
case "scala":
|
|
2989
2842
|
case "groovy":
|
|
2990
|
-
return
|
|
2843
|
+
return join27("pom.xml");
|
|
2991
2844
|
case "dotnet":
|
|
2992
|
-
return
|
|
2845
|
+
return join27(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
2993
2846
|
case "dart":
|
|
2994
|
-
return
|
|
2847
|
+
return join27("pubspec.yaml");
|
|
2995
2848
|
case "elixir":
|
|
2996
|
-
return
|
|
2849
|
+
return join27("mix.exs");
|
|
2997
2850
|
default:
|
|
2998
|
-
return
|
|
2851
|
+
return join27("package.json");
|
|
2999
2852
|
}
|
|
3000
2853
|
}
|
|
3001
2854
|
function packageReachSet(graph) {
|
|
@@ -3155,7 +3008,7 @@ function hoverMarkdown(dep, contribution) {
|
|
|
3155
3008
|
return lines.join("\n");
|
|
3156
3009
|
}
|
|
3157
3010
|
function startLanguageServer(opts) {
|
|
3158
|
-
if (!
|
|
3011
|
+
if (!fs7.existsSync(opts.root)) {
|
|
3159
3012
|
process.stderr.write(`vg lsp: root does not exist: ${opts.root}
|
|
3160
3013
|
`);
|
|
3161
3014
|
process.exit(1);
|
|
@@ -3292,8 +3145,8 @@ function registerShare(program) {
|
|
|
3292
3145
|
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) {
|
|
3293
3146
|
const global = readGlobal(this);
|
|
3294
3147
|
const root2 = rootOf(global);
|
|
3295
|
-
const gitDir =
|
|
3296
|
-
if (!
|
|
3148
|
+
const gitDir = path37.join(root2, ".git");
|
|
3149
|
+
if (!fs7.existsSync(gitDir)) {
|
|
3297
3150
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
3298
3151
|
}
|
|
3299
3152
|
if (opts.undo) {
|
|
@@ -3314,23 +3167,23 @@ function registerShare(program) {
|
|
|
3314
3167
|
applyGlobalOptions(cmd);
|
|
3315
3168
|
}
|
|
3316
3169
|
function writeVibgrateGitignore(root2, reports) {
|
|
3317
|
-
const dir =
|
|
3318
|
-
|
|
3170
|
+
const dir = path37.join(root2, ".vibgrate");
|
|
3171
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
3319
3172
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
3320
3173
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
3321
|
-
|
|
3174
|
+
fs7.writeFileSync(path37.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
3322
3175
|
`);
|
|
3323
3176
|
}
|
|
3324
3177
|
function writeGitAttributes(root2) {
|
|
3325
|
-
const file =
|
|
3178
|
+
const file = path37.join(root2, ".gitattributes");
|
|
3326
3179
|
const line = ".vibgrate/graph.json merge=vg";
|
|
3327
|
-
let content =
|
|
3180
|
+
let content = fs7.existsSync(file) ? fs7.readFileSync(file, "utf8") : "";
|
|
3328
3181
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
3329
3182
|
content = content.length ? `${content.replace(/\s*$/, "")}
|
|
3330
3183
|
${line}
|
|
3331
3184
|
` : `${line}
|
|
3332
3185
|
`;
|
|
3333
|
-
|
|
3186
|
+
fs7.writeFileSync(file, content);
|
|
3334
3187
|
}
|
|
3335
3188
|
}
|
|
3336
3189
|
function configureMergeDriver(root2) {
|
|
@@ -3339,8 +3192,8 @@ function configureMergeDriver(root2) {
|
|
|
3339
3192
|
}
|
|
3340
3193
|
function installPreCommitHook(root2) {
|
|
3341
3194
|
const hooksDir = hookDir(root2);
|
|
3342
|
-
|
|
3343
|
-
const file =
|
|
3195
|
+
fs7.mkdirSync(hooksDir, { recursive: true });
|
|
3196
|
+
const file = path37.join(hooksDir, "pre-commit");
|
|
3344
3197
|
const block = [
|
|
3345
3198
|
HOOK_BEGIN,
|
|
3346
3199
|
"if command -v vg >/dev/null 2>&1; then",
|
|
@@ -3349,7 +3202,7 @@ function installPreCommitHook(root2) {
|
|
|
3349
3202
|
"fi",
|
|
3350
3203
|
HOOK_END
|
|
3351
3204
|
].join("\n");
|
|
3352
|
-
let content =
|
|
3205
|
+
let content = fs7.existsSync(file) ? fs7.readFileSync(file, "utf8") : "#!/bin/sh\n";
|
|
3353
3206
|
const re = new RegExp(`${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}`);
|
|
3354
3207
|
if (re.test(content)) content = content.replace(re, block);
|
|
3355
3208
|
else content = `${content.replace(/\s*$/, "")}
|
|
@@ -3358,21 +3211,21 @@ ${block}
|
|
|
3358
3211
|
`;
|
|
3359
3212
|
if (!content.startsWith("#!")) content = `#!/bin/sh
|
|
3360
3213
|
${content}`;
|
|
3361
|
-
|
|
3362
|
-
|
|
3214
|
+
fs7.writeFileSync(file, content);
|
|
3215
|
+
fs7.chmodSync(file, 493);
|
|
3363
3216
|
}
|
|
3364
3217
|
function undo(root2) {
|
|
3365
|
-
const hookFile =
|
|
3366
|
-
if (
|
|
3218
|
+
const hookFile = path37.join(hookDir(root2), "pre-commit");
|
|
3219
|
+
if (fs7.existsSync(hookFile)) {
|
|
3367
3220
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
3368
|
-
const next2 =
|
|
3369
|
-
if (next2.trim() === "#!/bin/sh")
|
|
3370
|
-
else
|
|
3221
|
+
const next2 = fs7.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
3222
|
+
if (next2.trim() === "#!/bin/sh") fs7.rmSync(hookFile);
|
|
3223
|
+
else fs7.writeFileSync(hookFile, next2);
|
|
3371
3224
|
}
|
|
3372
|
-
const attr =
|
|
3373
|
-
if (
|
|
3374
|
-
const next2 =
|
|
3375
|
-
|
|
3225
|
+
const attr = path37.join(root2, ".gitattributes");
|
|
3226
|
+
if (fs7.existsSync(attr)) {
|
|
3227
|
+
const next2 = fs7.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
3228
|
+
fs7.writeFileSync(attr, next2);
|
|
3376
3229
|
}
|
|
3377
3230
|
try {
|
|
3378
3231
|
git(root2, ["config", "--remove-section", "merge.vg"]);
|
|
@@ -3382,10 +3235,10 @@ function undo(root2) {
|
|
|
3382
3235
|
function hookDir(root2) {
|
|
3383
3236
|
try {
|
|
3384
3237
|
const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
|
|
3385
|
-
if (configured) return
|
|
3238
|
+
if (configured) return path37.resolve(root2, configured);
|
|
3386
3239
|
} catch {
|
|
3387
3240
|
}
|
|
3388
|
-
return
|
|
3241
|
+
return path37.join(root2, ".git", "hooks");
|
|
3389
3242
|
}
|
|
3390
3243
|
function git(root2, args) {
|
|
3391
3244
|
return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
|
|
@@ -3413,9 +3266,9 @@ function registerWatch(program) {
|
|
|
3413
3266
|
const global = readGlobal(this);
|
|
3414
3267
|
const root2 = rootOf(global);
|
|
3415
3268
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
3416
|
-
const watchRoots = (paths.length ? paths : ["."]).map((p) =>
|
|
3269
|
+
const watchRoots = (paths.length ? paths : ["."]).map((p) => path37.resolve(root2, p));
|
|
3417
3270
|
for (const w of watchRoots) {
|
|
3418
|
-
if (!
|
|
3271
|
+
if (!fs7.existsSync(w)) {
|
|
3419
3272
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
3420
3273
|
}
|
|
3421
3274
|
}
|
|
@@ -3468,14 +3321,14 @@ function registerWatch(program) {
|
|
|
3468
3321
|
const watchers = [];
|
|
3469
3322
|
for (const w of watchRoots) {
|
|
3470
3323
|
try {
|
|
3471
|
-
const watcher =
|
|
3324
|
+
const watcher = fs7.watch(w, { recursive: true }, (_event, filename) => {
|
|
3472
3325
|
if (!filename) {
|
|
3473
3326
|
schedule("change");
|
|
3474
3327
|
return;
|
|
3475
3328
|
}
|
|
3476
|
-
const parts = filename.split(
|
|
3329
|
+
const parts = filename.split(path37.sep);
|
|
3477
3330
|
if (parts.some((p) => SKIP_NAME.has(p))) return;
|
|
3478
|
-
if (filename.includes(`${
|
|
3331
|
+
if (filename.includes(`${path37.sep}.vibgrate${path37.sep}`) || filename.startsWith(".vibgrate")) {
|
|
3479
3332
|
return;
|
|
3480
3333
|
}
|
|
3481
3334
|
schedule(filename);
|
|
@@ -3485,7 +3338,7 @@ function registerWatch(program) {
|
|
|
3485
3338
|
throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
|
|
3486
3339
|
}
|
|
3487
3340
|
}
|
|
3488
|
-
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) =>
|
|
3341
|
+
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path37.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
|
|
3489
3342
|
await new Promise((resolve21) => {
|
|
3490
3343
|
const stop = () => {
|
|
3491
3344
|
for (const w of watchers) w.close();
|
|
@@ -3818,10 +3671,10 @@ function normalizeStandards(raw) {
|
|
|
3818
3671
|
}
|
|
3819
3672
|
function loadStandards(root2) {
|
|
3820
3673
|
for (const rel of STANDARDS_FILES) {
|
|
3821
|
-
const p =
|
|
3674
|
+
const p = path37__default.join(root2, rel);
|
|
3822
3675
|
let text;
|
|
3823
3676
|
try {
|
|
3824
|
-
text =
|
|
3677
|
+
text = fs7__default.readFileSync(p, "utf8");
|
|
3825
3678
|
} catch {
|
|
3826
3679
|
continue;
|
|
3827
3680
|
}
|
|
@@ -4539,8 +4392,8 @@ async function runHostBench(options = {}) {
|
|
|
4539
4392
|
}
|
|
4540
4393
|
async function runArmSimulate(input) {
|
|
4541
4394
|
const { arm, lib, modelPath, turns, trie, env, live } = input;
|
|
4542
|
-
const
|
|
4543
|
-
const session = await acquireHostSession(lib,
|
|
4395
|
+
const path39 = `${modelPath}#${arm.id}`;
|
|
4396
|
+
const session = await acquireHostSession(lib, path39);
|
|
4544
4397
|
const system = "You are a coding agent with a Task Capsule.";
|
|
4545
4398
|
const capsule = "function readConfig(): Config { return load(); }";
|
|
4546
4399
|
let last = null;
|
|
@@ -5752,7 +5605,7 @@ function registerModels(program) {
|
|
|
5752
5605
|
);
|
|
5753
5606
|
}
|
|
5754
5607
|
} else {
|
|
5755
|
-
if (!target.path || !
|
|
5608
|
+
if (!target.path || !fs7.existsSync(target.path)) {
|
|
5756
5609
|
throw new CliError(
|
|
5757
5610
|
`model file not found at ${target.path || "(unknown path)"} \u2014 it may already be removed.`,
|
|
5758
5611
|
ExitCode.NOT_FOUND
|
|
@@ -5766,7 +5619,7 @@ function registerModels(program) {
|
|
|
5766
5619
|
}
|
|
5767
5620
|
if (!global.json) info(c.dim(` $ rm ${target.path}`));
|
|
5768
5621
|
try {
|
|
5769
|
-
|
|
5622
|
+
fs7.unlinkSync(target.path);
|
|
5770
5623
|
} catch (e) {
|
|
5771
5624
|
const msg = e instanceof Error ? e.message : String(e);
|
|
5772
5625
|
throw new CliError(`could not delete ${target.path}: ${msg}`, ExitCode.ERROR);
|
|
@@ -5904,9 +5757,9 @@ function registerModels(program) {
|
|
|
5904
5757
|
}
|
|
5905
5758
|
});
|
|
5906
5759
|
if (opts.out) {
|
|
5907
|
-
const outPath =
|
|
5908
|
-
|
|
5909
|
-
|
|
5760
|
+
const outPath = path37.resolve(opts.out);
|
|
5761
|
+
fs7.mkdirSync(path37.dirname(outPath), { recursive: true });
|
|
5762
|
+
fs7.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
5910
5763
|
`);
|
|
5911
5764
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
5912
5765
|
}
|
|
@@ -6055,14 +5908,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
|
|
|
6055
5908
|
}
|
|
6056
5909
|
return exact[0];
|
|
6057
5910
|
}
|
|
6058
|
-
const base =
|
|
5911
|
+
const base = path37.basename(wantLc);
|
|
6059
5912
|
const soft = fleet.filter((m) => {
|
|
6060
5913
|
const n = m.name.toLowerCase();
|
|
6061
|
-
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) ||
|
|
5914
|
+
return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path37.basename(n) === base;
|
|
6062
5915
|
});
|
|
6063
5916
|
if (soft.length === 1) return soft[0];
|
|
6064
5917
|
if (soft.length > 1) {
|
|
6065
|
-
const baseHits = soft.filter((m) =>
|
|
5918
|
+
const baseHits = soft.filter((m) => path37.basename(m.name).toLowerCase() === base);
|
|
6066
5919
|
const pool = baseHits.length ? baseHits : soft;
|
|
6067
5920
|
const order = ["ollama", "gguf", "lm-studio"];
|
|
6068
5921
|
for (const rt of order) {
|
|
@@ -6100,11 +5953,11 @@ function printBackends(backends) {
|
|
|
6100
5953
|
}
|
|
6101
5954
|
}
|
|
6102
5955
|
function codeConfigPath(root2) {
|
|
6103
|
-
return
|
|
5956
|
+
return path37.join(root2, ".vibgrate", "code.json");
|
|
6104
5957
|
}
|
|
6105
5958
|
function loadCodeConfig(root2) {
|
|
6106
5959
|
try {
|
|
6107
|
-
const raw = JSON.parse(
|
|
5960
|
+
const raw = JSON.parse(fs7.readFileSync(codeConfigPath(root2), "utf8"));
|
|
6108
5961
|
return sanitize(raw);
|
|
6109
5962
|
} catch {
|
|
6110
5963
|
return {};
|
|
@@ -6171,7 +6024,7 @@ function contextBudgetFor(config, modelContextWindow) {
|
|
|
6171
6024
|
var MCP_CONFIG_FILES = [".cursor/mcp.json", ".vscode/mcp.json", ".mcp.json"];
|
|
6172
6025
|
function readMcpServersFile(file) {
|
|
6173
6026
|
try {
|
|
6174
|
-
const raw = JSON.parse(
|
|
6027
|
+
const raw = JSON.parse(fs7.readFileSync(file, "utf8"));
|
|
6175
6028
|
const map = raw.mcpServers ?? raw.servers;
|
|
6176
6029
|
return map && typeof map === "object" ? parseMcpServers(map) : {};
|
|
6177
6030
|
} catch {
|
|
@@ -6182,7 +6035,7 @@ function discoverMcpServers(root2, ownServers) {
|
|
|
6182
6035
|
const servers = {};
|
|
6183
6036
|
const sources = [];
|
|
6184
6037
|
for (const rel of MCP_CONFIG_FILES) {
|
|
6185
|
-
const found = readMcpServersFile(
|
|
6038
|
+
const found = readMcpServersFile(path37.join(root2, rel));
|
|
6186
6039
|
const names = Object.keys(found);
|
|
6187
6040
|
if (names.length) {
|
|
6188
6041
|
sources.push(rel);
|
|
@@ -6211,7 +6064,7 @@ function registerCode(program) {
|
|
|
6211
6064
|
try {
|
|
6212
6065
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
6213
6066
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
|
|
6214
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6067
|
+
const { loadGraph: loadGraph2 } = await import('./load-YPSEDYIW.js');
|
|
6215
6068
|
const state = readOrchestratorState2();
|
|
6216
6069
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
6217
6070
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -6295,7 +6148,7 @@ function registerCode(program) {
|
|
|
6295
6148
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
6296
6149
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
6297
6150
|
}
|
|
6298
|
-
const { runInteractive } = await import('./interactive-
|
|
6151
|
+
const { runInteractive } = await import('./interactive-NJG6467J.js');
|
|
6299
6152
|
await runInteractive(
|
|
6300
6153
|
rootOf(global),
|
|
6301
6154
|
global,
|
|
@@ -6328,7 +6181,7 @@ function registerCode(program) {
|
|
|
6328
6181
|
let mockReply;
|
|
6329
6182
|
if (opts.mock) {
|
|
6330
6183
|
try {
|
|
6331
|
-
mockReply =
|
|
6184
|
+
mockReply = fs7.readFileSync(opts.mock, "utf8");
|
|
6332
6185
|
} catch {
|
|
6333
6186
|
throw new CliError(`couldn't read the --mock file: ${opts.mock}`, ExitCode.USAGE_ERROR);
|
|
6334
6187
|
}
|
|
@@ -6376,19 +6229,20 @@ function registerCode(program) {
|
|
|
6376
6229
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
6377
6230
|
};
|
|
6378
6231
|
try {
|
|
6232
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-5FQWHWYK.js');
|
|
6379
6233
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
6380
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
6234
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-3YOPU3LF.js');
|
|
6381
6235
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
6382
6236
|
const readline5 = await import('readline');
|
|
6383
6237
|
const child = await import('child_process');
|
|
6384
6238
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
6385
6239
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6386
6240
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6387
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6241
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-Y4ZD3QDO.js');
|
|
6388
6242
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6389
6243
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6390
6244
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6391
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6245
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-DH7AHQ23.js');
|
|
6392
6246
|
const federation = loadOrDiscoverFederation(root2);
|
|
6393
6247
|
const modelProfile = mergeModelExecutionProfile(
|
|
6394
6248
|
resolveModelExecutionProfile({
|
|
@@ -6405,6 +6259,18 @@ function registerCode(program) {
|
|
|
6405
6259
|
const runtime = await startCodeRuntimeSession({ root: root2 });
|
|
6406
6260
|
const git2 = detectGitRef(root2);
|
|
6407
6261
|
const repositoryId = repositoryIdFromRoot(root2);
|
|
6262
|
+
const runOutcome = new RunOutcomeRecorder(
|
|
6263
|
+
root2,
|
|
6264
|
+
repositoryId,
|
|
6265
|
+
git2.ref || null,
|
|
6266
|
+
{ mode: codeModeActive ? modeFlag : void 0, provider: primarySlug, model: route.providers[0]?.model },
|
|
6267
|
+
tier,
|
|
6268
|
+
!!auto
|
|
6269
|
+
);
|
|
6270
|
+
const emitAndRecord = (line) => {
|
|
6271
|
+
runOutcome.observe(line);
|
|
6272
|
+
emitStream(line);
|
|
6273
|
+
};
|
|
6408
6274
|
if (runtime.socketPath && git2.ref) {
|
|
6409
6275
|
try {
|
|
6410
6276
|
await vgdRequest2(
|
|
@@ -6434,7 +6300,7 @@ ${res.stderr}` : ""),
|
|
|
6434
6300
|
exitCode: res.status ?? 1
|
|
6435
6301
|
};
|
|
6436
6302
|
};
|
|
6437
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6303
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PZFGTZSA.js');
|
|
6438
6304
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6439
6305
|
getGraph: () => graph,
|
|
6440
6306
|
root: root2,
|
|
@@ -6455,10 +6321,10 @@ ${res.stderr}` : ""),
|
|
|
6455
6321
|
}
|
|
6456
6322
|
const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
|
|
6457
6323
|
const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
|
|
6458
|
-
const
|
|
6324
|
+
const os4 = await import('os');
|
|
6459
6325
|
const pathMod = await import('path');
|
|
6460
6326
|
const checkpointIndex = pathMod.join(
|
|
6461
|
-
|
|
6327
|
+
fs7.mkdtempSync(pathMod.join(os4.tmpdir(), "vg-code-cp-")),
|
|
6462
6328
|
"index"
|
|
6463
6329
|
);
|
|
6464
6330
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -6521,8 +6387,8 @@ ${res.stderr}` : ""),
|
|
|
6521
6387
|
};
|
|
6522
6388
|
try {
|
|
6523
6389
|
if (opts.session) {
|
|
6524
|
-
const { runCodeStreamJsonSession } = await import('./stream-json-
|
|
6525
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
6390
|
+
const { runCodeStreamJsonSession } = await import('./stream-json-3YOPU3LF.js');
|
|
6391
|
+
const { runAgent: runAgent2 } = await import('./agent-33BMKWJC.js');
|
|
6526
6392
|
const {
|
|
6527
6393
|
loadLatestSession,
|
|
6528
6394
|
newSession,
|
|
@@ -6557,8 +6423,9 @@ ${res.stderr}` : ""),
|
|
|
6557
6423
|
wakeTurn = resolve21;
|
|
6558
6424
|
});
|
|
6559
6425
|
};
|
|
6426
|
+
let turnIndex = 0;
|
|
6560
6427
|
await runCodeStreamJsonSession({
|
|
6561
|
-
emit:
|
|
6428
|
+
emit: emitAndRecord,
|
|
6562
6429
|
auto: !!auto,
|
|
6563
6430
|
sessionId: record.id,
|
|
6564
6431
|
resumed: !!resumedRecord,
|
|
@@ -6570,8 +6437,10 @@ ${res.stderr}` : ""),
|
|
|
6570
6437
|
rl.on("line", (raw) => {
|
|
6571
6438
|
const msg = parseHostMessage(raw);
|
|
6572
6439
|
if (!msg) return;
|
|
6573
|
-
if (msg.kind === "approve")
|
|
6574
|
-
|
|
6440
|
+
if (msg.kind === "approve") {
|
|
6441
|
+
session.submitDecision(msg.id, msg.approve);
|
|
6442
|
+
runOutcome.noteDecision(msg.id, msg.approve);
|
|
6443
|
+
} else if (msg.kind === "answer") session.submitAnswer(msg.id, msg.answer);
|
|
6575
6444
|
else if (msg.kind === "submit") pushTurn(msg.instruction);
|
|
6576
6445
|
else if (msg.kind === "restore") {
|
|
6577
6446
|
void import('./checkpoint-4WFZMKEO.js').then(({ restoreCheckpoint }) => {
|
|
@@ -6581,8 +6450,10 @@ ${res.stderr}` : ""),
|
|
|
6581
6450
|
});
|
|
6582
6451
|
emitStream({ event: "checkpoint-restored", commit: msg.commit, ...outcome });
|
|
6583
6452
|
});
|
|
6584
|
-
} else if (msg.kind === "cancel")
|
|
6585
|
-
|
|
6453
|
+
} else if (msg.kind === "cancel") {
|
|
6454
|
+
session.cancelTurn();
|
|
6455
|
+
runOutcome.cancelPending();
|
|
6456
|
+
} else if (msg.kind === "end") {
|
|
6586
6457
|
ended = true;
|
|
6587
6458
|
pushTurn(null);
|
|
6588
6459
|
}
|
|
@@ -6590,18 +6461,23 @@ ${res.stderr}` : ""),
|
|
|
6590
6461
|
rl.on("close", () => {
|
|
6591
6462
|
ended = true;
|
|
6592
6463
|
session.cancelTurn();
|
|
6464
|
+
runOutcome.cancelPending();
|
|
6593
6465
|
pushTurn(null);
|
|
6594
6466
|
});
|
|
6595
6467
|
},
|
|
6596
|
-
runTurn: ({ instruction: turnInstruction, priorSummary, signal, session }) =>
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6468
|
+
runTurn: ({ instruction: turnInstruction, priorSummary, signal, session }) => {
|
|
6469
|
+
turnIndex++;
|
|
6470
|
+
runOutcome.beginRun(turnRunId(record.id, turnIndex), turnInstruction);
|
|
6471
|
+
return runAgent2({
|
|
6472
|
+
...baseAgentOptions,
|
|
6473
|
+
instruction: turnInstruction,
|
|
6474
|
+
priorSummary,
|
|
6475
|
+
signal,
|
|
6476
|
+
approve: session.approve,
|
|
6477
|
+
askUser: session.askUser,
|
|
6478
|
+
onEvent: session.onEvent
|
|
6479
|
+
});
|
|
6480
|
+
},
|
|
6605
6481
|
onTurnEnd: (turn) => {
|
|
6606
6482
|
record = recordTask(
|
|
6607
6483
|
record,
|
|
@@ -6618,20 +6494,27 @@ ${res.stderr}` : ""),
|
|
|
6618
6494
|
}
|
|
6619
6495
|
});
|
|
6620
6496
|
} else {
|
|
6497
|
+
runOutcome.beginRun(newOneShotRunId(), instruction);
|
|
6621
6498
|
await runCodeStreamJson({
|
|
6622
6499
|
...baseAgentOptions,
|
|
6623
6500
|
instruction,
|
|
6624
|
-
emit:
|
|
6501
|
+
emit: emitAndRecord,
|
|
6625
6502
|
bindDecisions: (session) => {
|
|
6626
6503
|
streamApprove = (action) => session.approve(action);
|
|
6627
6504
|
const rl = readline5.createInterface({ input: process.stdin });
|
|
6628
6505
|
rl.on("line", (raw) => {
|
|
6629
6506
|
const msg = parseHostMessage(raw);
|
|
6630
6507
|
if (!msg) return;
|
|
6631
|
-
if (msg.kind === "approve")
|
|
6632
|
-
|
|
6633
|
-
|
|
6508
|
+
if (msg.kind === "approve") {
|
|
6509
|
+
session.submitDecision(msg.id, msg.approve);
|
|
6510
|
+
runOutcome.noteDecision(msg.id, msg.approve);
|
|
6511
|
+
} else if (msg.kind === "answer") session.submitAnswer(msg.id, msg.answer);
|
|
6512
|
+
else if (msg.kind === "cancel") {
|
|
6513
|
+
session.cancelTurn();
|
|
6514
|
+
runOutcome.cancelPending();
|
|
6515
|
+
}
|
|
6634
6516
|
});
|
|
6517
|
+
rl.on("close", () => runOutcome.cancelPending());
|
|
6635
6518
|
}
|
|
6636
6519
|
});
|
|
6637
6520
|
}
|
|
@@ -6653,7 +6536,7 @@ ${res.stderr}` : ""),
|
|
|
6653
6536
|
if (!autonomous && !tty) {
|
|
6654
6537
|
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).");
|
|
6655
6538
|
}
|
|
6656
|
-
const { agentTask } = await import('./interactive-
|
|
6539
|
+
const { agentTask } = await import('./interactive-NJG6467J.js');
|
|
6657
6540
|
const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
|
|
6658
6541
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
6659
6542
|
let priorSummary;
|
|
@@ -6663,7 +6546,7 @@ ${res.stderr}` : ""),
|
|
|
6663
6546
|
if (prev) priorSummary = summarizeSession(prev);
|
|
6664
6547
|
}
|
|
6665
6548
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
6666
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
6549
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PZFGTZSA.js');
|
|
6667
6550
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
6668
6551
|
getGraph: () => graph,
|
|
6669
6552
|
root: root2,
|
|
@@ -6687,11 +6570,11 @@ ${res.stderr}` : ""),
|
|
|
6687
6570
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
6688
6571
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
6689
6572
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
6690
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
6573
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-Y4ZD3QDO.js');
|
|
6691
6574
|
const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
|
|
6692
6575
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
6693
6576
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
6694
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6577
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-DH7AHQ23.js');
|
|
6695
6578
|
const federation = loadFederation(root2);
|
|
6696
6579
|
const modelProfile = mergeModelExecutionProfile(
|
|
6697
6580
|
resolveModelExecutionProfile({
|
|
@@ -6783,7 +6666,7 @@ ${res.stderr}` : ""),
|
|
|
6783
6666
|
attribution: { client: "vg-code", provider: providerSlug, model: primary?.model }
|
|
6784
6667
|
});
|
|
6785
6668
|
if (opts.out) {
|
|
6786
|
-
|
|
6669
|
+
fs7.writeFileSync(opts.out, JSON.stringify(result, null, 2) + "\n");
|
|
6787
6670
|
}
|
|
6788
6671
|
if (global.json) {
|
|
6789
6672
|
json(result);
|
|
@@ -6996,7 +6879,7 @@ async function addCmd(root2, rest, opts, asJson) {
|
|
|
6996
6879
|
}
|
|
6997
6880
|
function readPackageVersion(root2) {
|
|
6998
6881
|
try {
|
|
6999
|
-
const pkg = JSON.parse(
|
|
6882
|
+
const pkg = JSON.parse(fs7__default.readFileSync(path37__default.join(root2, "package.json"), "utf8"));
|
|
7000
6883
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
7001
6884
|
} catch {
|
|
7002
6885
|
return void 0;
|
|
@@ -7004,7 +6887,7 @@ function readPackageVersion(root2) {
|
|
|
7004
6887
|
}
|
|
7005
6888
|
function readOptionalFile(p) {
|
|
7006
6889
|
try {
|
|
7007
|
-
const t =
|
|
6890
|
+
const t = fs7__default.readFileSync(p, "utf8");
|
|
7008
6891
|
return t.trim() ? t : void 0;
|
|
7009
6892
|
} catch {
|
|
7010
6893
|
return void 0;
|
|
@@ -7019,8 +6902,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
|
|
|
7019
6902
|
if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
|
|
7020
6903
|
const version = (opts.version || readPackageVersion(root2) || "").trim();
|
|
7021
6904
|
if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
|
|
7022
|
-
const readme = readOptionalFile(opts.readme ?
|
|
7023
|
-
const dts = opts.dts ? readOptionalFile(
|
|
6905
|
+
const readme = readOptionalFile(opts.readme ? path37__default.resolve(opts.readme) : path37__default.join(root2, "README.md"));
|
|
6906
|
+
const dts = opts.dts ? readOptionalFile(path37__default.resolve(opts.dts)) : void 0;
|
|
7024
6907
|
if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
|
|
7025
6908
|
const result = await publishPrivateLibrary(
|
|
7026
6909
|
{ name, version, readme, dts, language: opts.language },
|
|
@@ -7152,8 +7035,8 @@ function registerExport(program) {
|
|
|
7152
7035
|
out(content.trimEnd());
|
|
7153
7036
|
return;
|
|
7154
7037
|
}
|
|
7155
|
-
|
|
7156
|
-
|
|
7038
|
+
fs7.mkdirSync(path37.dirname(path37.resolve(file)), { recursive: true });
|
|
7039
|
+
fs7.writeFileSync(file, content);
|
|
7157
7040
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
7158
7041
|
});
|
|
7159
7042
|
applyGlobalOptions(cmd);
|
|
@@ -7163,43 +7046,43 @@ function detectFormat(file) {
|
|
|
7163
7046
|
if (lower.endsWith(".cdx.json")) return "cyclonedx";
|
|
7164
7047
|
if (lower.endsWith(".spdx.json")) return "spdx";
|
|
7165
7048
|
if (file === "-") return "json";
|
|
7166
|
-
return formatForExt(
|
|
7049
|
+
return formatForExt(path37.extname(file));
|
|
7167
7050
|
}
|
|
7168
7051
|
function registerBundle(program) {
|
|
7169
7052
|
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) {
|
|
7170
7053
|
const global = readGlobal(this);
|
|
7171
7054
|
const root2 = rootOf(global);
|
|
7172
|
-
const outDir =
|
|
7055
|
+
const outDir = path37.resolve(root2, opts.out ?? "vg-bundle");
|
|
7173
7056
|
let grammarFiles;
|
|
7174
7057
|
try {
|
|
7175
7058
|
grammarFiles = resolvedGrammarFiles();
|
|
7176
7059
|
} catch {
|
|
7177
7060
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
7178
7061
|
}
|
|
7179
|
-
|
|
7062
|
+
fs7.mkdirSync(path37.join(outDir, "grammars"), { recursive: true });
|
|
7180
7063
|
let grammarCount = 0;
|
|
7181
7064
|
for (const { fileName, absPath } of grammarFiles) {
|
|
7182
|
-
|
|
7065
|
+
fs7.copyFileSync(absPath, path37.join(outDir, "grammars", fileName));
|
|
7183
7066
|
grammarCount++;
|
|
7184
7067
|
}
|
|
7185
7068
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
7186
7069
|
const graphSrc = resolveGraphPath(root2, global.graph);
|
|
7187
|
-
if (
|
|
7188
|
-
|
|
7070
|
+
if (fs7.existsSync(graphSrc)) {
|
|
7071
|
+
fs7.copyFileSync(graphSrc, path37.join(outDir, "graph.json"));
|
|
7189
7072
|
included.push("graph.json");
|
|
7190
7073
|
} else {
|
|
7191
7074
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
7192
7075
|
if (graph) {
|
|
7193
|
-
|
|
7076
|
+
fs7.writeFileSync(path37.join(outDir, "graph.json"), serializeGraph(graph));
|
|
7194
7077
|
included.push("graph.json");
|
|
7195
7078
|
}
|
|
7196
7079
|
}
|
|
7197
7080
|
const cat = catalogPath(root2);
|
|
7198
|
-
if (
|
|
7199
|
-
|
|
7081
|
+
if (fs7.existsSync(cat)) {
|
|
7082
|
+
fs7.copyFileSync(cat, path37.join(outDir, "vibgrate.lib.json"));
|
|
7200
7083
|
included.push("vibgrate.lib.json");
|
|
7201
|
-
if (
|
|
7202
|
-
|
|
7084
|
+
if (fs7.existsSync(libDir(root2))) {
|
|
7085
|
+
fs7.cpSync(libDir(root2), path37.join(outDir, "lib"), { recursive: true });
|
|
7203
7086
|
included.push("lib/");
|
|
7204
7087
|
}
|
|
7205
7088
|
}
|
|
@@ -7211,15 +7094,15 @@ function registerBundle(program) {
|
|
|
7211
7094
|
included,
|
|
7212
7095
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
7213
7096
|
};
|
|
7214
|
-
|
|
7097
|
+
fs7.writeFileSync(path37.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
7215
7098
|
`);
|
|
7216
7099
|
if (global.json) {
|
|
7217
|
-
json({ out:
|
|
7100
|
+
json({ out: path37.relative(root2, outDir), ...manifest });
|
|
7218
7101
|
return;
|
|
7219
7102
|
}
|
|
7220
|
-
info(`${c.cyan("vg bundle")} \xB7 wrote ${
|
|
7103
|
+
info(`${c.cyan("vg bundle")} \xB7 wrote ${path37.relative(root2, outDir)}/`);
|
|
7221
7104
|
for (const i of included) info(` ${c.green("\u2714")} ${i}`);
|
|
7222
|
-
info(c.dim(` offline: vg build --grammars "${
|
|
7105
|
+
info(c.dim(` offline: vg build --grammars "${path37.relative(root2, outDir)}/grammars"`));
|
|
7223
7106
|
});
|
|
7224
7107
|
applyGlobalOptions(cmd);
|
|
7225
7108
|
}
|
|
@@ -7237,7 +7120,7 @@ async function runDoctor(global) {
|
|
|
7237
7120
|
const root2 = rootOf(global);
|
|
7238
7121
|
const local = global.local === true;
|
|
7239
7122
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
7240
|
-
const configFile = CONFIG_BASENAMES.find((f) =>
|
|
7123
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs7.existsSync(path37.join(root2, f))) ?? null;
|
|
7241
7124
|
const graph = loadGraph(root2, graphPath);
|
|
7242
7125
|
let staleFiles = null;
|
|
7243
7126
|
if (graph) {
|
|
@@ -7263,14 +7146,14 @@ async function runDoctor(global) {
|
|
|
7263
7146
|
root: root2,
|
|
7264
7147
|
configFile,
|
|
7265
7148
|
map: {
|
|
7266
|
-
path:
|
|
7149
|
+
path: path37.relative(root2, graphPath),
|
|
7267
7150
|
built: graph !== null,
|
|
7268
7151
|
generatedAt: graph?.generatedAt ?? null,
|
|
7269
7152
|
staleFiles
|
|
7270
7153
|
},
|
|
7271
7154
|
libCatalog: {
|
|
7272
|
-
path:
|
|
7273
|
-
present:
|
|
7155
|
+
path: path37.relative(root2, catalogPath(root2)),
|
|
7156
|
+
present: fs7.existsSync(catalogPath(root2)),
|
|
7274
7157
|
libraries: libCount
|
|
7275
7158
|
},
|
|
7276
7159
|
credentials: creds,
|
|
@@ -7327,7 +7210,7 @@ async function runDoctor(global) {
|
|
|
7327
7210
|
);
|
|
7328
7211
|
info(
|
|
7329
7212
|
` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
|
|
7330
|
-
` \xB7 last ${
|
|
7213
|
+
` \xB7 last ${path37.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
|
|
7331
7214
|
) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
|
|
7332
7215
|
);
|
|
7333
7216
|
if (li.dynamicOnToken || li.dynamicCustomSampler) {
|
|
@@ -7503,7 +7386,7 @@ function registerDaemon(program) {
|
|
|
7503
7386
|
const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
|
|
7504
7387
|
const global = readGlobal(this);
|
|
7505
7388
|
const socketPath = socketOf(this);
|
|
7506
|
-
const root2 =
|
|
7389
|
+
const root2 = path37.resolve(rootArg ?? rootOf(global));
|
|
7507
7390
|
if (!await vgdIsRunning({ socketPath })) {
|
|
7508
7391
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
7509
7392
|
}
|
|
@@ -7539,7 +7422,7 @@ function registerDaemon(program) {
|
|
|
7539
7422
|
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) {
|
|
7540
7423
|
const global = readGlobal(this);
|
|
7541
7424
|
const socketPath = socketOf(this);
|
|
7542
|
-
const primary =
|
|
7425
|
+
const primary = path37.resolve(rootArg ?? rootOf(global));
|
|
7543
7426
|
if (!await vgdIsRunning({ socketPath })) {
|
|
7544
7427
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
7545
7428
|
}
|
|
@@ -7567,7 +7450,7 @@ function registerDaemon(program) {
|
|
|
7567
7450
|
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) {
|
|
7568
7451
|
const global = readGlobal(this);
|
|
7569
7452
|
const socketPath = socketOf(this);
|
|
7570
|
-
const root2 =
|
|
7453
|
+
const root2 = path37.resolve(rootArg ?? rootOf(global));
|
|
7571
7454
|
if (!await vgdIsRunning({ socketPath })) {
|
|
7572
7455
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
7573
7456
|
}
|
|
@@ -7581,7 +7464,7 @@ function registerDaemon(program) {
|
|
|
7581
7464
|
throw new CliError(loaded.error, ExitCode.NOT_FOUND);
|
|
7582
7465
|
}
|
|
7583
7466
|
if (!loaded.ok) {
|
|
7584
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
7467
|
+
const { loadGraph: loadGraph2 } = await import('./load-YPSEDYIW.js');
|
|
7585
7468
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7586
7469
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7587
7470
|
const graph = loadGraph2(root2, global.graph);
|
|
@@ -7697,7 +7580,7 @@ function socketOf(cmd) {
|
|
|
7697
7580
|
let c2 = cmd;
|
|
7698
7581
|
while (c2) {
|
|
7699
7582
|
const opts = c2.opts();
|
|
7700
|
-
if (opts.socket) return
|
|
7583
|
+
if (opts.socket) return path37.resolve(opts.socket);
|
|
7701
7584
|
c2 = c2.parent;
|
|
7702
7585
|
}
|
|
7703
7586
|
return vgdSocketPath();
|
|
@@ -7769,7 +7652,7 @@ async function restartVgdIfRunning(socketPath = vgdSocketPath()) {
|
|
|
7769
7652
|
}
|
|
7770
7653
|
function readVgdPid() {
|
|
7771
7654
|
try {
|
|
7772
|
-
const raw =
|
|
7655
|
+
const raw = fs7.readFileSync(vgdPidPath(), "utf8").trim();
|
|
7773
7656
|
const pid = Number.parseInt(raw, 10);
|
|
7774
7657
|
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
7775
7658
|
} catch {
|
|
@@ -7854,7 +7737,7 @@ function registerPolicy(program) {
|
|
|
7854
7737
|
const global = readGlobal(this);
|
|
7855
7738
|
let raw;
|
|
7856
7739
|
try {
|
|
7857
|
-
raw =
|
|
7740
|
+
raw = fs7.readFileSync(file, "utf8");
|
|
7858
7741
|
} catch {
|
|
7859
7742
|
throw new CliError(`cannot read ${file}`, ExitCode.NOT_FOUND);
|
|
7860
7743
|
}
|
|
@@ -7974,11 +7857,11 @@ function registerLlmHost(program) {
|
|
|
7974
7857
|
applyGlobalOptions(cmd);
|
|
7975
7858
|
}
|
|
7976
7859
|
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) => {
|
|
7977
|
-
const rootDir =
|
|
7978
|
-
const vibgrateDir2 =
|
|
7860
|
+
const rootDir = path37.resolve(targetPath);
|
|
7861
|
+
const vibgrateDir2 = path37.join(rootDir, ".vibgrate");
|
|
7979
7862
|
await ensureDir(vibgrateDir2);
|
|
7980
7863
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
|
|
7981
|
-
const configPath =
|
|
7864
|
+
const configPath = path37.join(rootDir, "vibgrate.config.ts");
|
|
7982
7865
|
if (await pathExists(configPath)) {
|
|
7983
7866
|
console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
|
|
7984
7867
|
} else {
|
|
@@ -7986,7 +7869,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
7986
7869
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
7987
7870
|
}
|
|
7988
7871
|
if (opts.baseline) {
|
|
7989
|
-
const { runBaseline } = await import('./baseline-
|
|
7872
|
+
const { runBaseline } = await import('./baseline-V6MYDEMS.js');
|
|
7990
7873
|
await runBaseline(rootDir);
|
|
7991
7874
|
}
|
|
7992
7875
|
console.log("");
|
|
@@ -8089,16 +7972,16 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
8089
7972
|
};
|
|
8090
7973
|
}
|
|
8091
7974
|
async function fileReferencesIdentifier(rootDir, relFile, identifier, readFile3) {
|
|
8092
|
-
const content = await readFile3(
|
|
7975
|
+
const content = await readFile3(path37.join(rootDir, relFile));
|
|
8093
7976
|
if (!content) return false;
|
|
8094
7977
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8095
7978
|
return new RegExp(`\\b${escaped}\\b`).test(content);
|
|
8096
7979
|
}
|
|
8097
7980
|
async function defaultReadFile(absPath) {
|
|
8098
7981
|
try {
|
|
8099
|
-
const stat2 = await
|
|
7982
|
+
const stat2 = await fs21.stat(absPath);
|
|
8100
7983
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
8101
|
-
return await
|
|
7984
|
+
return await fs21.readFile(absPath, "utf8");
|
|
8102
7985
|
} catch {
|
|
8103
7986
|
return null;
|
|
8104
7987
|
}
|
|
@@ -8284,7 +8167,7 @@ var AI_ASSISTANT_DETECTORS = [
|
|
|
8284
8167
|
async function detectAiAssistant(rootDir) {
|
|
8285
8168
|
for (const detector of AI_ASSISTANT_DETECTORS) {
|
|
8286
8169
|
for (const file of detector.files) {
|
|
8287
|
-
if (await pathExists$1(
|
|
8170
|
+
if (await pathExists$1(path37.join(rootDir, file))) {
|
|
8288
8171
|
return detector.name;
|
|
8289
8172
|
}
|
|
8290
8173
|
}
|
|
@@ -8478,7 +8361,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
8478
8361
|
collectExcludes,
|
|
8479
8362
|
[]
|
|
8480
8363
|
).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) => {
|
|
8481
|
-
const rootDir =
|
|
8364
|
+
const rootDir = path37.resolve(targetPath);
|
|
8482
8365
|
if (!await pathExists$1(rootDir)) {
|
|
8483
8366
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
8484
8367
|
process.exit(1);
|
|
@@ -8486,7 +8369,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
8486
8369
|
const hasDsn = !!resolveDsn(opts.dsn);
|
|
8487
8370
|
const willPush = !opts.offline && (opts.push || hasDsn);
|
|
8488
8371
|
const noLocalArtifacts = opts.localArtifacts === false;
|
|
8489
|
-
const isFirstRun = !await pathExists$1(
|
|
8372
|
+
const isFirstRun = !await pathExists$1(path37.join(rootDir, ".vibgrate", "scan_result.json"));
|
|
8490
8373
|
let pinnedRegion;
|
|
8491
8374
|
let planTier;
|
|
8492
8375
|
let upgradeUrl;
|
|
@@ -8745,7 +8628,7 @@ var SKIP_DIRS2 = /* @__PURE__ */ new Set([
|
|
|
8745
8628
|
function scanStaleness(rootDir, artifactPath) {
|
|
8746
8629
|
let ref;
|
|
8747
8630
|
try {
|
|
8748
|
-
ref =
|
|
8631
|
+
ref = fs7.statSync(artifactPath).mtimeMs;
|
|
8749
8632
|
} catch {
|
|
8750
8633
|
return { stale: false };
|
|
8751
8634
|
}
|
|
@@ -8757,7 +8640,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
8757
8640
|
if (depth > 8 || scanned > MAX_ENTRIES2) return;
|
|
8758
8641
|
let entries;
|
|
8759
8642
|
try {
|
|
8760
|
-
entries =
|
|
8643
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
8761
8644
|
} catch {
|
|
8762
8645
|
return;
|
|
8763
8646
|
}
|
|
@@ -8765,20 +8648,20 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
8765
8648
|
scanned++;
|
|
8766
8649
|
if (scanned > MAX_ENTRIES2) break;
|
|
8767
8650
|
if (e.isDirectory()) {
|
|
8768
|
-
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(
|
|
8651
|
+
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path37.join(dir, e.name), depth + 1);
|
|
8769
8652
|
continue;
|
|
8770
8653
|
}
|
|
8771
8654
|
if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
|
|
8772
|
-
const abs =
|
|
8655
|
+
const abs = path37.join(dir, e.name);
|
|
8773
8656
|
let mtimeMs;
|
|
8774
8657
|
try {
|
|
8775
|
-
mtimeMs =
|
|
8658
|
+
mtimeMs = fs7.statSync(abs).mtimeMs;
|
|
8776
8659
|
} catch {
|
|
8777
8660
|
continue;
|
|
8778
8661
|
}
|
|
8779
8662
|
if (mtimeMs > newest) {
|
|
8780
8663
|
newest = mtimeMs;
|
|
8781
|
-
newestChanged =
|
|
8664
|
+
newestChanged = path37.relative(rootDir, abs) || e.name;
|
|
8782
8665
|
}
|
|
8783
8666
|
}
|
|
8784
8667
|
};
|
|
@@ -8909,7 +8792,7 @@ function analyzeTree(root2, packages) {
|
|
|
8909
8792
|
if (depth > MAX_DEPTH || filesSeen >= MAX_FILES) return;
|
|
8910
8793
|
let entries;
|
|
8911
8794
|
try {
|
|
8912
|
-
entries =
|
|
8795
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
8913
8796
|
} catch {
|
|
8914
8797
|
return;
|
|
8915
8798
|
}
|
|
@@ -8918,17 +8801,17 @@ function analyzeTree(root2, packages) {
|
|
|
8918
8801
|
if (filesSeen >= MAX_FILES) return;
|
|
8919
8802
|
if (entry.isDirectory()) {
|
|
8920
8803
|
if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
8921
|
-
walk2(
|
|
8804
|
+
walk2(path37.join(dir, entry.name), depth + 1);
|
|
8922
8805
|
continue;
|
|
8923
8806
|
}
|
|
8924
|
-
const fileEco = EXT_ECOSYSTEM[
|
|
8807
|
+
const fileEco = EXT_ECOSYSTEM[path37.extname(entry.name)];
|
|
8925
8808
|
if (!fileEco || fileEco === "unknown") continue;
|
|
8926
8809
|
filesSeen++;
|
|
8927
|
-
const full =
|
|
8810
|
+
const full = path37.join(dir, entry.name);
|
|
8928
8811
|
let content;
|
|
8929
8812
|
try {
|
|
8930
|
-
if (
|
|
8931
|
-
content =
|
|
8813
|
+
if (fs7.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
8814
|
+
content = fs7.readFileSync(full, "utf8");
|
|
8932
8815
|
} catch {
|
|
8933
8816
|
continue;
|
|
8934
8817
|
}
|
|
@@ -9239,7 +9122,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
9239
9122
|
}
|
|
9240
9123
|
const outcomes = effective.map((t) => {
|
|
9241
9124
|
const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
|
|
9242
|
-
return { t, res: run(c2,
|
|
9125
|
+
return { t, res: run(c2, path37.join(rootDir, t.dir)) };
|
|
9243
9126
|
});
|
|
9244
9127
|
const failures = outcomes.filter((o) => !o.res.ok);
|
|
9245
9128
|
if (failures.length === 0) {
|
|
@@ -9268,8 +9151,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
9268
9151
|
return results;
|
|
9269
9152
|
}
|
|
9270
9153
|
var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
|
|
9271
|
-
var CACHE_DIR =
|
|
9272
|
-
var CACHE_FILE =
|
|
9154
|
+
var CACHE_DIR = path37.join(os.homedir(), ".vibgrate");
|
|
9155
|
+
var CACHE_FILE = path37.join(CACHE_DIR, "update-check.json");
|
|
9273
9156
|
async function fetchLatestVersion() {
|
|
9274
9157
|
try {
|
|
9275
9158
|
const controller = new AbortController();
|
|
@@ -9296,8 +9179,8 @@ async function fetchLatestVersion() {
|
|
|
9296
9179
|
}
|
|
9297
9180
|
async function writeCache(data) {
|
|
9298
9181
|
try {
|
|
9299
|
-
await
|
|
9300
|
-
await
|
|
9182
|
+
await fs21.mkdir(CACHE_DIR, { recursive: true });
|
|
9183
|
+
await fs21.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
9301
9184
|
} catch {
|
|
9302
9185
|
}
|
|
9303
9186
|
}
|
|
@@ -9308,7 +9191,7 @@ function detectGlobalInstall(execPath = process.argv[1] || "", cwd = process.cwd
|
|
|
9308
9191
|
if (!execPath) return null;
|
|
9309
9192
|
let resolved = execPath;
|
|
9310
9193
|
try {
|
|
9311
|
-
resolved =
|
|
9194
|
+
resolved = fs7.realpathSync(execPath);
|
|
9312
9195
|
} catch {
|
|
9313
9196
|
}
|
|
9314
9197
|
const p = resolved.replace(/\\/g, "/");
|
|
@@ -9338,14 +9221,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
|
|
|
9338
9221
|
pm: "yarn",
|
|
9339
9222
|
root: () => {
|
|
9340
9223
|
const dir = tryRun("yarn global dir");
|
|
9341
|
-
return dir ?
|
|
9224
|
+
return dir ? path37.join(dir, "node_modules") : null;
|
|
9342
9225
|
}
|
|
9343
9226
|
},
|
|
9344
|
-
{ pm: "bun", root: () =>
|
|
9227
|
+
{ pm: "bun", root: () => path37.join(os.homedir(), ".bun", "install", "global", "node_modules") }
|
|
9345
9228
|
];
|
|
9346
9229
|
for (const probe of probes) {
|
|
9347
9230
|
const root2 = probe.root();
|
|
9348
|
-
if (root2 && await pathExists(
|
|
9231
|
+
if (root2 && await pathExists(path37.join(root2, pkg))) return probe.pm;
|
|
9349
9232
|
}
|
|
9350
9233
|
return null;
|
|
9351
9234
|
}
|
|
@@ -9364,15 +9247,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
|
|
|
9364
9247
|
}
|
|
9365
9248
|
}
|
|
9366
9249
|
async function detectPackageManager(cwd) {
|
|
9367
|
-
if (await pathExists(
|
|
9368
|
-
if (await pathExists(
|
|
9369
|
-
if (await pathExists(
|
|
9250
|
+
if (await pathExists(path37.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
9251
|
+
if (await pathExists(path37.join(cwd, "bun.lockb"))) return "bun";
|
|
9252
|
+
if (await pathExists(path37.join(cwd, "yarn.lock"))) return "yarn";
|
|
9370
9253
|
return "npm";
|
|
9371
9254
|
}
|
|
9372
9255
|
async function detectWorkspaceRoot(cwd) {
|
|
9373
|
-
if (await pathExists(
|
|
9256
|
+
if (await pathExists(path37.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
9374
9257
|
try {
|
|
9375
|
-
const pkgPath =
|
|
9258
|
+
const pkgPath = path37.join(cwd, "package.json");
|
|
9376
9259
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
9377
9260
|
const pkg = JSON.parse(raw);
|
|
9378
9261
|
return pkg.workspaces != null;
|
|
@@ -9397,7 +9280,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
|
9397
9280
|
}
|
|
9398
9281
|
async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
9399
9282
|
try {
|
|
9400
|
-
const pkgPath =
|
|
9283
|
+
const pkgPath = path37.join(cwd, "package.json");
|
|
9401
9284
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
9402
9285
|
const parsed = JSON.parse(raw);
|
|
9403
9286
|
if (parsed.devDependencies?.[pkg]) return "dev";
|
|
@@ -9566,13 +9449,13 @@ function collectCandidates(artifact) {
|
|
|
9566
9449
|
return out2;
|
|
9567
9450
|
}
|
|
9568
9451
|
var defaultFixScanner = async (rootDir) => {
|
|
9569
|
-
const scratch =
|
|
9452
|
+
const scratch = path37.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
|
|
9570
9453
|
const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
|
|
9571
9454
|
const advanced = await loadAdvancedScanHook();
|
|
9572
9455
|
return runCoreScan(rootDir, scanOpts, advanced);
|
|
9573
9456
|
};
|
|
9574
9457
|
async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
|
|
9575
|
-
const artifactPath =
|
|
9458
|
+
const artifactPath = path37.isAbsolute(inFile) ? inFile : path37.join(rootDir, inFile);
|
|
9576
9459
|
if (await pathExists(artifactPath)) {
|
|
9577
9460
|
const staleness = scanStaleness(rootDir, artifactPath);
|
|
9578
9461
|
if (!staleness.stale) {
|
|
@@ -9599,7 +9482,7 @@ async function repositoryIdentity(rootDir, override) {
|
|
|
9599
9482
|
}
|
|
9600
9483
|
}
|
|
9601
9484
|
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) => {
|
|
9602
|
-
const rootDir =
|
|
9485
|
+
const rootDir = path37.resolve(targetPath);
|
|
9603
9486
|
if (!await pathExists(rootDir)) {
|
|
9604
9487
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
9605
9488
|
process.exit(1);
|
|
@@ -9760,7 +9643,7 @@ function emit(report, format) {
|
|
|
9760
9643
|
}
|
|
9761
9644
|
}
|
|
9762
9645
|
function relProjectDir(rootDir, projectPath) {
|
|
9763
|
-
const rel =
|
|
9646
|
+
const rel = path37.isAbsolute(projectPath) ? path37.relative(rootDir, projectPath) : projectPath;
|
|
9764
9647
|
return rel === "" ? "." : rel;
|
|
9765
9648
|
}
|
|
9766
9649
|
async function buildTargetResolver(rootDir, artifact) {
|
|
@@ -10595,7 +10478,7 @@ function formatMarkdown(artifact) {
|
|
|
10595
10478
|
|
|
10596
10479
|
// src/reporting/commands/report.ts
|
|
10597
10480
|
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) => {
|
|
10598
|
-
const artifactPath =
|
|
10481
|
+
const artifactPath = path37.resolve(opts.in);
|
|
10599
10482
|
if (!await pathExists(artifactPath)) {
|
|
10600
10483
|
console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
|
|
10601
10484
|
console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
|
|
@@ -10644,8 +10527,8 @@ function openUrl(url) {
|
|
|
10644
10527
|
// src/reporting/commands/login.ts
|
|
10645
10528
|
var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
10646
10529
|
function isInside(dir, file) {
|
|
10647
|
-
const rel =
|
|
10648
|
-
return !!rel && !rel.startsWith("..") && !
|
|
10530
|
+
const rel = path37.relative(dir, file);
|
|
10531
|
+
return !!rel && !rel.startsWith("..") && !path37.isAbsolute(rel);
|
|
10649
10532
|
}
|
|
10650
10533
|
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(
|
|
10651
10534
|
"--local",
|
|
@@ -10900,7 +10783,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
10900
10783
|
try {
|
|
10901
10784
|
const statements = [];
|
|
10902
10785
|
if (opts.from) {
|
|
10903
|
-
const fromPath =
|
|
10786
|
+
const fromPath = path37.resolve(opts.from);
|
|
10904
10787
|
if (!await pathExists(fromPath)) {
|
|
10905
10788
|
process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
|
|
10906
10789
|
`));
|
|
@@ -10918,9 +10801,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
10918
10801
|
});
|
|
10919
10802
|
const json2 = JSON.stringify(doc, null, 2);
|
|
10920
10803
|
if (opts.out) {
|
|
10921
|
-
await writeTextFile(
|
|
10804
|
+
await writeTextFile(path37.resolve(opts.out), json2 + "\n");
|
|
10922
10805
|
process.stderr.write(
|
|
10923
|
-
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${
|
|
10806
|
+
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path37.resolve(opts.out)}
|
|
10924
10807
|
`
|
|
10925
10808
|
);
|
|
10926
10809
|
} else {
|
|
@@ -11103,7 +10986,7 @@ function formatDeltaText(base, current) {
|
|
|
11103
10986
|
return lines.join("\n");
|
|
11104
10987
|
}
|
|
11105
10988
|
async function readArtifactOrExit(filePath) {
|
|
11106
|
-
const absolutePath =
|
|
10989
|
+
const absolutePath = path37.resolve(filePath);
|
|
11107
10990
|
if (!await pathExists(absolutePath)) {
|
|
11108
10991
|
console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
|
|
11109
10992
|
process.exit(1);
|
|
@@ -11120,7 +11003,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
|
|
|
11120
11003
|
const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
|
|
11121
11004
|
const body = JSON.stringify(sbom, null, 2);
|
|
11122
11005
|
if (opts.out) {
|
|
11123
|
-
await writeTextFile(
|
|
11006
|
+
await writeTextFile(path37.resolve(opts.out), body);
|
|
11124
11007
|
console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
|
|
11125
11008
|
} else {
|
|
11126
11009
|
console.log(body);
|
|
@@ -11131,7 +11014,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
|
|
|
11131
11014
|
const current = await readArtifactOrExit(opts.to);
|
|
11132
11015
|
const report = formatDeltaText(base, current);
|
|
11133
11016
|
if (opts.out) {
|
|
11134
|
-
await writeTextFile(
|
|
11017
|
+
await writeTextFile(path37.resolve(opts.out), report);
|
|
11135
11018
|
console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
|
|
11136
11019
|
} else {
|
|
11137
11020
|
console.log(report);
|
|
@@ -11262,20 +11145,20 @@ function resolveRegime(id) {
|
|
|
11262
11145
|
return regime;
|
|
11263
11146
|
}
|
|
11264
11147
|
function evidenceDir(root2) {
|
|
11265
|
-
return
|
|
11148
|
+
return path37.join(root2, ".vibgrate", "evidence");
|
|
11266
11149
|
}
|
|
11267
11150
|
function orgPath(root2) {
|
|
11268
|
-
return
|
|
11151
|
+
return path37.join(evidenceDir(root2), "org.json");
|
|
11269
11152
|
}
|
|
11270
11153
|
function productsPath(root2) {
|
|
11271
|
-
return
|
|
11154
|
+
return path37.join(evidenceDir(root2), "products.json");
|
|
11272
11155
|
}
|
|
11273
11156
|
function releasesDir(root2) {
|
|
11274
|
-
return
|
|
11157
|
+
return path37.join(evidenceDir(root2), "releases");
|
|
11275
11158
|
}
|
|
11276
11159
|
function releasePath(root2, productId, version) {
|
|
11277
11160
|
const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
11278
|
-
return
|
|
11161
|
+
return path37.join(releasesDir(root2), `${safe}.json`);
|
|
11279
11162
|
}
|
|
11280
11163
|
var DEFAULT_ORG = {
|
|
11281
11164
|
responsiblePersons: [],
|
|
@@ -11306,7 +11189,7 @@ async function freezeRelease(root2, release) {
|
|
|
11306
11189
|
const p = releasePath(root2, release.productId, release.version);
|
|
11307
11190
|
if (await pathExists(p)) {
|
|
11308
11191
|
throw new CliError(
|
|
11309
|
-
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${
|
|
11192
|
+
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path37.relative(root2, p)} only if it was frozen in error`,
|
|
11310
11193
|
ExitCode.USAGE_ERROR
|
|
11311
11194
|
);
|
|
11312
11195
|
}
|
|
@@ -11320,7 +11203,7 @@ async function loadReleases(root2, productId) {
|
|
|
11320
11203
|
const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
11321
11204
|
const releases = [];
|
|
11322
11205
|
for (const f of files) {
|
|
11323
|
-
const rel = await readJsonFile(
|
|
11206
|
+
const rel = await readJsonFile(path37.join(dir, f));
|
|
11324
11207
|
if (!productId || rel.productId === productId) releases.push(rel);
|
|
11325
11208
|
}
|
|
11326
11209
|
return releases;
|
|
@@ -12015,19 +11898,19 @@ function verifyEvidenceEnvelope(env, opts = {}) {
|
|
|
12015
11898
|
var DEFAULT_KEY = "attest-key.pem";
|
|
12016
11899
|
function resolveSigningKey(root2, explicit) {
|
|
12017
11900
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
12018
|
-
const keyPath = chosen ?
|
|
11901
|
+
const keyPath = chosen ? path37.resolve(chosen) : path37.join(root2, ".vibgrate", DEFAULT_KEY);
|
|
12019
11902
|
let minted = false;
|
|
12020
|
-
if (!
|
|
11903
|
+
if (!fs7.existsSync(keyPath)) {
|
|
12021
11904
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
12022
11905
|
const kp = generateKeypair();
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
11906
|
+
fs7.mkdirSync(path37.dirname(keyPath), { recursive: true });
|
|
11907
|
+
fs7.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
11908
|
+
fs7.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
12026
11909
|
minted = true;
|
|
12027
11910
|
}
|
|
12028
11911
|
let key2;
|
|
12029
11912
|
try {
|
|
12030
|
-
key2 = crypto3.createPrivateKey(
|
|
11913
|
+
key2 = crypto3.createPrivateKey(fs7.readFileSync(keyPath, "utf8"));
|
|
12031
11914
|
} catch {
|
|
12032
11915
|
throw new CliError(`could not read an Ed25519 private key from ${keyPath}`, ExitCode.USAGE_ERROR);
|
|
12033
11916
|
}
|
|
@@ -12038,16 +11921,16 @@ function resolveSigningKey(root2, explicit) {
|
|
|
12038
11921
|
}
|
|
12039
11922
|
function writeBundle(input) {
|
|
12040
11923
|
const dir = input.outDir;
|
|
12041
|
-
|
|
12042
|
-
const write = (rel, data) =>
|
|
11924
|
+
fs7.mkdirSync(path37.join(dir, "inputs", "releases"), { recursive: true });
|
|
11925
|
+
const write = (rel, data) => fs7.writeFileSync(path37.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
12043
11926
|
`);
|
|
12044
11927
|
write("result.json", input.result);
|
|
12045
|
-
write(
|
|
11928
|
+
write(path37.join("inputs", "advisory.json"), input.advisory);
|
|
12046
11929
|
for (const rel of input.releases) {
|
|
12047
11930
|
const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
12048
|
-
write(
|
|
11931
|
+
write(path37.join("inputs", "releases", `${safe}.json`), rel);
|
|
12049
11932
|
}
|
|
12050
|
-
write(
|
|
11933
|
+
write(path37.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
|
|
12051
11934
|
write("provenance.json", {
|
|
12052
11935
|
method: "deterministic",
|
|
12053
11936
|
modelDrafted: [],
|
|
@@ -12063,13 +11946,13 @@ function writeBundle(input) {
|
|
|
12063
11946
|
disclaimer: input.regime.disclaimer
|
|
12064
11947
|
});
|
|
12065
11948
|
if (input.envelope) {
|
|
12066
|
-
|
|
11949
|
+
fs7.writeFileSync(path37.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
12067
11950
|
`);
|
|
12068
11951
|
}
|
|
12069
11952
|
if (input.timestampToken) {
|
|
12070
|
-
|
|
11953
|
+
fs7.writeFileSync(path37.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
12071
11954
|
}
|
|
12072
|
-
|
|
11955
|
+
fs7.writeFileSync(path37.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
12073
11956
|
return dir;
|
|
12074
11957
|
}
|
|
12075
11958
|
function verifyDoc(input) {
|
|
@@ -12130,13 +12013,13 @@ function undeterminedFields(result, regime) {
|
|
|
12130
12013
|
return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
|
|
12131
12014
|
}
|
|
12132
12015
|
async function recordDrill(root2, record) {
|
|
12133
|
-
const dir =
|
|
12134
|
-
const p =
|
|
12016
|
+
const dir = path37.join(evidenceDir(root2), "drills");
|
|
12017
|
+
const p = path37.join(dir, `${record.drillId}.json`);
|
|
12135
12018
|
await writeJsonFile(p, record);
|
|
12136
12019
|
return p;
|
|
12137
12020
|
}
|
|
12138
12021
|
async function hasRecentDrill(root2, asOf) {
|
|
12139
|
-
const dir =
|
|
12022
|
+
const dir = path37.join(evidenceDir(root2), "drills");
|
|
12140
12023
|
if (!await pathExists(dir)) return void 0;
|
|
12141
12024
|
const { readdir } = await import('fs/promises');
|
|
12142
12025
|
const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
|
|
@@ -12144,7 +12027,7 @@ async function hasRecentDrill(root2, asOf) {
|
|
|
12144
12027
|
if (files.length === 0) return void 0;
|
|
12145
12028
|
const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
|
|
12146
12029
|
for (const f of files) {
|
|
12147
|
-
const rec = await readJsonFile2(
|
|
12030
|
+
const rec = await readJsonFile2(path37.join(dir, f));
|
|
12148
12031
|
if (rec.ranAt >= cutoff) return true;
|
|
12149
12032
|
}
|
|
12150
12033
|
return false;
|
|
@@ -12224,7 +12107,7 @@ function formatRegimeList() {
|
|
|
12224
12107
|
|
|
12225
12108
|
// src/reporting/commands/evidence/index.ts
|
|
12226
12109
|
function root(opts) {
|
|
12227
|
-
return
|
|
12110
|
+
return path37.resolve(opts.cwd ?? process.cwd());
|
|
12228
12111
|
}
|
|
12229
12112
|
function slug(name) {
|
|
12230
12113
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
|
|
@@ -12312,7 +12195,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
12312
12195
|
const release = await buildRelease({
|
|
12313
12196
|
productId: product.id,
|
|
12314
12197
|
version,
|
|
12315
|
-
from:
|
|
12198
|
+
from: path37.resolve(rootDir, opts.from),
|
|
12316
12199
|
shipDate: opts.shipDate,
|
|
12317
12200
|
buildId: opts.buildId,
|
|
12318
12201
|
artefactDigest: opts.digest,
|
|
@@ -12320,7 +12203,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
12320
12203
|
frozenAt: nowIso()
|
|
12321
12204
|
});
|
|
12322
12205
|
const p = await freezeRelease(rootDir, release);
|
|
12323
|
-
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${
|
|
12206
|
+
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path37.relative(rootDir, p)}`);
|
|
12324
12207
|
});
|
|
12325
12208
|
async function runExposure(rootDir, vuln, opts) {
|
|
12326
12209
|
const org = await loadOrg(rootDir);
|
|
@@ -12372,7 +12255,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
12372
12255
|
console.log("\n" + buildPack(result, regime, org, stage));
|
|
12373
12256
|
}
|
|
12374
12257
|
if (opts.bundle) {
|
|
12375
|
-
const dir =
|
|
12258
|
+
const dir = path37.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
|
|
12376
12259
|
let envelope;
|
|
12377
12260
|
if (opts.sign !== false) {
|
|
12378
12261
|
const { key: key2, minted } = resolveSigningKey(rootDir);
|
|
@@ -12380,7 +12263,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
12380
12263
|
envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
|
|
12381
12264
|
}
|
|
12382
12265
|
writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
|
|
12383
|
-
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${
|
|
12266
|
+
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path37.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
|
|
12384
12267
|
}
|
|
12385
12268
|
process.exitCode = exposureExit(result.overallStatus);
|
|
12386
12269
|
});
|
|
@@ -12412,7 +12295,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
12412
12295
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
12413
12296
|
const md = buildPack(result, regime, org, stage);
|
|
12414
12297
|
if (opts.out) {
|
|
12415
|
-
|
|
12298
|
+
fs7.writeFileSync(path37.resolve(rootDir, opts.out), md);
|
|
12416
12299
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
12417
12300
|
} else {
|
|
12418
12301
|
console.log(md);
|
|
@@ -12454,20 +12337,20 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
12454
12337
|
}
|
|
12455
12338
|
});
|
|
12456
12339
|
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) => {
|
|
12457
|
-
const abs =
|
|
12458
|
-
const envPath =
|
|
12459
|
-
if (!
|
|
12460
|
-
const envelope = JSON.parse(
|
|
12461
|
-
const resultPath =
|
|
12462
|
-
const result =
|
|
12463
|
-
const publicKeyPem = opts.pub ?
|
|
12340
|
+
const abs = path37.resolve(bundlePath);
|
|
12341
|
+
const envPath = fs7.statSync(abs).isDirectory() ? path37.join(abs, "evidence.intoto.jsonl") : abs;
|
|
12342
|
+
if (!fs7.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
12343
|
+
const envelope = JSON.parse(fs7.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
12344
|
+
const resultPath = path37.join(path37.dirname(envPath), "result.json");
|
|
12345
|
+
const result = fs7.existsSync(resultPath) ? JSON.parse(fs7.readFileSync(resultPath, "utf8")) : void 0;
|
|
12346
|
+
const publicKeyPem = opts.pub ? fs7.readFileSync(path37.resolve(opts.pub), "utf8") : void 0;
|
|
12464
12347
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
12465
12348
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
12466
12349
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
12467
12350
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
12468
|
-
const tsrPath =
|
|
12469
|
-
if (
|
|
12470
|
-
const t = verifyTimestamp(
|
|
12351
|
+
const tsrPath = path37.join(path37.dirname(envPath), "timestamp.tsr");
|
|
12352
|
+
if (fs7.existsSync(tsrPath) && result) {
|
|
12353
|
+
const t = verifyTimestamp(fs7.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
12471
12354
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
12472
12355
|
console.log(" " + tcolor("TIMESTAMP") + ` ${t.reason}`);
|
|
12473
12356
|
}
|
|
@@ -12534,12 +12417,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
|
|
|
12534
12417
|
const releases = [];
|
|
12535
12418
|
for (const list of releasesByProduct.values()) releases.push(...list);
|
|
12536
12419
|
const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
|
|
12537
|
-
const dir =
|
|
12538
|
-
await writeJsonFile(
|
|
12539
|
-
await writeJsonFile(
|
|
12540
|
-
for (const r of releases) await writeJsonFile(
|
|
12541
|
-
await writeJsonFile(
|
|
12542
|
-
console.error(chalk7.green("\u2714") + ` exported evidence state to ${
|
|
12420
|
+
const dir = path37.resolve(rootDir, opts.out);
|
|
12421
|
+
await writeJsonFile(path37.join(dir, "org.json"), org);
|
|
12422
|
+
await writeJsonFile(path37.join(dir, "products.json"), products);
|
|
12423
|
+
for (const r of releases) await writeJsonFile(path37.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
|
|
12424
|
+
await writeJsonFile(path37.join(dir, "readiness.json"), report);
|
|
12425
|
+
console.error(chalk7.green("\u2714") + ` exported evidence state to ${path37.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
|
|
12543
12426
|
});
|
|
12544
12427
|
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) => {
|
|
12545
12428
|
const rootDir = root(opts);
|
|
@@ -12565,10 +12448,10 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
12565
12448
|
}));
|
|
12566
12449
|
let exposure;
|
|
12567
12450
|
if (opts.result) {
|
|
12568
|
-
const raw =
|
|
12569
|
-
const resultPath =
|
|
12570
|
-
if (!
|
|
12571
|
-
exposure = JSON.parse(
|
|
12451
|
+
const raw = path37.resolve(rootDir, opts.result);
|
|
12452
|
+
const resultPath = fs7.existsSync(raw) && fs7.statSync(raw).isDirectory() ? path37.join(raw, "result.json") : raw;
|
|
12453
|
+
if (!fs7.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
12454
|
+
exposure = JSON.parse(fs7.readFileSync(resultPath, "utf8"));
|
|
12572
12455
|
}
|
|
12573
12456
|
const payload = { schemaVersion: "evidence-push-1", regime: regime.id, generatedAt: nowIso(), signed: Boolean(opts.signed), products: productPayload, exposure };
|
|
12574
12457
|
const body = JSON.stringify(payload);
|
|
@@ -12758,7 +12641,7 @@ function dispatch(argv, cwd) {
|
|
|
12758
12641
|
}
|
|
12759
12642
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
12760
12643
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
12761
|
-
if (
|
|
12644
|
+
if (fs7.existsSync(path37.resolve(cwd, first))) {
|
|
12762
12645
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
12763
12646
|
}
|
|
12764
12647
|
const moved = MOVED_COMMANDS[first];
|
|
@@ -12803,9 +12686,9 @@ async function main(argv = process.argv) {
|
|
|
12803
12686
|
}
|
|
12804
12687
|
function readCwd(raw) {
|
|
12805
12688
|
const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
|
|
12806
|
-
if (i >= 0 && raw[i + 1]) return
|
|
12689
|
+
if (i >= 0 && raw[i + 1]) return path37.resolve(raw[i + 1]);
|
|
12807
12690
|
const eq = raw.find((a) => a.startsWith("--cwd="));
|
|
12808
|
-
if (eq) return
|
|
12691
|
+
if (eq) return path37.resolve(eq.slice("--cwd=".length));
|
|
12809
12692
|
return process.cwd();
|
|
12810
12693
|
}
|
|
12811
12694
|
function handleError(err) {
|