@vibgrate/cli 2026.727.2 → 2026.727.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +21 -1
- package/README.md +2 -1
- package/dist/baseline-ATM5MXBZ.js +8 -0
- package/dist/{baseline-TG4ATZGZ.js.map → baseline-ATM5MXBZ.js.map} +1 -1
- package/dist/{chunk-CY4WKXB2.js → chunk-2VFWXNS5.js} +3 -3
- package/dist/{chunk-CY4WKXB2.js.map → chunk-2VFWXNS5.js.map} +1 -1
- package/dist/{chunk-LKVMI67M.js → chunk-6JIKUDWM.js} +3 -3
- package/dist/{chunk-LKVMI67M.js.map → chunk-6JIKUDWM.js.map} +1 -1
- package/dist/{chunk-6ABXHZRN.js → chunk-6UK6QPTR.js} +69 -70
- package/dist/chunk-6UK6QPTR.js.map +1 -0
- package/dist/{chunk-TCDAZZNP.js → chunk-77LYGXBI.js} +5 -5
- package/dist/{chunk-TCDAZZNP.js.map → chunk-77LYGXBI.js.map} +1 -1
- package/dist/{chunk-KCKYKDMS.js → chunk-AVQSHIJ5.js} +20 -17
- package/dist/chunk-AVQSHIJ5.js.map +1 -0
- package/dist/{chunk-2XQDMLKB.js → chunk-B3YUO3NW.js} +7 -3
- package/dist/chunk-B3YUO3NW.js.map +1 -0
- package/dist/{chunk-RNP3SMTV.js → chunk-C66GOHYB.js} +8 -8
- package/dist/{chunk-RNP3SMTV.js.map → chunk-C66GOHYB.js.map} +1 -1
- package/dist/{chunk-EX4PQT6W.js → chunk-FFWGT55D.js} +4 -4
- package/dist/{chunk-EX4PQT6W.js.map → chunk-FFWGT55D.js.map} +1 -1
- package/dist/{chunk-6AYDFFP5.js → chunk-HK3AWUXH.js} +3 -3
- package/dist/{chunk-6AYDFFP5.js.map → chunk-HK3AWUXH.js.map} +1 -1
- package/dist/{chunk-KNELIQJO.js → chunk-MAY5HLDH.js} +576 -189
- package/dist/chunk-MAY5HLDH.js.map +1 -0
- package/dist/{chunk-3Q7QBWFW.js → chunk-ON25BX6T.js} +9 -3
- package/dist/chunk-ON25BX6T.js.map +1 -0
- package/dist/{chunk-2MBL43EJ.js → chunk-XPJZTSY7.js} +3 -3
- package/dist/{chunk-2MBL43EJ.js.map → chunk-XPJZTSY7.js.map} +1 -1
- package/dist/{chunk-WGUL45AV.js → chunk-Y23HMSWU.js} +3 -3
- package/dist/{chunk-WGUL45AV.js.map → chunk-Y23HMSWU.js.map} +1 -1
- package/dist/{chunk-J4RFRKZH.js → chunk-Z7GP7XTJ.js} +7 -7
- package/dist/{chunk-J4RFRKZH.js.map → chunk-Z7GP7XTJ.js.map} +1 -1
- package/dist/{chunk-KSBHGWRV.js → chunk-ZBTY6VV4.js} +4 -4
- package/dist/{chunk-KSBHGWRV.js.map → chunk-ZBTY6VV4.js.map} +1 -1
- package/dist/{chunk-K3MZIVZW.js → chunk-ZKNB4YH4.js} +19 -5
- package/dist/chunk-ZKNB4YH4.js.map +1 -0
- package/dist/cli.js +424 -210
- package/dist/cli.js.map +1 -1
- package/dist/{graph-backend-73URGTFY.js → graph-backend-UTOL3SHE.js} +5 -5
- package/dist/{graph-backend-73URGTFY.js.map → graph-backend-UTOL3SHE.js.map} +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js +10 -10
- package/dist/{interactive-372NLI5C.js → interactive-INGJNSON.js} +19 -19
- package/dist/{interactive-372NLI5C.js.map → interactive-INGJNSON.js.map} +1 -1
- package/dist/load-QPOWQD7C.js +8 -0
- package/dist/{load-I333TGNI.js.map → load-QPOWQD7C.js.map} +1 -1
- package/dist/parse-worker.d.ts +1 -1
- package/dist/parse-worker.js +1 -1
- package/dist/{runtime-session-JRKCQUHY.js → runtime-session-4AMZIAAG.js} +7 -7
- package/dist/{runtime-session-JRKCQUHY.js.map → runtime-session-4AMZIAAG.js.map} +1 -1
- package/dist/{session-ITPYQ5XI.js → session-M72522AP.js} +6 -6
- package/dist/{session-ITPYQ5XI.js.map → session-M72522AP.js.map} +1 -1
- package/dist/sql-extract-JELDZA6W.js +81 -0
- package/dist/sql-extract-JELDZA6W.js.map +1 -0
- package/dist/{stream-json-SLMDKLXP.js → stream-json-6ZBUA2L3.js} +9 -9
- package/dist/{stream-json-SLMDKLXP.js.map → stream-json-6ZBUA2L3.js.map} +1 -1
- package/dist/{types-7AHBUbFm.d.ts → types-DLH-Ritr.d.ts} +18 -1
- package/dist/{vgd-7JV5KCNJ.js → vgd-CVLKBS7K.js} +6 -6
- package/dist/vgd-CVLKBS7K.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-TG4ATZGZ.js +0 -8
- package/dist/chunk-2XQDMLKB.js.map +0 -1
- package/dist/chunk-3Q7QBWFW.js.map +0 -1
- package/dist/chunk-6ABXHZRN.js.map +0 -1
- package/dist/chunk-K3MZIVZW.js.map +0 -1
- package/dist/chunk-KCKYKDMS.js.map +0 -1
- package/dist/chunk-KNELIQJO.js.map +0 -1
- package/dist/load-I333TGNI.js +0 -8
- package/dist/vgd-7JV5KCNJ.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
3
|
-
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-
|
|
4
|
-
export { runBuild } from './chunk-
|
|
5
|
-
import {
|
|
2
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-FFWGT55D.js';
|
|
3
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-C66GOHYB.js';
|
|
4
|
+
export { runBuild } from './chunk-C66GOHYB.js';
|
|
5
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-Z7GP7XTJ.js';
|
|
6
|
+
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
7
|
+
import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-77LYGXBI.js';
|
|
6
8
|
import './chunk-5I4VSBWQ.js';
|
|
7
9
|
import './chunk-IS7VTH2Q.js';
|
|
8
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-J4RFRKZH.js';
|
|
9
10
|
import { gatherSystemMemory } from './chunk-6UQMXIAG.js';
|
|
10
11
|
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-3V24O47U.js';
|
|
11
12
|
import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
12
13
|
import './chunk-IZDH67DX.js';
|
|
13
|
-
import './chunk-
|
|
14
|
+
import './chunk-HK3AWUXH.js';
|
|
14
15
|
import { vgdIsRunning, vgdRequest, vgdSocketPath } from './chunk-PMYWZRRS.js';
|
|
15
16
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-PXHNTC6D.js';
|
|
16
17
|
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-K7REHDQS.js';
|
|
17
18
|
import { buildIdentifierTrieFromGraph } from './chunk-JIBOJTGS.js';
|
|
18
19
|
import './chunk-NDMDSPFX.js';
|
|
19
|
-
import { runCodeSession } from './chunk-
|
|
20
|
+
import { runCodeSession } from './chunk-2VFWXNS5.js';
|
|
20
21
|
import { ensurePackage, ensureUnavailableMessage, isPackageInstalled, summarizeDiffs, ScriptedProvider } from './chunk-OFUC6RYN.js';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-
|
|
25
|
-
import {
|
|
22
|
+
import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-AVQSHIJ5.js';
|
|
23
|
+
import { resolveDsn, resolveIngestHost, dashHostForIngestHost, resolveCliInvocation, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, CliError, ExitCode, parseDsn as parseDsn$1, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, NPX_INVOCATION, refreshIfStale, driftCount, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath, SKIP_DIRS, SKIP_FILES } from './chunk-MAY5HLDH.js';
|
|
24
|
+
import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-6JIKUDWM.js';
|
|
25
|
+
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-Y23HMSWU.js';
|
|
26
|
+
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
26
27
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
27
28
|
import { discoverModels, listCachedWeights, isWeightCached, lookupCatalog, ensureWeightCached, catalogIntegrityReport, weightStoreDir } from './chunk-OOIG3RUM.js';
|
|
28
|
-
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-
|
|
29
|
-
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-
|
|
30
|
-
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-
|
|
29
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-ZBTY6VV4.js';
|
|
30
|
+
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-6UK6QPTR.js';
|
|
31
|
+
import { resolvedGrammarFiles, grammarSetVersion } from './chunk-ON25BX6T.js';
|
|
31
32
|
import './chunk-RXP66R2E.js';
|
|
32
|
-
import { resolveGraphPath, renderReport, loadGraph, writeArtifacts, vibgrateDir, SCHEMA_VERSION } from './chunk-
|
|
33
|
-
import { cacheDir, stableStringify } from './chunk-
|
|
33
|
+
import { resolveGraphPath, renderReport, loadGraph, writeArtifacts, vibgrateDir, SCHEMA_VERSION } from './chunk-B3YUO3NW.js';
|
|
34
|
+
import { cacheDir, stableStringify } from './chunk-ZKNB4YH4.js';
|
|
34
35
|
import './chunk-BWPBB45M.js';
|
|
35
36
|
import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
|
|
36
37
|
import './chunk-BPF3YX2U.js';
|
|
37
38
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-GI6W53LM.js';
|
|
38
|
-
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
39
39
|
import './chunk-DGUM43GV.js';
|
|
40
40
|
import * as fs8 from 'fs';
|
|
41
41
|
import fs8__default, { realpathSync } from 'fs';
|
|
42
|
-
import * as
|
|
43
|
-
import
|
|
42
|
+
import * as path37 from 'path';
|
|
43
|
+
import path37__default from 'path';
|
|
44
44
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
45
45
|
import { Command, CommanderError, Option } from 'commander';
|
|
46
46
|
import * as os from 'os';
|
|
@@ -49,7 +49,7 @@ import { randomUUID } from 'crypto';
|
|
|
49
49
|
import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
|
|
50
50
|
import * as readline from 'readline';
|
|
51
51
|
import chalk7 from 'chalk';
|
|
52
|
-
import * as
|
|
52
|
+
import * as fs21 from 'fs/promises';
|
|
53
53
|
import semver2 from 'semver';
|
|
54
54
|
|
|
55
55
|
function registerStatus(program) {
|
|
@@ -59,10 +59,10 @@ function registerStatus(program) {
|
|
|
59
59
|
applyGlobalOptions(cmd);
|
|
60
60
|
}
|
|
61
61
|
async function runStatus(global) {
|
|
62
|
-
const root2 =
|
|
62
|
+
const root2 = path37.resolve(global.cwd ?? ".");
|
|
63
63
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
64
64
|
const graph = loadGraph(root2, graphPath);
|
|
65
|
-
const hasCache = fs8.existsSync(
|
|
65
|
+
const hasCache = fs8.existsSync(path37.join(cacheDir(root2), "parse-cache.json"));
|
|
66
66
|
let stale = null;
|
|
67
67
|
let staleExact = false;
|
|
68
68
|
if (graph) {
|
|
@@ -82,8 +82,8 @@ async function runStatus(global) {
|
|
|
82
82
|
}
|
|
83
83
|
if (global.json) {
|
|
84
84
|
json({
|
|
85
|
-
root:
|
|
86
|
-
graphPath:
|
|
85
|
+
root: path37.relative(process.cwd(), root2) || ".",
|
|
86
|
+
graphPath: path37.relative(root2, graphPath),
|
|
87
87
|
built: graph !== null,
|
|
88
88
|
generatedAt: graph?.generatedAt ?? null,
|
|
89
89
|
counts: graph?.meta.counts ?? null,
|
|
@@ -98,11 +98,11 @@ async function runStatus(global) {
|
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
100
|
if (!graph) {
|
|
101
|
-
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(
|
|
101
|
+
info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path37.relative(root2, graphPath))}`);
|
|
102
102
|
info(` run ${c.bold("vg")} to build one`);
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
|
-
info(`${c.cyan("vg")} \xB7 ${
|
|
105
|
+
info(`${c.cyan("vg")} \xB7 ${path37.relative(root2, graphPath)}`);
|
|
106
106
|
info(` generated ${graph.generatedAt}`);
|
|
107
107
|
info(
|
|
108
108
|
` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
|
|
@@ -119,7 +119,7 @@ async function runStatus(global) {
|
|
|
119
119
|
if (vibgrateDir(root2)) ;
|
|
120
120
|
}
|
|
121
121
|
function rootOf(global) {
|
|
122
|
-
return
|
|
122
|
+
return path37.resolve(global.cwd ?? ".");
|
|
123
123
|
}
|
|
124
124
|
function requireGraph(global) {
|
|
125
125
|
const root2 = rootOf(global);
|
|
@@ -402,6 +402,19 @@ function registerPath(program) {
|
|
|
402
402
|
);
|
|
403
403
|
}
|
|
404
404
|
if (!result) {
|
|
405
|
+
const disc = pathDisconnect(graph, ra.node.id, rb.node.id);
|
|
406
|
+
if (global.json) {
|
|
407
|
+
json(disc);
|
|
408
|
+
throw new CliError(
|
|
409
|
+
`no path between ${ra.node.qualifiedName} and ${rb.node.qualifiedName}`,
|
|
410
|
+
ExitCode.NOT_FOUND
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
info(`${c.cyan("vg path")} \xB7 no path between ${c.bold(disc.from.name)} and ${c.bold(disc.to.name)}`);
|
|
414
|
+
printNeighborhood("from", disc.from);
|
|
415
|
+
printNeighborhood("to", disc.to);
|
|
416
|
+
info(c.dim(` ${disc.hint}`));
|
|
417
|
+
info(c.dim(` try: vg show ${disc.from.name} \xB7 vg impact ${disc.from.name} \xB7 vg show ${disc.to.name}`));
|
|
405
418
|
throw new CliError(
|
|
406
419
|
`no path between ${ra.node.qualifiedName} and ${rb.node.qualifiedName}`,
|
|
407
420
|
ExitCode.NOT_FOUND
|
|
@@ -418,6 +431,14 @@ function registerPath(program) {
|
|
|
418
431
|
});
|
|
419
432
|
applyGlobalOptions(cmd);
|
|
420
433
|
}
|
|
434
|
+
function printNeighborhood(label, n) {
|
|
435
|
+
const parts = [];
|
|
436
|
+
if (n.calls.length) parts.push(`calls ${n.calls.join(", ")}`);
|
|
437
|
+
if (n.calledBy.length) parts.push(`called by ${n.calledBy.join(", ")}`);
|
|
438
|
+
if (n.imports.length) parts.push(`imports ${n.imports.join(", ")}`);
|
|
439
|
+
if (n.importedBy.length) parts.push(`imported by ${n.importedBy.join(", ")}`);
|
|
440
|
+
info(` ${c.dim(label)} ${c.bold(n.name)}${parts.length ? c.dim(` \xB7 ${parts.join(" \xB7 ")}`) : c.dim(" \xB7 (no call/import neighbors)")}`);
|
|
441
|
+
}
|
|
421
442
|
|
|
422
443
|
// src/commands/tree.ts
|
|
423
444
|
function registerTree(program) {
|
|
@@ -531,12 +552,12 @@ function registerInsights(program) {
|
|
|
531
552
|
}
|
|
532
553
|
});
|
|
533
554
|
applyGlobalOptions(areas);
|
|
534
|
-
const oddities = program.command("oddities").description("surprising cross-area links (architectural smells)").option("-n, --limit <n>", "how many to show", "20").action(function(opts) {
|
|
555
|
+
const oddities = program.command("oddities").description("surprising cross-area links (architectural smells)").option("-n, --limit <n>", "how many to show", "20").option("--all", "include framework/runtime externals (default: filter them out)").action(function(opts) {
|
|
535
556
|
const global = readGlobal(this);
|
|
536
557
|
const { graph } = requireGraph(global);
|
|
537
558
|
const limit = Number(opts.limit) || 20;
|
|
538
559
|
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
539
|
-
const list = graph.edges.filter((e) => typeof e.surprise === "number" && e.surprise > 0).sort((a, b) => (b.surprise ?? 0) - (a.surprise ?? 0) || a.id.localeCompare(b.id)).slice(0, limit);
|
|
560
|
+
const list = graph.edges.filter((e) => typeof e.surprise === "number" && e.surprise > 0).filter((e) => opts.all || !isFrameworkOddity(byId.get(e.src), byId.get(e.dst), e.kind)).sort((a, b) => (b.surprise ?? 0) - (a.surprise ?? 0) || a.id.localeCompare(b.id)).slice(0, limit);
|
|
540
561
|
if (global.json) {
|
|
541
562
|
json(
|
|
542
563
|
list.map((e) => ({
|
|
@@ -549,7 +570,9 @@ function registerInsights(program) {
|
|
|
549
570
|
return;
|
|
550
571
|
}
|
|
551
572
|
if (!list.length) {
|
|
552
|
-
info(
|
|
573
|
+
info(
|
|
574
|
+
`${c.cyan("vg oddities")} \xB7 none found` + (opts.all ? " (no cross-area links, or only one area)" : " (no app-level surprises; try --all for framework links)")
|
|
575
|
+
);
|
|
553
576
|
return;
|
|
554
577
|
}
|
|
555
578
|
info(`${c.cyan("vg oddities")} \xB7 top ${list.length} surprising links`);
|
|
@@ -561,6 +584,70 @@ function registerInsights(program) {
|
|
|
561
584
|
});
|
|
562
585
|
applyGlobalOptions(oddities);
|
|
563
586
|
}
|
|
587
|
+
var FRAMEWORK_EXTERNALS = /* @__PURE__ */ new Set([
|
|
588
|
+
"react",
|
|
589
|
+
"react-dom",
|
|
590
|
+
"react-native",
|
|
591
|
+
"vue",
|
|
592
|
+
"vue-router",
|
|
593
|
+
"svelte",
|
|
594
|
+
"svelte/store",
|
|
595
|
+
"next",
|
|
596
|
+
"next/link",
|
|
597
|
+
"next/router",
|
|
598
|
+
"next/navigation",
|
|
599
|
+
"nuxt",
|
|
600
|
+
"angular",
|
|
601
|
+
"@angular/core",
|
|
602
|
+
"@angular/common",
|
|
603
|
+
"preact",
|
|
604
|
+
"solid-js",
|
|
605
|
+
"express",
|
|
606
|
+
"fastify",
|
|
607
|
+
"koa",
|
|
608
|
+
"hono",
|
|
609
|
+
"rxjs",
|
|
610
|
+
"lodash",
|
|
611
|
+
"lodash-es",
|
|
612
|
+
"underscore",
|
|
613
|
+
"jquery",
|
|
614
|
+
"axios",
|
|
615
|
+
"node:fs",
|
|
616
|
+
"node:path",
|
|
617
|
+
"node:url",
|
|
618
|
+
"node:http",
|
|
619
|
+
"node:https",
|
|
620
|
+
"fs",
|
|
621
|
+
"path",
|
|
622
|
+
"url",
|
|
623
|
+
"http",
|
|
624
|
+
"https",
|
|
625
|
+
"crypto",
|
|
626
|
+
"util",
|
|
627
|
+
"stream",
|
|
628
|
+
"events",
|
|
629
|
+
"assert",
|
|
630
|
+
"os",
|
|
631
|
+
"child_process"
|
|
632
|
+
]);
|
|
633
|
+
function isFrameworkOddity(from, to, kind) {
|
|
634
|
+
if (kind !== "import") return false;
|
|
635
|
+
for (const n of [from, to]) {
|
|
636
|
+
if (n?.kind === "external" && isFrameworkName(n.qualifiedName || n.name)) return true;
|
|
637
|
+
}
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
function isFrameworkName(name) {
|
|
641
|
+
if (!name) return false;
|
|
642
|
+
if (FRAMEWORK_EXTERNALS.has(name)) return true;
|
|
643
|
+
const base = name.startsWith("@") ? name.split("/").slice(0, 2).join("/") : name.split("/")[0];
|
|
644
|
+
if (FRAMEWORK_EXTERNALS.has(base)) return true;
|
|
645
|
+
if (base.startsWith("react-") || base.startsWith("@types/react")) return true;
|
|
646
|
+
if (base.startsWith("@vue/") || base.startsWith("@angular/") || base.startsWith("@sveltejs/")) {
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
564
651
|
function nodeSummary(n) {
|
|
565
652
|
return {
|
|
566
653
|
id: n.id,
|
|
@@ -743,8 +830,8 @@ function pad2(s, n) {
|
|
|
743
830
|
}
|
|
744
831
|
var SCHEMA_VERSION2 = "1";
|
|
745
832
|
var OFFSET_FILE = "stats-share.json";
|
|
746
|
-
var INSTALL_ID_DIR =
|
|
747
|
-
var INSTALL_ID_FILE =
|
|
833
|
+
var INSTALL_ID_DIR = path37.join(os.homedir(), ".vibgrate");
|
|
834
|
+
var INSTALL_ID_FILE = path37.join(INSTALL_ID_DIR, "install-id");
|
|
748
835
|
var SEND_TIMEOUT_MS = 4e3;
|
|
749
836
|
function telemetryOptOut(env = process.env) {
|
|
750
837
|
const dnt = (env.DO_NOT_TRACK ?? "").trim().toLowerCase();
|
|
@@ -796,10 +883,10 @@ function statsEndpoint() {
|
|
|
796
883
|
return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;
|
|
797
884
|
}
|
|
798
885
|
function offsetPath(root2) {
|
|
799
|
-
return
|
|
886
|
+
return path37.join(cacheDir(root2), OFFSET_FILE);
|
|
800
887
|
}
|
|
801
888
|
function ledgerFilePath(root2) {
|
|
802
|
-
return
|
|
889
|
+
return path37.join(cacheDir(root2), "savings.jsonl");
|
|
803
890
|
}
|
|
804
891
|
function readOffset(root2) {
|
|
805
892
|
try {
|
|
@@ -970,7 +1057,7 @@ var PUBLISH_INTERVAL_MS = 2e3;
|
|
|
970
1057
|
var KEEPALIVE_MS = 1e4;
|
|
971
1058
|
var STALE_MS = 6e4;
|
|
972
1059
|
function liveStatsDir(root2) {
|
|
973
|
-
return
|
|
1060
|
+
return path37.join(cacheDir(root2), "serve-live");
|
|
974
1061
|
}
|
|
975
1062
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
976
1063
|
let entries;
|
|
@@ -984,7 +1071,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
984
1071
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
985
1072
|
let parsed;
|
|
986
1073
|
try {
|
|
987
|
-
parsed = JSON.parse(fs8.readFileSync(
|
|
1074
|
+
parsed = JSON.parse(fs8.readFileSync(path37.join(dir, name), "utf8"));
|
|
988
1075
|
} catch {
|
|
989
1076
|
continue;
|
|
990
1077
|
}
|
|
@@ -1006,7 +1093,7 @@ var LiveStatsBus = class {
|
|
|
1006
1093
|
this.dir = dir;
|
|
1007
1094
|
this.stats = stats;
|
|
1008
1095
|
this.pid = pid;
|
|
1009
|
-
this.file =
|
|
1096
|
+
this.file = path37.join(dir, `serve-${this.pid}.json`);
|
|
1010
1097
|
}
|
|
1011
1098
|
dir;
|
|
1012
1099
|
stats;
|
|
@@ -1059,7 +1146,7 @@ var LiveStatsBus = class {
|
|
|
1059
1146
|
const out2 = [];
|
|
1060
1147
|
for (const name of entries.sort()) {
|
|
1061
1148
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1062
|
-
const file =
|
|
1149
|
+
const file = path37.join(this.dir, name);
|
|
1063
1150
|
let parsed;
|
|
1064
1151
|
try {
|
|
1065
1152
|
parsed = JSON.parse(fs8.readFileSync(file, "utf8"));
|
|
@@ -1487,8 +1574,8 @@ function registerServe(program) {
|
|
|
1487
1574
|
await serveHttp(graphPath, opts.host ?? "127.0.0.1", Number(opts.port) || 7437, serveOpts, freshness, () => display?.start());
|
|
1488
1575
|
} else {
|
|
1489
1576
|
info(c.dim(`vg \xB7 MCP server on stdio (read-only, ${freshness}). Connect your assistant to this process.`));
|
|
1490
|
-
await serveStdio(graphPath, serveOpts);
|
|
1491
1577
|
display?.start();
|
|
1578
|
+
await serveStdio(graphPath, serveOpts);
|
|
1492
1579
|
}
|
|
1493
1580
|
});
|
|
1494
1581
|
applyGlobalOptions(cmd);
|
|
@@ -1503,13 +1590,22 @@ async function ensureServableGraph(root2, graphPath, global, refresh, opts = {})
|
|
|
1503
1590
|
{ ...global, json: false }
|
|
1504
1591
|
);
|
|
1505
1592
|
} else {
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1593
|
+
const kick = refreshIfStale(root2, { inline: opts.inline, graphPath }).then((refreshed) => {
|
|
1594
|
+
if (refreshed.status === "refreshed") {
|
|
1595
|
+
const n = driftCount(refreshed.drift);
|
|
1596
|
+
info(
|
|
1597
|
+
c.dim(
|
|
1598
|
+
`vg \xB7 map refreshed in background \u2014 ${n} file(s) drifted (${(refreshed.ms / 1e3).toFixed(2)}s)`
|
|
1599
|
+
)
|
|
1600
|
+
);
|
|
1601
|
+
} else if (refreshed.status === "error") {
|
|
1602
|
+
info(c.yellow(`vg \xB7 map refresh failed (${refreshed.message}) \u2014 serving the last built map`));
|
|
1603
|
+
}
|
|
1604
|
+
}).catch((err) => {
|
|
1605
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1606
|
+
info(c.yellow(`vg \xB7 map refresh failed (${msg}) \u2014 serving the last built map`));
|
|
1607
|
+
});
|
|
1608
|
+
if (opts.awaitStaleRefresh) await kick;
|
|
1513
1609
|
}
|
|
1514
1610
|
}
|
|
1515
1611
|
if (!fs8.existsSync(graphPath)) {
|
|
@@ -1574,7 +1670,7 @@ async function serveHttp(graphPath, host, port, opts, freshness, onReady) {
|
|
|
1574
1670
|
info(c.red(`vg serve: request error: ${err.message}`));
|
|
1575
1671
|
}
|
|
1576
1672
|
});
|
|
1577
|
-
await new Promise((
|
|
1673
|
+
await new Promise((resolve20) => httpServer.listen(port, host, resolve20));
|
|
1578
1674
|
info(c.dim(`vg \xB7 MCP server on http://${host}:${port}/mcp (read-only, local, ${freshness})`));
|
|
1579
1675
|
onReady?.();
|
|
1580
1676
|
await new Promise(() => {
|
|
@@ -1788,7 +1884,7 @@ function endOfLine(text, line) {
|
|
|
1788
1884
|
}
|
|
1789
1885
|
var CACHE_VERSION = "vg-lsp-scan-cache/2";
|
|
1790
1886
|
function cachePath(root2) {
|
|
1791
|
-
return
|
|
1887
|
+
return path37.join(cacheDir(root2), "lsp-scan.json");
|
|
1792
1888
|
}
|
|
1793
1889
|
function manifestHash(root2) {
|
|
1794
1890
|
const files = [];
|
|
@@ -1800,7 +1896,7 @@ function manifestHash(root2) {
|
|
|
1800
1896
|
return;
|
|
1801
1897
|
}
|
|
1802
1898
|
for (const entry of entries) {
|
|
1803
|
-
const abs =
|
|
1899
|
+
const abs = path37.join(dir, entry.name);
|
|
1804
1900
|
if (entry.isDirectory()) {
|
|
1805
1901
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
1806
1902
|
walk2(abs);
|
|
@@ -1810,7 +1906,7 @@ function manifestHash(root2) {
|
|
|
1810
1906
|
const base = entry.name.toLowerCase();
|
|
1811
1907
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1812
1908
|
try {
|
|
1813
|
-
const rel =
|
|
1909
|
+
const rel = path37.relative(root2, abs).split(path37.sep).join("/");
|
|
1814
1910
|
files.push({ rel, hash: hashBytes(fs8.readFileSync(abs)) });
|
|
1815
1911
|
} catch {
|
|
1816
1912
|
}
|
|
@@ -2456,12 +2552,12 @@ function uriToPath(uri) {
|
|
|
2456
2552
|
}
|
|
2457
2553
|
}
|
|
2458
2554
|
function projectForFile(root2, a, filePath) {
|
|
2459
|
-
const dir =
|
|
2555
|
+
const dir = path37.dirname(path37.resolve(filePath));
|
|
2460
2556
|
let best;
|
|
2461
2557
|
let bestLen = -1;
|
|
2462
2558
|
for (const proj of a.projects ?? []) {
|
|
2463
|
-
const projDir =
|
|
2464
|
-
if ((dir === projDir || dir.startsWith(projDir +
|
|
2559
|
+
const projDir = path37.resolve(root2, proj.path);
|
|
2560
|
+
if ((dir === projDir || dir.startsWith(projDir + path37.sep)) && projDir.length > bestLen) {
|
|
2465
2561
|
best = proj;
|
|
2466
2562
|
bestLen = projDir.length;
|
|
2467
2563
|
}
|
|
@@ -2469,7 +2565,7 @@ function projectForFile(root2, a, filePath) {
|
|
|
2469
2565
|
return best;
|
|
2470
2566
|
}
|
|
2471
2567
|
function sameProject(location, projectPath) {
|
|
2472
|
-
return
|
|
2568
|
+
return path37.normalize(location) === path37.normalize(projectPath);
|
|
2473
2569
|
}
|
|
2474
2570
|
function hasReleaseDates(a) {
|
|
2475
2571
|
for (const proj of a.projects ?? []) {
|
|
@@ -2795,7 +2891,7 @@ function registerShare(program) {
|
|
|
2795
2891
|
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) {
|
|
2796
2892
|
const global = readGlobal(this);
|
|
2797
2893
|
const root2 = rootOf(global);
|
|
2798
|
-
const gitDir =
|
|
2894
|
+
const gitDir = path37.join(root2, ".git");
|
|
2799
2895
|
if (!fs8.existsSync(gitDir)) {
|
|
2800
2896
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
2801
2897
|
}
|
|
@@ -2817,15 +2913,15 @@ function registerShare(program) {
|
|
|
2817
2913
|
applyGlobalOptions(cmd);
|
|
2818
2914
|
}
|
|
2819
2915
|
function writeVibgrateGitignore(root2, reports) {
|
|
2820
|
-
const dir =
|
|
2916
|
+
const dir = path37.join(root2, ".vibgrate");
|
|
2821
2917
|
fs8.mkdirSync(dir, { recursive: true });
|
|
2822
2918
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl"];
|
|
2823
2919
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
2824
|
-
fs8.writeFileSync(
|
|
2920
|
+
fs8.writeFileSync(path37.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
2825
2921
|
`);
|
|
2826
2922
|
}
|
|
2827
2923
|
function writeGitAttributes(root2) {
|
|
2828
|
-
const file =
|
|
2924
|
+
const file = path37.join(root2, ".gitattributes");
|
|
2829
2925
|
const line = ".vibgrate/graph.json merge=vg";
|
|
2830
2926
|
let content = fs8.existsSync(file) ? fs8.readFileSync(file, "utf8") : "";
|
|
2831
2927
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
@@ -2843,7 +2939,7 @@ function configureMergeDriver(root2) {
|
|
|
2843
2939
|
function installPreCommitHook(root2) {
|
|
2844
2940
|
const hooksDir = hookDir(root2);
|
|
2845
2941
|
fs8.mkdirSync(hooksDir, { recursive: true });
|
|
2846
|
-
const file =
|
|
2942
|
+
const file = path37.join(hooksDir, "pre-commit");
|
|
2847
2943
|
const block = [
|
|
2848
2944
|
HOOK_BEGIN,
|
|
2849
2945
|
"if command -v vg >/dev/null 2>&1; then",
|
|
@@ -2865,14 +2961,14 @@ ${content}`;
|
|
|
2865
2961
|
fs8.chmodSync(file, 493);
|
|
2866
2962
|
}
|
|
2867
2963
|
function undo(root2) {
|
|
2868
|
-
const hookFile =
|
|
2964
|
+
const hookFile = path37.join(hookDir(root2), "pre-commit");
|
|
2869
2965
|
if (fs8.existsSync(hookFile)) {
|
|
2870
2966
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
2871
2967
|
const next2 = fs8.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
2872
2968
|
if (next2.trim() === "#!/bin/sh") fs8.rmSync(hookFile);
|
|
2873
2969
|
else fs8.writeFileSync(hookFile, next2);
|
|
2874
2970
|
}
|
|
2875
|
-
const attr =
|
|
2971
|
+
const attr = path37.join(root2, ".gitattributes");
|
|
2876
2972
|
if (fs8.existsSync(attr)) {
|
|
2877
2973
|
const next2 = fs8.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
2878
2974
|
fs8.writeFileSync(attr, next2);
|
|
@@ -2885,10 +2981,10 @@ function undo(root2) {
|
|
|
2885
2981
|
function hookDir(root2) {
|
|
2886
2982
|
try {
|
|
2887
2983
|
const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
|
|
2888
|
-
if (configured) return
|
|
2984
|
+
if (configured) return path37.resolve(root2, configured);
|
|
2889
2985
|
} catch {
|
|
2890
2986
|
}
|
|
2891
|
-
return
|
|
2987
|
+
return path37.join(root2, ".git", "hooks");
|
|
2892
2988
|
}
|
|
2893
2989
|
function git(root2, args) {
|
|
2894
2990
|
return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
|
|
@@ -2896,6 +2992,111 @@ function git(root2, args) {
|
|
|
2896
2992
|
function escapeRe(s) {
|
|
2897
2993
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2898
2994
|
}
|
|
2995
|
+
var DEFAULT_DEBOUNCE_MS = 400;
|
|
2996
|
+
var SKIP_NAME = /* @__PURE__ */ new Set([
|
|
2997
|
+
".git",
|
|
2998
|
+
"node_modules",
|
|
2999
|
+
".vibgrate",
|
|
3000
|
+
"dist",
|
|
3001
|
+
"build",
|
|
3002
|
+
"out",
|
|
3003
|
+
"coverage",
|
|
3004
|
+
".next",
|
|
3005
|
+
"target",
|
|
3006
|
+
"__pycache__",
|
|
3007
|
+
".venv",
|
|
3008
|
+
"venv"
|
|
3009
|
+
]);
|
|
3010
|
+
function registerWatch(program) {
|
|
3011
|
+
const cmd = program.command("watch").description("rebuild the code map when files change (debounced)").argument("[paths...]", "folders to watch (default: current folder)").option("--debounce <ms>", "settle time after a change before rebuild", String(DEFAULT_DEBOUNCE_MS)).option("--no-html", "do not write graph.html on each rebuild").option("--no-report", "do not write GRAPH_REPORT.md on each rebuild").option("--fast", "skip precise tsc resolve on rebuilds (heuristic only)").action(async function(paths, opts) {
|
|
3012
|
+
const global = readGlobal(this);
|
|
3013
|
+
const root2 = rootOf(global);
|
|
3014
|
+
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
3015
|
+
const watchRoots = (paths.length ? paths : ["."]).map((p) => path37.resolve(root2, p));
|
|
3016
|
+
for (const w of watchRoots) {
|
|
3017
|
+
if (!fs8.existsSync(w)) {
|
|
3018
|
+
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
let building = false;
|
|
3022
|
+
let pending = false;
|
|
3023
|
+
let timer = null;
|
|
3024
|
+
const rebuild = async (reason) => {
|
|
3025
|
+
if (building) {
|
|
3026
|
+
pending = true;
|
|
3027
|
+
return;
|
|
3028
|
+
}
|
|
3029
|
+
building = true;
|
|
3030
|
+
try {
|
|
3031
|
+
info(c.dim(`vg watch \xB7 rebuild (${reason})`));
|
|
3032
|
+
const result = await buildGraph({
|
|
3033
|
+
root: root2,
|
|
3034
|
+
paths: paths.length ? paths : void 0,
|
|
3035
|
+
fast: opts.fast === true,
|
|
3036
|
+
noGround: false
|
|
3037
|
+
});
|
|
3038
|
+
writeArtifacts(result.graph, {
|
|
3039
|
+
root: root2,
|
|
3040
|
+
html: opts.html !== false,
|
|
3041
|
+
report: opts.report !== false,
|
|
3042
|
+
graphPath: global.graph
|
|
3043
|
+
});
|
|
3044
|
+
writeSnapshot(root2, result.graph.provenance.corpusHash, result.fileStats);
|
|
3045
|
+
const { counts } = result.graph.meta;
|
|
3046
|
+
info(
|
|
3047
|
+
`${c.cyan("vg watch")} \xB7 ${counts.nodes} nodes \xB7 ${counts.edges} edges \xB7 ${(result.timing.totalMs / 1e3).toFixed(2)}s` + (result.statHits ? c.dim(` \xB7 ${result.statHits} mtime hits`) : "")
|
|
3048
|
+
);
|
|
3049
|
+
} catch (err) {
|
|
3050
|
+
info(c.yellow(`vg watch \xB7 rebuild failed: ${err.message}`));
|
|
3051
|
+
} finally {
|
|
3052
|
+
building = false;
|
|
3053
|
+
if (pending) {
|
|
3054
|
+
pending = false;
|
|
3055
|
+
void rebuild("queued changes");
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
const schedule = (label) => {
|
|
3060
|
+
if (timer) clearTimeout(timer);
|
|
3061
|
+
timer = setTimeout(() => {
|
|
3062
|
+
timer = null;
|
|
3063
|
+
void rebuild(label);
|
|
3064
|
+
}, debounceMs);
|
|
3065
|
+
};
|
|
3066
|
+
await rebuild("initial");
|
|
3067
|
+
const watchers = [];
|
|
3068
|
+
for (const w of watchRoots) {
|
|
3069
|
+
try {
|
|
3070
|
+
const watcher = fs8.watch(w, { recursive: true }, (_event, filename) => {
|
|
3071
|
+
if (!filename) {
|
|
3072
|
+
schedule("change");
|
|
3073
|
+
return;
|
|
3074
|
+
}
|
|
3075
|
+
const parts = filename.split(path37.sep);
|
|
3076
|
+
if (parts.some((p) => SKIP_NAME.has(p))) return;
|
|
3077
|
+
if (filename.includes(`${path37.sep}.vibgrate${path37.sep}`) || filename.startsWith(".vibgrate")) {
|
|
3078
|
+
return;
|
|
3079
|
+
}
|
|
3080
|
+
schedule(filename);
|
|
3081
|
+
});
|
|
3082
|
+
watchers.push(watcher);
|
|
3083
|
+
} catch (err) {
|
|
3084
|
+
throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path37.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
|
|
3088
|
+
await new Promise((resolve20) => {
|
|
3089
|
+
const stop = () => {
|
|
3090
|
+
for (const w of watchers) w.close();
|
|
3091
|
+
if (timer) clearTimeout(timer);
|
|
3092
|
+
resolve20();
|
|
3093
|
+
};
|
|
3094
|
+
process.once("SIGINT", stop);
|
|
3095
|
+
process.once("SIGTERM", stop);
|
|
3096
|
+
});
|
|
3097
|
+
});
|
|
3098
|
+
applyGlobalOptions(cmd);
|
|
3099
|
+
}
|
|
2899
3100
|
function registerTests(program) {
|
|
2900
3101
|
const cmd = program.command("tests").description("which tests cover a node (call/coverage linkage)").argument("<name>", "node to inspect").option("--missing", "show untested nodes nearby instead").option("--run", "print the command to run exactly these tests").option("--exec", "run that command").option("--pick <n>", "pick the nth candidate when ambiguous").action(function(name, opts) {
|
|
2901
3102
|
const global = readGlobal(this);
|
|
@@ -2951,8 +3152,17 @@ function registerFacts(program) {
|
|
|
2951
3152
|
const { node: node2, candidates } = resolveOne(graph, name, opts.pick ? Number(opts.pick) : void 0);
|
|
2952
3153
|
if (!node2) throw ambiguityError(`"${name}" ${candidates.length ? "is ambiguous" : "not found"}`, candidates);
|
|
2953
3154
|
if (!graph.facts) {
|
|
2954
|
-
if (global.json)
|
|
2955
|
-
|
|
3155
|
+
if (global.json) {
|
|
3156
|
+
json({
|
|
3157
|
+
node: node2.qualifiedName,
|
|
3158
|
+
facts: [],
|
|
3159
|
+
note: "map has no facts \u2014 rebuild with a current vg (facts ship on every build)"
|
|
3160
|
+
});
|
|
3161
|
+
} else {
|
|
3162
|
+
info(
|
|
3163
|
+
`${c.cyan("vg facts")} \xB7 none in this map \u2014 rebuild with ${c.bold("vg")} (facts ship on every build)`
|
|
3164
|
+
);
|
|
3165
|
+
}
|
|
2956
3166
|
return;
|
|
2957
3167
|
}
|
|
2958
3168
|
const facts = graph.facts.filter((f) => f.subjectIds.includes(node2.id));
|
|
@@ -3207,7 +3417,7 @@ function normalizeStandards(raw) {
|
|
|
3207
3417
|
}
|
|
3208
3418
|
function loadStandards(root2) {
|
|
3209
3419
|
for (const rel of STANDARDS_FILES) {
|
|
3210
|
-
const p =
|
|
3420
|
+
const p = path37__default.join(root2, rel);
|
|
3211
3421
|
let text;
|
|
3212
3422
|
try {
|
|
3213
3423
|
text = fs8__default.readFileSync(p, "utf8");
|
|
@@ -4083,8 +4293,8 @@ async function runHostBench(options = {}) {
|
|
|
4083
4293
|
}
|
|
4084
4294
|
async function runArmSimulate(input) {
|
|
4085
4295
|
const { arm, lib, modelPath, turns, trie, env, live } = input;
|
|
4086
|
-
const
|
|
4087
|
-
const session = await acquireHostSession(lib,
|
|
4296
|
+
const path39 = `${modelPath}#${arm.id}`;
|
|
4297
|
+
const session = await acquireHostSession(lib, path39);
|
|
4088
4298
|
const system = "You are a coding agent with a Task Capsule.";
|
|
4089
4299
|
const capsule = "function readConfig(): Config { return load(); }";
|
|
4090
4300
|
let last = null;
|
|
@@ -5026,7 +5236,7 @@ function registerModels(program) {
|
|
|
5026
5236
|
);
|
|
5027
5237
|
});
|
|
5028
5238
|
applyGlobalOptions(modeCmd);
|
|
5029
|
-
const
|
|
5239
|
+
const resolve20 = cmd.command("resolve").description("resolve a Code Mode to pack + underlying model + fit (no download)").argument("[mode]", "spark | flow | forge (default: auto-fit or configured default)").action(function(modeArg) {
|
|
5030
5240
|
const global = readGlobal(this);
|
|
5031
5241
|
const root2 = rootOf(global);
|
|
5032
5242
|
const sys = gatherSystemMemory();
|
|
@@ -5058,7 +5268,7 @@ function registerModels(program) {
|
|
|
5058
5268
|
info(c.yellow(" will not fit \u2014 choose a lower mode or free memory before loading"));
|
|
5059
5269
|
}
|
|
5060
5270
|
});
|
|
5061
|
-
applyGlobalOptions(
|
|
5271
|
+
applyGlobalOptions(resolve20);
|
|
5062
5272
|
const installCmd = cmd.command("install").description("resolve the best Code Mode for this machine and install the pack").argument("[mode]", "spark | flow | forge (default: auto-fit)").option("--dry-run", "print the install plan only \u2014 do not download").option("--yes", "skip prompts (install already runs by default)").action(async function(modeArg, opts) {
|
|
5063
5273
|
const global = readGlobal(this);
|
|
5064
5274
|
const root2 = rootOf(global);
|
|
@@ -5396,8 +5606,8 @@ function registerModels(program) {
|
|
|
5396
5606
|
}
|
|
5397
5607
|
});
|
|
5398
5608
|
if (opts.out) {
|
|
5399
|
-
const outPath =
|
|
5400
|
-
fs8.mkdirSync(
|
|
5609
|
+
const outPath = path37.resolve(opts.out);
|
|
5610
|
+
fs8.mkdirSync(path37.dirname(outPath), { recursive: true });
|
|
5401
5611
|
fs8.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
5402
5612
|
`);
|
|
5403
5613
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
@@ -5508,11 +5718,11 @@ function fitColor(label) {
|
|
|
5508
5718
|
return label;
|
|
5509
5719
|
}
|
|
5510
5720
|
function confirmYesNo(question) {
|
|
5511
|
-
return new Promise((
|
|
5721
|
+
return new Promise((resolve20) => {
|
|
5512
5722
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
5513
5723
|
rl.question(`${question} [y/N] `, (answer) => {
|
|
5514
5724
|
rl.close();
|
|
5515
|
-
|
|
5725
|
+
resolve20(/^y(es)?$/i.test(answer.trim()));
|
|
5516
5726
|
});
|
|
5517
5727
|
});
|
|
5518
5728
|
}
|
|
@@ -5538,7 +5748,7 @@ function printBackends(backends) {
|
|
|
5538
5748
|
}
|
|
5539
5749
|
}
|
|
5540
5750
|
function codeConfigPath(root2) {
|
|
5541
|
-
return
|
|
5751
|
+
return path37.join(root2, ".vibgrate", "code.json");
|
|
5542
5752
|
}
|
|
5543
5753
|
function loadCodeConfig(root2) {
|
|
5544
5754
|
try {
|
|
@@ -5620,7 +5830,7 @@ function discoverMcpServers(root2, ownServers) {
|
|
|
5620
5830
|
const servers = {};
|
|
5621
5831
|
const sources = [];
|
|
5622
5832
|
for (const rel of MCP_CONFIG_FILES) {
|
|
5623
|
-
const found = readMcpServersFile(
|
|
5833
|
+
const found = readMcpServersFile(path37.join(root2, rel));
|
|
5624
5834
|
const names = Object.keys(found);
|
|
5625
5835
|
if (names.length) {
|
|
5626
5836
|
sources.push(rel);
|
|
@@ -5647,7 +5857,7 @@ function registerCode(program) {
|
|
|
5647
5857
|
try {
|
|
5648
5858
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2, providerForBackend: providerForBackend2 } = await import('./model-orchestrator-TVONAUPS.js');
|
|
5649
5859
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-5O2NN3GA.js');
|
|
5650
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
5860
|
+
const { loadGraph: loadGraph2 } = await import('./load-QPOWQD7C.js');
|
|
5651
5861
|
const state = readOrchestratorState2();
|
|
5652
5862
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
5653
5863
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -5731,7 +5941,7 @@ function registerCode(program) {
|
|
|
5731
5941
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
5732
5942
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
5733
5943
|
}
|
|
5734
|
-
const { runInteractive } = await import('./interactive-
|
|
5944
|
+
const { runInteractive } = await import('./interactive-INGJNSON.js');
|
|
5735
5945
|
await runInteractive(
|
|
5736
5946
|
rootOf(global),
|
|
5737
5947
|
global,
|
|
@@ -5785,18 +5995,18 @@ function registerCode(program) {
|
|
|
5785
5995
|
}
|
|
5786
5996
|
if (opts.streamJson && !opts.mock) {
|
|
5787
5997
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
5788
|
-
const { runCodeStreamJson } = await import('./stream-json-
|
|
5789
|
-
const { nodeCodeFs } = await import('./session-
|
|
5998
|
+
const { runCodeStreamJson } = await import('./stream-json-6ZBUA2L3.js');
|
|
5999
|
+
const { nodeCodeFs } = await import('./session-M72522AP.js');
|
|
5790
6000
|
const readline5 = await import('readline');
|
|
5791
6001
|
const child = await import('child_process');
|
|
5792
6002
|
const { loadOrDiscoverFederation } = await import('./federation-SZWZIFZ7.js');
|
|
5793
6003
|
const { resolveExecutionEnv } = await import('./execution-env-ZU45JZ4G.js');
|
|
5794
6004
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-TFBKCNJG.js');
|
|
5795
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
5796
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
6005
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-4AMZIAAG.js');
|
|
6006
|
+
const { resolveGraphBackend } = await import('./graph-backend-UTOL3SHE.js');
|
|
5797
6007
|
const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
|
|
5798
6008
|
const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
|
|
5799
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6009
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-CVLKBS7K.js');
|
|
5800
6010
|
const federation = loadOrDiscoverFederation(root2);
|
|
5801
6011
|
const modelProfile = mergeModelExecutionProfile(
|
|
5802
6012
|
resolveModelExecutionProfile({
|
|
@@ -5885,8 +6095,8 @@ ${res.stderr}` : ""), exitCode: res.status ?? 1 };
|
|
|
5885
6095
|
if (!autonomous && !tty) {
|
|
5886
6096
|
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).");
|
|
5887
6097
|
}
|
|
5888
|
-
const { agentTask } = await import('./interactive-
|
|
5889
|
-
const { nodeCodeFs } = await import('./session-
|
|
6098
|
+
const { agentTask } = await import('./interactive-INGJNSON.js');
|
|
6099
|
+
const { nodeCodeFs } = await import('./session-M72522AP.js');
|
|
5890
6100
|
const { TtyPrompter } = await import('./ui-Q6DJ3GCU.js');
|
|
5891
6101
|
let priorSummary;
|
|
5892
6102
|
if (opts.continue) {
|
|
@@ -5908,11 +6118,11 @@ ${res.stderr}` : ""), exitCode: res.status ?? 1 };
|
|
|
5908
6118
|
const { loadFederation } = await import('./federation-SZWZIFZ7.js');
|
|
5909
6119
|
const { resolveExecutionEnv } = await import('./execution-env-ZU45JZ4G.js');
|
|
5910
6120
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-TFBKCNJG.js');
|
|
5911
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
5912
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
6121
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-4AMZIAAG.js');
|
|
6122
|
+
const { resolveGraphBackend } = await import('./graph-backend-UTOL3SHE.js');
|
|
5913
6123
|
const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
|
|
5914
6124
|
const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
|
|
5915
|
-
const { vgdRequest: vgdRequest2 } = await import('./vgd-
|
|
6125
|
+
const { vgdRequest: vgdRequest2 } = await import('./vgd-CVLKBS7K.js');
|
|
5916
6126
|
const federation = loadFederation(root2);
|
|
5917
6127
|
const modelProfile = mergeModelExecutionProfile(
|
|
5918
6128
|
resolveModelExecutionProfile({
|
|
@@ -6056,11 +6266,11 @@ function resolveSecurityTierFlag(flag, fromConfig, auto) {
|
|
|
6056
6266
|
return auto ? "L1" : "L0";
|
|
6057
6267
|
}
|
|
6058
6268
|
function confirm(question) {
|
|
6059
|
-
return new Promise((
|
|
6269
|
+
return new Promise((resolve20) => {
|
|
6060
6270
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
6061
6271
|
rl.question(`${question} [y/N] `, (answer) => {
|
|
6062
6272
|
rl.close();
|
|
6063
|
-
|
|
6273
|
+
resolve20(/^y(es)?$/i.test(answer.trim()));
|
|
6064
6274
|
});
|
|
6065
6275
|
});
|
|
6066
6276
|
}
|
|
@@ -6217,7 +6427,7 @@ async function addCmd(root2, rest, opts, asJson) {
|
|
|
6217
6427
|
}
|
|
6218
6428
|
function readPackageVersion(root2) {
|
|
6219
6429
|
try {
|
|
6220
|
-
const pkg = JSON.parse(fs8__default.readFileSync(
|
|
6430
|
+
const pkg = JSON.parse(fs8__default.readFileSync(path37__default.join(root2, "package.json"), "utf8"));
|
|
6221
6431
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
6222
6432
|
} catch {
|
|
6223
6433
|
return void 0;
|
|
@@ -6240,8 +6450,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
|
|
|
6240
6450
|
if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
|
|
6241
6451
|
const version = (opts.version || readPackageVersion(root2) || "").trim();
|
|
6242
6452
|
if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
|
|
6243
|
-
const readme = readOptionalFile(opts.readme ?
|
|
6244
|
-
const dts = opts.dts ? readOptionalFile(
|
|
6453
|
+
const readme = readOptionalFile(opts.readme ? path37__default.resolve(opts.readme) : path37__default.join(root2, "README.md"));
|
|
6454
|
+
const dts = opts.dts ? readOptionalFile(path37__default.resolve(opts.dts)) : void 0;
|
|
6245
6455
|
if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
|
|
6246
6456
|
const result = await publishPrivateLibrary(
|
|
6247
6457
|
{ name, version, readme, dts, language: opts.language },
|
|
@@ -6354,7 +6564,7 @@ async function showCmd(root2, name, budget, asJson, opts = {}) {
|
|
|
6354
6564
|
out(doc);
|
|
6355
6565
|
}
|
|
6356
6566
|
function registerExport(program) {
|
|
6357
|
-
const cmd = program.command("export").description("export the map (format inferred: json|ndjson|graphml|dot|cypher|sql|md|html|cdx.json|spdx.json)").argument("[file]", "target file (or - for stdout)", "map.json").action(function(file) {
|
|
6567
|
+
const cmd = program.command("export").description("export the map (format inferred: json|ndjson|graphml|dot|cypher|sql|md|html|cdx.json|spdx.json)").argument("[file]", "target file (or - for stdout)", "map.json").option("--compact", "compact JSON (no pretty-print; auto for large maps)").option("--slim", "drop heavy fields (area member lists, grounding) for smaller exports").action(function(file, opts) {
|
|
6358
6568
|
const global = readGlobal(this);
|
|
6359
6569
|
const { graph } = requireGraph(global);
|
|
6360
6570
|
const root2 = rootOf(global);
|
|
@@ -6365,13 +6575,15 @@ function registerExport(program) {
|
|
|
6365
6575
|
graph,
|
|
6366
6576
|
deps: needsDeps ? inventory(root2).records : void 0,
|
|
6367
6577
|
models: needsDeps && !global.local ? discoverModels() : void 0,
|
|
6368
|
-
generatedAt: graph.generatedAt
|
|
6578
|
+
generatedAt: graph.generatedAt,
|
|
6579
|
+
compact: opts.compact === true ? true : opts.compact === false ? false : void 0,
|
|
6580
|
+
slim: opts.slim === true
|
|
6369
6581
|
});
|
|
6370
6582
|
if (file === "-") {
|
|
6371
6583
|
out(content.trimEnd());
|
|
6372
6584
|
return;
|
|
6373
6585
|
}
|
|
6374
|
-
fs8.mkdirSync(
|
|
6586
|
+
fs8.mkdirSync(path37.dirname(path37.resolve(file)), { recursive: true });
|
|
6375
6587
|
fs8.writeFileSync(file, content);
|
|
6376
6588
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
6377
6589
|
});
|
|
@@ -6382,37 +6594,37 @@ function detectFormat(file) {
|
|
|
6382
6594
|
if (lower.endsWith(".cdx.json")) return "cyclonedx";
|
|
6383
6595
|
if (lower.endsWith(".spdx.json")) return "spdx";
|
|
6384
6596
|
if (file === "-") return "json";
|
|
6385
|
-
return formatForExt(
|
|
6597
|
+
return formatForExt(path37.extname(file));
|
|
6386
6598
|
}
|
|
6387
6599
|
function registerBundle(program) {
|
|
6388
6600
|
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) {
|
|
6389
6601
|
const global = readGlobal(this);
|
|
6390
6602
|
const root2 = rootOf(global);
|
|
6391
|
-
const outDir =
|
|
6603
|
+
const outDir = path37.resolve(root2, opts.out ?? "vg-bundle");
|
|
6392
6604
|
let grammarFiles;
|
|
6393
6605
|
try {
|
|
6394
6606
|
grammarFiles = resolvedGrammarFiles();
|
|
6395
6607
|
} catch {
|
|
6396
6608
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
6397
6609
|
}
|
|
6398
|
-
fs8.mkdirSync(
|
|
6610
|
+
fs8.mkdirSync(path37.join(outDir, "grammars"), { recursive: true });
|
|
6399
6611
|
let grammarCount = 0;
|
|
6400
6612
|
for (const { fileName, absPath } of grammarFiles) {
|
|
6401
|
-
fs8.copyFileSync(absPath,
|
|
6613
|
+
fs8.copyFileSync(absPath, path37.join(outDir, "grammars", fileName));
|
|
6402
6614
|
grammarCount++;
|
|
6403
6615
|
}
|
|
6404
6616
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
6405
6617
|
const graphSrc = resolveGraphPath(root2, global.graph);
|
|
6406
6618
|
if (fs8.existsSync(graphSrc)) {
|
|
6407
|
-
fs8.copyFileSync(graphSrc,
|
|
6619
|
+
fs8.copyFileSync(graphSrc, path37.join(outDir, "graph.json"));
|
|
6408
6620
|
included.push("graph.json");
|
|
6409
6621
|
}
|
|
6410
6622
|
const cat = catalogPath(root2);
|
|
6411
6623
|
if (fs8.existsSync(cat)) {
|
|
6412
|
-
fs8.copyFileSync(cat,
|
|
6624
|
+
fs8.copyFileSync(cat, path37.join(outDir, "vibgrate.lib.json"));
|
|
6413
6625
|
included.push("vibgrate.lib.json");
|
|
6414
6626
|
if (fs8.existsSync(libDir(root2))) {
|
|
6415
|
-
fs8.cpSync(libDir(root2),
|
|
6627
|
+
fs8.cpSync(libDir(root2), path37.join(outDir, "lib"), { recursive: true });
|
|
6416
6628
|
included.push("lib/");
|
|
6417
6629
|
}
|
|
6418
6630
|
}
|
|
@@ -6424,15 +6636,15 @@ function registerBundle(program) {
|
|
|
6424
6636
|
included,
|
|
6425
6637
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
6426
6638
|
};
|
|
6427
|
-
fs8.writeFileSync(
|
|
6639
|
+
fs8.writeFileSync(path37.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
6428
6640
|
`);
|
|
6429
6641
|
if (global.json) {
|
|
6430
|
-
json({ out:
|
|
6642
|
+
json({ out: path37.relative(root2, outDir), ...manifest });
|
|
6431
6643
|
return;
|
|
6432
6644
|
}
|
|
6433
|
-
info(`${c.cyan("vg bundle")} \xB7 wrote ${
|
|
6645
|
+
info(`${c.cyan("vg bundle")} \xB7 wrote ${path37.relative(root2, outDir)}/`);
|
|
6434
6646
|
for (const i of included) info(` ${c.green("\u2714")} ${i}`);
|
|
6435
|
-
info(c.dim(` offline: vg build --grammars "${
|
|
6647
|
+
info(c.dim(` offline: vg build --grammars "${path37.relative(root2, outDir)}/grammars"`));
|
|
6436
6648
|
});
|
|
6437
6649
|
applyGlobalOptions(cmd);
|
|
6438
6650
|
}
|
|
@@ -6450,7 +6662,7 @@ async function runDoctor(global) {
|
|
|
6450
6662
|
const root2 = rootOf(global);
|
|
6451
6663
|
const local = global.local === true;
|
|
6452
6664
|
const graphPath = resolveGraphPath(root2, global.graph);
|
|
6453
|
-
const configFile = CONFIG_BASENAMES.find((f) => fs8.existsSync(
|
|
6665
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs8.existsSync(path37.join(root2, f))) ?? null;
|
|
6454
6666
|
const graph = loadGraph(root2, graphPath);
|
|
6455
6667
|
let staleFiles = null;
|
|
6456
6668
|
if (graph) {
|
|
@@ -6476,13 +6688,13 @@ async function runDoctor(global) {
|
|
|
6476
6688
|
root: root2,
|
|
6477
6689
|
configFile,
|
|
6478
6690
|
map: {
|
|
6479
|
-
path:
|
|
6691
|
+
path: path37.relative(root2, graphPath),
|
|
6480
6692
|
built: graph !== null,
|
|
6481
6693
|
generatedAt: graph?.generatedAt ?? null,
|
|
6482
6694
|
staleFiles
|
|
6483
6695
|
},
|
|
6484
6696
|
libCatalog: {
|
|
6485
|
-
path:
|
|
6697
|
+
path: path37.relative(root2, catalogPath(root2)),
|
|
6486
6698
|
present: fs8.existsSync(catalogPath(root2)),
|
|
6487
6699
|
libraries: libCount
|
|
6488
6700
|
},
|
|
@@ -6540,7 +6752,7 @@ async function runDoctor(global) {
|
|
|
6540
6752
|
);
|
|
6541
6753
|
info(
|
|
6542
6754
|
` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
|
|
6543
|
-
` \xB7 last ${
|
|
6755
|
+
` \xB7 last ${path37.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
|
|
6544
6756
|
) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
|
|
6545
6757
|
);
|
|
6546
6758
|
if (li.dynamicOnToken || li.dynamicCustomSampler) {
|
|
@@ -6676,7 +6888,7 @@ function registerDaemon(program) {
|
|
|
6676
6888
|
const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
|
|
6677
6889
|
const global = readGlobal(this);
|
|
6678
6890
|
const socketPath = socketOf(this);
|
|
6679
|
-
const root2 =
|
|
6891
|
+
const root2 = path37.resolve(rootArg ?? rootOf(global));
|
|
6680
6892
|
if (!await vgdIsRunning({ socketPath })) {
|
|
6681
6893
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
6682
6894
|
}
|
|
@@ -6712,7 +6924,7 @@ function registerDaemon(program) {
|
|
|
6712
6924
|
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) {
|
|
6713
6925
|
const global = readGlobal(this);
|
|
6714
6926
|
const socketPath = socketOf(this);
|
|
6715
|
-
const primary =
|
|
6927
|
+
const primary = path37.resolve(rootArg ?? rootOf(global));
|
|
6716
6928
|
if (!await vgdIsRunning({ socketPath })) {
|
|
6717
6929
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
6718
6930
|
}
|
|
@@ -6740,11 +6952,11 @@ function registerDaemon(program) {
|
|
|
6740
6952
|
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) {
|
|
6741
6953
|
const global = readGlobal(this);
|
|
6742
6954
|
const socketPath = socketOf(this);
|
|
6743
|
-
const root2 =
|
|
6955
|
+
const root2 = path37.resolve(rootArg ?? rootOf(global));
|
|
6744
6956
|
if (!await vgdIsRunning({ socketPath })) {
|
|
6745
6957
|
throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
|
|
6746
6958
|
}
|
|
6747
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
6959
|
+
const { loadGraph: loadGraph2 } = await import('./load-QPOWQD7C.js');
|
|
6748
6960
|
const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
|
|
6749
6961
|
const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
|
|
6750
6962
|
const opts = this.opts();
|
|
@@ -6860,7 +7072,7 @@ function socketOf(cmd) {
|
|
|
6860
7072
|
let c2 = cmd;
|
|
6861
7073
|
while (c2) {
|
|
6862
7074
|
const opts = c2.opts();
|
|
6863
|
-
if (opts.socket) return
|
|
7075
|
+
if (opts.socket) return path37.resolve(opts.socket);
|
|
6864
7076
|
c2 = c2.parent;
|
|
6865
7077
|
}
|
|
6866
7078
|
return vgdSocketPath();
|
|
@@ -7077,11 +7289,11 @@ function registerLlmHost(program) {
|
|
|
7077
7289
|
applyGlobalOptions(cmd);
|
|
7078
7290
|
}
|
|
7079
7291
|
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) => {
|
|
7080
|
-
const rootDir =
|
|
7081
|
-
const vibgrateDir2 =
|
|
7292
|
+
const rootDir = path37.resolve(targetPath);
|
|
7293
|
+
const vibgrateDir2 = path37.join(rootDir, ".vibgrate");
|
|
7082
7294
|
await ensureDir(vibgrateDir2);
|
|
7083
7295
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
|
|
7084
|
-
const configPath =
|
|
7296
|
+
const configPath = path37.join(rootDir, "vibgrate.config.ts");
|
|
7085
7297
|
if (await pathExists(configPath)) {
|
|
7086
7298
|
console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
|
|
7087
7299
|
} else {
|
|
@@ -7089,7 +7301,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
7089
7301
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
7090
7302
|
}
|
|
7091
7303
|
if (opts.baseline) {
|
|
7092
|
-
const { runBaseline } = await import('./baseline-
|
|
7304
|
+
const { runBaseline } = await import('./baseline-ATM5MXBZ.js');
|
|
7093
7305
|
await runBaseline(rootDir);
|
|
7094
7306
|
}
|
|
7095
7307
|
console.log("");
|
|
@@ -7192,16 +7404,16 @@ function collectPackageImports(graph, ecosystem, pkg) {
|
|
|
7192
7404
|
};
|
|
7193
7405
|
}
|
|
7194
7406
|
async function fileReferencesIdentifier(rootDir, relFile, identifier, readFile3) {
|
|
7195
|
-
const content = await readFile3(
|
|
7407
|
+
const content = await readFile3(path37.join(rootDir, relFile));
|
|
7196
7408
|
if (!content) return false;
|
|
7197
7409
|
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7198
7410
|
return new RegExp(`\\b${escaped}\\b`).test(content);
|
|
7199
7411
|
}
|
|
7200
7412
|
async function defaultReadFile(absPath) {
|
|
7201
7413
|
try {
|
|
7202
|
-
const stat2 = await
|
|
7414
|
+
const stat2 = await fs21.stat(absPath);
|
|
7203
7415
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
7204
|
-
return await
|
|
7416
|
+
return await fs21.readFile(absPath, "utf8");
|
|
7205
7417
|
} catch {
|
|
7206
7418
|
return null;
|
|
7207
7419
|
}
|
|
@@ -7386,7 +7598,7 @@ var AI_ASSISTANT_DETECTORS = [
|
|
|
7386
7598
|
async function detectAiAssistant(rootDir) {
|
|
7387
7599
|
for (const detector of AI_ASSISTANT_DETECTORS) {
|
|
7388
7600
|
for (const file of detector.files) {
|
|
7389
|
-
if (await pathExists$1(
|
|
7601
|
+
if (await pathExists$1(path37.join(rootDir, file))) {
|
|
7390
7602
|
return detector.name;
|
|
7391
7603
|
}
|
|
7392
7604
|
}
|
|
@@ -7579,7 +7791,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
7579
7791
|
collectExcludes,
|
|
7580
7792
|
[]
|
|
7581
7793
|
).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) => {
|
|
7582
|
-
const rootDir =
|
|
7794
|
+
const rootDir = path37.resolve(targetPath);
|
|
7583
7795
|
if (!await pathExists$1(rootDir)) {
|
|
7584
7796
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
7585
7797
|
process.exit(1);
|
|
@@ -7587,7 +7799,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
7587
7799
|
const hasDsn = !!resolveDsn(opts.dsn);
|
|
7588
7800
|
const willPush = !opts.offline && (opts.push || hasDsn);
|
|
7589
7801
|
const noLocalArtifacts = opts.localArtifacts === false;
|
|
7590
|
-
const isFirstRun = !await pathExists$1(
|
|
7802
|
+
const isFirstRun = !await pathExists$1(path37.join(rootDir, ".vibgrate", "scan_result.json"));
|
|
7591
7803
|
let pinnedRegion;
|
|
7592
7804
|
let planTier;
|
|
7593
7805
|
let upgradeUrl;
|
|
@@ -7866,11 +8078,11 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
7866
8078
|
scanned++;
|
|
7867
8079
|
if (scanned > MAX_ENTRIES) break;
|
|
7868
8080
|
if (e.isDirectory()) {
|
|
7869
|
-
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(
|
|
8081
|
+
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path37.join(dir, e.name), depth + 1);
|
|
7870
8082
|
continue;
|
|
7871
8083
|
}
|
|
7872
8084
|
if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
|
|
7873
|
-
const abs =
|
|
8085
|
+
const abs = path37.join(dir, e.name);
|
|
7874
8086
|
let mtimeMs;
|
|
7875
8087
|
try {
|
|
7876
8088
|
mtimeMs = fs8.statSync(abs).mtimeMs;
|
|
@@ -7879,7 +8091,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
7879
8091
|
}
|
|
7880
8092
|
if (mtimeMs > newest) {
|
|
7881
8093
|
newest = mtimeMs;
|
|
7882
|
-
newestChanged =
|
|
8094
|
+
newestChanged = path37.relative(rootDir, abs) || e.name;
|
|
7883
8095
|
}
|
|
7884
8096
|
}
|
|
7885
8097
|
};
|
|
@@ -8016,13 +8228,13 @@ function analyzeTree(root2, packages) {
|
|
|
8016
8228
|
if (filesSeen >= MAX_FILES) return;
|
|
8017
8229
|
if (entry.isDirectory()) {
|
|
8018
8230
|
if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
8019
|
-
walk2(
|
|
8231
|
+
walk2(path37.join(dir, entry.name), depth + 1);
|
|
8020
8232
|
continue;
|
|
8021
8233
|
}
|
|
8022
|
-
const fileEco = EXT_ECOSYSTEM[
|
|
8234
|
+
const fileEco = EXT_ECOSYSTEM[path37.extname(entry.name)];
|
|
8023
8235
|
if (!fileEco || fileEco === "unknown") continue;
|
|
8024
8236
|
filesSeen++;
|
|
8025
|
-
const full =
|
|
8237
|
+
const full = path37.join(dir, entry.name);
|
|
8026
8238
|
let content;
|
|
8027
8239
|
try {
|
|
8028
8240
|
if (fs8.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
@@ -8337,7 +8549,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
8337
8549
|
}
|
|
8338
8550
|
const outcomes = effective.map((t) => {
|
|
8339
8551
|
const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
|
|
8340
|
-
return { t, res: run(c2,
|
|
8552
|
+
return { t, res: run(c2, path37.join(rootDir, t.dir)) };
|
|
8341
8553
|
});
|
|
8342
8554
|
const failures = outcomes.filter((o) => !o.res.ok);
|
|
8343
8555
|
if (failures.length === 0) {
|
|
@@ -8366,8 +8578,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
8366
8578
|
return results;
|
|
8367
8579
|
}
|
|
8368
8580
|
var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
|
|
8369
|
-
var CACHE_DIR =
|
|
8370
|
-
var CACHE_FILE =
|
|
8581
|
+
var CACHE_DIR = path37.join(os.homedir(), ".vibgrate");
|
|
8582
|
+
var CACHE_FILE = path37.join(CACHE_DIR, "update-check.json");
|
|
8371
8583
|
async function fetchLatestVersion() {
|
|
8372
8584
|
try {
|
|
8373
8585
|
const controller = new AbortController();
|
|
@@ -8394,8 +8606,8 @@ async function fetchLatestVersion() {
|
|
|
8394
8606
|
}
|
|
8395
8607
|
async function writeCache(data) {
|
|
8396
8608
|
try {
|
|
8397
|
-
await
|
|
8398
|
-
await
|
|
8609
|
+
await fs21.mkdir(CACHE_DIR, { recursive: true });
|
|
8610
|
+
await fs21.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
8399
8611
|
} catch {
|
|
8400
8612
|
}
|
|
8401
8613
|
}
|
|
@@ -8436,14 +8648,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
|
|
|
8436
8648
|
pm: "yarn",
|
|
8437
8649
|
root: () => {
|
|
8438
8650
|
const dir = tryRun("yarn global dir");
|
|
8439
|
-
return dir ?
|
|
8651
|
+
return dir ? path37.join(dir, "node_modules") : null;
|
|
8440
8652
|
}
|
|
8441
8653
|
},
|
|
8442
|
-
{ pm: "bun", root: () =>
|
|
8654
|
+
{ pm: "bun", root: () => path37.join(os.homedir(), ".bun", "install", "global", "node_modules") }
|
|
8443
8655
|
];
|
|
8444
8656
|
for (const probe of probes) {
|
|
8445
8657
|
const root2 = probe.root();
|
|
8446
|
-
if (root2 && await pathExists(
|
|
8658
|
+
if (root2 && await pathExists(path37.join(root2, pkg))) return probe.pm;
|
|
8447
8659
|
}
|
|
8448
8660
|
return null;
|
|
8449
8661
|
}
|
|
@@ -8462,15 +8674,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
|
|
|
8462
8674
|
}
|
|
8463
8675
|
}
|
|
8464
8676
|
async function detectPackageManager(cwd) {
|
|
8465
|
-
if (await pathExists(
|
|
8466
|
-
if (await pathExists(
|
|
8467
|
-
if (await pathExists(
|
|
8677
|
+
if (await pathExists(path37.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
8678
|
+
if (await pathExists(path37.join(cwd, "bun.lockb"))) return "bun";
|
|
8679
|
+
if (await pathExists(path37.join(cwd, "yarn.lock"))) return "yarn";
|
|
8468
8680
|
return "npm";
|
|
8469
8681
|
}
|
|
8470
8682
|
async function detectWorkspaceRoot(cwd) {
|
|
8471
|
-
if (await pathExists(
|
|
8683
|
+
if (await pathExists(path37.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
8472
8684
|
try {
|
|
8473
|
-
const pkgPath =
|
|
8685
|
+
const pkgPath = path37.join(cwd, "package.json");
|
|
8474
8686
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
8475
8687
|
const pkg = JSON.parse(raw);
|
|
8476
8688
|
return pkg.workspaces != null;
|
|
@@ -8495,7 +8707,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
|
8495
8707
|
}
|
|
8496
8708
|
async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
8497
8709
|
try {
|
|
8498
|
-
const pkgPath =
|
|
8710
|
+
const pkgPath = path37.join(cwd, "package.json");
|
|
8499
8711
|
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
8500
8712
|
const parsed = JSON.parse(raw);
|
|
8501
8713
|
if (parsed.devDependencies?.[pkg]) return "dev";
|
|
@@ -8507,11 +8719,11 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
|
|
|
8507
8719
|
async function confirmWorkspaceRoot(pm) {
|
|
8508
8720
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
|
|
8509
8721
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8510
|
-
return new Promise((
|
|
8722
|
+
return new Promise((resolve20) => {
|
|
8511
8723
|
rl.question(chalk7.yellow(`Update the ${pm} workspace root with -w? [y/N]: `), (ans) => {
|
|
8512
8724
|
rl.close();
|
|
8513
8725
|
const t = ans.trim().toLowerCase();
|
|
8514
|
-
|
|
8726
|
+
resolve20(t === "y" || t === "yes");
|
|
8515
8727
|
});
|
|
8516
8728
|
});
|
|
8517
8729
|
}
|
|
@@ -8643,13 +8855,13 @@ function collectCandidates(artifact) {
|
|
|
8643
8855
|
return out2;
|
|
8644
8856
|
}
|
|
8645
8857
|
var defaultFixScanner = async (rootDir) => {
|
|
8646
|
-
const scratch =
|
|
8858
|
+
const scratch = path37.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
|
|
8647
8859
|
const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
|
|
8648
8860
|
const advanced = await loadAdvancedScanHook();
|
|
8649
8861
|
return runCoreScan(rootDir, scanOpts, advanced);
|
|
8650
8862
|
};
|
|
8651
8863
|
async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
|
|
8652
|
-
const artifactPath =
|
|
8864
|
+
const artifactPath = path37.isAbsolute(inFile) ? inFile : path37.join(rootDir, inFile);
|
|
8653
8865
|
if (await pathExists(artifactPath)) {
|
|
8654
8866
|
const staleness = scanStaleness(rootDir, artifactPath);
|
|
8655
8867
|
if (!staleness.stale) {
|
|
@@ -8676,7 +8888,7 @@ async function repositoryIdentity(rootDir, override) {
|
|
|
8676
8888
|
}
|
|
8677
8889
|
}
|
|
8678
8890
|
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) => {
|
|
8679
|
-
const rootDir =
|
|
8891
|
+
const rootDir = path37.resolve(targetPath);
|
|
8680
8892
|
if (!await pathExists(rootDir)) {
|
|
8681
8893
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
8682
8894
|
process.exit(1);
|
|
@@ -8837,7 +9049,7 @@ function emit(report, format) {
|
|
|
8837
9049
|
}
|
|
8838
9050
|
}
|
|
8839
9051
|
function relProjectDir(rootDir, projectPath) {
|
|
8840
|
-
const rel =
|
|
9052
|
+
const rel = path37.isAbsolute(projectPath) ? path37.relative(rootDir, projectPath) : projectPath;
|
|
8841
9053
|
return rel === "" ? "." : rel;
|
|
8842
9054
|
}
|
|
8843
9055
|
async function buildTargetResolver(rootDir, artifact) {
|
|
@@ -8878,14 +9090,14 @@ function promptPlanSelection(response) {
|
|
|
8878
9090
|
const defaultIdx = plans.findIndex((p) => p.tier === response.recommended);
|
|
8879
9091
|
const def = defaultIdx >= 0 ? defaultIdx + 1 : 1;
|
|
8880
9092
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8881
|
-
return new Promise((
|
|
9093
|
+
return new Promise((resolve20) => {
|
|
8882
9094
|
rl.question(`Plan [1-${plans.length}, default ${def}, q to cancel]: `, (ans) => {
|
|
8883
9095
|
rl.close();
|
|
8884
9096
|
const t = ans.trim().toLowerCase();
|
|
8885
|
-
if (t === "q" || t === "quit") return
|
|
9097
|
+
if (t === "q" || t === "quit") return resolve20(null);
|
|
8886
9098
|
const n = t === "" ? def : Number.parseInt(t, 10);
|
|
8887
|
-
if (!Number.isInteger(n) || n < 1 || n > plans.length) return
|
|
8888
|
-
|
|
9099
|
+
if (!Number.isInteger(n) || n < 1 || n > plans.length) return resolve20(null);
|
|
9100
|
+
resolve20(plans[n - 1].tier);
|
|
8889
9101
|
});
|
|
8890
9102
|
});
|
|
8891
9103
|
}
|
|
@@ -9672,7 +9884,7 @@ function formatMarkdown(artifact) {
|
|
|
9672
9884
|
|
|
9673
9885
|
// src/reporting/commands/report.ts
|
|
9674
9886
|
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) => {
|
|
9675
|
-
const artifactPath =
|
|
9887
|
+
const artifactPath = path37.resolve(opts.in);
|
|
9676
9888
|
if (!await pathExists(artifactPath)) {
|
|
9677
9889
|
console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
|
|
9678
9890
|
console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
|
|
@@ -9718,10 +9930,10 @@ function openUrl(url) {
|
|
|
9718
9930
|
}
|
|
9719
9931
|
|
|
9720
9932
|
// src/reporting/commands/login.ts
|
|
9721
|
-
var delay = (ms) => new Promise((
|
|
9933
|
+
var delay = (ms) => new Promise((resolve20) => setTimeout(resolve20, ms));
|
|
9722
9934
|
function isInside(dir, file) {
|
|
9723
|
-
const rel =
|
|
9724
|
-
return !!rel && !rel.startsWith("..") && !
|
|
9935
|
+
const rel = path37.relative(dir, file);
|
|
9936
|
+
return !!rel && !rel.startsWith("..") && !path37.isAbsolute(rel);
|
|
9725
9937
|
}
|
|
9726
9938
|
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(
|
|
9727
9939
|
"--local",
|
|
@@ -9976,7 +10188,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
9976
10188
|
try {
|
|
9977
10189
|
const statements = [];
|
|
9978
10190
|
if (opts.from) {
|
|
9979
|
-
const fromPath =
|
|
10191
|
+
const fromPath = path37.resolve(opts.from);
|
|
9980
10192
|
if (!await pathExists(fromPath)) {
|
|
9981
10193
|
process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
|
|
9982
10194
|
`));
|
|
@@ -9994,9 +10206,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
|
|
|
9994
10206
|
});
|
|
9995
10207
|
const json2 = JSON.stringify(doc, null, 2);
|
|
9996
10208
|
if (opts.out) {
|
|
9997
|
-
await writeTextFile(
|
|
10209
|
+
await writeTextFile(path37.resolve(opts.out), json2 + "\n");
|
|
9998
10210
|
process.stderr.write(
|
|
9999
|
-
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${
|
|
10211
|
+
chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path37.resolve(opts.out)}
|
|
10000
10212
|
`
|
|
10001
10213
|
);
|
|
10002
10214
|
} else {
|
|
@@ -10179,7 +10391,7 @@ function formatDeltaText(base, current) {
|
|
|
10179
10391
|
return lines.join("\n");
|
|
10180
10392
|
}
|
|
10181
10393
|
async function readArtifactOrExit(filePath) {
|
|
10182
|
-
const absolutePath =
|
|
10394
|
+
const absolutePath = path37.resolve(filePath);
|
|
10183
10395
|
if (!await pathExists(absolutePath)) {
|
|
10184
10396
|
console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
|
|
10185
10397
|
process.exit(1);
|
|
@@ -10196,7 +10408,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
|
|
|
10196
10408
|
const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
|
|
10197
10409
|
const body = JSON.stringify(sbom, null, 2);
|
|
10198
10410
|
if (opts.out) {
|
|
10199
|
-
await writeTextFile(
|
|
10411
|
+
await writeTextFile(path37.resolve(opts.out), body);
|
|
10200
10412
|
console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
|
|
10201
10413
|
} else {
|
|
10202
10414
|
console.log(body);
|
|
@@ -10207,7 +10419,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
|
|
|
10207
10419
|
const current = await readArtifactOrExit(opts.to);
|
|
10208
10420
|
const report = formatDeltaText(base, current);
|
|
10209
10421
|
if (opts.out) {
|
|
10210
|
-
await writeTextFile(
|
|
10422
|
+
await writeTextFile(path37.resolve(opts.out), report);
|
|
10211
10423
|
console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
|
|
10212
10424
|
} else {
|
|
10213
10425
|
console.log(report);
|
|
@@ -10338,20 +10550,20 @@ function resolveRegime(id) {
|
|
|
10338
10550
|
return regime;
|
|
10339
10551
|
}
|
|
10340
10552
|
function evidenceDir(root2) {
|
|
10341
|
-
return
|
|
10553
|
+
return path37.join(root2, ".vibgrate", "evidence");
|
|
10342
10554
|
}
|
|
10343
10555
|
function orgPath(root2) {
|
|
10344
|
-
return
|
|
10556
|
+
return path37.join(evidenceDir(root2), "org.json");
|
|
10345
10557
|
}
|
|
10346
10558
|
function productsPath(root2) {
|
|
10347
|
-
return
|
|
10559
|
+
return path37.join(evidenceDir(root2), "products.json");
|
|
10348
10560
|
}
|
|
10349
10561
|
function releasesDir(root2) {
|
|
10350
|
-
return
|
|
10562
|
+
return path37.join(evidenceDir(root2), "releases");
|
|
10351
10563
|
}
|
|
10352
10564
|
function releasePath(root2, productId, version) {
|
|
10353
10565
|
const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
10354
|
-
return
|
|
10566
|
+
return path37.join(releasesDir(root2), `${safe}.json`);
|
|
10355
10567
|
}
|
|
10356
10568
|
var DEFAULT_ORG = {
|
|
10357
10569
|
responsiblePersons: [],
|
|
@@ -10382,7 +10594,7 @@ async function freezeRelease(root2, release) {
|
|
|
10382
10594
|
const p = releasePath(root2, release.productId, release.version);
|
|
10383
10595
|
if (await pathExists(p)) {
|
|
10384
10596
|
throw new CliError(
|
|
10385
|
-
`release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${
|
|
10597
|
+
`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`,
|
|
10386
10598
|
ExitCode.USAGE_ERROR
|
|
10387
10599
|
);
|
|
10388
10600
|
}
|
|
@@ -10396,7 +10608,7 @@ async function loadReleases(root2, productId) {
|
|
|
10396
10608
|
const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
10397
10609
|
const releases = [];
|
|
10398
10610
|
for (const f of files) {
|
|
10399
|
-
const rel = await readJsonFile(
|
|
10611
|
+
const rel = await readJsonFile(path37.join(dir, f));
|
|
10400
10612
|
if (!productId || rel.productId === productId) releases.push(rel);
|
|
10401
10613
|
}
|
|
10402
10614
|
return releases;
|
|
@@ -11091,12 +11303,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
|
|
|
11091
11303
|
var DEFAULT_KEY = "attest-key.pem";
|
|
11092
11304
|
function resolveSigningKey(root2, explicit) {
|
|
11093
11305
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
11094
|
-
const keyPath = chosen ?
|
|
11306
|
+
const keyPath = chosen ? path37.resolve(chosen) : path37.join(root2, ".vibgrate", DEFAULT_KEY);
|
|
11095
11307
|
let minted = false;
|
|
11096
11308
|
if (!fs8.existsSync(keyPath)) {
|
|
11097
11309
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
11098
11310
|
const kp = generateKeypair();
|
|
11099
|
-
fs8.mkdirSync(
|
|
11311
|
+
fs8.mkdirSync(path37.dirname(keyPath), { recursive: true });
|
|
11100
11312
|
fs8.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
11101
11313
|
fs8.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
11102
11314
|
minted = true;
|
|
@@ -11114,16 +11326,16 @@ function resolveSigningKey(root2, explicit) {
|
|
|
11114
11326
|
}
|
|
11115
11327
|
function writeBundle(input) {
|
|
11116
11328
|
const dir = input.outDir;
|
|
11117
|
-
fs8.mkdirSync(
|
|
11118
|
-
const write = (rel, data) => fs8.writeFileSync(
|
|
11329
|
+
fs8.mkdirSync(path37.join(dir, "inputs", "releases"), { recursive: true });
|
|
11330
|
+
const write = (rel, data) => fs8.writeFileSync(path37.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
11119
11331
|
`);
|
|
11120
11332
|
write("result.json", input.result);
|
|
11121
|
-
write(
|
|
11333
|
+
write(path37.join("inputs", "advisory.json"), input.advisory);
|
|
11122
11334
|
for (const rel of input.releases) {
|
|
11123
11335
|
const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
|
|
11124
|
-
write(
|
|
11336
|
+
write(path37.join("inputs", "releases", `${safe}.json`), rel);
|
|
11125
11337
|
}
|
|
11126
|
-
write(
|
|
11338
|
+
write(path37.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
|
|
11127
11339
|
write("provenance.json", {
|
|
11128
11340
|
method: "deterministic",
|
|
11129
11341
|
modelDrafted: [],
|
|
@@ -11139,13 +11351,13 @@ function writeBundle(input) {
|
|
|
11139
11351
|
disclaimer: input.regime.disclaimer
|
|
11140
11352
|
});
|
|
11141
11353
|
if (input.envelope) {
|
|
11142
|
-
fs8.writeFileSync(
|
|
11354
|
+
fs8.writeFileSync(path37.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
11143
11355
|
`);
|
|
11144
11356
|
}
|
|
11145
11357
|
if (input.timestampToken) {
|
|
11146
|
-
fs8.writeFileSync(
|
|
11358
|
+
fs8.writeFileSync(path37.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
11147
11359
|
}
|
|
11148
|
-
fs8.writeFileSync(
|
|
11360
|
+
fs8.writeFileSync(path37.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
11149
11361
|
return dir;
|
|
11150
11362
|
}
|
|
11151
11363
|
function verifyDoc(input) {
|
|
@@ -11206,13 +11418,13 @@ function undeterminedFields(result, regime) {
|
|
|
11206
11418
|
return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
|
|
11207
11419
|
}
|
|
11208
11420
|
async function recordDrill(root2, record) {
|
|
11209
|
-
const dir =
|
|
11210
|
-
const p =
|
|
11421
|
+
const dir = path37.join(evidenceDir(root2), "drills");
|
|
11422
|
+
const p = path37.join(dir, `${record.drillId}.json`);
|
|
11211
11423
|
await writeJsonFile(p, record);
|
|
11212
11424
|
return p;
|
|
11213
11425
|
}
|
|
11214
11426
|
async function hasRecentDrill(root2, asOf) {
|
|
11215
|
-
const dir =
|
|
11427
|
+
const dir = path37.join(evidenceDir(root2), "drills");
|
|
11216
11428
|
if (!await pathExists(dir)) return void 0;
|
|
11217
11429
|
const { readdir } = await import('fs/promises');
|
|
11218
11430
|
const { readJsonFile: readJsonFile2 } = await import('./fs-O5IQYXHO.js');
|
|
@@ -11220,7 +11432,7 @@ async function hasRecentDrill(root2, asOf) {
|
|
|
11220
11432
|
if (files.length === 0) return void 0;
|
|
11221
11433
|
const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
|
|
11222
11434
|
for (const f of files) {
|
|
11223
|
-
const rec = await readJsonFile2(
|
|
11435
|
+
const rec = await readJsonFile2(path37.join(dir, f));
|
|
11224
11436
|
if (rec.ranAt >= cutoff) return true;
|
|
11225
11437
|
}
|
|
11226
11438
|
return false;
|
|
@@ -11300,7 +11512,7 @@ function formatRegimeList() {
|
|
|
11300
11512
|
|
|
11301
11513
|
// src/reporting/commands/evidence/index.ts
|
|
11302
11514
|
function root(opts) {
|
|
11303
|
-
return
|
|
11515
|
+
return path37.resolve(opts.cwd ?? process.cwd());
|
|
11304
11516
|
}
|
|
11305
11517
|
function slug(name) {
|
|
11306
11518
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
|
|
@@ -11388,7 +11600,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
11388
11600
|
const release = await buildRelease({
|
|
11389
11601
|
productId: product.id,
|
|
11390
11602
|
version,
|
|
11391
|
-
from:
|
|
11603
|
+
from: path37.resolve(rootDir, opts.from),
|
|
11392
11604
|
shipDate: opts.shipDate,
|
|
11393
11605
|
buildId: opts.buildId,
|
|
11394
11606
|
artefactDigest: opts.digest,
|
|
@@ -11396,7 +11608,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
|
|
|
11396
11608
|
frozenAt: nowIso()
|
|
11397
11609
|
});
|
|
11398
11610
|
const p = await freezeRelease(rootDir, release);
|
|
11399
|
-
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${
|
|
11611
|
+
console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path37.relative(rootDir, p)}`);
|
|
11400
11612
|
});
|
|
11401
11613
|
async function runExposure(rootDir, vuln, opts) {
|
|
11402
11614
|
const org = await loadOrg(rootDir);
|
|
@@ -11448,7 +11660,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
11448
11660
|
console.log("\n" + buildPack(result, regime, org, stage));
|
|
11449
11661
|
}
|
|
11450
11662
|
if (opts.bundle) {
|
|
11451
|
-
const dir =
|
|
11663
|
+
const dir = path37.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
|
|
11452
11664
|
let envelope;
|
|
11453
11665
|
if (opts.sign !== false) {
|
|
11454
11666
|
const { key: key2, minted } = resolveSigningKey(rootDir);
|
|
@@ -11456,7 +11668,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
|
|
|
11456
11668
|
envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
|
|
11457
11669
|
}
|
|
11458
11670
|
writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
|
|
11459
|
-
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${
|
|
11671
|
+
console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path37.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
|
|
11460
11672
|
}
|
|
11461
11673
|
process.exitCode = exposureExit(result.overallStatus);
|
|
11462
11674
|
});
|
|
@@ -11488,7 +11700,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
11488
11700
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
11489
11701
|
const md = buildPack(result, regime, org, stage);
|
|
11490
11702
|
if (opts.out) {
|
|
11491
|
-
fs8.writeFileSync(
|
|
11703
|
+
fs8.writeFileSync(path37.resolve(rootDir, opts.out), md);
|
|
11492
11704
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
11493
11705
|
} else {
|
|
11494
11706
|
console.log(md);
|
|
@@ -11530,18 +11742,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
11530
11742
|
}
|
|
11531
11743
|
});
|
|
11532
11744
|
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) => {
|
|
11533
|
-
const abs =
|
|
11534
|
-
const envPath = fs8.statSync(abs).isDirectory() ?
|
|
11745
|
+
const abs = path37.resolve(bundlePath);
|
|
11746
|
+
const envPath = fs8.statSync(abs).isDirectory() ? path37.join(abs, "evidence.intoto.jsonl") : abs;
|
|
11535
11747
|
if (!fs8.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
11536
11748
|
const envelope = JSON.parse(fs8.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
11537
|
-
const resultPath =
|
|
11749
|
+
const resultPath = path37.join(path37.dirname(envPath), "result.json");
|
|
11538
11750
|
const result = fs8.existsSync(resultPath) ? JSON.parse(fs8.readFileSync(resultPath, "utf8")) : void 0;
|
|
11539
|
-
const publicKeyPem = opts.pub ? fs8.readFileSync(
|
|
11751
|
+
const publicKeyPem = opts.pub ? fs8.readFileSync(path37.resolve(opts.pub), "utf8") : void 0;
|
|
11540
11752
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
11541
11753
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
11542
11754
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
11543
11755
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
11544
|
-
const tsrPath =
|
|
11756
|
+
const tsrPath = path37.join(path37.dirname(envPath), "timestamp.tsr");
|
|
11545
11757
|
if (fs8.existsSync(tsrPath) && result) {
|
|
11546
11758
|
const t = verifyTimestamp(fs8.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
11547
11759
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
@@ -11610,12 +11822,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
|
|
|
11610
11822
|
const releases = [];
|
|
11611
11823
|
for (const list of releasesByProduct.values()) releases.push(...list);
|
|
11612
11824
|
const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
|
|
11613
|
-
const dir =
|
|
11614
|
-
await writeJsonFile(
|
|
11615
|
-
await writeJsonFile(
|
|
11616
|
-
for (const r of releases) await writeJsonFile(
|
|
11617
|
-
await writeJsonFile(
|
|
11618
|
-
console.error(chalk7.green("\u2714") + ` exported evidence state to ${
|
|
11825
|
+
const dir = path37.resolve(rootDir, opts.out);
|
|
11826
|
+
await writeJsonFile(path37.join(dir, "org.json"), org);
|
|
11827
|
+
await writeJsonFile(path37.join(dir, "products.json"), products);
|
|
11828
|
+
for (const r of releases) await writeJsonFile(path37.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
|
|
11829
|
+
await writeJsonFile(path37.join(dir, "readiness.json"), report);
|
|
11830
|
+
console.error(chalk7.green("\u2714") + ` exported evidence state to ${path37.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
|
|
11619
11831
|
});
|
|
11620
11832
|
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) => {
|
|
11621
11833
|
const rootDir = root(opts);
|
|
@@ -11641,8 +11853,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
11641
11853
|
}));
|
|
11642
11854
|
let exposure;
|
|
11643
11855
|
if (opts.result) {
|
|
11644
|
-
const raw =
|
|
11645
|
-
const resultPath = fs8.existsSync(raw) && fs8.statSync(raw).isDirectory() ?
|
|
11856
|
+
const raw = path37.resolve(rootDir, opts.result);
|
|
11857
|
+
const resultPath = fs8.existsSync(raw) && fs8.statSync(raw).isDirectory() ? path37.join(raw, "result.json") : raw;
|
|
11646
11858
|
if (!fs8.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
11647
11859
|
exposure = JSON.parse(fs8.readFileSync(resultPath, "utf8"));
|
|
11648
11860
|
}
|
|
@@ -11708,6 +11920,7 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
11708
11920
|
"install",
|
|
11709
11921
|
"uninstall",
|
|
11710
11922
|
"share",
|
|
11923
|
+
"watch",
|
|
11711
11924
|
"help",
|
|
11712
11925
|
// Drift-reporting verbs (merged from the Vibgrate CLI).
|
|
11713
11926
|
"init",
|
|
@@ -11748,6 +11961,7 @@ ${aliasNote}Docs: https://vibgrate.com/help`;
|
|
|
11748
11961
|
registerLsp(program);
|
|
11749
11962
|
registerInstall(program);
|
|
11750
11963
|
registerShare(program);
|
|
11964
|
+
registerWatch(program);
|
|
11751
11965
|
registerTests(program);
|
|
11752
11966
|
registerFacts(program);
|
|
11753
11967
|
registerGuide(program);
|
|
@@ -11832,7 +12046,7 @@ function dispatch(argv, cwd) {
|
|
|
11832
12046
|
}
|
|
11833
12047
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
11834
12048
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
11835
|
-
if (fs8.existsSync(
|
|
12049
|
+
if (fs8.existsSync(path37.resolve(cwd, first))) {
|
|
11836
12050
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
11837
12051
|
}
|
|
11838
12052
|
const moved = MOVED_COMMANDS[first];
|
|
@@ -11877,9 +12091,9 @@ async function main(argv = process.argv) {
|
|
|
11877
12091
|
}
|
|
11878
12092
|
function readCwd(raw) {
|
|
11879
12093
|
const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
|
|
11880
|
-
if (i >= 0 && raw[i + 1]) return
|
|
12094
|
+
if (i >= 0 && raw[i + 1]) return path37.resolve(raw[i + 1]);
|
|
11881
12095
|
const eq = raw.find((a) => a.startsWith("--cwd="));
|
|
11882
|
-
if (eq) return
|
|
12096
|
+
if (eq) return path37.resolve(eq.slice("--cwd=".length));
|
|
11883
12097
|
return process.cwd();
|
|
11884
12098
|
}
|
|
11885
12099
|
function handleError(err) {
|