@vibgrate/cli 2026.720.2 → 2026.720.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baseline-YJT32DP2.js +6 -0
- package/dist/{baseline-WIZAFIJS.js.map → baseline-YJT32DP2.js.map} +1 -1
- package/dist/{chunk-7R4O5CZD.js → chunk-AS7DIHZZ.js} +891 -722
- package/dist/chunk-AS7DIHZZ.js.map +1 -0
- package/dist/{chunk-OD5654VF.js → chunk-RAQBGOP5.js} +3 -3
- package/dist/{chunk-OD5654VF.js.map → chunk-RAQBGOP5.js.map} +1 -1
- package/dist/{chunk-DDQ5JGBV.js → chunk-ULAYELSU.js} +3 -3
- package/dist/{chunk-DDQ5JGBV.js.map → chunk-ULAYELSU.js.map} +1 -1
- package/dist/cli.js +245 -94
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/skills/vg/SKILL.md +29 -9
- package/dist/baseline-WIZAFIJS.js +0 -6
- package/dist/chunk-7R4O5CZD.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { resolveDsn, resolveIngestHost, dashHostForIngestHost, resolveCliInvocation, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, inventory, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, CliError, ExitCode, NPX_INVOCATION, refreshIfStale, driftCount, embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, recordCliCall, CLI_TOOL_ALIASES, countPending, resolveOne, indexFor, countTokens, shortestPath, renderReport, impactOf, testsToRun, detectRunner, defaultGraphPath, savingsLedgerPath, serveStdio, ASSISTANTS, detectAssistants, usageError, loadGraph, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, enrichOnline, ECOSYSTEMS, discoverModels, readSavings, readUsage, exportGraph, catalogPath, libDir, stableStringify, buildGraph, writeArtifacts, writeSnapshot, UsageError, ResourceLimitError, epistemicBreakdown, cacheDir, probeFreshness, discover, vibgrateDir, modelCacheInfo, clearModelCache, GraphSource, createServer, assistantById, serializeGraph, resolveLimits, loadCatalog, driftFor, addLibrary, parseDsn as parseDsn$1, publishPrivateLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, formatForExt, hostedBase, verifyDeterminism, renderHtml, isModelReady, SAVINGS_TOOLS, sanitizeClient, readStoredCredentials, projectCredentialsPath, homeCredentialsPath, SKIP_DIRS, SKIP_FILES } from './chunk-
|
|
2
|
+
import { resolveDsn, resolveIngestHost, dashHostForIngestHost, resolveCliInvocation, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, inventory, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, CliError, ExitCode, NPX_INVOCATION, refreshIfStale, driftCount, embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, recordCliCall, CLI_TOOL_ALIASES, countPending, resolveOne, indexFor, countTokens, shortestPath, renderReport, impactOf, testsToRun, detectRunner, defaultGraphPath, savingsLedgerPath, serveStdio, ASSISTANTS, detectAssistants, usageError, loadGraph, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, enrichOnline, ECOSYSTEMS, discoverModels, readSavings, readUsage, exportGraph, catalogPath, libDir, stableStringify, buildGraph, writeArtifacts, writeSnapshot, UsageError, ResourceLimitError, refreshInstalledInstructions, SMALL_REPO_FILES, epistemicBreakdown, cacheDir, probeFreshness, discover, vibgrateDir, modelCacheInfo, clearModelCache, GraphSource, createServer, assistantById, serializeGraph, resolveLimits, loadCatalog, driftFor, addLibrary, parseDsn as parseDsn$1, publishPrivateLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, formatForExt, hostedBase, verifyDeterminism, renderHtml, isModelReady, SAVINGS_TOOLS, sanitizeClient, readStoredCredentials, projectCredentialsPath, homeCredentialsPath, SKIP_DIRS, SKIP_FILES } from './chunk-AS7DIHZZ.js';
|
|
3
3
|
import { resolvedGrammarFiles, grammarSetVersion, hashString, canonicalize, hashBytes } from './chunk-BHA7QIPD.js';
|
|
4
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
5
|
-
import { ensureDir, pathExists, writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, readJsonFile, writeTextFile, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, brandProgressBar, resolveHead, workingTreeDirty } from './chunk-
|
|
4
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-ULAYELSU.js';
|
|
5
|
+
import { ensureDir, pathExists, writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, readJsonFile, writeTextFile, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, brandProgressBar, resolveHead, workingTreeDirty } from './chunk-RAQBGOP5.js';
|
|
6
6
|
import './chunk-RXP66R2E.js';
|
|
7
7
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-GI6W53LM.js';
|
|
8
|
-
import * as
|
|
9
|
-
import
|
|
8
|
+
import * as fs10 from 'fs';
|
|
9
|
+
import fs10__default, { realpathSync } from 'fs';
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import path__default from 'path';
|
|
12
12
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -16,7 +16,7 @@ import * as crypto from 'crypto';
|
|
|
16
16
|
import { randomUUID } from 'crypto';
|
|
17
17
|
import chalk8 from 'chalk';
|
|
18
18
|
import * as os from 'os';
|
|
19
|
-
import * as
|
|
19
|
+
import * as fs17 from 'fs/promises';
|
|
20
20
|
import * as readline from 'readline';
|
|
21
21
|
import semver from 'semver';
|
|
22
22
|
|
|
@@ -178,14 +178,14 @@ async function signGraphAttestation(root, graph, opts) {
|
|
|
178
178
|
const explicitKey = opts.key ?? process.env.VG_ATTEST_KEY;
|
|
179
179
|
const keyPath = explicitKey ? path.resolve(explicitKey) : path.join(root, ".vibgrate", DEFAULT_KEY);
|
|
180
180
|
let keyGeneratedAt;
|
|
181
|
-
if (!
|
|
181
|
+
if (!fs10.existsSync(keyPath)) {
|
|
182
182
|
if (explicitKey) {
|
|
183
183
|
throw new CliError(`signing key not found: ${explicitKey}`, ExitCode.USAGE_ERROR);
|
|
184
184
|
}
|
|
185
185
|
const kp = generateKeypair();
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
fs10.mkdirSync(path.dirname(keyPath), { recursive: true });
|
|
187
|
+
fs10.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
188
|
+
fs10.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
189
189
|
keyGeneratedAt = keyPath;
|
|
190
190
|
notices.push(
|
|
191
191
|
`minted a new Ed25519 signing key at ${rel(root, keyPath)} (keyid ${kp.keyid}) \u2014 keep it, add it to .gitignore, and reuse it to re-sign reproducibly`
|
|
@@ -193,7 +193,7 @@ async function signGraphAttestation(root, graph, opts) {
|
|
|
193
193
|
}
|
|
194
194
|
let privateKey;
|
|
195
195
|
try {
|
|
196
|
-
privateKey = crypto.createPrivateKey(
|
|
196
|
+
privateKey = crypto.createPrivateKey(fs10.readFileSync(keyPath, "utf8"));
|
|
197
197
|
} catch {
|
|
198
198
|
throw new CliError(`could not read an Ed25519 private key from ${rel(root, keyPath)}`, ExitCode.USAGE_ERROR);
|
|
199
199
|
}
|
|
@@ -207,8 +207,8 @@ async function signGraphAttestation(root, graph, opts) {
|
|
|
207
207
|
const statement = buildStatement(graph, { commit });
|
|
208
208
|
const envelope = signStatement(statement, privateKey);
|
|
209
209
|
const outPath = opts.attestation ? path.resolve(opts.attestation) : path.join(root, ".vibgrate", DEFAULT_ATTESTATION);
|
|
210
|
-
|
|
211
|
-
|
|
210
|
+
fs10.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
211
|
+
fs10.writeFileSync(outPath, serializeEnvelope(envelope));
|
|
212
212
|
return {
|
|
213
213
|
summary: {
|
|
214
214
|
keyid: envelope.signatures[0]?.keyid ?? "",
|
|
@@ -223,7 +223,7 @@ async function signGraphAttestation(root, graph, opts) {
|
|
|
223
223
|
}
|
|
224
224
|
function verifyGraphAttestation(root, opts) {
|
|
225
225
|
const bundlePath = opts.attestation ? path.resolve(opts.attestation) : path.join(root, ".vibgrate", DEFAULT_ATTESTATION);
|
|
226
|
-
if (!
|
|
226
|
+
if (!fs10.existsSync(bundlePath)) {
|
|
227
227
|
if (opts.attestation || opts.pub) {
|
|
228
228
|
throw new CliError(
|
|
229
229
|
`no attestation at ${rel(root, bundlePath)} \u2014 sign one with \`vg build --attest\``,
|
|
@@ -232,8 +232,8 @@ function verifyGraphAttestation(root, opts) {
|
|
|
232
232
|
}
|
|
233
233
|
return { bundlePath, missing: true };
|
|
234
234
|
}
|
|
235
|
-
const envelope = parseEnvelope(
|
|
236
|
-
const publicKeyPem = opts.pub ?
|
|
235
|
+
const envelope = parseEnvelope(fs10.readFileSync(bundlePath, "utf8"));
|
|
236
|
+
const publicKeyPem = opts.pub ? fs10.readFileSync(path.resolve(opts.pub), "utf8") : void 0;
|
|
237
237
|
const graph = loadGraph(root) ?? void 0;
|
|
238
238
|
return { bundlePath, missing: false, result: verifyEnvelope(envelope, { publicKeyPem, graph }) };
|
|
239
239
|
}
|
|
@@ -431,6 +431,15 @@ async function runBuild(paths, opts, global) {
|
|
|
431
431
|
});
|
|
432
432
|
}
|
|
433
433
|
if (opts.export) writeExport(result.graph, opts.export);
|
|
434
|
+
if (!global.graph) {
|
|
435
|
+
const fileCount = result.graph.nodes.filter((n) => n.kind === "file").length;
|
|
436
|
+
const refreshed = refreshInstalledInstructions(root, fileCount > 0 && fileCount < SMALL_REPO_FILES);
|
|
437
|
+
if (interactive) {
|
|
438
|
+
for (const r of refreshed) {
|
|
439
|
+
info(c.dim(`vg \xB7 refreshed assistant instructions ${r.file} (v${r.from} \u2192 v${r.to})`));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
434
443
|
let attestation;
|
|
435
444
|
const attestNotices = [];
|
|
436
445
|
if (opts.attest) {
|
|
@@ -586,8 +595,8 @@ function writeExport(graph, target) {
|
|
|
586
595
|
ExitCode.USAGE_ERROR
|
|
587
596
|
);
|
|
588
597
|
}
|
|
589
|
-
|
|
590
|
-
|
|
598
|
+
fs10.mkdirSync(path.dirname(path.resolve(target)), { recursive: true });
|
|
599
|
+
fs10.writeFileSync(target, content);
|
|
591
600
|
}
|
|
592
601
|
function collect(value, prev) {
|
|
593
602
|
return [...prev, value];
|
|
@@ -606,7 +615,7 @@ async function runStatus(global) {
|
|
|
606
615
|
const root = path.resolve(global.cwd ?? ".");
|
|
607
616
|
const graphPath = global.graph ?? defaultGraphPath(root);
|
|
608
617
|
const graph = loadGraph(root, graphPath);
|
|
609
|
-
const hasCache =
|
|
618
|
+
const hasCache = fs10.existsSync(path.join(cacheDir(root), "parse-cache.json"));
|
|
610
619
|
let stale = null;
|
|
611
620
|
let staleExact = false;
|
|
612
621
|
if (graph) {
|
|
@@ -1315,14 +1324,14 @@ function isCI(env = process.env) {
|
|
|
1315
1324
|
function installId(env = process.env) {
|
|
1316
1325
|
if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();
|
|
1317
1326
|
try {
|
|
1318
|
-
const existing =
|
|
1327
|
+
const existing = fs10.readFileSync(INSTALL_ID_FILE, "utf8").trim();
|
|
1319
1328
|
if (isUuid(existing)) return existing;
|
|
1320
1329
|
} catch {
|
|
1321
1330
|
}
|
|
1322
1331
|
const id = randomUuid();
|
|
1323
1332
|
try {
|
|
1324
|
-
|
|
1325
|
-
|
|
1333
|
+
fs10.mkdirSync(INSTALL_ID_DIR, { recursive: true });
|
|
1334
|
+
fs10.writeFileSync(INSTALL_ID_FILE, id + "\n", { mode: 384 });
|
|
1326
1335
|
} catch {
|
|
1327
1336
|
}
|
|
1328
1337
|
return id;
|
|
@@ -1346,7 +1355,7 @@ function ledgerFilePath(root) {
|
|
|
1346
1355
|
}
|
|
1347
1356
|
function readOffset(root) {
|
|
1348
1357
|
try {
|
|
1349
|
-
const raw = JSON.parse(
|
|
1358
|
+
const raw = JSON.parse(fs10.readFileSync(offsetPath(root), "utf8"));
|
|
1350
1359
|
return typeof raw.offset === "number" && raw.offset >= 0 ? raw.offset : 0;
|
|
1351
1360
|
} catch {
|
|
1352
1361
|
return 0;
|
|
@@ -1354,8 +1363,8 @@ function readOffset(root) {
|
|
|
1354
1363
|
}
|
|
1355
1364
|
function writeOffset(root, offset) {
|
|
1356
1365
|
try {
|
|
1357
|
-
|
|
1358
|
-
|
|
1366
|
+
fs10.mkdirSync(cacheDir(root), { recursive: true });
|
|
1367
|
+
fs10.writeFileSync(offsetPath(root), JSON.stringify({ offset }) + "\n");
|
|
1359
1368
|
} catch {
|
|
1360
1369
|
}
|
|
1361
1370
|
}
|
|
@@ -1363,7 +1372,7 @@ function buildBatch(root, fromOffset, id = installId()) {
|
|
|
1363
1372
|
const file = ledgerFilePath(root);
|
|
1364
1373
|
let size = 0;
|
|
1365
1374
|
try {
|
|
1366
|
-
size =
|
|
1375
|
+
size = fs10.statSync(file).size;
|
|
1367
1376
|
} catch {
|
|
1368
1377
|
return { batch: null, newOffset: 0 };
|
|
1369
1378
|
}
|
|
@@ -1371,13 +1380,13 @@ function buildBatch(root, fromOffset, id = installId()) {
|
|
|
1371
1380
|
if (start >= size) return { batch: null, newOffset: size };
|
|
1372
1381
|
let text = "";
|
|
1373
1382
|
try {
|
|
1374
|
-
const fd =
|
|
1383
|
+
const fd = fs10.openSync(file, "r");
|
|
1375
1384
|
try {
|
|
1376
1385
|
const buf = Buffer.alloc(size - start);
|
|
1377
|
-
|
|
1386
|
+
fs10.readSync(fd, buf, 0, buf.length, start);
|
|
1378
1387
|
text = buf.toString("utf8");
|
|
1379
1388
|
} finally {
|
|
1380
|
-
|
|
1389
|
+
fs10.closeSync(fd);
|
|
1381
1390
|
}
|
|
1382
1391
|
} catch {
|
|
1383
1392
|
return { batch: null, newOffset: fromOffset };
|
|
@@ -1509,6 +1518,139 @@ function isLoopbackOrigin(origin) {
|
|
|
1509
1518
|
if (host === "localhost" || host === "[::1]" || host === "::1") return true;
|
|
1510
1519
|
return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
1511
1520
|
}
|
|
1521
|
+
var PUBLISH_INTERVAL_MS = 2e3;
|
|
1522
|
+
var KEEPALIVE_MS = 1e4;
|
|
1523
|
+
var STALE_MS = 6e4;
|
|
1524
|
+
function liveStatsDir(root) {
|
|
1525
|
+
return path.join(cacheDir(root), "serve-live");
|
|
1526
|
+
}
|
|
1527
|
+
var LiveStatsBus = class {
|
|
1528
|
+
constructor(dir, stats, pid = process.pid) {
|
|
1529
|
+
this.dir = dir;
|
|
1530
|
+
this.stats = stats;
|
|
1531
|
+
this.pid = pid;
|
|
1532
|
+
this.file = path.join(dir, `serve-${this.pid}.json`);
|
|
1533
|
+
}
|
|
1534
|
+
dir;
|
|
1535
|
+
stats;
|
|
1536
|
+
pid;
|
|
1537
|
+
timer = null;
|
|
1538
|
+
lastRevision = -1;
|
|
1539
|
+
lastWriteAt = 0;
|
|
1540
|
+
file;
|
|
1541
|
+
start() {
|
|
1542
|
+
if (this.timer) return;
|
|
1543
|
+
this.publish();
|
|
1544
|
+
this.timer = setInterval(() => this.publish(), PUBLISH_INTERVAL_MS);
|
|
1545
|
+
this.timer.unref?.();
|
|
1546
|
+
process.on("exit", this.unlinkOwn);
|
|
1547
|
+
}
|
|
1548
|
+
stop() {
|
|
1549
|
+
if (this.timer) {
|
|
1550
|
+
clearInterval(this.timer);
|
|
1551
|
+
this.timer = null;
|
|
1552
|
+
}
|
|
1553
|
+
process.removeListener("exit", this.unlinkOwn);
|
|
1554
|
+
this.unlinkOwn();
|
|
1555
|
+
}
|
|
1556
|
+
/** Write the current snapshot when it changed (or as a keepalive). Never throws. */
|
|
1557
|
+
publish(now2 = Date.now()) {
|
|
1558
|
+
const snap = this.stats.snapshot();
|
|
1559
|
+
if (snap.revision === this.lastRevision && now2 - this.lastWriteAt < KEEPALIVE_MS) return;
|
|
1560
|
+
this.lastRevision = snap.revision;
|
|
1561
|
+
this.lastWriteAt = now2;
|
|
1562
|
+
const body = { pid: this.pid, updatedAt: now2, snapshot: snap };
|
|
1563
|
+
try {
|
|
1564
|
+
fs10.mkdirSync(this.dir, { recursive: true });
|
|
1565
|
+
const tmp = `${this.file}.tmp`;
|
|
1566
|
+
fs10.writeFileSync(tmp, JSON.stringify(body));
|
|
1567
|
+
fs10.renameSync(tmp, this.file);
|
|
1568
|
+
} catch {
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Fresh snapshots of the OTHER serve processes in this repo. Stale files
|
|
1573
|
+
* (crashed processes) are swept best-effort while reading.
|
|
1574
|
+
*/
|
|
1575
|
+
siblings(now2 = Date.now()) {
|
|
1576
|
+
let entries;
|
|
1577
|
+
try {
|
|
1578
|
+
entries = fs10.readdirSync(this.dir);
|
|
1579
|
+
} catch {
|
|
1580
|
+
return [];
|
|
1581
|
+
}
|
|
1582
|
+
const out2 = [];
|
|
1583
|
+
for (const name of entries.sort()) {
|
|
1584
|
+
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1585
|
+
const file = path.join(this.dir, name);
|
|
1586
|
+
let parsed;
|
|
1587
|
+
try {
|
|
1588
|
+
parsed = JSON.parse(fs10.readFileSync(file, "utf8"));
|
|
1589
|
+
} catch {
|
|
1590
|
+
continue;
|
|
1591
|
+
}
|
|
1592
|
+
if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
|
|
1593
|
+
if (now2 - parsed.updatedAt > STALE_MS) {
|
|
1594
|
+
try {
|
|
1595
|
+
fs10.unlinkSync(file);
|
|
1596
|
+
} catch {
|
|
1597
|
+
}
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1600
|
+
if (parsed.pid === this.pid) continue;
|
|
1601
|
+
out2.push(parsed.snapshot);
|
|
1602
|
+
}
|
|
1603
|
+
return out2;
|
|
1604
|
+
}
|
|
1605
|
+
unlinkOwn = () => {
|
|
1606
|
+
try {
|
|
1607
|
+
fs10.unlinkSync(this.file);
|
|
1608
|
+
} catch {
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
};
|
|
1612
|
+
function addInto(target, add) {
|
|
1613
|
+
target.calls += add.calls;
|
|
1614
|
+
target.complete += add.complete;
|
|
1615
|
+
target.partial += add.partial;
|
|
1616
|
+
target.miss += add.miss;
|
|
1617
|
+
target.timed += add.timed;
|
|
1618
|
+
target.totalMs += add.totalMs;
|
|
1619
|
+
target.vgTokens += add.vgTokens;
|
|
1620
|
+
target.baselineTokens += add.baselineTokens;
|
|
1621
|
+
}
|
|
1622
|
+
function mergeRows(base, extra) {
|
|
1623
|
+
const byKey = new Map(base.map((r) => [r.key, { ...r }]));
|
|
1624
|
+
for (const row of extra) {
|
|
1625
|
+
const hit = byKey.get(row.key);
|
|
1626
|
+
if (hit) addInto(hit, row);
|
|
1627
|
+
else byKey.set(row.key, { ...row });
|
|
1628
|
+
}
|
|
1629
|
+
return [...byKey.values()].sort((a, b) => b.calls - a.calls || a.key.localeCompare(b.key));
|
|
1630
|
+
}
|
|
1631
|
+
function mergeSnapshots(own, siblings) {
|
|
1632
|
+
if (!siblings.length) return own;
|
|
1633
|
+
const merged = {
|
|
1634
|
+
startedAt: own.startedAt,
|
|
1635
|
+
revision: own.revision,
|
|
1636
|
+
lastCallAt: own.lastCallAt,
|
|
1637
|
+
totals: { ...own.totals },
|
|
1638
|
+
clients: [...own.clients.map((r) => ({ ...r }))],
|
|
1639
|
+
tools: [...own.tools.map((r) => ({ ...r }))],
|
|
1640
|
+
sources: [...own.sources.map((r) => ({ ...r }))]
|
|
1641
|
+
};
|
|
1642
|
+
for (const s of siblings) {
|
|
1643
|
+
merged.revision += s.revision;
|
|
1644
|
+
if (s.lastCallAt !== null && (merged.lastCallAt === null || s.lastCallAt > merged.lastCallAt)) {
|
|
1645
|
+
merged.lastCallAt = s.lastCallAt;
|
|
1646
|
+
}
|
|
1647
|
+
addInto(merged.totals, s.totals);
|
|
1648
|
+
merged.clients = mergeRows(merged.clients, s.clients);
|
|
1649
|
+
merged.tools = mergeRows(merged.tools, s.tools);
|
|
1650
|
+
merged.sources = mergeRows(merged.sources, s.sources);
|
|
1651
|
+
}
|
|
1652
|
+
return merged;
|
|
1653
|
+
}
|
|
1512
1654
|
|
|
1513
1655
|
// src/mcp/serve-stats.ts
|
|
1514
1656
|
function zeroRow(key2) {
|
|
@@ -1590,14 +1732,16 @@ var teal2 = (s) => c.hex("#3FB0A4")(s);
|
|
|
1590
1732
|
var mint2 = (s) => c.hex("#4FE3C1")(s);
|
|
1591
1733
|
var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1592
1734
|
var MAX_TOOL_ROWS = 8;
|
|
1593
|
-
function serveStatusLines(snap, now2, tick = 0) {
|
|
1735
|
+
function serveStatusLines(snap, now2, tick = 0, siblingServers = 0) {
|
|
1594
1736
|
const spinner = mint2(SPINNER[tick % SPINNER.length]);
|
|
1595
1737
|
const up = fmtUptime(now2 - snap.startedAt);
|
|
1596
1738
|
const lines = [];
|
|
1739
|
+
const siblingNote = siblingServers > 0 ? ` ${c.dim(`incl. ${siblingServers} assistant-spawned server${siblingServers === 1 ? "" : "s"} in this repo`)}` : null;
|
|
1597
1740
|
if (snap.totals.calls === 0) {
|
|
1598
1741
|
lines.push(
|
|
1599
1742
|
` ${spinner} ${c.bold.white("vg serve")} ${c.dim("\xB7")} up ${teal2(up)} ${c.dim("\xB7 waiting for your assistant\u2019s first call (MCP tool call, or `vg \u2026 --client=<ai>` CLI)\u2026")}`
|
|
1600
1743
|
);
|
|
1744
|
+
if (siblingNote) lines.push(siblingNote);
|
|
1601
1745
|
return lines;
|
|
1602
1746
|
}
|
|
1603
1747
|
const t = snap.totals;
|
|
@@ -1634,6 +1778,7 @@ function serveStatusLines(snap, now2, tick = 0) {
|
|
|
1634
1778
|
` ${c.dim("est. saved \u2248")} ${mint2(`${fmtTokens(savedTokens)} context tokens`)} ${c.dim("(estimate)")}`
|
|
1635
1779
|
);
|
|
1636
1780
|
}
|
|
1781
|
+
if (siblingNote) lines.push(siblingNote);
|
|
1637
1782
|
return lines;
|
|
1638
1783
|
}
|
|
1639
1784
|
function serveHeartbeatLine(snap, now2) {
|
|
@@ -1653,13 +1798,15 @@ function serveHeartbeatLine(snap, now2) {
|
|
|
1653
1798
|
var TTY_INTERVAL_MS = 1e3;
|
|
1654
1799
|
var HEARTBEAT_INTERVAL_MS = 15 * 60 * 1e3;
|
|
1655
1800
|
var ServeStatusDisplay = class {
|
|
1656
|
-
constructor(stats, stream = process.stderr) {
|
|
1801
|
+
constructor(stats, stream = process.stderr, siblings) {
|
|
1657
1802
|
this.stats = stats;
|
|
1658
1803
|
this.stream = stream;
|
|
1804
|
+
this.siblings = siblings;
|
|
1659
1805
|
this.isTTY = (stream.isTTY ?? false) && process.env.VIBGRATE_PROGRESS_MODE !== "plain";
|
|
1660
1806
|
}
|
|
1661
1807
|
stats;
|
|
1662
1808
|
stream;
|
|
1809
|
+
siblings;
|
|
1663
1810
|
timer = null;
|
|
1664
1811
|
tick = 0;
|
|
1665
1812
|
lastRowCount = 0;
|
|
@@ -1702,7 +1849,9 @@ var ServeStatusDisplay = class {
|
|
|
1702
1849
|
}
|
|
1703
1850
|
renderTTY() {
|
|
1704
1851
|
this.tick++;
|
|
1705
|
-
const
|
|
1852
|
+
const sibs = this.siblings?.() ?? [];
|
|
1853
|
+
const snap = mergeSnapshots(this.stats.snapshot(), sibs);
|
|
1854
|
+
const lines = serveStatusLines(snap, Date.now(), this.tick, sibs.length);
|
|
1706
1855
|
const content = lines.join("\n") + "\n";
|
|
1707
1856
|
if (content === this.lastFrame) return;
|
|
1708
1857
|
this.lastFrame = content;
|
|
@@ -1774,12 +1923,12 @@ var LedgerTail = class {
|
|
|
1774
1923
|
if (size === this.offset) return;
|
|
1775
1924
|
let chunk;
|
|
1776
1925
|
try {
|
|
1777
|
-
const fd =
|
|
1926
|
+
const fd = fs10.openSync(this.file, "r");
|
|
1778
1927
|
try {
|
|
1779
1928
|
chunk = Buffer.alloc(size - this.offset);
|
|
1780
|
-
|
|
1929
|
+
fs10.readSync(fd, chunk, 0, chunk.length, this.offset);
|
|
1781
1930
|
} finally {
|
|
1782
|
-
|
|
1931
|
+
fs10.closeSync(fd);
|
|
1783
1932
|
}
|
|
1784
1933
|
} catch {
|
|
1785
1934
|
return;
|
|
@@ -1792,7 +1941,7 @@ var LedgerTail = class {
|
|
|
1792
1941
|
}
|
|
1793
1942
|
sizeOf() {
|
|
1794
1943
|
try {
|
|
1795
|
-
return
|
|
1944
|
+
return fs10.statSync(this.file).size;
|
|
1796
1945
|
} catch {
|
|
1797
1946
|
return 0;
|
|
1798
1947
|
}
|
|
@@ -1856,8 +2005,11 @@ function registerServe(program) {
|
|
|
1856
2005
|
info(c.dim(`vg \xB7 --share-stats disabled by ${optOut}: recording locally, not uploading.`));
|
|
1857
2006
|
}
|
|
1858
2007
|
if (shareStats) startSharing(root);
|
|
1859
|
-
const
|
|
1860
|
-
|
|
2008
|
+
const interactive = process.stderr.isTTY === true;
|
|
2009
|
+
const bus = stats ? new LiveStatsBus(liveStatsDir(root), stats) : void 0;
|
|
2010
|
+
if (bus && !interactive) bus.start();
|
|
2011
|
+
const display = stats ? new ServeStatusDisplay(stats, process.stderr, bus && interactive ? () => bus.siblings() : void 0) : void 0;
|
|
2012
|
+
if (stats && interactive) new LedgerTail(savingsLedgerPath(root), stats).start();
|
|
1861
2013
|
const freshness = refresh ? "auto-refresh" : "as built";
|
|
1862
2014
|
if (opts.http) {
|
|
1863
2015
|
await serveHttp(graphPath, opts.host ?? "127.0.0.1", Number(opts.port) || 7437, serveOpts, freshness, () => display?.start());
|
|
@@ -1871,7 +2023,7 @@ function registerServe(program) {
|
|
|
1871
2023
|
}
|
|
1872
2024
|
async function ensureServableGraph(root, graphPath, global, refresh, opts = {}) {
|
|
1873
2025
|
if (refresh) {
|
|
1874
|
-
if (!
|
|
2026
|
+
if (!fs10.existsSync(graphPath)) {
|
|
1875
2027
|
info(c.dim("vg \xB7 no map found \u2014 building it before serving\u2026"));
|
|
1876
2028
|
await runBuild(
|
|
1877
2029
|
[],
|
|
@@ -1888,7 +2040,7 @@ async function ensureServableGraph(root, graphPath, global, refresh, opts = {})
|
|
|
1888
2040
|
}
|
|
1889
2041
|
}
|
|
1890
2042
|
}
|
|
1891
|
-
if (!
|
|
2043
|
+
if (!fs10.existsSync(graphPath)) {
|
|
1892
2044
|
throw new CliError(
|
|
1893
2045
|
`no map found at ${graphPath} \u2014 run \`vg\` to build one first`,
|
|
1894
2046
|
ExitCode.NOT_FOUND
|
|
@@ -2171,7 +2323,7 @@ function manifestHash(root) {
|
|
|
2171
2323
|
const walk2 = (dir) => {
|
|
2172
2324
|
let entries;
|
|
2173
2325
|
try {
|
|
2174
|
-
entries =
|
|
2326
|
+
entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
2175
2327
|
} catch {
|
|
2176
2328
|
return;
|
|
2177
2329
|
}
|
|
@@ -2187,7 +2339,7 @@ function manifestHash(root) {
|
|
|
2187
2339
|
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
2188
2340
|
try {
|
|
2189
2341
|
const rel3 = path.relative(root, abs).split(path.sep).join("/");
|
|
2190
|
-
files.push({ rel: rel3, hash: hashBytes(
|
|
2342
|
+
files.push({ rel: rel3, hash: hashBytes(fs10.readFileSync(abs)) });
|
|
2191
2343
|
} catch {
|
|
2192
2344
|
}
|
|
2193
2345
|
}
|
|
@@ -2198,7 +2350,7 @@ function manifestHash(root) {
|
|
|
2198
2350
|
}
|
|
2199
2351
|
function loadScanCache(root, key2) {
|
|
2200
2352
|
try {
|
|
2201
|
-
const raw = JSON.parse(
|
|
2353
|
+
const raw = JSON.parse(fs10.readFileSync(cachePath(root), "utf8"));
|
|
2202
2354
|
if (raw.version === CACHE_VERSION && raw.manifestHash === key2.manifestHash && raw.toolVersion === key2.toolVersion && raw.offline === key2.offline && raw.artifact) {
|
|
2203
2355
|
return { manifestHash: raw.manifestHash, artifact: raw.artifact };
|
|
2204
2356
|
}
|
|
@@ -2208,8 +2360,8 @@ function loadScanCache(root, key2) {
|
|
|
2208
2360
|
}
|
|
2209
2361
|
function writeScanCache(root, key2, artifact) {
|
|
2210
2362
|
try {
|
|
2211
|
-
|
|
2212
|
-
|
|
2363
|
+
fs10.mkdirSync(cacheDir(root), { recursive: true });
|
|
2364
|
+
fs10.writeFileSync(
|
|
2213
2365
|
cachePath(root),
|
|
2214
2366
|
stableStringify(
|
|
2215
2367
|
{ version: CACHE_VERSION, manifestHash: key2.manifestHash, toolVersion: key2.toolVersion, offline: key2.offline, artifact },
|
|
@@ -3033,7 +3185,7 @@ function hoverMarkdown(dep, contribution) {
|
|
|
3033
3185
|
return lines.join("\n");
|
|
3034
3186
|
}
|
|
3035
3187
|
function startLanguageServer(opts) {
|
|
3036
|
-
if (!
|
|
3188
|
+
if (!fs10.existsSync(opts.root)) {
|
|
3037
3189
|
process.stderr.write(`vg lsp: root does not exist: ${opts.root}
|
|
3038
3190
|
`);
|
|
3039
3191
|
process.exit(1);
|
|
@@ -3077,7 +3229,6 @@ function registerLsp(program) {
|
|
|
3077
3229
|
}
|
|
3078
3230
|
|
|
3079
3231
|
// src/commands/install.ts
|
|
3080
|
-
var SMALL_REPO_FILES = 150;
|
|
3081
3232
|
function registerInstall(program) {
|
|
3082
3233
|
const install = program.command("install").description("add vg to your AI assistant(s): skill + MCP + advisory nudge").argument("[tools...]", `assistant ids: ${ASSISTANTS.map((a) => a.id).join(", ")}`).option("--all", "install for every supported assistant").option("--detect", "detect assistants in use (repo footprint, home config, PATH) and install for those; with --list, only report what was detected").option("--list", "show the support matrix and exit").option("--no-hook", "skip the advisory nudge").action(function(tools, opts) {
|
|
3083
3234
|
const global = readGlobal(this);
|
|
@@ -3172,7 +3323,7 @@ function registerShare(program) {
|
|
|
3172
3323
|
const global = readGlobal(this);
|
|
3173
3324
|
const root = rootOf(global);
|
|
3174
3325
|
const gitDir = path.join(root, ".git");
|
|
3175
|
-
if (!
|
|
3326
|
+
if (!fs10.existsSync(gitDir)) {
|
|
3176
3327
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
3177
3328
|
}
|
|
3178
3329
|
if (opts.undo) {
|
|
@@ -3194,22 +3345,22 @@ function registerShare(program) {
|
|
|
3194
3345
|
}
|
|
3195
3346
|
function writeVibgrateGitignore(root, reports) {
|
|
3196
3347
|
const dir = path.join(root, ".vibgrate");
|
|
3197
|
-
|
|
3348
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
3198
3349
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl"];
|
|
3199
3350
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
3200
|
-
|
|
3351
|
+
fs10.writeFileSync(path.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
3201
3352
|
`);
|
|
3202
3353
|
}
|
|
3203
3354
|
function writeGitAttributes(root) {
|
|
3204
3355
|
const file = path.join(root, ".gitattributes");
|
|
3205
3356
|
const line = ".vibgrate/graph.json merge=vg";
|
|
3206
|
-
let content =
|
|
3357
|
+
let content = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
3207
3358
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
3208
3359
|
content = content.length ? `${content.replace(/\s*$/, "")}
|
|
3209
3360
|
${line}
|
|
3210
3361
|
` : `${line}
|
|
3211
3362
|
`;
|
|
3212
|
-
|
|
3363
|
+
fs10.writeFileSync(file, content);
|
|
3213
3364
|
}
|
|
3214
3365
|
}
|
|
3215
3366
|
function configureMergeDriver(root) {
|
|
@@ -3218,7 +3369,7 @@ function configureMergeDriver(root) {
|
|
|
3218
3369
|
}
|
|
3219
3370
|
function installPreCommitHook(root) {
|
|
3220
3371
|
const hooksDir = hookDir(root);
|
|
3221
|
-
|
|
3372
|
+
fs10.mkdirSync(hooksDir, { recursive: true });
|
|
3222
3373
|
const file = path.join(hooksDir, "pre-commit");
|
|
3223
3374
|
const block = [
|
|
3224
3375
|
HOOK_BEGIN,
|
|
@@ -3228,7 +3379,7 @@ function installPreCommitHook(root) {
|
|
|
3228
3379
|
"fi",
|
|
3229
3380
|
HOOK_END
|
|
3230
3381
|
].join("\n");
|
|
3231
|
-
let content =
|
|
3382
|
+
let content = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "#!/bin/sh\n";
|
|
3232
3383
|
const re = new RegExp(`${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}`);
|
|
3233
3384
|
if (re.test(content)) content = content.replace(re, block);
|
|
3234
3385
|
else content = `${content.replace(/\s*$/, "")}
|
|
@@ -3237,21 +3388,21 @@ ${block}
|
|
|
3237
3388
|
`;
|
|
3238
3389
|
if (!content.startsWith("#!")) content = `#!/bin/sh
|
|
3239
3390
|
${content}`;
|
|
3240
|
-
|
|
3241
|
-
|
|
3391
|
+
fs10.writeFileSync(file, content);
|
|
3392
|
+
fs10.chmodSync(file, 493);
|
|
3242
3393
|
}
|
|
3243
3394
|
function undo(root) {
|
|
3244
3395
|
const hookFile = path.join(hookDir(root), "pre-commit");
|
|
3245
|
-
if (
|
|
3396
|
+
if (fs10.existsSync(hookFile)) {
|
|
3246
3397
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
3247
|
-
const next2 =
|
|
3248
|
-
if (next2.trim() === "#!/bin/sh")
|
|
3249
|
-
else
|
|
3398
|
+
const next2 = fs10.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
3399
|
+
if (next2.trim() === "#!/bin/sh") fs10.rmSync(hookFile);
|
|
3400
|
+
else fs10.writeFileSync(hookFile, next2);
|
|
3250
3401
|
}
|
|
3251
3402
|
const attr = path.join(root, ".gitattributes");
|
|
3252
|
-
if (
|
|
3253
|
-
const next2 =
|
|
3254
|
-
|
|
3403
|
+
if (fs10.existsSync(attr)) {
|
|
3404
|
+
const next2 = fs10.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
3405
|
+
fs10.writeFileSync(attr, next2);
|
|
3255
3406
|
}
|
|
3256
3407
|
try {
|
|
3257
3408
|
git(root, ["config", "--remove-section", "merge.vg"]);
|
|
@@ -3384,7 +3535,7 @@ function grepBaselineTokens(term, files) {
|
|
|
3384
3535
|
if (f.size > 512 * 1024) continue;
|
|
3385
3536
|
let content = "";
|
|
3386
3537
|
try {
|
|
3387
|
-
content =
|
|
3538
|
+
content = fs10.readFileSync(f.abs, "utf8");
|
|
3388
3539
|
} catch {
|
|
3389
3540
|
continue;
|
|
3390
3541
|
}
|
|
@@ -3394,7 +3545,7 @@ function grepBaselineTokens(term, files) {
|
|
|
3394
3545
|
}
|
|
3395
3546
|
function safeSize(abs) {
|
|
3396
3547
|
try {
|
|
3397
|
-
return
|
|
3548
|
+
return fs10.statSync(abs).size;
|
|
3398
3549
|
} catch {
|
|
3399
3550
|
return 0;
|
|
3400
3551
|
}
|
|
@@ -3728,7 +3879,7 @@ function loadStandards(root) {
|
|
|
3728
3879
|
const p = path__default.join(root, rel3);
|
|
3729
3880
|
let text;
|
|
3730
3881
|
try {
|
|
3731
|
-
text =
|
|
3882
|
+
text = fs10__default.readFileSync(p, "utf8");
|
|
3732
3883
|
} catch {
|
|
3733
3884
|
continue;
|
|
3734
3885
|
}
|
|
@@ -3967,7 +4118,7 @@ async function addCmd(root, rest, opts, asJson) {
|
|
|
3967
4118
|
}
|
|
3968
4119
|
function readPackageVersion(root) {
|
|
3969
4120
|
try {
|
|
3970
|
-
const pkg = JSON.parse(
|
|
4121
|
+
const pkg = JSON.parse(fs10__default.readFileSync(path__default.join(root, "package.json"), "utf8"));
|
|
3971
4122
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
3972
4123
|
} catch {
|
|
3973
4124
|
return void 0;
|
|
@@ -3975,7 +4126,7 @@ function readPackageVersion(root) {
|
|
|
3975
4126
|
}
|
|
3976
4127
|
function readOptionalFile(p) {
|
|
3977
4128
|
try {
|
|
3978
|
-
const t =
|
|
4129
|
+
const t = fs10__default.readFileSync(p, "utf8");
|
|
3979
4130
|
return t.trim() ? t : void 0;
|
|
3980
4131
|
} catch {
|
|
3981
4132
|
return void 0;
|
|
@@ -4121,8 +4272,8 @@ function registerExport(program) {
|
|
|
4121
4272
|
out(content.trimEnd());
|
|
4122
4273
|
return;
|
|
4123
4274
|
}
|
|
4124
|
-
|
|
4125
|
-
|
|
4275
|
+
fs10.mkdirSync(path.dirname(path.resolve(file)), { recursive: true });
|
|
4276
|
+
fs10.writeFileSync(file, content);
|
|
4126
4277
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
4127
4278
|
});
|
|
4128
4279
|
applyGlobalOptions(cmd);
|
|
@@ -4145,24 +4296,24 @@ function registerBundle(program) {
|
|
|
4145
4296
|
} catch {
|
|
4146
4297
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
4147
4298
|
}
|
|
4148
|
-
|
|
4299
|
+
fs10.mkdirSync(path.join(outDir, "grammars"), { recursive: true });
|
|
4149
4300
|
let grammarCount = 0;
|
|
4150
4301
|
for (const { fileName, absPath } of grammarFiles) {
|
|
4151
|
-
|
|
4302
|
+
fs10.copyFileSync(absPath, path.join(outDir, "grammars", fileName));
|
|
4152
4303
|
grammarCount++;
|
|
4153
4304
|
}
|
|
4154
4305
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
4155
4306
|
const graphSrc = global.graph ?? defaultGraphPath(root);
|
|
4156
|
-
if (
|
|
4157
|
-
|
|
4307
|
+
if (fs10.existsSync(graphSrc)) {
|
|
4308
|
+
fs10.copyFileSync(graphSrc, path.join(outDir, "graph.json"));
|
|
4158
4309
|
included.push("graph.json");
|
|
4159
4310
|
}
|
|
4160
4311
|
const cat = catalogPath(root);
|
|
4161
|
-
if (
|
|
4162
|
-
|
|
4312
|
+
if (fs10.existsSync(cat)) {
|
|
4313
|
+
fs10.copyFileSync(cat, path.join(outDir, "vibgrate.lib.json"));
|
|
4163
4314
|
included.push("vibgrate.lib.json");
|
|
4164
|
-
if (
|
|
4165
|
-
|
|
4315
|
+
if (fs10.existsSync(libDir(root))) {
|
|
4316
|
+
fs10.cpSync(libDir(root), path.join(outDir, "lib"), { recursive: true });
|
|
4166
4317
|
included.push("lib/");
|
|
4167
4318
|
}
|
|
4168
4319
|
}
|
|
@@ -4174,7 +4325,7 @@ function registerBundle(program) {
|
|
|
4174
4325
|
included,
|
|
4175
4326
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
4176
4327
|
};
|
|
4177
|
-
|
|
4328
|
+
fs10.writeFileSync(path.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
4178
4329
|
`);
|
|
4179
4330
|
if (global.json) {
|
|
4180
4331
|
json({ out: path.relative(root, outDir), ...manifest });
|
|
@@ -4198,7 +4349,7 @@ async function runDoctor(global) {
|
|
|
4198
4349
|
const root = rootOf(global);
|
|
4199
4350
|
const local = global.local === true;
|
|
4200
4351
|
const graphPath = global.graph ?? defaultGraphPath(root);
|
|
4201
|
-
const configFile = CONFIG_BASENAMES.find((f) =>
|
|
4352
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs10.existsSync(path.join(root, f))) ?? null;
|
|
4202
4353
|
const graph = loadGraph(root, graphPath);
|
|
4203
4354
|
let staleFiles = null;
|
|
4204
4355
|
if (graph) {
|
|
@@ -4226,7 +4377,7 @@ async function runDoctor(global) {
|
|
|
4226
4377
|
},
|
|
4227
4378
|
libCatalog: {
|
|
4228
4379
|
path: path.relative(root, catalogPath(root)),
|
|
4229
|
-
present:
|
|
4380
|
+
present: fs10.existsSync(catalogPath(root)),
|
|
4230
4381
|
libraries: libCount
|
|
4231
4382
|
},
|
|
4232
4383
|
credentials: creds,
|
|
@@ -4318,7 +4469,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
4318
4469
|
console.log(chalk8.green("\u2714") + ` Created ${chalk8.bold("vibgrate.config.ts")}`);
|
|
4319
4470
|
}
|
|
4320
4471
|
if (opts.baseline) {
|
|
4321
|
-
const { runBaseline } = await import('./baseline-
|
|
4472
|
+
const { runBaseline } = await import('./baseline-YJT32DP2.js');
|
|
4322
4473
|
await runBaseline(rootDir);
|
|
4323
4474
|
}
|
|
4324
4475
|
console.log("");
|
|
@@ -4428,9 +4579,9 @@ async function fileReferencesIdentifier(rootDir, relFile, identifier, readFile3)
|
|
|
4428
4579
|
}
|
|
4429
4580
|
async function defaultReadFile(absPath) {
|
|
4430
4581
|
try {
|
|
4431
|
-
const stat2 = await
|
|
4582
|
+
const stat2 = await fs17.stat(absPath);
|
|
4432
4583
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
4433
|
-
return await
|
|
4584
|
+
return await fs17.readFile(absPath, "utf8");
|
|
4434
4585
|
} catch {
|
|
4435
4586
|
return null;
|
|
4436
4587
|
}
|
|
@@ -5075,7 +5226,7 @@ var SKIP_DIRS2 = /* @__PURE__ */ new Set([
|
|
|
5075
5226
|
function scanStaleness(rootDir, artifactPath) {
|
|
5076
5227
|
let ref;
|
|
5077
5228
|
try {
|
|
5078
|
-
ref =
|
|
5229
|
+
ref = fs10.statSync(artifactPath).mtimeMs;
|
|
5079
5230
|
} catch {
|
|
5080
5231
|
return { stale: false };
|
|
5081
5232
|
}
|
|
@@ -5087,7 +5238,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
5087
5238
|
if (depth > 8 || scanned > MAX_ENTRIES) return;
|
|
5088
5239
|
let entries;
|
|
5089
5240
|
try {
|
|
5090
|
-
entries =
|
|
5241
|
+
entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
5091
5242
|
} catch {
|
|
5092
5243
|
return;
|
|
5093
5244
|
}
|
|
@@ -5102,7 +5253,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
5102
5253
|
const abs = path.join(dir, e.name);
|
|
5103
5254
|
let mtimeMs;
|
|
5104
5255
|
try {
|
|
5105
|
-
mtimeMs =
|
|
5256
|
+
mtimeMs = fs10.statSync(abs).mtimeMs;
|
|
5106
5257
|
} catch {
|
|
5107
5258
|
continue;
|
|
5108
5259
|
}
|
|
@@ -5236,7 +5387,7 @@ function analyzeTree(root, packages) {
|
|
|
5236
5387
|
if (depth > MAX_DEPTH || filesSeen >= MAX_FILES) return;
|
|
5237
5388
|
let entries;
|
|
5238
5389
|
try {
|
|
5239
|
-
entries =
|
|
5390
|
+
entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
5240
5391
|
} catch {
|
|
5241
5392
|
return;
|
|
5242
5393
|
}
|
|
@@ -5254,8 +5405,8 @@ function analyzeTree(root, packages) {
|
|
|
5254
5405
|
const full = path.join(dir, entry.name);
|
|
5255
5406
|
let content;
|
|
5256
5407
|
try {
|
|
5257
|
-
if (
|
|
5258
|
-
content =
|
|
5408
|
+
if (fs10.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
5409
|
+
content = fs10.readFileSync(full, "utf8");
|
|
5259
5410
|
} catch {
|
|
5260
5411
|
continue;
|
|
5261
5412
|
}
|
|
@@ -5623,8 +5774,8 @@ async function fetchLatestVersion() {
|
|
|
5623
5774
|
}
|
|
5624
5775
|
async function writeCache(data) {
|
|
5625
5776
|
try {
|
|
5626
|
-
await
|
|
5627
|
-
await
|
|
5777
|
+
await fs17.mkdir(CACHE_DIR, { recursive: true });
|
|
5778
|
+
await fs17.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
5628
5779
|
} catch {
|
|
5629
5780
|
}
|
|
5630
5781
|
}
|
|
@@ -5635,7 +5786,7 @@ function detectGlobalInstall(execPath = process.argv[1] || "", cwd = process.cwd
|
|
|
5635
5786
|
if (!execPath) return null;
|
|
5636
5787
|
let resolved = execPath;
|
|
5637
5788
|
try {
|
|
5638
|
-
resolved =
|
|
5789
|
+
resolved = fs10.realpathSync(execPath);
|
|
5639
5790
|
} catch {
|
|
5640
5791
|
}
|
|
5641
5792
|
const p = resolved.replace(/\\/g, "/");
|
|
@@ -7575,7 +7726,7 @@ function dispatch(argv, cwd) {
|
|
|
7575
7726
|
}
|
|
7576
7727
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
7577
7728
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
7578
|
-
if (
|
|
7729
|
+
if (fs10.existsSync(path.resolve(cwd, first))) {
|
|
7579
7730
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
7580
7731
|
}
|
|
7581
7732
|
const moved = MOVED_COMMANDS[first];
|